Merge pull request #455 from carpedm20/add-spell-check

Add spell checking.

Use sphinxcontrib-spelling to fix documentation and docstring spelling errors.
This commit is contained in:
Mads Marquart
2019-07-25 18:51:53 +02:00
committed by GitHub
28 changed files with 148 additions and 113 deletions

View File

@@ -21,8 +21,8 @@ Traceback (most recent call last):
File "[site-packages]/fbchat/client.py", line 78, in __init__ File "[site-packages]/fbchat/client.py", line 78, in __init__
self.login(email, password, max_tries) self.login(email, password, max_tries)
File "[site-packages]/fbchat/client.py", line 407, in login File "[site-packages]/fbchat/client.py", line 407, in login
raise FBchatUserError('Login failed. Check email/password. (Failed on url: {})'.format(login_url)) raise FBchatUserError('Login failed. Check email/password. (Failed on URL: {})'.format(login_url))
fbchat.models.FBchatUserError: Login failed. Check email/password. (Failed on url: https://m.facebook.com/login.php?login_attempt=1) fbchat.models.FBchatUserError: Login failed. Check email/password. (Failed on URL: https://m.facebook.com/login.php?login_attempt=1)
``` ```
## Environment information ## Environment information

View File

@@ -30,7 +30,7 @@ jobs:
script: black --check --verbose . script: black --check --verbose .
- stage: deploy - stage: deploy
name: Github Releases name: GitHub Releases
if: tag IS present if: tag IS present
install: skip install: skip
script: flit build script: flit build

View File

@@ -1,5 +1,5 @@
Contributing to fbchat Contributing to ``fbchat``
====================== ==========================
Thanks for reading this, all contributions are very much welcome! Thanks for reading this, all contributions are very much welcome!

View File

@@ -1,5 +1,5 @@
fbchat: Facebook Chat (Messenger) for Python ``fbchat``: Facebook Chat (Messenger) for Python
============================================ ================================================
.. image:: https://img.shields.io/badge/license-BSD-blue.svg .. image:: https://img.shields.io/badge/license-BSD-blue.svg
:target: https://github.com/carpedm20/fbchat/tree/master/LICENSE :target: https://github.com/carpedm20/fbchat/tree/master/LICENSE

View File

@@ -42,6 +42,7 @@ extensions = [
"sphinx.ext.todo", "sphinx.ext.todo",
"sphinx.ext.viewcode", "sphinx.ext.viewcode",
"sphinx.ext.napoleon", "sphinx.ext.napoleon",
"sphinxcontrib.spelling",
] ]
# Add any paths that contain templates here, relative to this directory. # Add any paths that contain templates here, relative to this directory.
@@ -193,3 +194,15 @@ napoleon_numpy_docstring = False
# napoleon_use_admonition_for_examples = False # napoleon_use_admonition_for_examples = False
# napoleon_use_admonition_for_notes = False # napoleon_use_admonition_for_notes = False
# napoleon_use_admonition_for_references = False # napoleon_use_admonition_for_references = False
# -- Options for spelling extension ----------------------------------------------
spelling_word_list_filename = [
"spelling/names.txt",
"spelling/technical.txt",
"spelling/fixes.txt",
]
spelling_ignore_wiki_words = False
# spelling_ignore_acronyms = False
spelling_ignore_python_builtins = False
spelling_ignore_importable_modules = False

View File

@@ -30,8 +30,8 @@ This will show the different ways of fetching information about users and thread
.. literalinclude:: ../examples/fetch.py .. literalinclude:: ../examples/fetch.py
Echobot ``Echobot``
------- -----------
This will reply to any message with the same message This will reply to any message with the same message

View File

@@ -9,7 +9,7 @@ Version X broke my installation
We try to provide backwards compatibility where possible, but since we're not part of Facebook, We try to provide backwards compatibility where possible, but since we're not part of Facebook,
most of the things may be broken at any point in time most of the things may be broken at any point in time
Downgrade to an earlier version of fbchat, run this command Downgrade to an earlier version of ``fbchat``, run this command
.. code-block:: sh .. code-block:: sh
@@ -28,7 +28,7 @@ Submitting Issues
----------------- -----------------
If you're having trouble with some of the snippets, or you think some of the functionality is broken, If you're having trouble with some of the snippets, or you think some of the functionality is broken,
please feel free to submit an issue on `Github <https://github.com/carpedm20/fbchat>`_. please feel free to submit an issue on `GitHub <https://github.com/carpedm20/fbchat>`_.
You should first login with ``logging_level`` set to ``logging.DEBUG``:: You should first login with ``logging_level`` set to ``logging.DEBUG``::
from fbchat import Client from fbchat import Client

View File

@@ -6,8 +6,8 @@
.. This documentation's layout is heavily inspired by requests' layout: https://requests.readthedocs.io .. This documentation's layout is heavily inspired by requests' layout: https://requests.readthedocs.io
Some documentation is also partially copied from facebook-chat-api: https://github.com/Schmavery/facebook-chat-api Some documentation is also partially copied from facebook-chat-api: https://github.com/Schmavery/facebook-chat-api
fbchat: Facebook Chat (Messenger) for Python ``fbchat``: Facebook Chat (Messenger) for Python
============================================ ================================================
Release v\ |version|. (:ref:`install`) Release v\ |version|. (:ref:`install`)
@@ -35,7 +35,7 @@ This means doing the exact same GET/POST requests and tricking Facebook into thi
Therefore, this API requires the credentials of a Facebook account. Therefore, this API requires the credentials of a Facebook account.
.. note:: .. note::
If you're having problems, please check the :ref:`faq`, before asking questions on Github If you're having problems, please check the :ref:`faq`, before asking questions on GitHub
.. warning:: .. warning::
We are not responsible if your account gets banned for spammy activities, We are not responsible if your account gets banned for spammy activities,
@@ -44,7 +44,7 @@ Therefore, this API requires the credentials of a Facebook account.
.. note:: .. note::
Facebook now has an `official API <https://developers.facebook.com/docs/messenger-platform>`_ for chat bots, Facebook now has an `official API <https://developers.facebook.com/docs/messenger-platform>`_ for chat bots,
so if you're familiar with node.js, this might be what you're looking for. 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``

