diff --git a/.travis.yml b/.travis.yml index a04077f..00c5228 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,17 +11,9 @@ script: pytest -m offline jobs: include: - - python: 2.7 - before_install: - - sudo apt-get -y install python3-pip python3-setuptools - - sudo pip3 install flit - install: flit install --python python --deps production --extras test - - python: 3.4 - python: 3.5 - python: 3.6 - python: 3.7 - dist: xenial - sudo: required - python: pypy3.5 - name: Lint diff --git a/README.rst b/README.rst index a857438..eb3cc5f 100644 --- a/README.rst +++ b/README.rst @@ -1,23 +1,27 @@ ``fbchat``: Facebook Chat (Messenger) for Python ================================================ -.. image:: https://img.shields.io/badge/license-BSD-blue.svg +.. image:: https://badgen.net/pypi/license/fbchat :target: https://github.com/carpedm20/fbchat/tree/master/LICENSE :alt: License: BSD 3-Clause -.. image:: https://img.shields.io/badge/python-2.7%2C%203.4%2C%203.5%2C%203.6%203.7%20pypy-blue.svg +.. image:: https://badgen.net/badge/python/3.5,3.6,3.7,3.8,pypy?list=| :target: https://pypi.python.org/pypi/fbchat - :alt: Supported python versions: 2.7, 3.4, 3.5, 3.6, 3.7 and pypy + :alt: Supported python versions: 3.5, 3.6, 3.7, 3.8 and pypy -.. image:: https://readthedocs.org/projects/fbchat/badge/?version=latest +.. image:: https://badgen.net/pypi/v/fbchat + :target: https://pypi.python.org/pypi/fbchat + :alt: Project version + +.. image:: https://readthedocs.org/projects/fbchat/badge/?version=stable :target: https://fbchat.readthedocs.io :alt: Documentation -.. image:: https://travis-ci.org/carpedm20/fbchat.svg?branch=master +.. image:: https://badgen.net/travis/carpedm20/fbchat :target: https://travis-ci.org/carpedm20/fbchat :alt: Travis CI -.. image:: https://img.shields.io/badge/code%20style-black-000000.svg +.. image:: https://badgen.net/badge/code%20style/black/black :target: https://github.com/ambv/black :alt: Code style diff --git a/docs/_static/license.svg b/docs/_static/license.svg deleted file mode 100644 index 900d32c..0000000 --- a/docs/_static/license.svg +++ /dev/null @@ -1 +0,0 @@ -licenselicenseBSDBSD \ No newline at end of file diff --git a/docs/_static/python-versions.svg b/docs/_static/python-versions.svg deleted file mode 100644 index f3f3bd4..0000000 --- a/docs/_static/python-versions.svg +++ /dev/null @@ -1 +0,0 @@ -pythonpython2.7, 3.4, 3.5, 3.62.7, 3.4, 3.5, 3.6 \ No newline at end of file diff --git a/docs/conf.py b/docs/conf.py index 0e5309d..4f95bb1 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- -# # Configuration file for the Sphinx documentation builder. # # This file does only contain a selection of the most common options. For a diff --git a/docs/index.rst b/docs/index.rst index b58df24..7efdb5a 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -11,24 +11,12 @@ Release v\ |version|. (:ref:`install`) -.. generated with: https://img.shields.io/badge/license-BSD-blue.svg - -.. image:: /_static/license.svg - :target: https://github.com/carpedm20/fbchat/blob/master/LICENSE.txt - :alt: License: BSD - -.. generated with: https://img.shields.io/badge/python-2.7%2C%203.4%2C%203.5%2C%203.6-blue.svg - -.. image:: /_static/python-versions.svg - :target: https://pypi.python.org/pypi/fbchat - :alt: Supported python versions: 2.7, 3.4, 3.5 and 3.6 - Facebook Chat (`Messenger `_) for Python. This project was inspired by `facebook-chat-api `_. **No XMPP or API key is needed**. Just use your email and password. -Currently ``fbchat`` support Python 2.7, 3.4, 3.5 and 3.6: +Currently ``fbchat`` support Python 3.5, 3.6, 3.7 and 3.8: ``fbchat`` works by emulating the browser. This means doing the exact same GET/POST requests and tricking Facebook into thinking it's accessing the website normally. diff --git a/examples/basic_usage.py b/examples/basic_usage.py index c712dcd..b64f30e 100644 --- a/examples/basic_usage.py +++ b/examples/basic_usage.py @@ -1,5 +1,3 @@ -# -*- coding: UTF-8 -*- - from fbchat import Client from fbchat.models import * diff --git a/examples/echobot.py b/examples/echobot.py index d03159e..ac1e6ab 100644 --- a/examples/echobot.py +++ b/examples/echobot.py @@ -1,5 +1,3 @@ -# -*- coding: UTF-8 -*- - from fbchat import log, Client # Subclass fbchat.Client and override required methods diff --git a/examples/fetch.py b/examples/fetch.py index cbcef40..f18c048 100644 --- a/examples/fetch.py +++ b/examples/fetch.py @@ -1,5 +1,3 @@ -# -*- coding: UTF-8 -*- - from itertools import islice from fbchat import Client from fbchat.models import * diff --git a/examples/interract.py b/examples/interract.py index 12dc21e..f40f1ca 100644 --- a/examples/interract.py +++ b/examples/interract.py @@ -1,5 +1,3 @@ -# -*- coding: UTF-8 -*- - from fbchat import Client from fbchat.models import * diff --git a/examples/keepbot.py b/examples/keepbot.py index b3e835e..73a213c 100644 --- a/examples/keepbot.py +++ b/examples/keepbot.py @@ -1,5 +1,3 @@ -# -*- coding: UTF-8 -*- - from fbchat import log, Client from fbchat.models import * diff --git a/examples/removebot.py b/examples/removebot.py index 91979ff..8b1a941 100644 --- a/examples/removebot.py +++ b/examples/removebot.py @@ -1,5 +1,3 @@ -# -*- coding: UTF-8 -*- - from fbchat import log, Client from fbchat.models import * diff --git a/fbchat/__init__.py b/fbchat/__init__.py index fa53c73..fa58ba9 100644 --- a/fbchat/__init__.py +++ b/fbchat/__init__.py @@ -1,10 +1,8 @@ -# -*- coding: UTF-8 -*- """Facebook Chat (Messenger) for Python :copyright: (c) 2015 - 2019 by Taehoon Kim :license: BSD 3-Clause, see LICENSE for more details. """ -from __future__ import unicode_literals # These imports are far too general, but they're needed for backwards compatbility. from .models import * diff --git a/fbchat/_attachment.py b/fbchat/_attachment.py index 8ce3296..ec48721 100644 --- a/fbchat/_attachment.py +++ b/fbchat/_attachment.py @@ -1,12 +1,9 @@ -# -*- coding: UTF-8 -*- -from __future__ import unicode_literals - import attr from . import _util @attr.s(cmp=False) -class Attachment(object): +class Attachment: """Represents a Facebook attachment.""" #: The attachment ID diff --git a/fbchat/_client.py b/fbchat/_client.py index 7c8b7ee..ec7efee 100644 --- a/fbchat/_client.py +++ b/fbchat/_client.py @@ -1,6 +1,3 @@ -# -*- coding: UTF-8 -*- -from __future__ import unicode_literals - import requests import urllib from uuid import uuid1 @@ -15,11 +12,6 @@ from ._state import State import time import json -try: - from urllib.parse import urlparse, parse_qs -except ImportError: - from urlparse import urlparse, parse_qs - ACONTEXT = { "action_history": [ @@ -28,7 +20,7 @@ ACONTEXT = { } -class Client(object): +class Client: """A client for the Facebook Chat (Messenger). This is the main class of ``fbchat``, which contains all the methods you use to diff --git a/fbchat/_core.py b/fbchat/_core.py index e7d86b4..e6df0aa 100644 --- a/fbchat/_core.py +++ b/fbchat/_core.py @@ -1,6 +1,3 @@ -# -*- coding: UTF-8 -*- -from __future__ import unicode_literals - import logging import aenum diff --git a/fbchat/_exception.py b/fbchat/_exception.py index e49537c..c28d68b 100644 --- a/fbchat/_exception.py +++ b/fbchat/_exception.py @@ -1,7 +1,3 @@ -# -*- coding: UTF-8 -*- -from __future__ import unicode_literals - - class FBchatException(Exception): """Custom exception thrown by ``fbchat``. diff --git a/fbchat/_file.py b/fbchat/_file.py index 40ab04d..db3ebf1 100644 --- a/fbchat/_file.py +++ b/fbchat/_file.py @@ -1,6 +1,3 @@ -# -*- coding: UTF-8 -*- -from __future__ import unicode_literals - import attr from ._attachment import Attachment diff --git a/fbchat/_graphql.py b/fbchat/_graphql.py index 375f307..9a186ec 100644 --- a/fbchat/_graphql.py +++ b/fbchat/_graphql.py @@ -1,6 +1,3 @@ -# -*- coding: UTF-8 -*- -from __future__ import unicode_literals - import json import re from . import _util diff --git a/fbchat/_group.py b/fbchat/_group.py index 1d7b584..e4af880 100644 --- a/fbchat/_group.py +++ b/fbchat/_group.py @@ -1,6 +1,3 @@ -# -*- coding: UTF-8 -*- -from __future__ import unicode_literals - import attr from . import _plan from ._thread import ThreadType, Thread diff --git a/fbchat/_location.py b/fbchat/_location.py index e3cc566..a3dc829 100644 --- a/fbchat/_location.py +++ b/fbchat/_location.py @@ -1,6 +1,3 @@ -# -*- coding: UTF-8 -*- -from __future__ import unicode_literals - import attr from ._attachment import Attachment from . import _util diff --git a/fbchat/_message.py b/fbchat/_message.py index f2d3a8c..9f6afa6 100644 --- a/fbchat/_message.py +++ b/fbchat/_message.py @@ -1,6 +1,3 @@ -# -*- coding: UTF-8 -*- -from __future__ import unicode_literals - import attr import json from string import Formatter @@ -46,7 +43,7 @@ class MessageReaction(Enum): @attr.s(cmp=False) -class Mention(object): +class Mention: """Represents a ``@mention``.""" #: The thread ID the mention is pointing at @@ -58,7 +55,7 @@ class Mention(object): @attr.s(cmp=False) -class Message(object): +class Message: """Represents a Facebook message.""" #: The actual message diff --git a/fbchat/_page.py b/fbchat/_page.py index 7721cf2..76bbad7 100644 --- a/fbchat/_page.py +++ b/fbchat/_page.py @@ -1,6 +1,3 @@ -# -*- coding: UTF-8 -*- -from __future__ import unicode_literals - import attr from . import _plan from ._thread import ThreadType, Thread diff --git a/fbchat/_plan.py b/fbchat/_plan.py index bc4cd47..1a3c5bd 100644 --- a/fbchat/_plan.py +++ b/fbchat/_plan.py @@ -1,6 +1,3 @@ -# -*- coding: UTF-8 -*- -from __future__ import unicode_literals - import attr import json from ._core import Enum @@ -13,7 +10,7 @@ class GuestStatus(Enum): @attr.s(cmp=False) -class Plan(object): +class Plan: """Represents a plan.""" #: ID of the plan diff --git a/fbchat/_poll.py b/fbchat/_poll.py index b5944b9..08c6de6 100644 --- a/fbchat/_poll.py +++ b/fbchat/_poll.py @@ -1,11 +1,8 @@ -# -*- coding: UTF-8 -*- -from __future__ import unicode_literals - import attr @attr.s(cmp=False) -class Poll(object): +class Poll: """Represents a poll.""" #: Title of the poll @@ -28,7 +25,7 @@ class Poll(object): @attr.s(cmp=False) -class PollOption(object): +class PollOption: """Represents a poll option.""" #: Text of the poll option diff --git a/fbchat/_quick_reply.py b/fbchat/_quick_reply.py index 1163edc..5a9a262 100644 --- a/fbchat/_quick_reply.py +++ b/fbchat/_quick_reply.py @@ -1,12 +1,9 @@ -# -*- coding: UTF-8 -*- -from __future__ import unicode_literals - import attr from ._attachment import Attachment @attr.s(cmp=False) -class QuickReply(object): +class QuickReply: """Represents a quick reply.""" #: Payload of the quick reply diff --git a/fbchat/_state.py b/fbchat/_state.py index a20e4f2..8062b16 100644 --- a/fbchat/_state.py +++ b/fbchat/_state.py @@ -1,6 +1,3 @@ -# -*- coding: UTF-8 -*- -from __future__ import unicode_literals - import attr import bs4 import re @@ -100,7 +97,7 @@ def _2fa_helper(session, code, r): @attr.s(slots=True) # TODO i Python 3: Add kw_only=True -class State(object): +class State: """Stores and manages state required for most Facebook requests.""" user_id = attr.ib() diff --git a/fbchat/_sticker.py b/fbchat/_sticker.py index 024132d..a56ce2a 100644 --- a/fbchat/_sticker.py +++ b/fbchat/_sticker.py @@ -1,6 +1,3 @@ -# -*- coding: UTF-8 -*- -from __future__ import unicode_literals - import attr from ._attachment import Attachment diff --git a/fbchat/_thread.py b/fbchat/_thread.py index a93a178..e39b4b4 100644 --- a/fbchat/_thread.py +++ b/fbchat/_thread.py @@ -1,6 +1,3 @@ -# -*- coding: UTF-8 -*- -from __future__ import unicode_literals - import attr from ._core import Enum @@ -73,7 +70,7 @@ class ThreadColor(Enum): @attr.s(cmp=False, init=False) -class Thread(object): +class Thread: """Represents a Facebook thread.""" #: The unique identifier of the thread. Can be used a ``thread_id``. See :ref:`intro_threads` for more info diff --git a/fbchat/_user.py b/fbchat/_user.py index eae5fdb..b864b13 100644 --- a/fbchat/_user.py +++ b/fbchat/_user.py @@ -1,6 +1,3 @@ -# -*- coding: UTF-8 -*- -from __future__ import unicode_literals - import attr from ._core import Enum from . import _plan @@ -183,7 +180,7 @@ class User(Thread): @attr.s(cmp=False) -class ActiveStatus(object): +class ActiveStatus: #: Whether the user is active now active = attr.ib(None) #: Timestamp when the user was last active diff --git a/fbchat/_util.py b/fbchat/_util.py index 58fa657..cb8a677 100644 --- a/fbchat/_util.py +++ b/fbchat/_util.py @@ -1,6 +1,3 @@ -# -*- coding: UTF-8 -*- - -from __future__ import unicode_literals import re import json from time import time @@ -8,6 +5,7 @@ from random import random from contextlib import contextmanager from mimetypes import guess_type from os.path import basename +from urllib.parse import parse_qs, urlparse import warnings import logging import requests @@ -19,22 +17,6 @@ from ._exception import ( FBchatPleaseRefresh, ) -try: - from urllib.parse import urlencode, parse_qs, urlparse - - basestring = (str, bytes) -except ImportError: - from urllib import urlencode - from urlparse import parse_qs, urlparse - - basestring = basestring - -# Python 2's `input` executes the input, whereas `raw_input` just returns the input -try: - input = raw_input -except NameError: - pass - # Log settings log = logging.getLogger("client") log.setLevel(logging.DEBUG) diff --git a/fbchat/models.py b/fbchat/models.py index 1bab61b..69bfd84 100644 --- a/fbchat/models.py +++ b/fbchat/models.py @@ -1,11 +1,9 @@ -# -*- coding: UTF-8 -*- """This file is here to maintain backwards compatability, and to re-export our models into the global module (see `__init__.py`). A common pattern was to use `from fbchat.models import *`, hence we need this while transitioning to a better code structure. """ -from __future__ import unicode_literals from ._core import Enum from ._exception import FBchatException, FBchatFacebookError, FBchatUserError diff --git a/pyproject.toml b/pyproject.toml index 136268d..0641406 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -27,12 +27,12 @@ classifiers = [ "Operating System :: OS Independent", "Natural Language :: English", "Programming Language :: Python", - "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.4", + "Programming Language :: Python :: 3 :: Only", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: PyPy", "Topic :: Communications :: Chat", @@ -41,7 +41,7 @@ classifiers = [ "Topic :: Software Development :: Libraries", "Topic :: Software Development :: Libraries :: Python Modules", ] -requires-python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, <4.0" +requires-python = ">=3.5, <4.0" keywords = "Facebook FB Messenger Library Chat Api Bot" license = "BSD 3-Clause" @@ -52,7 +52,6 @@ Repository = "https://github.com/carpedm20/fbchat/" [tool.flit.metadata.requires-extra] test = [ "pytest~=4.0", - "six~=1.0", ] docs = [ "sphinx~=2.0", diff --git a/tests/conftest.py b/tests/conftest.py index 2e1f486..07d598b 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,7 +1,3 @@ -# -*- coding: utf-8 -*- - -from __future__ import unicode_literals - import pytest import json diff --git a/tests/test_base.py b/tests/test_base.py index 6a60482..16ab01c 100644 --- a/tests/test_base.py +++ b/tests/test_base.py @@ -1,7 +1,3 @@ -# -*- coding: utf-8 -*- - -from __future__ import unicode_literals - import pytest import py_compile diff --git a/tests/test_fetch.py b/tests/test_fetch.py index d509fad..8515c3f 100644 --- a/tests/test_fetch.py +++ b/tests/test_fetch.py @@ -1,7 +1,3 @@ -# -*- coding: utf-8 -*- - -from __future__ import unicode_literals - import pytest from os import path diff --git a/tests/test_message_management.py b/tests/test_message_management.py index 00291ee..adde421 100644 --- a/tests/test_message_management.py +++ b/tests/test_message_management.py @@ -1,7 +1,3 @@ -# -*- coding: utf-8 -*- - -from __future__ import unicode_literals - import pytest from fbchat.models import Message, MessageReaction diff --git a/tests/test_plans.py b/tests/test_plans.py index 9e5e6b6..5388e6c 100644 --- a/tests/test_plans.py +++ b/tests/test_plans.py @@ -1,7 +1,3 @@ -# -*- coding: utf-8 -*- - -from __future__ import unicode_literals - import pytest from fbchat.models import Plan, FBchatFacebookError, ThreadType diff --git a/tests/test_polls.py b/tests/test_polls.py index 32c2457..daa6f1c 100644 --- a/tests/test_polls.py +++ b/tests/test_polls.py @@ -1,7 +1,3 @@ -# -*- coding: utf-8 -*- - -from __future__ import unicode_literals - import pytest from fbchat.models import Poll, PollOption, ThreadType diff --git a/tests/test_search.py b/tests/test_search.py index dda9568..07cc88e 100644 --- a/tests/test_search.py +++ b/tests/test_search.py @@ -1,7 +1,3 @@ -# -*- coding: utf-8 -*- - -from __future__ import unicode_literals - from fbchat.models import ThreadType diff --git a/tests/test_send.py b/tests/test_send.py index b5dec30..c45be33 100644 --- a/tests/test_send.py +++ b/tests/test_send.py @@ -1,7 +1,3 @@ -# -*- coding: utf-8 -*- - -from __future__ import unicode_literals - import pytest from os import path diff --git a/tests/test_tests.py b/tests/test_tests.py index 1367628..2132f8f 100644 --- a/tests/test_tests.py +++ b/tests/test_tests.py @@ -1,7 +1,3 @@ -# -*- coding: utf-8 -*- - -from __future__ import unicode_literals - import pytest diff --git a/tests/test_thread_interraction.py b/tests/test_thread_interraction.py index 041346b..b809c6d 100644 --- a/tests/test_thread_interraction.py +++ b/tests/test_thread_interraction.py @@ -1,7 +1,3 @@ -# -*- coding: utf-8 -*- - -from __future__ import unicode_literals - import pytest from fbchat.models import ( diff --git a/tests/utils.py b/tests/utils.py index 52863b5..21bed11 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -1,16 +1,10 @@ -# -*- coding: utf-8 -*- - -from __future__ import unicode_literals - import threading import logging -import six import pytest from os import environ from random import randrange from contextlib import contextmanager -from six import viewitems from fbchat import Client from fbchat.models import ThreadType, EmojiSize, FBchatFacebookError, Sticker @@ -63,13 +57,7 @@ class ClientThread(threading.Thread): self.client.stopListening() -if six.PY2: - event_class = threading._Event -else: - event_class = threading.Event - - -class CaughtValue(event_class): +class CaughtValue(threading.Event): def set(self, res): self.res = res super(CaughtValue, self).set() @@ -85,7 +73,7 @@ def random_hex(length=20): def subset(a, **b): print(a) print(b) - return viewitems(b) <= viewitems(a) + return b.items() <= a.items() def load_variable(name, cache):