From 589cec66e1477b1cb944c46f80bf968f1b1c4aa6 Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Wed, 3 Jul 2019 12:29:17 +0200 Subject: [PATCH 01/11] Refactor doc files to match format generated by sphinx-quickstart --- docs/Makefile | 3 +- docs/conf.py | 161 ++++++++++++++++++++++++++++++-------------------- docs/make.bat | 11 ++-- 3 files changed, 104 insertions(+), 71 deletions(-) diff --git a/docs/Makefile b/docs/Makefile index f343705..5128596 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -3,8 +3,7 @@ # You can set these variables from the command line. SPHINXOPTS = -SPHINXBUILD = python3.6 -msphinx -SPHINXPROJ = fbchat +SPHINXBUILD = sphinx-build SOURCEDIR = . BUILDDIR = _build diff --git a/docs/conf.py b/docs/conf.py index f2763f1..1faae77 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -1,21 +1,12 @@ -#!/usr/bin/env python3 # -*- coding: utf-8 -*- # -# fbchat documentation build configuration file, created by -# sphinx-quickstart on Thu May 25 15:43:01 2017. +# Configuration file for the Sphinx documentation builder. # -# This file is execfile()d with the current directory set to its -# containing dir. -# -# Note that not all possible configuration values are present in this -# autogenerated file. -# -# All configuration values have a default; values that are commented out -# serve to show the default. +# This file does only contain a selection of the most common options. For a +# full list see the documentation: +# http://www.sphinx-doc.org/en/master/config -# If extensions (or modules to document with autodoc) are in another directory, -# add these directories to sys.path here. If the directory is relative to the -# documentation root, use os.path.abspath to make it absolute, like shown here. +# -- Path setup -------------------------------------------------------------- import os import sys @@ -23,11 +14,20 @@ import sys sys.path.insert(0, os.path.abspath("..")) import fbchat -import tests -from fbchat import __copyright__, __author__, __version__, __description__ + +# -- Project information ----------------------------------------------------- + +project = fbchat.__name__ +copyright = fbchat.__copyright__ +author = fbchat.__author__ + +# The short X.Y version +version = fbchat.__version__ +# The full version, including alpha/beta/rc tags +release = fbchat.__version__ -# -- General configuration ------------------------------------------------ +# -- General configuration --------------------------------------------------- # If your documentation needs a minimal Sphinx version, state it here. # @@ -55,22 +55,6 @@ source_suffix = ".rst" # The master toctree document. master_doc = "index" -# General information about the project. -project = "fbchat" -title = "fbchat Documentation" -copyright = __copyright__ -author = __author__ -description = __description__ - -# The version info for the project you're documenting, acts as replacement for -# |version| and |release|, also used in various other places throughout the -# built documents. -# -# The short X.Y version. -version = __version__ -# The full version, including alpha/beta/rc tags. -release = __version__ - # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. # @@ -80,43 +64,71 @@ language = None # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. -# This patterns also effect to html_static_path and html_extra_path +# This pattern also affects html_static_path and html_extra_path. exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"] +# If true, '()' will be appended to :func: etc. cross-reference text. +# +add_function_parentheses = False + # The name of the Pygments (syntax highlighting) style to use. -pygments_style = "sphinx" - -# If true, `todo` and `todoList` produce output, else they produce nothing. -todo_include_todos = True +pygments_style = None -# -- Options for HTML output ---------------------------------------------- +# -- Options for HTML output ------------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. # - html_theme = "alabaster" # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. # -# html_theme_options = {} +html_theme_options = { + "show_powered_by": False, + "github_user": "carpedm20", + "github_repo": project, + "github_banner": True, + "show_related": False, +} # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". html_static_path = ["_static"] +# Custom sidebar templates, must be a dictionary that maps document names +# to template names. +# +# The default sidebars (for documents that don't match any pattern) are +# defined by theme itself. Builtin themes are using these templates by +# default: ``['localtoc.html', 'relations.html', 'sourcelink.html', +# 'searchbox.html']``. +# +html_sidebars = {"**": ["sidebar.html", "searchbox.html"]} -# -- Options for HTMLHelp output ------------------------------------------ +# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. +# +html_show_sphinx = False + +# If true, links to the reST sources are added to the pages. +# +html_show_sourcelink = False + +# A shorter title for the navigation bar. Default is the same as html_title. +# +html_short_title = fbchat.__description__ + + +# -- Options for HTMLHelp output --------------------------------------------- # Output file base name for HTML help builder. htmlhelp_basename = project + "doc" -# -- Options for LaTeX output --------------------------------------------- +# -- Options for LaTeX output ------------------------------------------------ latex_elements = { # The paper size ('letterpaper' or 'a4paper'). @@ -136,43 +148,66 @@ latex_elements = { # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, # author, documentclass [howto, manual, or own class]). -latex_documents = [(master_doc, project + ".tex", title, author, "manual")] +latex_documents = [(master_doc, project + ".tex", fbchat.__title__, author, "manual")] -# -- Options for manual page output --------------------------------------- +# -- Options for manual page output ------------------------------------------ # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). -man_pages = [(master_doc, project, title, [author], 1)] +man_pages = [ + (master_doc, project, fbchat.__title__, [x.strip() for x in author.split(";")], 1) +] -# -- Options for Texinfo output ------------------------------------------- +# -- Options for Texinfo output ---------------------------------------------- # Grouping the document tree into Texinfo files. List of tuples # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ - (master_doc, project, title, author, project, description, "Miscellaneous") + ( + master_doc, + project, + fbchat.__title__, + author, + project, + fbchat.__description__, + "Miscellaneous", + ) ] -# Example configuration for intersphinx: refer to the Python standard library. -intersphinx_mapping = {"https://docs.python.org/3/": None} +# -- Options for Epub output ------------------------------------------------- + +# Bibliographic Dublin Core info. +epub_title = project + +# The unique identifier of the text. This can be a ISBN number +# or the project homepage. +# +# epub_identifier = '' + +# A unique identification for the text. +# +# epub_uid = '' + +# A list of files that should not be packed into the epub file. +epub_exclude_files = ["search.html"] -add_function_parentheses = False +# -- Extension configuration ------------------------------------------------- -html_theme_options = { - "show_powered_by": False, - "github_user": "carpedm20", - "github_repo": project, - "github_banner": True, - "show_related": False, -} +# -- Options for autodoc extension --------------------------------------- -html_sidebars = {"**": ["sidebar.html", "searchbox.html"]} - -html_show_sphinx = False -html_show_sourcelink = False autoclass_content = "both" -html_short_title = description + +# -- Options for intersphinx extension --------------------------------------- + +# Example configuration for intersphinx: refer to the Python standard library. +intersphinx_mapping = {"https://docs.python.org/": None} + +# -- Options for todo extension ---------------------------------------------- + +# If true, `todo` and `todoList` produce output, else they produce nothing. +todo_include_todos = True diff --git a/docs/make.bat b/docs/make.bat index c11e517..27f573b 100644 --- a/docs/make.bat +++ b/docs/make.bat @@ -5,21 +5,20 @@ pushd %~dp0 REM Command file for Sphinx documentation if "%SPHINXBUILD%" == "" ( - set SPHINXBUILD=python -msphinx + set SPHINXBUILD=sphinx-build ) set SOURCEDIR=. set BUILDDIR=_build -set SPHINXPROJ=fbchat if "%1" == "" goto help %SPHINXBUILD% >NUL 2>NUL if errorlevel 9009 ( echo. - echo.The Sphinx module was not found. Make sure you have Sphinx installed, - echo.then set the SPHINXBUILD environment variable to point to the full - echo.path of the 'sphinx-build' executable. Alternatively you may add the - echo.Sphinx directory to PATH. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. echo. echo.If you don't have Sphinx installed, grab it from echo.http://sphinx-doc.org/ From 81278ed55399ae7c74b789bcfe5f793b514c8c94 Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Wed, 3 Jul 2019 14:19:11 +0200 Subject: [PATCH 02/11] Remove doc configuration entries that are set to the default --- docs/conf.py | 48 ------------------------------------------------ 1 file changed, 48 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index 1faae77..ecd4474 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -46,22 +46,9 @@ extensions = [ # Add any paths that contain templates here, relative to this directory. templates_path = ["_templates"] -# The suffix(es) of source filenames. -# You can specify multiple suffix as a list of string: -# -# source_suffix = ['.rst', '.md'] -source_suffix = ".rst" - # The master toctree document. master_doc = "index" -# The language for content autogenerated by Sphinx. Refer to documentation -# for a list of supported languages. -# -# This is also used if you do content translation via gettext catalogs. -# Usually you set "language" from the command line for these cases. -language = None - # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. # This pattern also affects html_static_path and html_extra_path. @@ -71,9 +58,6 @@ exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"] # add_function_parentheses = False -# The name of the Pygments (syntax highlighting) style to use. -pygments_style = None - # -- Options for HTML output ------------------------------------------------- @@ -94,11 +78,6 @@ html_theme_options = { "show_related": False, } -# Add any paths that contain custom static files (such as style sheets) here, -# relative to this directory. They are copied after the builtin static files, -# so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ["_static"] - # Custom sidebar templates, must be a dictionary that maps document names # to template names. # @@ -130,21 +109,6 @@ htmlhelp_basename = project + "doc" # -- Options for LaTeX output ------------------------------------------------ -latex_elements = { - # The paper size ('letterpaper' or 'a4paper'). - # - # 'papersize': 'letterpaper', - # The font size ('10pt', '11pt' or '12pt'). - # - # 'pointsize': '10pt', - # Additional stuff for the LaTeX preamble. - # - # 'preamble': '', - # Latex figure (float) alignment - # - # 'figure_align': 'htbp', -} - # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, # author, documentclass [howto, manual, or own class]). @@ -180,18 +144,6 @@ texinfo_documents = [ # -- Options for Epub output ------------------------------------------------- -# Bibliographic Dublin Core info. -epub_title = project - -# The unique identifier of the text. This can be a ISBN number -# or the project homepage. -# -# epub_identifier = '' - -# A unique identification for the text. -# -# epub_uid = '' - # A list of files that should not be packed into the epub file. epub_exclude_files = ["search.html"] From 2bd08c8254d56415f24d55f7ee58c1eda56867b1 Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Wed, 3 Jul 2019 14:20:37 +0200 Subject: [PATCH 03/11] Update Sphinx to version 2.0 --- docs/api.rst | 2 +- docs/conf.py | 2 +- docs/faq.rst | 2 +- docs/index.rst | 2 +- docs/intro.rst | 2 +- docs/testing.rst | 6 +----- docs/todo.rst | 2 +- pyproject.toml | 3 +++ 8 files changed, 10 insertions(+), 11 deletions(-) diff --git a/docs/api.rst b/docs/api.rst index 3c9202a..244e596 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -1,4 +1,4 @@ -.. module:: fbchat +.. currentmodule:: fbchat .. highlight:: python .. _api: diff --git a/docs/conf.py b/docs/conf.py index ecd4474..f3a47ae 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -31,7 +31,7 @@ release = fbchat.__version__ # If your documentation needs a minimal Sphinx version, state it here. # -# needs_sphinx = '1.0' +needs_sphinx = "2.0" # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom diff --git a/docs/faq.rst b/docs/faq.rst index d4bcc1a..c1c1602 100644 --- a/docs/faq.rst +++ b/docs/faq.rst @@ -1,5 +1,5 @@ .. highlight:: python -.. module:: fbchat +.. currentmodule:: fbchat .. _faq: FAQ diff --git a/docs/index.rst b/docs/index.rst index 67a8c11..653bc05 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -1,5 +1,5 @@ .. highlight:: python -.. module:: fbchat +.. currentmodule:: fbchat .. fbchat documentation master file, created by sphinx-quickstart on Thu May 25 15:43:01 2017. You can adapt this file completely to your liking, but it should at least diff --git a/docs/intro.rst b/docs/intro.rst index 8fabddd..c1a501d 100644 --- a/docs/intro.rst +++ b/docs/intro.rst @@ -1,5 +1,5 @@ .. highlight:: python -.. module:: fbchat +.. currentmodule:: fbchat .. _intro: Introduction diff --git a/docs/testing.rst b/docs/testing.rst index f7d01a0..7b73608 100644 --- a/docs/testing.rst +++ b/docs/testing.rst @@ -1,5 +1,5 @@ .. highlight:: sh -.. module:: fbchat +.. currentmodule:: fbchat .. _testing: Testing @@ -23,7 +23,3 @@ If you only want to execute specific tests, pass the function names in the comma Do not execute the full set of tests in too quick succession. This can get your account temporarily blocked for spam! (You should execute the script at max about 10 times a day) - -.. automodule:: tests - :members: TestFbchat - :undoc-members: TestFbchat diff --git a/docs/todo.rst b/docs/todo.rst index d0af13b..33b3ab9 100644 --- a/docs/todo.rst +++ b/docs/todo.rst @@ -1,5 +1,5 @@ .. highlight:: python -.. module:: fbchat +.. currentmodule:: fbchat .. _todo: Todo diff --git a/pyproject.toml b/pyproject.toml index d4473e3..e309e40 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -54,6 +54,9 @@ test = [ "pytest~=4.0", "six~=1.0", ] +docs = [ + "sphinx~=2.0", +] lint = [ "black", ] From 2dc93ed18b28bea03e9bb1f97c6a685830ebc40b Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Wed, 3 Jul 2019 15:18:11 +0200 Subject: [PATCH 04/11] Add .readthedocs.yml --- .readthedocs.yml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 .readthedocs.yml diff --git a/.readthedocs.yml b/.readthedocs.yml new file mode 100644 index 0000000..ec7a00d --- /dev/null +++ b/.readthedocs.yml @@ -0,0 +1,18 @@ +# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details +version: 2 + +formats: + - pdf + - htmlzip + +python: + version: 3.6 + install: + - path: . + extra_requirements: + - docs + +# Build documentation in the docs/ directory with Sphinx +sphinx: + configuration: docs/conf.py + fail_on_warning: true From a2930b4386599d4209151a8c06087fd893c8e1c8 Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Wed, 3 Jul 2019 17:15:21 +0200 Subject: [PATCH 05/11] Deprecate the doc url at /en/master/ in favor of /en/latest/ --- docs/conf.py | 2 ++ docs/robots.txt | 2 ++ 2 files changed, 4 insertions(+) create mode 100644 docs/robots.txt diff --git a/docs/conf.py b/docs/conf.py index f3a47ae..759bb0b 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -78,6 +78,8 @@ html_theme_options = { "show_related": False, } +html_extra_path = ["robots.txt"] + # Custom sidebar templates, must be a dictionary that maps document names # to template names. # diff --git a/docs/robots.txt b/docs/robots.txt new file mode 100644 index 0000000..f592924 --- /dev/null +++ b/docs/robots.txt @@ -0,0 +1,2 @@ +User-agent: * +Disallow: /en/master/ From 8b47bf3e5df38ec536d25ab10dd846153a20f5e7 Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Wed, 3 Jul 2019 17:16:25 +0200 Subject: [PATCH 06/11] Add instructions for installing with pip > 19.0 --- README.rst | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/README.rst b/README.rst index 40d3463..3f8b1d6 100644 --- a/README.rst +++ b/README.rst @@ -35,14 +35,12 @@ Installation: $ pip install fbchat -You can also install from source, by using `flit`: +You can also install from source if you have ``pip>=19.0``: .. code-block:: - $ pip install flit $ git clone https://github.com/carpedm20/fbchat.git - $ cd fbchat - $ flit install + $ pip install fbchat Maintainer From 708869ea93e3b3cd402e6b5c07b33168ab13ed66 Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Wed, 3 Jul 2019 17:18:54 +0200 Subject: [PATCH 07/11] Include missing models in auto-generated API docs --- docs/api.rst | 83 ++++++++++++++++++++++++++++++++++++---------- docs/conf.py | 2 ++ fbchat/_client.py | 6 ++-- fbchat/_message.py | 10 +++--- 4 files changed, 75 insertions(+), 26 deletions(-) diff --git a/docs/api.rst b/docs/api.rst index 244e596..ba29e44 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -2,32 +2,79 @@ .. highlight:: python .. _api: +.. Note: we're using () to hide the __init__ method where relevant + Full API ======== If you are looking for information on a specific function, class, or method, this part of the documentation is for you. - -.. _api_client: - Client ------ -This is the main class of `fbchat`, which contains all the methods you use to interact with Facebook. -You can extend this class, and overwrite the events, to provide custom event handling (mainly used while listening) +.. autoclass:: Client -.. autoclass:: Client(email, password, user_agent=None, max_tries=5, session_cookies=None, logging_level=logging.INFO) - :members: +Threads +------- - -.. _api_models: - -Models ------- - -These models are used in various functions, both as inputs and return values. -A good tip is to write ``from fbchat.models import *`` at the start of your source, so you can use these models freely - -.. automodule:: fbchat.models - :members: +.. autoclass:: Thread() +.. autoclass:: ThreadType(Enum) + :undoc-members: +.. autoclass:: Page() +.. autoclass:: User() +.. autoclass:: Group() + +Messages +-------- + +.. autoclass:: Message +.. autoclass:: Mention +.. autoclass:: EmojiSize(Enum) + :undoc-members: +.. autoclass:: MessageReaction(Enum) + :undoc-members: + +Exceptions +---------- + +.. autoexception:: FBchatException() +.. autoexception:: FBchatFacebookError() +.. autoexception:: FBchatUserError() + +Attachments +----------- + +.. autoclass:: Attachment() +.. autoclass:: ShareAttachment() +.. autoclass:: Sticker() +.. autoclass:: LocationAttachment() +.. autoclass:: LiveLocationAttachment() +.. autoclass:: FileAttachment() +.. autoclass:: AudioAttachment() +.. autoclass:: ImageAttachment() +.. autoclass:: VideoAttachment() +.. autoclass:: ImageAttachment() + +Miscellaneous +------------- + +.. autoclass:: ThreadLocation(Enum) + :undoc-members: +.. autoclass:: ThreadColor(Enum) + :undoc-members: +.. autoclass:: ActiveStatus() +.. autoclass:: TypingStatus(Enum) + :undoc-members: + +.. autoclass:: QuickReply +.. autoclass:: QuickReplyText +.. autoclass:: QuickReplyLocation +.. autoclass:: QuickReplyPhoneNumber +.. autoclass:: QuickReplyEmail + +.. autoclass:: Poll +.. autoclass:: PollOption + +.. autoclass:: Plan +.. autoclass:: GuestStatus(Enum) :undoc-members: diff --git a/docs/conf.py b/docs/conf.py index 759bb0b..98c908a 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -155,6 +155,8 @@ epub_exclude_files = ["search.html"] # -- Options for autodoc extension --------------------------------------- autoclass_content = "both" +autodoc_member_order = "bysource" +autodoc_default_options = {"members": True} # -- Options for intersphinx extension --------------------------------------- diff --git a/fbchat/_client.py b/fbchat/_client.py index ed671d0..31db216 100644 --- a/fbchat/_client.py +++ b/fbchat/_client.py @@ -31,7 +31,9 @@ ACONTEXT = { class Client(object): """A client for the Facebook Chat (Messenger). - See https://fbchat.readthedocs.io for complete documentation of the API. + This is the main class of `fbchat`, which contains all the methods you use to + interact with Facebook. You can extend this class, and overwrite the ``on`` methods, + to provide custom event handling (mainly useful while listening). """ listening = False @@ -64,7 +66,7 @@ class Client(object): session_cookies=None, logging_level=logging.INFO, ): - """Initializes and logs in the client + """Initialize and log in the client. :param email: Facebook `email`, `id` or `phone number` :param password: Facebook account password diff --git a/fbchat/_message.py b/fbchat/_message.py index ebc8a0d..3a67cbf 100644 --- a/fbchat/_message.py +++ b/fbchat/_message.py @@ -99,13 +99,11 @@ class Message(object): Returns a `Message` object, with the formatted string and relevant mentions. - ``` - >>> Message.formatMentions("Hey {!r}! My name is {}", ("1234", "Peter"), ("4321", "Michael")) - , ] emoji_size=None attachments=[]> + >>> Message.formatMentions("Hey {!r}! My name is {}", ("1234", "Peter"), ("4321", "Michael")) + , ] emoji_size=None attachments=[]> - >>> Message.formatMentions("Hey {p}! My name is {}", ("1234", "Michael"), p=("4321", "Peter")) - , ] emoji_size=None attachments=[]> - ``` + >>> Message.formatMentions("Hey {p}! My name is {}", ("1234", "Michael"), p=("4321", "Peter")) + , ] emoji_size=None attachments=[]> """ result = "" mentions = list() From 47c744e5e28102c1d94371edb2ff002d10ed866c Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Wed, 3 Jul 2019 17:35:38 +0200 Subject: [PATCH 08/11] Fix reST any roles/references --- docs/conf.py | 5 +++++ docs/examples.rst | 8 ++++---- docs/faq.rst | 2 +- docs/index.rst | 6 +++--- docs/intro.rst | 26 +++++++++++++------------- docs/testing.rst | 2 +- fbchat/_attachment.py | 2 +- fbchat/_client.py | 24 ++++++++++++------------ fbchat/_thread.py | 4 ++-- 9 files changed, 42 insertions(+), 37 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index 98c908a..6307ba6 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -54,6 +54,11 @@ master_doc = "index" # This pattern also affects html_static_path and html_extra_path. exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"] +# The reST default role (used for this markup: `text`) to use for all +# documents. +# +default_role = "any" + # If true, '()' will be appended to :func: etc. cross-reference text. # add_function_parentheses = False diff --git a/docs/examples.rst b/docs/examples.rst index 9b4e682..44204ee 100644 --- a/docs/examples.rst +++ b/docs/examples.rst @@ -4,13 +4,13 @@ Examples ======== -These are a few examples on how to use `fbchat`. Remember to swap out `` and `` for your email and password +These are a few examples on how to use ``fbchat``. Remember to swap out ```` and ```` for your email and password Basic example ------------- -This will show basic usage of `fbchat` +This will show basic usage of ``fbchat`` .. literalinclude:: ../examples/basic_usage.py @@ -18,7 +18,7 @@ This will show basic usage of `fbchat` Interacting with Threads ------------------------ -This will interact with the thread in every way `fbchat` supports +This will interact with the thread in every way ``fbchat`` supports .. literalinclude:: ../examples/interract.py @@ -42,7 +42,7 @@ This will reply to any message with the same message Remove Bot ---------- -This will remove a user from a group if they write the message `Remove me!` +This will remove a user from a group if they write the message ``Remove me!`` .. literalinclude:: ../examples/removebot.py diff --git a/docs/faq.rst b/docs/faq.rst index c1c1602..a5cc660 100644 --- a/docs/faq.rst +++ b/docs/faq.rst @@ -23,7 +23,7 @@ Where you replace ```` with the version you want to use Will you be supporting creating posts/events/pages and so on? ------------------------------------------------------------- -We won't be focusing on anything else than chat-related things. This API is called `fbCHAT`, after all ;) +We won't be focusing on anything else than chat-related things. This API is called ``fbCHAT``, after all ;) Submitting Issues diff --git a/docs/index.rst b/docs/index.rst index 653bc05..671cd69 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -30,9 +30,9 @@ This project was inspired by `facebook-chat-api `_ for chat bots, so if you're familiar with node.js, this might be what you're looking for. -If you're already familiar with the basics of how Facebook works internally, go to :ref:`examples` to see example usage of `fbchat` +If you're already familiar with the basics of how Facebook works internally, go to :ref:`examples` to see example usage of ``fbchat`` Overview diff --git a/docs/intro.rst b/docs/intro.rst index c1a501d..0ac22dd 100644 --- a/docs/intro.rst +++ b/docs/intro.rst @@ -5,7 +5,7 @@ Introduction ============ -`fbchat` uses your email and password to communicate with the Facebook server. +``fbchat`` uses your email and password to communicate with the Facebook server. That means that you should always store your password in a separate file, in case e.g. someone looks over your shoulder while you're writing code. You should also make sure that the file's access control is appropriately restrictive @@ -28,7 +28,7 @@ Replace ```` and ```` with your email and password respectively For ease of use then most of the code snippets in this document will assume you've already completed the login process Though the second line, ``from fbchat.models import *``, is not strictly neccesary here, later code snippets will assume you've done this -If you want to change how verbose `fbchat` is, change the logging level (in :class:`Client`) +If you want to change how verbose ``fbchat`` is, change the logging level (in :class:`Client`) Throughout your code, if you want to check whether you are still logged in, use :func:`Client.isLoggedIn`. An example would be to login again if you've been logged out, using :func:`Client.login`:: @@ -50,7 +50,7 @@ A thread can refer to two things: A Messenger group chat or a single Facebook us :class:`models.ThreadType` is an enumerator with two values: ``USER`` and ``GROUP``. These will specify whether the thread is a single user chat or a group chat. -This is required for many of `fbchat`'s functions, since Facebook differentiates between these two internally +This is required for many of ``fbchat``'s functions, since Facebook differentiates between these two internally Searching for group chats and finding their ID can be done via. :func:`Client.searchForGroups`, and searching for users is possible via. :func:`Client.searchForUsers`. See :ref:`intro_fetching` @@ -87,7 +87,7 @@ Message IDs Every message you send on Facebook has a unique ID, and every action you do in a thread, like changing a nickname or adding a person, has a unique ID too. -Some of `fbchat`'s functions require these ID's, like :func:`Client.reactToMessage`, +Some of ``fbchat``'s functions require these ID's, like :func:`Client.reactToMessage`, and some of then provide this ID, like :func:`Client.sendMessage`. This snippet shows how to send a message, and then use the returned ID to react to that message with a 😍 emoji:: @@ -100,17 +100,17 @@ This snippet shows how to send a message, and then use the returned ID to react Interacting with Threads ------------------------ -`fbchat` provides multiple functions for interacting with threads +``fbchat`` provides multiple functions for interacting with threads Most functionality works on all threads, though some things, like adding users to and removing users from a group chat, logically only works on group chats -The simplest way of using `fbchat` is to send a message. -The following snippet will, as you've probably already figured out, send the message `test message` to your account:: +The simplest way of using ``fbchat`` is to send a message. +The following snippet will, as you've probably already figured out, send the message ``test message`` to your account:: message_id = client.send(Message(text='test message'), thread_id=client.uid, thread_type=ThreadType.USER) -You can see a full example showing all the possible thread interactions with `fbchat` by going to :ref:`examples` +You can see a full example showing all the possible thread interactions with ``fbchat`` by going to :ref:`examples` .. _intro_fetching: @@ -118,7 +118,7 @@ You can see a full example showing all the possible thread interactions with `fb Fetching Information -------------------- -You can use `fbchat` to fetch basic information like user names, profile pictures, thread names and user IDs +You can use ``fbchat`` to fetch basic information like user names, profile pictures, thread names and user IDs You can retrieve a user's ID with :func:`Client.searchForUsers`. The following snippet will search for users by their name, take the first (and most likely) user, and then get their user ID from the result:: @@ -132,7 +132,7 @@ The following snippet will search for users by their name, take the first (and m Since this uses Facebook's search functions, you don't have to specify the whole name, first names will usually be enough -You can see a full example showing all the possible ways to fetch information with `fbchat` by going to :ref:`examples` +You can see a full example showing all the possible ways to fetch information with ``fbchat`` by going to :ref:`examples` .. _intro_sessions: @@ -140,7 +140,7 @@ You can see a full example showing all the possible ways to fetch information wi Sessions -------- -`fbchat` provides functions to retrieve and set the session cookies. +``fbchat`` provides functions to retrieve and set the session cookies. This will enable you to store the session cookies in a separate file, so that you don't have to login each time you start your script. Use :func:`Client.getSession` to retrieve the cookies:: @@ -164,13 +164,13 @@ Or you can set the ``session_cookies`` on your initial login. Listening & Events ------------------ -To use the listening functions `fbchat` offers (like :func:`Client.listen`), +To use the listening functions ``fbchat`` offers (like :func:`Client.listen`), you have to define what should be executed when certain events happen. By default, (most) events will just be a `logging.info` statement, meaning it will simply print information to the console when an event happens .. note:: - You can identify the event methods by their `on` prefix, e.g. `onMessage` + You can identify the event methods by their ``on`` prefix, e.g. `onMessage` The event actions can be changed by subclassing the :class:`Client`, and then overwriting the event methods:: diff --git a/docs/testing.rst b/docs/testing.rst index 7b73608..9dbb9b7 100644 --- a/docs/testing.rst +++ b/docs/testing.rst @@ -15,7 +15,7 @@ To use the tests, copy ``tests/data.json`` to ``tests/my_data.json`` or type the Please remember to test all supported python versions. If you've made any changes to the 2FA functionality, test it with a 2FA enabled account. -If you only want to execute specific tests, pass the function names in the command line (not including the `test_` prefix). Example:: +If you only want to execute specific tests, pass the function names in the command line (not including the ``test_`` prefix). Example:: $ python tests.py sendMessage sessions sendEmoji diff --git a/fbchat/_attachment.py b/fbchat/_attachment.py index 7270c74..640f7a6 100644 --- a/fbchat/_attachment.py +++ b/fbchat/_attachment.py @@ -36,7 +36,7 @@ class ShareAttachment(Attachment): source = attr.ib(None) #: URL of the attachment image image_url = attr.ib(None) - #: URL of the original image if Facebook uses `safe_image` + #: URL of the original image if Facebook uses ``safe_image`` original_image_url = attr.ib(None) #: Width of the image image_width = attr.ib(None) diff --git a/fbchat/_client.py b/fbchat/_client.py index 31db216..3fc2235 100644 --- a/fbchat/_client.py +++ b/fbchat/_client.py @@ -31,7 +31,7 @@ ACONTEXT = { class Client(object): """A client for the Facebook Chat (Messenger). - This is the main class of `fbchat`, which contains all the methods you use to + This is the main class of ``fbchat``, which contains all the methods you use to interact with Facebook. You can extend this class, and overwrite the ``on`` methods, to provide custom event handling (mainly useful while listening). """ @@ -53,7 +53,7 @@ class Client(object): def uid(self): """The ID of the client. - Can be used as `thread_id`. See :ref:`intro_threads` for more info. + Can be used as ``thread_id``. See :ref:`intro_threads` for more info. """ return self._uid @@ -68,12 +68,12 @@ class Client(object): ): """Initialize and log in the client. - :param email: Facebook `email`, `id` or `phone number` + :param email: Facebook ``email``, ``id`` or ``phone number`` :param password: Facebook account password :param user_agent: Custom user agent to use when sending requests. If `None`, user agent will be chosen from a premade list :param max_tries: Maximum number of times to try logging in :param session_cookies: Cookies from a previous session (Will default to login if these are invalid) - :param logging_level: Configures the `logging level `_. Defaults to `INFO` + :param logging_level: Configures the `logging level `_. Defaults to ``logging.INFO`` :type max_tries: int :type session_cookies: dict :type logging_level: int @@ -178,7 +178,7 @@ class Client(object): def graphql_request(self, query): """ - Shorthand for `graphql_requests(query)[0]` + Shorthand for ``graphql_requests(query)[0]`` :raises: FBchatException if request failed """ @@ -214,7 +214,7 @@ class Client(object): :param session_cookies: A dictionay containing session cookies :type session_cookies: dict - :return: False if `session_cookies` does not contain proper cookies + :return: False if ``session_cookies`` does not contain proper cookies :rtype: bool """ try: @@ -233,9 +233,9 @@ class Client(object): def login(self, email, password, max_tries=5, user_agent=None): """ - Uses `email` and `password` to login the user (If the user is already logged in, this will do a re-login) + Uses ``email`` and ``password`` to login the user (If the user is already logged in, this will do a re-login) - :param email: Facebook `email` or `id` or `phone number` + :param email: Facebook ``email`` or ``id`` or ``phone number`` :param password: Facebook account password :param max_tries: Maximum number of times to try logging in :type max_tries: int @@ -965,7 +965,7 @@ class Client(object): def getUserActiveStatus(self, user_id): """ Gets friend active status as an :class:`models.ActiveStatus` object. - Returns `None` if status isn't known. + Returns ``None`` if status isn't known. .. warning:: Only works when listening. @@ -2845,8 +2845,8 @@ class Client(object): This method is useful if you want to control fbchat from an external event loop .. warning:: - `markAlive` parameter is deprecated now, use :func:`fbchat.Client.setActiveStatus` - or `markAlive` parameter in :func:`fbchat.Client.listen` instead. + ``markAlive`` parameter is deprecated, use :func:`Client.setActiveStatus` + or ``markAlive`` parameter in :func:`Client.listen` instead. :return: Whether the loop should keep running :rtype: bool @@ -2970,7 +2970,7 @@ class Client(object): :param mid: The message ID :param author_id: The ID of the author - :param message: (deprecated. Use `message_object.text` instead) + :param message: (deprecated. Use ``message_object.text`` instead) :param message_object: The message (As a `Message` object) :param thread_id: Thread ID that the message was sent to. See :ref:`intro_threads` :param thread_type: Type of thread that the message was sent to. See :ref:`intro_threads` diff --git a/fbchat/_thread.py b/fbchat/_thread.py index 3206140..6e44bc1 100644 --- a/fbchat/_thread.py +++ b/fbchat/_thread.py @@ -62,9 +62,9 @@ class ThreadColor(Enum): class Thread(object): """Represents a Facebook thread""" - #: The unique identifier of the thread. Can be used a `thread_id`. See :ref:`intro_threads` for more info + #: The unique identifier of the thread. Can be used a ``thread_id``. See :ref:`intro_threads` for more info uid = attr.ib(converter=str) - #: Specifies the type of thread. Can be used a `thread_type`. See :ref:`intro_threads` for more info + #: Specifies the type of thread. Can be used a ``thread_type``. See :ref:`intro_threads` for more info type = attr.ib() #: A url to the thread's picture photo = attr.ib(None) From d30589d1faf58178ea8f10179f2536a48449009a Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Wed, 3 Jul 2019 17:46:42 +0200 Subject: [PATCH 09/11] Add rst_prolog to docs/conf.py --- docs/conf.py | 7 +++++++ docs/examples.rst | 1 - docs/faq.rst | 2 -- docs/index.rst | 2 -- docs/intro.rst | 2 -- docs/testing.rst | 1 - docs/todo.rst | 2 -- 7 files changed, 7 insertions(+), 10 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index 6307ba6..8e40314 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -54,6 +54,13 @@ master_doc = "index" # This pattern also affects html_static_path and html_extra_path. exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"] +rst_prolog = """ +.. highlight:: python +.. currentmodule:: {} +""".format( + project +) + # The reST default role (used for this markup: `text`) to use for all # documents. # diff --git a/docs/examples.rst b/docs/examples.rst index 44204ee..9c58a2a 100644 --- a/docs/examples.rst +++ b/docs/examples.rst @@ -1,4 +1,3 @@ -.. highlight:: python .. _examples: Examples diff --git a/docs/faq.rst b/docs/faq.rst index a5cc660..c3dd8f0 100644 --- a/docs/faq.rst +++ b/docs/faq.rst @@ -1,5 +1,3 @@ -.. highlight:: python -.. currentmodule:: fbchat .. _faq: FAQ diff --git a/docs/index.rst b/docs/index.rst index 671cd69..6d4e997 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -1,5 +1,3 @@ -.. highlight:: python -.. currentmodule:: fbchat .. fbchat documentation master file, created by sphinx-quickstart on Thu May 25 15:43:01 2017. You can adapt this file completely to your liking, but it should at least diff --git a/docs/intro.rst b/docs/intro.rst index 0ac22dd..0334140 100644 --- a/docs/intro.rst +++ b/docs/intro.rst @@ -1,5 +1,3 @@ -.. highlight:: python -.. currentmodule:: fbchat .. _intro: Introduction diff --git a/docs/testing.rst b/docs/testing.rst index 9dbb9b7..75d11d9 100644 --- a/docs/testing.rst +++ b/docs/testing.rst @@ -1,5 +1,4 @@ .. highlight:: sh -.. currentmodule:: fbchat .. _testing: Testing diff --git a/docs/todo.rst b/docs/todo.rst index 33b3ab9..9b89848 100644 --- a/docs/todo.rst +++ b/docs/todo.rst @@ -1,5 +1,3 @@ -.. highlight:: python -.. currentmodule:: fbchat .. _todo: Todo From d279c96dd5b2c4b344bafa886f6eddf9576af82f Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Wed, 3 Jul 2019 23:18:02 +0200 Subject: [PATCH 10/11] Make docs parsing "nitpicky" --- docs/conf.py | 4 + docs/intro.rst | 2 +- fbchat/_client.py | 204 +++++++++++++++++++++++----------------------- 3 files changed, 106 insertions(+), 104 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index 8e40314..d9c243d 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -66,6 +66,10 @@ rst_prolog = """ # default_role = "any" +# Make the reference parsing more strict +# +nitpicky = True + # If true, '()' will be appended to :func: etc. cross-reference text. # add_function_parentheses = False diff --git a/docs/intro.rst b/docs/intro.rst index 0334140..74b2a88 100644 --- a/docs/intro.rst +++ b/docs/intro.rst @@ -46,7 +46,7 @@ Threads A thread can refer to two things: A Messenger group chat or a single Facebook user -:class:`models.ThreadType` is an enumerator with two values: ``USER`` and ``GROUP``. +:class:`ThreadType` is an enumerator with two values: ``USER`` and ``GROUP``. These will specify whether the thread is a single user chat or a group chat. This is required for many of ``fbchat``'s functions, since Facebook differentiates between these two internally diff --git a/fbchat/_client.py b/fbchat/_client.py index 3fc2235..3415883 100644 --- a/fbchat/_client.py +++ b/fbchat/_client.py @@ -309,7 +309,7 @@ class Client(object): :param thread_id: User/Group ID to default to. See :ref:`intro_threads` :param thread_type: See :ref:`intro_threads` - :type thread_type: models.ThreadType + :type thread_type: ThreadType """ self._default_thread_id = thread_id self._default_thread_type = thread_type @@ -335,11 +335,11 @@ class Client(object): Get all threads in thread_location. Threads will be sorted from newest to oldest. - :param thread_location: models.ThreadLocation: INBOX, PENDING, ARCHIVED or OTHER + :param thread_location: ThreadLocation: INBOX, PENDING, ARCHIVED or OTHER :param before: Fetch only thread before this epoch (in ms) (default all threads) :param after: Fetch only thread after this epoch (in ms) (default all threads) :param limit: The max. amount of threads to fetch (default all threads) - :return: :class:`models.Thread` objects + :return: :class:`Thread` objects :rtype: list :raises: FBchatException if request failed """ @@ -387,8 +387,8 @@ class Client(object): """ Get all users involved in threads. - :param threads: models.Thread: List of threads to check for users - :return: :class:`models.User` objects + :param threads: Thread: List of threads to check for users + :return: :class:`User` objects :rtype: list :raises: FBchatException if request failed """ @@ -413,7 +413,7 @@ class Client(object): """ Gets all users the client is currently chatting with - :return: :class:`models.User` objects + :return: :class:`User` objects :rtype: list :raises: FBchatException if request failed """ @@ -435,7 +435,7 @@ class Client(object): :param name: Name of the user :param limit: The max. amount of users to fetch - :return: :class:`models.User` objects, ordered by relevance + :return: :class:`User` objects, ordered by relevance :rtype: list :raises: FBchatException if request failed """ @@ -449,7 +449,7 @@ class Client(object): Find and get page by its name :param name: Name of the page - :return: :class:`models.Page` objects, ordered by relevance + :return: :class:`Page` objects, ordered by relevance :rtype: list :raises: FBchatException if request failed """ @@ -464,7 +464,7 @@ class Client(object): :param name: Name of the group thread :param limit: The max. amount of groups to fetch - :return: :class:`models.Group` objects, ordered by relevance + :return: :class:`Group` objects, ordered by relevance :rtype: list :raises: FBchatException if request failed """ @@ -479,7 +479,7 @@ class Client(object): :param name: Name of the thread :param limit: The max. amount of groups to fetch - :return: :class:`models.User`, :class:`models.Group` and :class:`models.Page` objects, ordered by relevance + :return: :class:`User`, :class:`Group` and :class:`Page` objects, ordered by relevance :rtype: list :raises: FBchatException if request failed """ @@ -516,7 +516,7 @@ class Client(object): :type offset: int :type limit: int :return: Found Message IDs - :rtype: generator + :rtype: typing.Iterable :raises: FBchatException if request failed """ thread_id, thread_type = self._getThread(thread_id, None) @@ -537,7 +537,7 @@ class Client(object): def searchForMessages(self, query, offset=0, limit=5, thread_id=None): """ - Find and get :class:`models.Message` objects by query + Find and get :class:`Message` objects by query .. warning:: This method sends request for every found message ID. @@ -548,8 +548,8 @@ class Client(object): :param thread_id: User/Group ID to search in. See :ref:`intro_threads` :type offset: int :type limit: int - :return: Found :class:`models.Message` objects - :rtype: generator + :return: Found :class:`Message` objects + :rtype: typing.Iterable :raises: FBchatException if request failed """ message_ids = self.searchForMessageIDs( @@ -563,13 +563,13 @@ class Client(object): Searches for messages in all threads :param query: Text to search for - :param fetch_messages: Whether to fetch :class:`models.Message` objects or IDs only + :param fetch_messages: Whether to fetch :class:`Message` objects or IDs only :param thread_limit: Max. number of threads to retrieve :param message_limit: Max. number of messages to retrieve :type thread_limit: int :type message_limit: int - :return: Dictionary with thread IDs as keys and generators to get messages as values - :rtype: generator + :return: Dictionary with thread IDs as keys and iterables to get messages as values + :rtype: typing.Dict[str, typing.Iterable] :raises: FBchatException if request failed """ data = {"query": query, "snippetLimit": thread_limit} @@ -634,7 +634,7 @@ class Client(object): Sends two requests, to fetch all available info! :param user_ids: One or more user ID(s) to query - :return: :class:`models.User` objects, labeled by their ID + :return: :class:`User` objects, labeled by their ID :rtype: dict :raises: FBchatException if request failed """ @@ -656,7 +656,7 @@ class Client(object): Sends two requests, to fetch all available info! :param page_ids: One or more page ID(s) to query - :return: :class:`models.Page` objects, labeled by their ID + :return: :class:`Page` objects, labeled by their ID :rtype: dict :raises: FBchatException if request failed """ @@ -675,7 +675,7 @@ class Client(object): Get groups' info from IDs, unordered :param group_ids: One or more group ID(s) to query - :return: :class:`models.Group` objects, labeled by their ID + :return: :class:`Group` objects, labeled by their ID :rtype: dict :raises: FBchatException if request failed """ @@ -697,7 +697,7 @@ class Client(object): Sends two requests if users or pages are present, to fetch all available info! :param thread_ids: One or more thread ID(s) to query - :return: :class:`models.Thread` objects, labeled by their ID + :return: :class:`Thread` objects, labeled by their ID :rtype: dict :raises: FBchatException if request failed """ @@ -762,7 +762,7 @@ class Client(object): :param before: A timestamp, indicating from which point to retrieve messages :type limit: int :type before: int - :return: :class:`models.Message` objects + :return: :class:`Message` objects :rtype: list :raises: FBchatException if request failed """ @@ -802,11 +802,11 @@ class Client(object): :param offset: Deprecated. Do not use! :param limit: Max. number of threads to retrieve. Capped at 20 - :param thread_location: models.ThreadLocation: INBOX, PENDING, ARCHIVED or OTHER + :param thread_location: ThreadLocation: INBOX, PENDING, ARCHIVED or OTHER :param before: A timestamp (in milliseconds), indicating from which point to retrieve threads :type limit: int :type before: int - :return: :class:`models.Thread` objects + :return: :class:`Thread` objects :rtype: list :raises: FBchatException if request failed """ @@ -899,12 +899,12 @@ class Client(object): def fetchMessageInfo(self, mid, thread_id=None): """ - Fetches :class:`models.Message` object from the message id + Fetches :class:`Message` object from the message id :param mid: Message ID to fetch from :param thread_id: User/Group ID to get message info from. See :ref:`intro_threads` - :return: :class:`models.Message` object - :rtype: models.Message + :return: :class:`Message` object + :rtype: Message :raises: FBchatException if request failed """ thread_id, thread_type = self._getThread(thread_id, None) @@ -913,7 +913,7 @@ class Client(object): def fetchPollOptions(self, poll_id): """ - Fetches list of :class:`models.PollOption` objects from the poll id + Fetches list of :class:`PollOption` objects from the poll id :param poll_id: Poll ID to fetch from :rtype: list @@ -925,11 +925,11 @@ class Client(object): def fetchPlanInfo(self, plan_id): """ - Fetches a :class:`models.Plan` object from the plan id + Fetches a :class:`Plan` object from the plan id :param plan_id: Plan ID to fetch from - :return: :class:`models.Plan` object - :rtype: models.Plan + :return: :class:`Plan` object + :rtype: Plan :raises: FBchatException if request failed """ data = {"event_reminder_id": plan_id} @@ -964,7 +964,7 @@ class Client(object): def getUserActiveStatus(self, user_id): """ - Gets friend active status as an :class:`models.ActiveStatus` object. + Gets friend active status as an :class:`ActiveStatus` object. Returns ``None`` if status isn't known. .. warning:: @@ -972,7 +972,7 @@ class Client(object): :param user_id: ID of the user :return: Given user active status - :rtype: models.ActiveStatus + :rtype: ActiveStatus """ return self._buddylist.get(str(user_id)) @@ -1090,8 +1090,8 @@ class Client(object): :param message: Message to send :param thread_id: User/Group ID to send to. See :ref:`intro_threads` :param thread_type: See :ref:`intro_threads` - :type message: models.Message - :type thread_type: models.ThreadType + :type message: Message + :type thread_type: ThreadType :return: :ref:`Message ID ` of the sent message :raises: FBchatException if request failed """ @@ -1132,7 +1132,7 @@ class Client(object): :param wave_first: Whether to wave first or wave back :param thread_id: User/Group ID to send to. See :ref:`intro_threads` :param thread_type: See :ref:`intro_threads` - :type thread_type: models.ThreadType + :type thread_type: ThreadType :return: :ref:`Message ID ` of the sent message :raises: FBchatException if request failed """ @@ -1155,8 +1155,8 @@ class Client(object): :param payload: Optional answer to the quick reply :param thread_id: User/Group ID to send to. See :ref:`intro_threads` :param thread_type: See :ref:`intro_threads` - :type quick_reply: models.QuickReply - :type thread_type: models.ThreadType + :type quick_reply: QuickReply + :type thread_type: ThreadType :return: :ref:`Message ID ` of the sent message :raises: FBchatException if request failed """ @@ -1168,7 +1168,7 @@ class Client(object): elif isinstance(quick_reply, QuickReplyLocation): if not isinstance(payload, LocationAttachment): raise ValueError( - "Payload must be an instance of `fbchat.models.LocationAttachment`" + "Payload must be an instance of `fbchat.LocationAttachment`" ) return self.sendLocation( payload, thread_id=thread_id, thread_type=thread_type @@ -1216,9 +1216,9 @@ class Client(object): :param message: Additional message :param thread_id: User/Group ID to send to. See :ref:`intro_threads` :param thread_type: See :ref:`intro_threads` - :type location: models.LocationAttachment - :type message: models.Message - :type thread_type: models.ThreadType + :type location: LocationAttachment + :type message: Message + :type thread_type: ThreadType :return: :ref:`Message ID ` of the sent message :raises: FBchatException if request failed """ @@ -1240,9 +1240,9 @@ class Client(object): :param message: Additional message :param thread_id: User/Group ID to send to. See :ref:`intro_threads` :param thread_type: See :ref:`intro_threads` - :type location: models.LocationAttachment - :type message: models.Message - :type thread_type: models.ThreadType + :type location: LocationAttachment + :type message: Message + :type thread_type: ThreadType :return: :ref:`Message ID ` of the sent message :raises: FBchatException if request failed """ @@ -1314,7 +1314,7 @@ class Client(object): :param message: Additional message :param thread_id: User/Group ID to send to. See :ref:`intro_threads` :param thread_type: See :ref:`intro_threads` - :type thread_type: models.ThreadType + :type thread_type: ThreadType :return: :ref:`Message ID ` of the sent files :raises: FBchatException if request failed """ @@ -1334,7 +1334,7 @@ class Client(object): :param message: Additional message :param thread_id: User/Group ID to send to. See :ref:`intro_threads` :param thread_type: See :ref:`intro_threads` - :type thread_type: models.ThreadType + :type thread_type: ThreadType :return: :ref:`Message ID ` of the sent files :raises: FBchatException if request failed """ @@ -1355,7 +1355,7 @@ class Client(object): :param message: Additional message :param thread_id: User/Group ID to send to. See :ref:`intro_threads` :param thread_type: See :ref:`intro_threads` - :type thread_type: models.ThreadType + :type thread_type: ThreadType :return: :ref:`Message ID ` of the sent files :raises: FBchatException if request failed """ @@ -1375,7 +1375,7 @@ class Client(object): :param message: Additional message :param thread_id: User/Group ID to send to. See :ref:`intro_threads` :param thread_type: See :ref:`intro_threads` - :type thread_type: models.ThreadType + :type thread_type: ThreadType :return: :ref:`Message ID ` of the sent files :raises: FBchatException if request failed """ @@ -1394,9 +1394,7 @@ class Client(object): thread_type=ThreadType.USER, is_gif=False, ): - """ - Deprecated. Use :func:`fbchat.Client._sendFiles` instead - """ + """Deprecated.""" if is_gif: mimetype = "image/gif" else: @@ -1649,7 +1647,7 @@ class Client(object): :param title: New group thread title :param thread_id: Group ID to change title of. See :ref:`intro_threads` :param thread_type: See :ref:`intro_threads` - :type thread_type: models.ThreadType + :type thread_type: ThreadType :raises: FBchatException if request failed """ thread_id, thread_type = self._getThread(thread_id, thread_type) @@ -1673,7 +1671,7 @@ class Client(object): :param user_id: User that will have their nickname changed :param thread_id: User/Group ID to change color of. See :ref:`intro_threads` :param thread_type: See :ref:`intro_threads` - :type thread_type: models.ThreadType + :type thread_type: ThreadType :raises: FBchatException if request failed """ thread_id, thread_type = self._getThread(thread_id, thread_type) @@ -1693,7 +1691,7 @@ class Client(object): :param color: New thread color :param thread_id: User/Group ID to change color of. See :ref:`intro_threads` - :type color: models.ThreadColor + :type color: ThreadColor :raises: FBchatException if request failed """ thread_id, thread_type = self._getThread(thread_id, None) @@ -1729,7 +1727,7 @@ class Client(object): :param message_id: :ref:`Message ID ` to react to :param reaction: Reaction emoji to use, if None removes reaction - :type reaction: models.MessageReaction or None + :type reaction: MessageReaction or None :raises: FBchatException if request failed """ data = { @@ -1749,7 +1747,7 @@ class Client(object): :param plan: Plan to set :param thread_id: User/Group ID to send plan to. See :ref:`intro_threads` - :type plan: models.Plan + :type plan: Plan :raises: FBchatException if request failed """ thread_id, thread_type = self._getThread(thread_id, None) @@ -1776,7 +1774,7 @@ class Client(object): :param plan: Plan to edit :param new_plan: New plan - :type plan: models.Plan + :type plan: Plan :raises: FBchatException if request failed """ data = { @@ -1828,7 +1826,7 @@ class Client(object): :param poll: Poll to create :param thread_id: User/Group ID to create poll in. See :ref:`intro_threads` - :type poll: models.Poll + :type poll: Poll :raises: FBchatException if request failed """ thread_id, thread_type = self._getThread(thread_id, None) @@ -1859,7 +1857,7 @@ class Client(object): :param new_options: List of the new option names :param thread_id: User/Group ID to change status in. See :ref:`intro_threads` :param thread_type: See :ref:`intro_threads` - :type thread_type: models.ThreadType + :type thread_type: ThreadType :raises: FBchatException if request failed """ data = {"question_id": poll_id} @@ -1884,8 +1882,8 @@ class Client(object): :param status: Specify the typing status :param thread_id: User/Group ID to change status in. See :ref:`intro_threads` :param thread_type: See :ref:`intro_threads` - :type status: models.TypingStatus - :type thread_type: models.ThreadType + :type status: TypingStatus + :type thread_type: ThreadType :raises: FBchatException if request failed """ thread_id, thread_type = self._getThread(thread_id, thread_type) @@ -2005,7 +2003,7 @@ class Client(object): """ Moves threads to specifed location - :param location: models.ThreadLocation: INBOX, PENDING, ARCHIVED or OTHER + :param location: ThreadLocation: INBOX, PENDING, ARCHIVED or OTHER :param thread_ids: Thread IDs to move. See :ref:`intro_threads` :return: True :raises: FBchatException if request failed @@ -2977,8 +2975,8 @@ class Client(object): :param ts: The timestamp of the message :param metadata: Extra metadata about the message :param msg: A full set of the data recieved - :type message_object: models.Message - :type thread_type: models.ThreadType + :type message_object: Message + :type thread_type: ThreadType """ log.info("{} from {} in {}".format(message_object, thread_id, thread_type.name)) @@ -3004,8 +3002,8 @@ class Client(object): :param ts: A timestamp of the action :param metadata: Extra metadata about the action :param msg: A full set of the data recieved - :type new_color: models.ThreadColor - :type thread_type: models.ThreadType + :type new_color: ThreadColor + :type thread_type: ThreadType """ log.info( "Color change from {} in {} ({}): {}".format( @@ -3035,7 +3033,7 @@ class Client(object): :param ts: A timestamp of the action :param metadata: Extra metadata about the action :param msg: A full set of the data recieved - :type thread_type: models.ThreadType + :type thread_type: ThreadType """ log.info( "Emoji change from {} in {} ({}): {}".format( @@ -3065,7 +3063,7 @@ class Client(object): :param ts: A timestamp of the action :param metadata: Extra metadata about the action :param msg: A full set of the data recieved - :type thread_type: models.ThreadType + :type thread_type: ThreadType """ log.info( "Title change from {} in {} ({}): {}".format( @@ -3093,7 +3091,7 @@ class Client(object): :param thread_type: Type of thread that the action was sent to. See :ref:`intro_threads` :param ts: A timestamp of the action :param msg: A full set of the data recieved - :type thread_type: models.ThreadType + :type thread_type: ThreadType """ log.info("{} changed thread image in {}".format(author_id, thread_id)) @@ -3121,7 +3119,7 @@ class Client(object): :param ts: A timestamp of the action :param metadata: Extra metadata about the action :param msg: A full set of the data recieved - :type thread_type: models.ThreadType + :type thread_type: ThreadType """ log.info( "Nickname change from {} in {} ({}) for {}: {}".format( @@ -3218,7 +3216,7 @@ class Client(object): :param ts: A timestamp of the action :param metadata: Extra metadata about the action :param msg: A full set of the data recieved - :type thread_type: models.ThreadType + :type thread_type: ThreadType """ log.info( "Messages seen by {} in {} ({}) at {}s".format( @@ -3246,7 +3244,7 @@ class Client(object): :param ts: A timestamp of the action :param metadata: Extra metadata about the action :param msg: A full set of the data recieved - :type thread_type: models.ThreadType + :type thread_type: ThreadType """ log.info( "Messages {} delivered to {} in {} ({}) at {}s".format( @@ -3266,7 +3264,7 @@ class Client(object): :param ts: A timestamp of the action :param metadata: Extra metadata about the action :param msg: A full set of the data recieved - :type thread_type: models.ThreadType + :type thread_type: ThreadType """ log.info( "Marked messages as seen in threads {} at {}s".format( @@ -3292,7 +3290,7 @@ class Client(object): :param thread_type: Type of thread that the action was sent to. See :ref:`intro_threads` :param ts: A timestamp of the action :param msg: A full set of the data recieved - :type thread_type: models.ThreadType + :type thread_type: ThreadType """ log.info( "{} unsent the message {} in {} ({}) at {}s".format( @@ -3376,8 +3374,8 @@ class Client(object): :param thread_id: Thread ID that the action was sent to. See :ref:`intro_threads` :param thread_type: Type of thread that the action was sent to. See :ref:`intro_threads` :param msg: A full set of the data recieved - :type typing_status: models.TypingStatus - :type thread_type: models.ThreadType + :type typing_status: TypingStatus + :type thread_type: ThreadType """ pass @@ -3409,7 +3407,7 @@ class Client(object): :param ts: A timestamp of the action :param metadata: Extra metadata about the action :param msg: A full set of the data recieved - :type thread_type: models.ThreadType + :type thread_type: ThreadType """ log.info( '{} played "{}" in {} ({})'.format( @@ -3438,8 +3436,8 @@ class Client(object): :param thread_type: Type of thread that the action was sent to. See :ref:`intro_threads` :param ts: A timestamp of the action :param msg: A full set of the data recieved - :type reaction: models.MessageReaction - :type thread_type: models.ThreadType + :type reaction: MessageReaction + :type thread_type: ThreadType """ log.info( "{} reacted to message {} with {} in {} ({})".format( @@ -3465,7 +3463,7 @@ class Client(object): :param thread_type: Type of thread that the action was sent to. See :ref:`intro_threads` :param ts: A timestamp of the action :param msg: A full set of the data recieved - :type thread_type: models.ThreadType + :type thread_type: ThreadType """ log.info( "{} removed reaction from {} message in {} ({})".format( @@ -3484,7 +3482,7 @@ class Client(object): :param thread_type: Type of thread that the action was sent to. See :ref:`intro_threads` :param ts: A timestamp of the action :param msg: A full set of the data recieved - :type thread_type: models.ThreadType + :type thread_type: ThreadType """ log.info( "{} blocked {} ({}) thread".format(author_id, thread_id, thread_type.name) @@ -3501,7 +3499,7 @@ class Client(object): :param thread_type: Type of thread that the action was sent to. See :ref:`intro_threads` :param ts: A timestamp of the action :param msg: A full set of the data recieved - :type thread_type: models.ThreadType + :type thread_type: ThreadType """ log.info( "{} unblocked {} ({}) thread".format(author_id, thread_id, thread_type.name) @@ -3527,8 +3525,8 @@ class Client(object): :param thread_type: Type of thread that the action was sent to. See :ref:`intro_threads` :param ts: A timestamp of the action :param msg: A full set of the data recieved - :type location: models.LiveLocationAttachment - :type thread_type: models.ThreadType + :type location: LiveLocationAttachment + :type thread_type: ThreadType """ log.info( "{} sent live location info in {} ({}) with latitude {} and longitude {}".format( @@ -3561,7 +3559,7 @@ class Client(object): :param ts: A timestamp of the action :param metadata: Extra metadata about the action :param msg: A full set of the data recieved - :type thread_type: models.ThreadType + :type thread_type: ThreadType """ log.info( "{} started call in {} ({})".format(caller_id, thread_id, thread_type.name) @@ -3594,7 +3592,7 @@ class Client(object): :param ts: A timestamp of the action :param metadata: Extra metadata about the action :param msg: A full set of the data recieved - :type thread_type: models.ThreadType + :type thread_type: ThreadType """ log.info( "{} ended call in {} ({})".format(caller_id, thread_id, thread_type.name) @@ -3622,7 +3620,7 @@ class Client(object): :param ts: A timestamp of the action :param metadata: Extra metadata about the action :param msg: A full set of the data recieved - :type thread_type: models.ThreadType + :type thread_type: ThreadType """ log.info( "{} joined call in {} ({})".format(joined_id, thread_id, thread_type.name) @@ -3650,8 +3648,8 @@ class Client(object): :param ts: A timestamp of the action :param metadata: Extra metadata about the action :param msg: A full set of the data recieved - :type poll: models.Poll - :type thread_type: models.ThreadType + :type poll: Poll + :type thread_type: ThreadType """ log.info( "{} created poll {} in {} ({})".format( @@ -3683,8 +3681,8 @@ class Client(object): :param ts: A timestamp of the action :param metadata: Extra metadata about the action :param msg: A full set of the data recieved - :type poll: models.Poll - :type thread_type: models.ThreadType + :type poll: Poll + :type thread_type: ThreadType """ log.info( "{} voted in poll {} in {} ({})".format( @@ -3714,8 +3712,8 @@ class Client(object): :param ts: A timestamp of the action :param metadata: Extra metadata about the action :param msg: A full set of the data recieved - :type plan: models.Plan - :type thread_type: models.ThreadType + :type plan: Plan + :type thread_type: ThreadType """ log.info( "{} created plan {} in {} ({})".format( @@ -3743,8 +3741,8 @@ class Client(object): :param ts: A timestamp of the action :param metadata: Extra metadata about the action :param msg: A full set of the data recieved - :type plan: models.Plan - :type thread_type: models.ThreadType + :type plan: Plan + :type thread_type: ThreadType """ log.info( "Plan {} has ended in {} ({})".format(plan, thread_id, thread_type.name) @@ -3772,8 +3770,8 @@ class Client(object): :param ts: A timestamp of the action :param metadata: Extra metadata about the action :param msg: A full set of the data recieved - :type plan: models.Plan - :type thread_type: models.ThreadType + :type plan: Plan + :type thread_type: ThreadType """ log.info( "{} edited plan {} in {} ({})".format( @@ -3803,8 +3801,8 @@ class Client(object): :param ts: A timestamp of the action :param metadata: Extra metadata about the action :param msg: A full set of the data recieved - :type plan: models.Plan - :type thread_type: models.ThreadType + :type plan: Plan + :type thread_type: ThreadType """ log.info( "{} deleted plan {} in {} ({})".format( @@ -3836,9 +3834,9 @@ class Client(object): :param ts: A timestamp of the action :param metadata: Extra metadata about the action :param msg: A full set of the data recieved - :type plan: models.Plan + :type plan: Plan :type take_part: bool - :type thread_type: models.ThreadType + :type thread_type: ThreadType """ if take_part: log.info( @@ -3875,7 +3873,7 @@ class Client(object): """ Called when the client is listening and client receives information about friend active status - :param statuses: Dictionary with user IDs as keys and :class:`models.ActiveStatus` as values + :param statuses: Dictionary with user IDs as keys and :class:`ActiveStatus` as values :param msg: A full set of the data recieved :type statuses: dict """ From a9c681818a6bbefc98f32f0fa07bd1b7bd97a0ae Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Wed, 3 Jul 2019 23:42:32 +0200 Subject: [PATCH 11/11] Enable strict/explicit code highlighting --- docs/api.rst | 3 +-- docs/conf.py | 11 +++++------ docs/install.rst | 19 +++++++++++++------ docs/testing.rst | 5 +++-- fbchat/_message.py | 8 ++++---- 5 files changed, 26 insertions(+), 20 deletions(-) diff --git a/docs/api.rst b/docs/api.rst index ba29e44..3d9a920 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -1,5 +1,4 @@ -.. currentmodule:: fbchat -.. highlight:: python +.. module:: fbchat .. _api: .. Note: we're using () to hide the __init__ method where relevant diff --git a/docs/conf.py b/docs/conf.py index d9c243d..3a6dde4 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -54,12 +54,7 @@ master_doc = "index" # This pattern also affects html_static_path and html_extra_path. exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"] -rst_prolog = """ -.. highlight:: python -.. currentmodule:: {} -""".format( - project -) +rst_prolog = ".. currentmodule:: " + project # The reST default role (used for this markup: `text`) to use for all # documents. @@ -70,6 +65,10 @@ default_role = "any" # nitpicky = True +# Prefer strict Python highlighting +# +highlight_language = "python3" + # If true, '()' will be appended to :func: etc. cross-reference text. # add_function_parentheses = False diff --git a/docs/install.rst b/docs/install.rst index 672330a..fda0cd3 100644 --- a/docs/install.rst +++ b/docs/install.rst @@ -1,4 +1,3 @@ -.. highlight:: sh .. _install: Installation @@ -7,7 +6,9 @@ Installation Pip Install fbchat ------------------ -To install fbchat, run this command:: +To install fbchat, run this command: + +.. code-block:: sh $ pip install fbchat @@ -21,16 +22,22 @@ Get the Source Code fbchat is developed on GitHub, where the code is `always available `_. -You can either clone the public repository:: +You can either clone the public repository: + +.. code-block:: sh $ git clone git://github.com/carpedm20/fbchat.git -Or, download a `tarball `_:: +Or, download a `tarball `_: + +.. code-block:: sh $ curl -OL https://github.com/carpedm20/fbchat/tarball/master - # optionally, zipball is also available (for Windows users). + # optionally, zipball is also available (for Windows users). Once you have a copy of the source, you can embed it in your own Python -package, or install it into your site-packages easily:: +package, or install it into your site-packages easily: + +.. code-block:: sh $ python setup.py install diff --git a/docs/testing.rst b/docs/testing.rst index 75d11d9..16dbd57 100644 --- a/docs/testing.rst +++ b/docs/testing.rst @@ -1,4 +1,3 @@ -.. highlight:: sh .. _testing: Testing @@ -14,7 +13,9 @@ To use the tests, copy ``tests/data.json`` to ``tests/my_data.json`` or type the Please remember to test all supported python versions. If you've made any changes to the 2FA functionality, test it with a 2FA enabled account. -If you only want to execute specific tests, pass the function names in the command line (not including the ``test_`` prefix). Example:: +If you only want to execute specific tests, pass the function names in the command line (not including the ``test_`` prefix). Example: + +.. code-block:: sh $ python tests.py sendMessage sessions sendEmoji diff --git a/fbchat/_message.py b/fbchat/_message.py index 3a67cbf..e4d886c 100644 --- a/fbchat/_message.py +++ b/fbchat/_message.py @@ -99,11 +99,11 @@ class Message(object): Returns a `Message` object, with the formatted string and relevant mentions. - >>> Message.formatMentions("Hey {!r}! My name is {}", ("1234", "Peter"), ("4321", "Michael")) - , ] emoji_size=None attachments=[]> + >>> Message.formatMentions("Hey {!r}! My name is {}", ("1234", "Peter"), ("4321", "Michael")) + , ] emoji_size=None attachments=[]> - >>> Message.formatMentions("Hey {p}! My name is {}", ("1234", "Michael"), p=("4321", "Peter")) - , ] emoji_size=None attachments=[]> + >>> Message.formatMentions("Hey {p}! My name is {}", ("1234", "Michael"), p=("4321", "Peter")) + , ] emoji_size=None attachments=[]> """ result = "" mentions = list()