View File

@@ -3,10 +3,10 @@
Installation Installation
============ ============
Pip Install fbchat Install using pip
------------------ -----------------
To install fbchat, run this command: To install ``fbchat``, run this command:
.. code-block:: sh .. code-block:: sh
@@ -19,7 +19,7 @@ can guide you through the process.
Get the Source Code Get the Source Code
------------------- -------------------
fbchat is developed on GitHub, where the code is ``fbchat`` is developed on GitHub, where the code is
`always available <https://github.com/carpedm20/fbchat>`_. `always available <https://github.com/carpedm20/fbchat>`_.
You can either clone the public repository: You can either clone the public repository:

View File

@@ -24,7 +24,7 @@ Replace ``<email>`` and ``<password>`` with your email and password respectively
.. note:: .. note::
For ease of use then most of the code snippets in this document will assume you've already completed the login process 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 Though the second line, ``from fbchat.models import *``, is not strictly necessary 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`)
@@ -125,8 +125,8 @@ The following snippet will search for users by their name, take the first (and m
user = users[0] user = users[0]
print("User's ID: {}".format(user.uid)) print("User's ID: {}".format(user.uid))
print("User's name: {}".format(user.name)) print("User's name: {}".format(user.name))
print("User's profile picture url: {}".format(user.photo)) print("User's profile picture URL: {}".format(user.photo))
print("User's main url: {}".format(user.url)) print("User's main URL: {}".format(user.url))
Since this uses Facebook's search functions, you don't have to specify the whole name, first names will usually be enough Since this uses Facebook's search functions, you don't have to specify the whole name, first names will usually be enough
@@ -154,7 +154,7 @@ Or you can set the ``session_cookies`` on your initial login.
client = Client('<email>', '<password>', session_cookies=session_cookies) client = Client('<email>', '<password>', session_cookies=session_cookies)
.. warning:: .. warning::
You session cookies can be just as valueable as you password, so store them with equal care You session cookies can be just as valuable as you password, so store them with equal care
.. _intro_events: .. _intro_events:
@@ -192,7 +192,7 @@ The change was in the parameters that our `onMessage` method took: ``message_obj
and ``mid``, ``ts``, ``metadata`` and ``msg`` got removed, but the function still works, since we included ``**kwargs`` and ``mid``, ``ts``, ``metadata`` and ``msg`` got removed, but the function still works, since we included ``**kwargs``
.. note:: .. note::
Therefore, for both backwards and forwards compatability, Therefore, for both backwards and forwards compatibility,
the API actually requires that you include ``**kwargs`` as your final argument. the API actually requires that you include ``**kwargs`` as your final argument.
View the :ref:`examples` to see some more examples illustrating the event system View the :ref:`examples` to see some more examples illustrating the event system

3
docs/spelling/fixes.txt Normal file
View File

@@ -0,0 +1,3 @@
premade
todo
emoji

3
docs/spelling/names.txt Normal file
View File

@@ -0,0 +1,3 @@
Facebook
GraphQL
GitHub

View File

@@ -0,0 +1,14 @@
iterables
timestamp
metadata
spam
spammy
admin
admins
unsend
unsends
unmute
spritemap
online
inbox
subclassing

View File

@@ -9,11 +9,11 @@ This page will be periodically updated to show missing features and documentatio
Missing Functionality Missing Functionality
--------------------- ---------------------
- Implement Client.searchForMessage - Implement ``Client.searchForMessage``
- This will use the graphql request API - This will use the GraphQL request API
- Implement chatting with pages properly - Implement chatting with pages properly
- Write better FAQ - Write better FAQ
- Explain usage of graphql - Explain usage of GraphQL
Documentation Documentation

View File

@@ -47,7 +47,7 @@ client.sendLocalImage(
thread_type=thread_type, thread_type=thread_type,
) )
# Will download the image at the url `<image url>`, and then send it # Will download the image at the URL `<image url>`, and then send it
client.sendRemoteImage( client.sendRemoteImage(
"<image url>", "<image url>",
message=Message(text="This is a remote image"), message=Message(text="This is a remote image"),

View File

@@ -20,7 +20,7 @@ class UnsentMessage(Attachment):
@attr.s(cmp=False) @attr.s(cmp=False)
class ShareAttachment(Attachment): class ShareAttachment(Attachment):
"""Represents a shared item (eg. URL) attachment.""" """Represents a shared item (e.g. URL) attachment."""
#: ID of the author of the shared post #: ID of the author of the shared post
author = attr.ib(None) author = attr.ib(None)

View File

@@ -44,7 +44,7 @@ class Client(object):
@property @property
def ssl_verify(self): def ssl_verify(self):
"""Verify ssl certificate. """Verify SSL certificate.
Set to False to allow debugging with a proxy. Set to False to allow debugging with a proxy.
""" """
@@ -167,13 +167,13 @@ class Client(object):
raise FBchatException("Missing payload: {}".format(j)) raise FBchatException("Missing payload: {}".format(j))
def graphql_requests(self, *queries): def graphql_requests(self, *queries):
"""Execute graphql queries. """Execute GraphQL queries.
Args: Args:
queries (dict): Zero or more dictionaries queries (dict): Zero or more dictionaries
Returns: Returns:
tuple: A tuple containing json graphql queries tuple: A tuple containing JSON GraphQL queries
Raises: Raises:
FBchatException: If request failed FBchatException: If request failed
@@ -213,7 +213,7 @@ class Client(object):
"""Retrieve session cookies. """Retrieve session cookies.
Returns: Returns:
dict: A dictionay containing session cookies dict: A dictionary containing session cookies
""" """
return self._state.get_cookies() return self._state.get_cookies()
@@ -221,7 +221,7 @@ class Client(object):
"""Load session cookies. """Load session cookies.
Args: Args:
session_cookies (dict): A dictionay containing session cookies session_cookies (dict): A dictionary containing session cookies
Returns: Returns:
bool: False if ``session_cookies`` does not contain proper cookies bool: False if ``session_cookies`` does not contain proper cookies
@@ -936,13 +936,13 @@ class Client(object):
return result["thread_fbids"] + result["other_user_fbids"] return result["thread_fbids"] + result["other_user_fbids"]
def fetchImageUrl(self, image_id): def fetchImageUrl(self, image_id):
"""Fetch url to download the original image from an image attachment ID. """Fetch URL to download the original image from an image attachment ID.
Args: Args:
image_id (str): The image you want to fethc image_id (str): The image you want to fetch
Returns: Returns:
str: An url where you can download the original image str: An URL where you can download the original image
Raises: Raises:
FBchatException: If request failed FBchatException: If request failed
@@ -953,7 +953,7 @@ class Client(object):
url = get_jsmods_require(j, 3) url = get_jsmods_require(j, 3)
if url is None: if url is None:
raise FBchatException("Could not fetch image url from: {}".format(j)) raise FBchatException("Could not fetch image URL from: {}".format(j))
return url return url
def fetchMessageInfo(self, mid, thread_id=None): def fetchMessageInfo(self, mid, thread_id=None):
@@ -1658,7 +1658,7 @@ class Client(object):
j = self._payload_post("/messaging/save_admins/?dpr=1", data) j = self._payload_post("/messaging/save_admins/?dpr=1", data)
def addGroupAdmins(self, admin_ids, thread_id=None): def addGroupAdmins(self, admin_ids, thread_id=None):
"""Set specifed users as group admins. """Set specified users as group admins.
Args: Args:
admin_ids: One or more user IDs to set admin admin_ids: One or more user IDs to set admin
@@ -1670,7 +1670,7 @@ class Client(object):
self._adminStatus(admin_ids, True, thread_id) self._adminStatus(admin_ids, True, thread_id)
def removeGroupAdmins(self, admin_ids, thread_id=None): def removeGroupAdmins(self, admin_ids, thread_id=None):
"""Remove admin status from specifed users. """Remove admin status from specified users.
Args: Args:
admin_ids: One or more user IDs to remove admin admin_ids: One or more user IDs to remove admin
@@ -1989,10 +1989,10 @@ class Client(object):
""" """
thread_id, thread_type = self._getThread(thread_id, None) thread_id, thread_type = self._getThread(thread_id, None)
# We're using ordered dicts, because the Facebook endpoint that parses the POST # We're using ordered dictionaries, because the Facebook endpoint that parses
# parameters is badly implemented, and deals with ordering the options wrongly. # the POST parameters is badly implemented, and deals with ordering the options
# If you can find a way to fix this for the endpoint, or if you find another # wrongly. If you can find a way to fix this for the endpoint, or if you find
# endpoint, please do suggest it ;) # another endpoint, please do suggest it ;)
data = OrderedDict([("question_text", poll.title), ("target_id", thread_id)]) data = OrderedDict([("question_text", poll.title), ("target_id", thread_id)])
for i, option in enumerate(poll.options): for i, option in enumerate(poll.options):
@@ -2133,7 +2133,7 @@ class Client(object):
j = self._payload_post("/ajax/add_friend/action.php?dpr=1", data) j = self._payload_post("/ajax/add_friend/action.php?dpr=1", data)
def removeFriend(self, friend_id=None): def removeFriend(self, friend_id=None):
"""Remove a specifed friend from the client's friend list. """Remove a specified friend from the client's friend list.
Args: Args:
friend_id: The ID of the friend that you want to remove friend_id: The ID of the friend that you want to remove
@@ -2149,7 +2149,7 @@ class Client(object):
return True return True
def blockUser(self, user_id): def blockUser(self, user_id):
"""Block messages from a specifed user. """Block messages from a specified user.
Args: Args:
user_id: The ID of the user that you want to block user_id: The ID of the user that you want to block
@@ -2181,7 +2181,7 @@ class Client(object):
return True return True
def moveThreads(self, location, thread_ids): def moveThreads(self, location, thread_ids):
"""Move threads to specifed location. """Move threads to specified location.
Args: Args:
location (ThreadLocation): INBOX, PENDING, ARCHIVED or OTHER location (ThreadLocation): INBOX, PENDING, ARCHIVED or OTHER
@@ -2261,7 +2261,7 @@ class Client(object):
return True return True
def deleteMessages(self, message_ids): def deleteMessages(self, message_ids):
"""Delete specifed messages. """Delete specified messages.
Args: Args:
message_ids: Message IDs to delete message_ids: Message IDs to delete
@@ -3040,7 +3040,8 @@ class Client(object):
def doOneListen(self, markAlive=None): def doOneListen(self, markAlive=None):
"""Do one cycle of the listening loop. """Do one cycle of the listening loop.
This method is useful if you want to control fbchat from an external event loop. This method is useful if you want to control the client from an external event
loop.
Warning: Warning:
``markAlive`` parameter is deprecated, use :func:`Client.setActiveStatus` ``markAlive`` parameter is deprecated, use :func:`Client.setActiveStatus`
@@ -3174,7 +3175,7 @@ class Client(object):
thread_type (ThreadType): Type of thread that the message was sent to. See :ref:`intro_threads` thread_type (ThreadType): Type of thread that the message was sent to. See :ref:`intro_threads`
ts: The timestamp of the message ts: The timestamp of the message
metadata: Extra metadata about the message metadata: Extra metadata about the message
msg: A full set of the data recieved msg: A full set of the data received
""" """
log.info("{} from {} in {}".format(message_object, thread_id, thread_type.name)) log.info("{} from {} in {}".format(message_object, thread_id, thread_type.name))
@@ -3199,7 +3200,7 @@ class Client(object):
thread_type (ThreadType): Type of thread that the action was sent to. See :ref:`intro_threads` thread_type (ThreadType): Type of thread that the action was sent to. See :ref:`intro_threads`
ts: A timestamp of the action ts: A timestamp of the action
metadata: Extra metadata about the action metadata: Extra metadata about the action
msg: A full set of the data recieved msg: A full set of the data received
""" """
log.info( log.info(
"Color change from {} in {} ({}): {}".format( "Color change from {} in {} ({}): {}".format(
@@ -3228,7 +3229,7 @@ class Client(object):
thread_type (ThreadType): Type of thread that the action was sent to. See :ref:`intro_threads` thread_type (ThreadType): Type of thread that the action was sent to. See :ref:`intro_threads`
ts: A timestamp of the action ts: A timestamp of the action
metadata: Extra metadata about the action metadata: Extra metadata about the action
msg: A full set of the data recieved msg: A full set of the data received
""" """
log.info( log.info(
"Emoji change from {} in {} ({}): {}".format( "Emoji change from {} in {} ({}): {}".format(
@@ -3257,7 +3258,7 @@ class Client(object):
thread_type (ThreadType): Type of thread that the action was sent to. See :ref:`intro_threads` thread_type (ThreadType): Type of thread that the action was sent to. See :ref:`intro_threads`
ts: A timestamp of the action ts: A timestamp of the action
metadata: Extra metadata about the action metadata: Extra metadata about the action
msg: A full set of the data recieved msg: A full set of the data received
""" """
log.info( log.info(
"Title change from {} in {} ({}): {}".format( "Title change from {} in {} ({}): {}".format(
@@ -3284,7 +3285,7 @@ class Client(object):
thread_id: Thread ID that the action was sent to. See :ref:`intro_threads` thread_id: Thread ID that the action was sent to. See :ref:`intro_threads`
thread_type (ThreadType): Type of thread that the action was sent to. See :ref:`intro_threads` thread_type (ThreadType): Type of thread that the action was sent to. See :ref:`intro_threads`
ts: A timestamp of the action ts: A timestamp of the action
msg: A full set of the data recieved msg: A full set of the data received
""" """
log.info("{} changed thread image in {}".format(author_id, thread_id)) log.info("{} changed thread image in {}".format(author_id, thread_id))
@@ -3311,7 +3312,7 @@ class Client(object):
thread_type (ThreadType): Type of thread that the action was sent to. See :ref:`intro_threads` thread_type (ThreadType): Type of thread that the action was sent to. See :ref:`intro_threads`
ts: A timestamp of the action ts: A timestamp of the action
metadata: Extra metadata about the action metadata: Extra metadata about the action
msg: A full set of the data recieved msg: A full set of the data received
""" """
log.info( log.info(
"Nickname change from {} in {} ({}) for {}: {}".format( "Nickname change from {} in {} ({}) for {}: {}".format(
@@ -3337,7 +3338,7 @@ class Client(object):
author_id: The ID of the person who added the admins author_id: The ID of the person who added the admins
thread_id: Thread ID that the action was sent to. See :ref:`intro_threads` thread_id: Thread ID that the action was sent to. See :ref:`intro_threads`
ts: A timestamp of the action ts: A timestamp of the action
msg: A full set of the data recieved msg: A full set of the data received
""" """
log.info("{} added admin: {} in {}".format(author_id, added_id, thread_id)) log.info("{} added admin: {} in {}".format(author_id, added_id, thread_id))
@@ -3359,7 +3360,7 @@ class Client(object):
author_id: The ID of the person who removed the admins author_id: The ID of the person who removed the admins
thread_id: Thread ID that the action was sent to. See :ref:`intro_threads` thread_id: Thread ID that the action was sent to. See :ref:`intro_threads`
ts: A timestamp of the action ts: A timestamp of the action
msg: A full set of the data recieved msg: A full set of the data received
""" """
log.info("{} removed admin: {} in {}".format(author_id, removed_id, thread_id)) log.info("{} removed admin: {} in {}".format(author_id, removed_id, thread_id))
@@ -3381,7 +3382,7 @@ class Client(object):
author_id: The ID of the person who changed approval mode author_id: The ID of the person who changed approval mode
thread_id: Thread ID that the action was sent to. See :ref:`intro_threads` thread_id: Thread ID that the action was sent to. See :ref:`intro_threads`
ts: A timestamp of the action ts: A timestamp of the action
msg: A full set of the data recieved msg: A full set of the data received
""" """
if approval_mode: if approval_mode:
log.info("{} activated approval mode in {}".format(author_id, thread_id)) log.info("{} activated approval mode in {}".format(author_id, thread_id))
@@ -3407,7 +3408,7 @@ class Client(object):
seen_ts: A timestamp of when the person saw the message seen_ts: A timestamp of when the person saw the message
ts: A timestamp of the action ts: A timestamp of the action
metadata: Extra metadata about the action metadata: Extra metadata about the action
msg: A full set of the data recieved msg: A full set of the data received
""" """
log.info( log.info(
"Messages seen by {} in {} ({}) at {}s".format( "Messages seen by {} in {} ({}) at {}s".format(
@@ -3434,7 +3435,7 @@ class Client(object):
thread_type (ThreadType): Type of thread that the action was sent to. See :ref:`intro_threads` thread_type (ThreadType): Type of thread that the action was sent to. See :ref:`intro_threads`
ts: A timestamp of the action ts: A timestamp of the action
metadata: Extra metadata about the action metadata: Extra metadata about the action
msg: A full set of the data recieved msg: A full set of the data received
""" """
log.info( log.info(
"Messages {} delivered to {} in {} ({}) at {}s".format( "Messages {} delivered to {} in {} ({}) at {}s".format(
@@ -3453,7 +3454,7 @@ class Client(object):
seen_ts: A timestamp of when the threads were seen seen_ts: A timestamp of when the threads were seen
ts: A timestamp of the action ts: A timestamp of the action
metadata: Extra metadata about the action metadata: Extra metadata about the action
msg: A full set of the data recieved msg: A full set of the data received
""" """
log.info( log.info(
"Marked messages as seen in threads {} at {}s".format( "Marked messages as seen in threads {} at {}s".format(
@@ -3478,7 +3479,7 @@ class Client(object):
thread_id: Thread ID that the action was sent to. See :ref:`intro_threads` thread_id: Thread ID that the action was sent to. See :ref:`intro_threads`
thread_type (ThreadType): Type of thread that the action was sent to. See :ref:`intro_threads` thread_type (ThreadType): Type of thread that the action was sent to. See :ref:`intro_threads`
ts: A timestamp of the action ts: A timestamp of the action
msg: A full set of the data recieved msg: A full set of the data received
""" """
log.info( log.info(
"{} unsent the message {} in {} ({}) at {}s".format( "{} unsent the message {} in {} ({}) at {}s".format(
@@ -3503,7 +3504,7 @@ class Client(object):
author_id: The ID of the person who added the people author_id: The ID of the person who added the people
thread_id: Thread ID that the action was sent to. See :ref:`intro_threads` thread_id: Thread ID that the action was sent to. See :ref:`intro_threads`
ts: A timestamp of the action ts: A timestamp of the action
msg: A full set of the data recieved msg: A full set of the data received
""" """
log.info( log.info(
"{} added: {} in {}".format(author_id, ", ".join(added_ids), thread_id) "{} added: {} in {}".format(author_id, ", ".join(added_ids), thread_id)
@@ -3526,7 +3527,7 @@ class Client(object):
author_id: The ID of the person who removed the person author_id: The ID of the person who removed the person
thread_id: Thread ID that the action was sent to. See :ref:`intro_threads` thread_id: Thread ID that the action was sent to. See :ref:`intro_threads`
ts: A timestamp of the action ts: A timestamp of the action
msg: A full set of the data recieved msg: A full set of the data received
""" """
log.info("{} removed: {} in {}".format(author_id, removed_id, thread_id)) log.info("{} removed: {} in {}".format(author_id, removed_id, thread_id))
@@ -3535,7 +3536,7 @@ class Client(object):
Args: Args:
from_id: The ID of the person that sent the request from_id: The ID of the person that sent the request
msg: A full set of the data recieved msg: A full set of the data received
""" """
log.info("Friend request from {}".format(from_id)) log.info("Friend request from {}".format(from_id))
@@ -3548,7 +3549,7 @@ class Client(object):
unseen: -- unseen: --
unread: -- unread: --
recent_unread: -- recent_unread: --
msg: A full set of the data recieved msg: A full set of the data received
""" """
log.info("Inbox event: {}, {}, {}".format(unseen, unread, recent_unread)) log.info("Inbox event: {}, {}, {}".format(unseen, unread, recent_unread))
@@ -3562,7 +3563,7 @@ class Client(object):
status (TypingStatus): The typing status status (TypingStatus): The typing status
thread_id: Thread ID that the action was sent to. See :ref:`intro_threads` thread_id: Thread ID that the action was sent to. See :ref:`intro_threads`
thread_type (ThreadType): Type of thread that the action was sent to. See :ref:`intro_threads` thread_type (ThreadType): Type of thread that the action was sent to. See :ref:`intro_threads`
msg: A full set of the data recieved msg: A full set of the data received
""" """
pass pass
@@ -3588,12 +3589,12 @@ class Client(object):
game_id: The ID of the game game_id: The ID of the game
game_name: Name of the game game_name: Name of the game
score: Score obtained in the game score: Score obtained in the game
leaderboard: Actual leaderboard of the game in the thread leaderboard: Actual leader board of the game in the thread
thread_id: Thread ID that the action was sent to. See :ref:`intro_threads` thread_id: Thread ID that the action was sent to. See :ref:`intro_threads`
thread_type (ThreadType): Type of thread that the action was sent to. See :ref:`intro_threads` thread_type (ThreadType): Type of thread that the action was sent to. See :ref:`intro_threads`
ts: A timestamp of the action ts: A timestamp of the action
metadata: Extra metadata about the action metadata: Extra metadata about the action
msg: A full set of the data recieved msg: A full set of the data received
""" """
log.info( log.info(
'{} played "{}" in {} ({})'.format( '{} played "{}" in {} ({})'.format(
@@ -3621,7 +3622,7 @@ class Client(object):
thread_id: Thread ID that the action was sent to. See :ref:`intro_threads` thread_id: Thread ID that the action was sent to. See :ref:`intro_threads`
thread_type (ThreadType): Type of thread that the action was sent to. See :ref:`intro_threads` thread_type (ThreadType): Type of thread that the action was sent to. See :ref:`intro_threads`
ts: A timestamp of the action ts: A timestamp of the action
msg: A full set of the data recieved msg: A full set of the data received
""" """
log.info( log.info(
"{} reacted to message {} with {} in {} ({})".format( "{} reacted to message {} with {} in {} ({})".format(
@@ -3646,7 +3647,7 @@ class Client(object):
thread_id: Thread ID that the action was sent to. See :ref:`intro_threads` thread_id: Thread ID that the action was sent to. See :ref:`intro_threads`
thread_type (ThreadType): Type of thread that the action was sent to. See :ref:`intro_threads` thread_type (ThreadType): Type of thread that the action was sent to. See :ref:`intro_threads`
ts: A timestamp of the action ts: A timestamp of the action
msg: A full set of the data recieved msg: A full set of the data received
""" """
log.info( log.info(
"{} removed reaction from {} message in {} ({})".format( "{} removed reaction from {} message in {} ({})".format(
@@ -3664,7 +3665,7 @@ class Client(object):
thread_id: Thread ID that the action was sent to. See :ref:`intro_threads` thread_id: Thread ID that the action was sent to. See :ref:`intro_threads`
thread_type (ThreadType): Type of thread that the action was sent to. See :ref:`intro_threads` thread_type (ThreadType): Type of thread that the action was sent to. See :ref:`intro_threads`
ts: A timestamp of the action ts: A timestamp of the action
msg: A full set of the data recieved msg: A full set of the data received
""" """
log.info( log.info(
"{} blocked {} ({}) thread".format(author_id, thread_id, thread_type.name) "{} blocked {} ({}) thread".format(author_id, thread_id, thread_type.name)
@@ -3680,7 +3681,7 @@ class Client(object):
thread_id: Thread ID that the action was sent to. See :ref:`intro_threads` thread_id: Thread ID that the action was sent to. See :ref:`intro_threads`
thread_type (ThreadType): Type of thread that the action was sent to. See :ref:`intro_threads` thread_type (ThreadType): Type of thread that the action was sent to. See :ref:`intro_threads`
ts: A timestamp of the action ts: A timestamp of the action
msg: A full set of the data recieved msg: A full set of the data received
""" """
log.info( log.info(
"{} unblocked {} ({}) thread".format(author_id, thread_id, thread_type.name) "{} unblocked {} ({}) thread".format(author_id, thread_id, thread_type.name)
@@ -3705,7 +3706,7 @@ class Client(object):
thread_id: Thread ID that the action was sent to. See :ref:`intro_threads` thread_id: Thread ID that the action was sent to. See :ref:`intro_threads`
thread_type (ThreadType): Type of thread that the action was sent to. See :ref:`intro_threads` thread_type (ThreadType): Type of thread that the action was sent to. See :ref:`intro_threads`
ts: A timestamp of the action ts: A timestamp of the action
msg: A full set of the data recieved msg: A full set of the data received
""" """
log.info( log.info(
"{} sent live location info in {} ({}) with latitude {} and longitude {}".format( "{} sent live location info in {} ({}) with latitude {} and longitude {}".format(
@@ -3737,7 +3738,7 @@ class Client(object):
thread_type (ThreadType): Type of thread that the action was sent to. See :ref:`intro_threads` thread_type (ThreadType): Type of thread that the action was sent to. See :ref:`intro_threads`
ts: A timestamp of the action ts: A timestamp of the action
metadata: Extra metadata about the action metadata: Extra metadata about the action
msg: A full set of the data recieved msg: A full set of the data received
""" """
log.info( log.info(
"{} started call in {} ({})".format(caller_id, thread_id, thread_type.name) "{} started call in {} ({})".format(caller_id, thread_id, thread_type.name)
@@ -3769,7 +3770,7 @@ class Client(object):
thread_type (ThreadType): Type of thread that the action was sent to. See :ref:`intro_threads` thread_type (ThreadType): Type of thread that the action was sent to. See :ref:`intro_threads`
ts: A timestamp of the action ts: A timestamp of the action
metadata: Extra metadata about the action metadata: Extra metadata about the action
msg: A full set of the data recieved msg: A full set of the data received
""" """
log.info( log.info(
"{} ended call in {} ({})".format(caller_id, thread_id, thread_type.name) "{} ended call in {} ({})".format(caller_id, thread_id, thread_type.name)
@@ -3796,7 +3797,7 @@ class Client(object):
thread_type (ThreadType): Type of thread that the action was sent to. See :ref:`intro_threads` thread_type (ThreadType): Type of thread that the action was sent to. See :ref:`intro_threads`
ts: A timestamp of the action ts: A timestamp of the action
metadata: Extra metadata about the action metadata: Extra metadata about the action
msg: A full set of the data recieved msg: A full set of the data received
""" """
log.info( log.info(
"{} joined call in {} ({})".format(joined_id, thread_id, thread_type.name) "{} joined call in {} ({})".format(joined_id, thread_id, thread_type.name)
@@ -3823,7 +3824,7 @@ class Client(object):
thread_type (ThreadType): Type of thread that the action was sent to. See :ref:`intro_threads` thread_type (ThreadType): Type of thread that the action was sent to. See :ref:`intro_threads`
ts: A timestamp of the action ts: A timestamp of the action
metadata: Extra metadata about the action metadata: Extra metadata about the action
msg: A full set of the data recieved msg: A full set of the data received
""" """
log.info( log.info(
"{} created poll {} in {} ({})".format( "{} created poll {} in {} ({})".format(
@@ -3854,7 +3855,7 @@ class Client(object):
thread_type (ThreadType): Type of thread that the action was sent to. See :ref:`intro_threads` thread_type (ThreadType): Type of thread that the action was sent to. See :ref:`intro_threads`
ts: A timestamp of the action ts: A timestamp of the action
metadata: Extra metadata about the action metadata: Extra metadata about the action
msg: A full set of the data recieved msg: A full set of the data received
""" """
log.info( log.info(
"{} voted in poll {} in {} ({})".format( "{} voted in poll {} in {} ({})".format(
@@ -3883,7 +3884,7 @@ class Client(object):
thread_type (ThreadType): Type of thread that the action was sent to. See :ref:`intro_threads` thread_type (ThreadType): Type of thread that the action was sent to. See :ref:`intro_threads`
ts: A timestamp of the action ts: A timestamp of the action
metadata: Extra metadata about the action metadata: Extra metadata about the action
msg: A full set of the data recieved msg: A full set of the data received
""" """
log.info( log.info(
"{} created plan {} in {} ({})".format( "{} created plan {} in {} ({})".format(
@@ -3910,7 +3911,7 @@ class Client(object):
thread_type (ThreadType): Type of thread that the action was sent to. See :ref:`intro_threads` thread_type (ThreadType): Type of thread that the action was sent to. See :ref:`intro_threads`
ts: A timestamp of the action ts: A timestamp of the action
metadata: Extra metadata about the action metadata: Extra metadata about the action
msg: A full set of the data recieved msg: A full set of the data received
""" """
log.info( log.info(
"Plan {} has ended in {} ({})".format(plan, thread_id, thread_type.name) "Plan {} has ended in {} ({})".format(plan, thread_id, thread_type.name)
@@ -3937,7 +3938,7 @@ class Client(object):
thread_type (ThreadType): Type of thread that the action was sent to. See :ref:`intro_threads` thread_type (ThreadType): Type of thread that the action was sent to. See :ref:`intro_threads`
ts: A timestamp of the action ts: A timestamp of the action
metadata: Extra metadata about the action metadata: Extra metadata about the action
msg: A full set of the data recieved msg: A full set of the data received
""" """
log.info( log.info(
"{} edited plan {} in {} ({})".format( "{} edited plan {} in {} ({})".format(
@@ -3966,7 +3967,7 @@ class Client(object):
thread_type (ThreadType): Type of thread that the action was sent to. See :ref:`intro_threads` thread_type (ThreadType): Type of thread that the action was sent to. See :ref:`intro_threads`
ts: A timestamp of the action ts: A timestamp of the action
metadata: Extra metadata about the action metadata: Extra metadata about the action
msg: A full set of the data recieved msg: A full set of the data received
""" """
log.info( log.info(
"{} deleted plan {} in {} ({})".format( "{} deleted plan {} in {} ({})".format(
@@ -3997,7 +3998,7 @@ class Client(object):
thread_type (ThreadType): Type of thread that the action was sent to. See :ref:`intro_threads` thread_type (ThreadType): Type of thread that the action was sent to. See :ref:`intro_threads`
ts: A timestamp of the action ts: A timestamp of the action
metadata: Extra metadata about the action metadata: Extra metadata about the action
msg: A full set of the data recieved msg: A full set of the data received
""" """
if take_part: if take_part:
log.info( log.info(
@@ -4017,7 +4018,7 @@ class Client(object):
Args: Args:
ts: A timestamp of the action ts: A timestamp of the action
msg: A full set of the data recieved msg: A full set of the data received
""" """
pass pass
@@ -4025,8 +4026,8 @@ class Client(object):
"""Called when the client receives chat online presence update. """Called when the client receives chat online presence update.
Args: Args:
buddylist: A list of dicts with friend id and last seen timestamp buddylist: A list of dictionaries with friend id and last seen timestamp
msg: A full set of the data recieved msg: A full set of the data received
""" """
log.debug("Chat Timestamps received: {}".format(buddylist)) log.debug("Chat Timestamps received: {}".format(buddylist))
@@ -4035,24 +4036,24 @@ class Client(object):
Args: Args:
statuses (dict): Dictionary with user IDs as keys and :class:`ActiveStatus` as values statuses (dict): Dictionary with user IDs as keys and :class:`ActiveStatus` as values
msg: A full set of the data recieved msg: A full set of the data received
""" """
log.debug("Buddylist overlay received: {}".format(statuses)) log.debug("Buddylist overlay received: {}".format(statuses))
def onUnknownMesssageType(self, msg=None): def onUnknownMesssageType(self, msg=None):
"""Called when the client is listening, and some unknown data was recieved. """Called when the client is listening, and some unknown data was received.
Args: Args:
msg: A full set of the data recieved msg: A full set of the data received
""" """
log.debug("Unknown message received: {}".format(msg)) log.debug("Unknown message received: {}".format(msg))
def onMessageError(self, exception=None, msg=None): def onMessageError(self, exception=None, msg=None):
"""Called when an error was encountered while parsing recieved data. """Called when an error was encountered while parsing received data.
Args: Args:
exception: The exception that was encountered exception: The exception that was encountered
msg: A full set of the data recieved msg: A full set of the data received
""" """
log.exception("Exception in parsing of {}".format(msg)) log.exception("Exception in parsing of {}".format(msg))

View File

@@ -8,7 +8,7 @@ log = logging.getLogger("client")
class Enum(aenum.Enum): class Enum(aenum.Enum):
"""Used internally by fbchat to support enumerations""" """Used internally by ``fbchat`` to support enumerations"""
def __repr__(self): def __repr__(self):
# For documentation: # For documentation:

View File

@@ -3,9 +3,9 @@ from __future__ import unicode_literals
class FBchatException(Exception): class FBchatException(Exception):
"""Custom exception thrown by fbchat. """Custom exception thrown by ``fbchat``.
All exceptions in the fbchat module inherits this. All exceptions in the ``fbchat`` module inherits this.
""" """
@@ -14,7 +14,7 @@ class FBchatFacebookError(FBchatException):
fb_error_code = None fb_error_code = None
#: The error message that Facebook returned (In the user's own language) #: The error message that Facebook returned (In the user's own language)
fb_error_message = None fb_error_message = None
#: The status code that was sent in the http response (eg. 404) (Usually only set if not successful, aka. not 200) #: The status code that was sent in the HTTP response (e.g. 404) (Usually only set if not successful, aka. not 200)
request_status_code = None request_status_code = None
def __init__( def __init__(
@@ -25,7 +25,7 @@ class FBchatFacebookError(FBchatException):
request_status_code=None, request_status_code=None,
): ):
super(FBchatFacebookError, self).__init__(message) super(FBchatFacebookError, self).__init__(message)
"""Thrown by fbchat when Facebook returns an error""" """Thrown by ``fbchat`` when Facebook returns an error"""
self.fb_error_code = str(fb_error_code) self.fb_error_code = str(fb_error_code)
self.fb_error_message = fb_error_message self.fb_error_message = fb_error_message
self.request_status_code = request_status_code self.request_status_code = request_status_code
@@ -57,4 +57,4 @@ class FBchatPleaseRefresh(FBchatFacebookError):
class FBchatUserError(FBchatException): class FBchatUserError(FBchatException):
"""Thrown by fbchat when wrong values are entered.""" """Thrown by ``fbchat`` when wrong values are entered."""

View File

@@ -9,7 +9,7 @@ from ._attachment import Attachment
class FileAttachment(Attachment): class FileAttachment(Attachment):
"""Represents a file that has been sent as a Facebook attachment.""" """Represents a file that has been sent as a Facebook attachment."""
#: Url where you can download the file #: URL where you can download the file
url = attr.ib(None) url = attr.ib(None)
#: Size of the file in bytes #: Size of the file in bytes
size = attr.ib(None) size = attr.ib(None)
@@ -37,9 +37,9 @@ class AudioAttachment(Attachment):
#: Name of the file #: Name of the file
filename = attr.ib(None) filename = attr.ib(None)
#: Url of the audio file #: URL of the audio file
url = attr.ib(None) url = attr.ib(None)
#: Duration of the audioclip in milliseconds #: Duration of the audio clip in milliseconds
duration = attr.ib(None) duration = attr.ib(None)
#: Audio type #: Audio type
audio_type = attr.ib(None) audio_type = attr.ib(None)
@@ -61,11 +61,11 @@ class AudioAttachment(Attachment):
class ImageAttachment(Attachment): class ImageAttachment(Attachment):
"""Represents an image that has been sent as a Facebook attachment. """Represents an image that has been sent as a Facebook attachment.
To retrieve the full image url, use: `Client.fetchImageUrl`, and pass it the id of To retrieve the full image URL, use: `Client.fetchImageUrl`, and pass it the id of
the image attachment. the image attachment.
""" """
#: The extension of the original image (eg. 'png') #: The extension of the original image (e.g. ``png``)
original_extension = attr.ib(None) original_extension = attr.ib(None)
#: Width of original image #: Width of original image
width = attr.ib(None, converter=lambda x: None if x is None else int(x)) width = attr.ib(None, converter=lambda x: None if x is None else int(x))
@@ -92,7 +92,7 @@ class ImageAttachment(Attachment):
#: Height of the large preview image #: Height of the large preview image
large_preview_height = attr.ib(None) large_preview_height = attr.ib(None)
#: URL to an animated preview of the image (eg. for gifs) #: URL to an animated preview of the image (e.g. for GIFs)
animated_preview_url = attr.ib(None) animated_preview_url = attr.ib(None)
#: Width of the animated preview image #: Width of the animated preview image
animated_preview_width = attr.ib(None) animated_preview_width = attr.ib(None)

View File

@@ -12,7 +12,7 @@ class Group(Thread):
#: Unique list (set) of the group thread's participant user IDs #: Unique list (set) of the group thread's participant user IDs
participants = attr.ib(factory=set, converter=lambda x: set() if x is None else x) participants = attr.ib(factory=set, converter=lambda x: set() if x is None else x)
#: A dict, containing user nicknames mapped to their IDs #: A dictionary, containing user nicknames mapped to their IDs
nicknames = attr.ib(factory=dict, converter=lambda x: {} if x is None else x) nicknames = attr.ib(factory=dict, converter=lambda x: {} if x is None else x)
#: A :class:`ThreadColor`. The groups's message color #: A :class:`ThreadColor`. The groups's message color
color = attr.ib(None) color = attr.ib(None)

View File

@@ -75,9 +75,9 @@ class Message(object):
timestamp = attr.ib(None, init=False) timestamp = attr.ib(None, init=False)
#: Whether the message is read #: Whether the message is read
is_read = attr.ib(None, init=False) is_read = attr.ib(None, init=False)
#: A list of pepole IDs who read the message, works only with :func:`fbchat.Client.fetchThreadMessages` #: A list of people IDs who read the message, works only with :func:`fbchat.Client.fetchThreadMessages`
read_by = attr.ib(factory=list, init=False) read_by = attr.ib(factory=list, init=False)
#: A dict with user's IDs as keys, and their :class:`MessageReaction` as values #: A dictionary with user's IDs as keys, and their :class:`MessageReaction` as values
reactions = attr.ib(factory=dict, init=False) reactions = attr.ib(factory=dict, init=False)
#: A :class:`Sticker` #: A :class:`Sticker`
sticker = attr.ib(None) sticker = attr.ib(None)

View File

@@ -10,7 +10,7 @@ from ._thread import ThreadType, Thread
class Page(Thread): class Page(Thread):
"""Represents a Facebook page. Inherits `Thread`.""" """Represents a Facebook page. Inherits `Thread`."""
#: The page's custom url #: The page's custom URL
url = attr.ib(None) url = attr.ib(None)
#: The name of the page's location city #: The name of the page's location city
city = attr.ib(None) city = attr.ib(None)

View File

@@ -18,7 +18,7 @@ class Plan(object):
#: ID of the plan #: ID of the plan
uid = attr.ib(None, init=False) uid = attr.ib(None, init=False)
#: Plan time (unix time stamp), only precise down to the minute #: Plan time (timestamp), only precise down to the minute
time = attr.ib(converter=int) time = attr.ib(converter=int)
#: Plan title #: Plan title
title = attr.ib() title = attr.ib()
@@ -28,7 +28,7 @@ class Plan(object):
location_id = attr.ib(None, converter=lambda x: x or "") location_id = attr.ib(None, converter=lambda x: x or "")
#: ID of the plan creator #: ID of the plan creator
author_id = attr.ib(None, init=False) author_id = attr.ib(None, init=False)
#: Dict of `User` IDs mapped to their `GuestStatus` #: Dictionary of `User` IDs mapped to their `GuestStatus`
guests = attr.ib(None, init=False) guests = attr.ib(None, init=False)
@property @property

View File

@@ -21,7 +21,7 @@ class Sticker(Attachment):
large_sprite_image = attr.ib(None) large_sprite_image = attr.ib(None)
#: The amount of frames present in the spritemap pr. row #: The amount of frames present in the spritemap pr. row
frames_per_row = attr.ib(None) frames_per_row = attr.ib(None)
#: The amount of frames present in the spritemap pr. coloumn #: The amount of frames present in the spritemap pr. column
frames_per_col = attr.ib(None) frames_per_col = attr.ib(None)
#: The frame rate the spritemap is intended to be played in #: The frame rate the spritemap is intended to be played in
frame_rate = attr.ib(None) frame_rate = attr.ib(None)

View File

@@ -69,7 +69,7 @@ class Thread(object):
uid = attr.ib(converter=str) 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() type = attr.ib()
#: A url to the thread's picture #: A URL to the thread's picture
photo = attr.ib(None) photo = attr.ib(None)
#: The name of the thread #: The name of the thread
name = attr.ib(None) name = attr.ib(None)

View File

@@ -48,7 +48,7 @@ class TypingStatus(Enum):
class User(Thread): class User(Thread):
"""Represents a Facebook user. Inherits `Thread`.""" """Represents a Facebook user. Inherits `Thread`."""
#: The profile url #: The profile URL
url = attr.ib(None) url = attr.ib(None)
#: The users first name #: The users first name
first_name = attr.ib(None) first_name = attr.ib(None)

View File

@@ -56,6 +56,7 @@ test = [
] ]
docs = [ docs = [
"sphinx~=2.0", "sphinx~=2.0",
"sphinxcontrib-spelling~=4.0"
] ]
lint = [ lint = [
"black", "black",