From 1861f546746a7a62627230fac0883af68bb1a6a9 Mon Sep 17 00:00:00 2001 From: Arne Beer Date: Tue, 4 Aug 2020 00:59:47 +0200 Subject: [PATCH] Switch to new sentry-sdk --- poetry.lock | 380 ++++++++++-------- pyproject.toml | 2 +- stickerfinder/logic/sticker_set.py | 2 +- stickerfinder/logic/tag.py | 3 +- stickerfinder/sentry.py | 57 ++- stickerfinder/session.py | 30 +- stickerfinder/stickerfinder.py | 4 - .../telegram/callback_handlers/__init__.py | 4 +- stickerfinder/telegram/commands/admin.py | 28 +- stickerfinder/telegram/commands/chat.py | 4 +- .../telegram/commands/maintenance.py | 6 +- stickerfinder/telegram/commands/misc.py | 8 +- .../telegram/commands/sticker_set.py | 4 +- stickerfinder/telegram/commands/tag.py | 6 +- stickerfinder/telegram/commands/usage.py | 4 +- stickerfinder/telegram/error_handler.py | 34 -- .../telegram/inline_query/__init__.py | 4 +- stickerfinder/telegram/inline_query/search.py | 8 +- stickerfinder/telegram/jobs.py | 14 +- stickerfinder/telegram/message_handlers.py | 10 +- 20 files changed, 313 insertions(+), 299 deletions(-) delete mode 100644 stickerfinder/telegram/error_handler.py diff --git a/poetry.lock b/poetry.lock index 509033e..1f27791 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,33 +1,33 @@ [[package]] -category = "main" -description = "A database migration tool for SQLAlchemy." name = "alembic" +version = "1.4.2" +description = "A database migration tool for SQLAlchemy." +category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -version = "1.4.0" [package.dependencies] Mako = "*" -SQLAlchemy = ">=1.1.0" python-dateutil = "*" python-editor = ">=0.3" +SQLAlchemy = ">=1.1.0" [[package]] -category = "dev" -description = "Atomic file writes." -marker = "sys_platform == \"win32\"" name = "atomicwrites" +version = "1.4.0" +description = "Atomic file writes." +category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -version = "1.4.0" +marker = "sys_platform == \"win32\"" [[package]] -category = "dev" -description = "Classes Without Boilerplate" name = "attrs" +version = "19.3.0" +description = "Classes Without Boilerplate" +category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -version = "19.3.0" [package.extras] azure-pipelines = ["coverage", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface", "pytest-azurepipelines"] @@ -36,44 +36,40 @@ docs = ["sphinx", "zope.interface"] tests = ["coverage", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface"] [[package]] -category = "main" -description = "Python package for providing Mozilla's CA Bundle." name = "certifi" +version = "2020.6.20" +description = "Python package for providing Mozilla's CA Bundle." +category = "main" optional = false python-versions = "*" -version = "2020.6.20" [[package]] -category = "main" -description = "Foreign Function Interface for Python calling C code." name = "cffi" +version = "1.14.1" +description = "Foreign Function Interface for Python calling C code." +category = "main" optional = false python-versions = "*" -version = "1.14.1" [package.dependencies] pycparser = "*" [[package]] -category = "dev" -description = "Cross-platform colored terminal text." -marker = "sys_platform == \"win32\"" name = "colorama" +version = "0.4.3" +description = "Cross-platform colored terminal text." +category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -version = "0.4.3" +marker = "sys_platform == \"win32\"" [[package]] -category = "main" -description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." name = "cryptography" +version = "3.0" +description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." +category = "main" optional = false python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*" -version = "3.0" - -[package.dependencies] -cffi = ">=1.8,<1.11.3 || >1.11.3" -six = ">=1.4.1" [package.extras] docs = ["sphinx (>=1.6.5,<1.8.0 || >1.8.0,<3.1.0 || >3.1.0,<3.1.1 || >3.1.1)", "sphinx-rtd-theme"] @@ -83,87 +79,91 @@ pep8test = ["black", "flake8", "flake8-import-order", "pep8-naming"] ssh = ["bcrypt (>=3.1.5)"] test = ["pytest (>=3.6.0,<3.9.0 || >3.9.0,<3.9.1 || >3.9.1,<3.9.2 || >3.9.2)", "pretend", "iso8601", "pytz", "hypothesis (>=1.11.4,<3.79.2 || >3.79.2)"] +[package.dependencies] +cffi = ">=1.8,<1.11.3 || >1.11.3" +six = ">=1.4.1" + [[package]] -category = "main" -description = "Composable style cycles" name = "cycler" +version = "0.10.0" +description = "Composable style cycles" +category = "main" optional = false python-versions = "*" -version = "0.10.0" [package.dependencies] six = "*" [[package]] -category = "main" -description = "Decorators for Humans" name = "decorator" +version = "4.4.2" +description = "Decorators for Humans" +category = "main" optional = false python-versions = ">=2.6, !=3.0.*, !=3.1.*" -version = "4.4.2" [[package]] -category = "dev" -description = "Read metadata from Python packages" -marker = "python_version < \"3.8\"" name = "importlib-metadata" +version = "1.7.0" +description = "Read metadata from Python packages" +category = "dev" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" -version = "1.7.0" - -[package.dependencies] -zipp = ">=0.5" +marker = "python_version < \"3.8\"" [package.extras] docs = ["sphinx", "rst.linker"] testing = ["packaging", "pep517", "importlib-resources (>=1.3)"] +[package.dependencies] +zipp = ">=0.5" + [[package]] -category = "main" -description = "A series of convenience functions to make basic image processing functions such as translation, rotation, resizing, skeletonization, displaying Matplotlib images, sorting contours, detecting edges, and much more easier with OpenCV and both Python 2.7 and Python 3." name = "imutils" +version = "0.5.3" +description = "A series of convenience functions to make basic image processing functions such as translation, rotation, resizing, skeletonization, displaying Matplotlib images, sorting contours, detecting edges, and much more easier with OpenCV and both Python 2.7 and Python 3." +category = "main" optional = false python-versions = "*" -version = "0.5.3" [[package]] -category = "main" -description = "A fast implementation of the Cassowary constraint solver" name = "kiwisolver" +version = "1.2.0" +description = "A fast implementation of the Cassowary constraint solver" +category = "main" optional = false python-versions = ">=3.6" -version = "1.2.0" [[package]] -category = "main" -description = "A super-fast templating language that borrows the best ideas from the existing templating languages." name = "mako" +version = "1.1.3" +description = "A super-fast templating language that borrows the best ideas from the existing templating languages." +category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -version = "1.1.3" - -[package.dependencies] -MarkupSafe = ">=0.9.2" [package.extras] babel = ["babel"] lingua = ["lingua"] +[package.dependencies] +MarkupSafe = ">=0.9.2" + [[package]] -category = "main" -description = "Safely add untrusted strings to HTML/XML markup." name = "markupsafe" +version = "1.1.1" +description = "Safely add untrusted strings to HTML/XML markup." +category = "main" optional = false python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*" -version = "1.1.1" [[package]] -category = "main" -description = "Python plotting package" name = "matplotlib" +version = "3.3.0" +description = "Python plotting package" +category = "main" optional = false python-versions = ">=3.6" -version = "3.3.0" [package.dependencies] cycler = ">=0.10" @@ -174,123 +174,127 @@ pyparsing = ">=2.0.3,<2.0.4 || >2.0.4,<2.1.2 || >2.1.2,<2.1.6 || >2.1.6" python-dateutil = ">=2.1" [[package]] -category = "dev" -description = "More routines for operating on iterables, beyond itertools" name = "more-itertools" +version = "8.4.0" +description = "More routines for operating on iterables, beyond itertools" +category = "dev" optional = false python-versions = ">=3.5" -version = "8.4.0" [[package]] -category = "main" -description = "NumPy is the fundamental package for array computing with Python." name = "numpy" +version = "1.19.1" +description = "NumPy is the fundamental package for array computing with Python." +category = "main" optional = false python-versions = ">=3.6" -version = "1.19.1" [[package]] -category = "dev" -description = "Core utilities for Python packages" name = "packaging" +version = "20.4" +description = "Core utilities for Python packages" +category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -version = "20.4" [package.dependencies] pyparsing = ">=2.0.2" six = "*" [[package]] -category = "main" -description = "Powerful data structures for data analysis, time series, and statistics" name = "pandas" +version = "1.1.0" +description = "Powerful data structures for data analysis, time series, and statistics" +category = "main" optional = false python-versions = ">=3.6.1" -version = "1.1.0" + +[package.extras] +test = ["pytest (>=4.0.2)", "pytest-xdist", "hypothesis (>=3.58)"] [package.dependencies] numpy = ">=1.15.4" python-dateutil = ">=2.7.3" pytz = ">=2017.2" -[package.extras] -test = ["pytest (>=4.0.2)", "pytest-xdist", "hypothesis (>=3.58)"] - [[package]] -category = "main" -description = "Python Imaging Library (Fork)" name = "pillow" +version = "7.2.0" +description = "Python Imaging Library (Fork)" +category = "main" optional = false python-versions = ">=3.5" -version = "7.2.0" [[package]] -category = "dev" -description = "plugin and hook calling mechanisms for python" name = "pluggy" +version = "0.13.1" +description = "plugin and hook calling mechanisms for python" +category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -version = "0.13.1" + +[package.extras] +dev = ["pre-commit", "tox"] [package.dependencies] [package.dependencies.importlib-metadata] -python = "<3.8" version = ">=0.12" - -[package.extras] -dev = ["pre-commit", "tox"] +python = "<3.8" [[package]] -category = "main" -description = "psycopg2 - Python-PostgreSQL Database Adapter" name = "psycopg2-binary" +version = "2.8.5" +description = "psycopg2 - Python-PostgreSQL Database Adapter" +category = "main" optional = false python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*" -version = "2.8.5" [[package]] -category = "dev" -description = "library with cross-python path, ini-parsing, io, code, log facilities" name = "py" +version = "1.9.0" +description = "library with cross-python path, ini-parsing, io, code, log facilities" +category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -version = "1.9.0" [[package]] -category = "main" -description = "C parser in Python" name = "pycparser" +version = "2.20" +description = "C parser in Python" +category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -version = "2.20" [[package]] -category = "main" -description = "Python parsing module" name = "pyparsing" +version = "2.4.7" +description = "Python parsing module" +category = "main" optional = false python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" -version = "2.4.7" [[package]] -category = "main" -description = "Python-tesseract is a python wrapper for Google's Tesseract-OCR" name = "pytesseract" +version = "0.3.4" +description = "Python-tesseract is a python wrapper for Google's Tesseract-OCR" +category = "main" optional = false python-versions = "*" -version = "0.3.4" [package.dependencies] Pillow = "*" [[package]] -category = "dev" -description = "pytest: simple powerful testing with Python" name = "pytest" +version = "5.4.3" +description = "pytest: simple powerful testing with Python" +category = "dev" optional = false python-versions = ">=3.5" -version = "5.4.3" + +[package.extras] +checkqa-mypy = ["mypy (v0.761)"] +testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xmlschema"] [package.dependencies] atomicwrites = ">=1.0" @@ -303,69 +307,69 @@ py = ">=1.5.0" wcwidth = "*" [package.dependencies.importlib-metadata] -python = "<3.8" version = ">=0.12" - -[package.extras] -checkqa-mypy = ["mypy (v0.761)"] -testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xmlschema"] +python = "<3.8" [[package]] -category = "dev" -description = "Thin-wrapper around the mock package for easier use with pytest" name = "pytest-mock" +version = "3.2.0" +description = "Thin-wrapper around the mock package for easier use with pytest" +category = "dev" optional = false python-versions = ">=3.5" -version = "3.2.0" - -[package.dependencies] -pytest = ">=2.7" [package.extras] dev = ["pre-commit", "tox", "pytest-asyncio"] +[package.dependencies] +pytest = ">=2.7" + [[package]] -category = "main" -description = "Extensions to the standard Python datetime module" name = "python-dateutil" +version = "2.8.1" +description = "Extensions to the standard Python datetime module" +category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" -version = "2.8.1" [package.dependencies] six = ">=1.5" [[package]] -category = "main" -description = "Programmatically open an editor, capture the result." name = "python-editor" +version = "1.0.4" +description = "Programmatically open an editor, capture the result." +category = "main" optional = false python-versions = "*" -version = "1.0.4" [[package]] -category = "main" -description = "Translation library for Python" name = "python-i18n" +version = "0.3.7" +description = "Translation library for Python" +category = "main" optional = false python-versions = "*" -version = "0.3.7" + +[package.extras] +yaml = ["pyyaml (>=3.10)"] [package.dependencies] [package.dependencies.pyyaml] -optional = true version = ">=3.10" - -[package.extras] -yaml = ["pyyaml (>=3.10)"] +optional = true [[package]] -category = "main" -description = "We have made you a wrapper you can't refuse" name = "python-telegram-bot" +version = "12.8" +description = "We have made you a wrapper you can't refuse" +category = "main" optional = false python-versions = "*" -version = "12.8" + +[package.extras] +json = ["ujson"] +socks = ["pysocks"] [package.dependencies] certifi = "*" @@ -373,53 +377,63 @@ cryptography = "*" decorator = ">=4.4.0" tornado = ">=5.1" -[package.extras] -json = ["ujson"] -socks = ["pysocks"] - [[package]] -category = "main" -description = "World timezone definitions, modern and historical" name = "pytz" +version = "2020.1" +description = "World timezone definitions, modern and historical" +category = "main" optional = false python-versions = "*" -version = "2020.1" [[package]] -category = "main" -description = "YAML parser and emitter for Python" name = "pyyaml" +version = "5.3.1" +description = "YAML parser and emitter for Python" +category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -version = "5.3.1" [[package]] +name = "sentry-sdk" +version = "0.16.0" +description = "Python client for Sentry (https://getsentry.com)" category = "main" -description = "Raven is a client for Sentry (https://getsentry.com)" -name = "raven" optional = false python-versions = "*" -version = "6.10.0" [package.extras] -flask = ["Flask (>=0.8)", "blinker (>=1.1)"] -tests = ["bottle", "celery (>=2.5)", "coverage (<4)", "exam (>=0.5.2)", "flake8 (3.5.0)", "logbook", "mock", "nose", "pytz", "pytest (>=3.2.0,<3.3.0)", "pytest-timeout (1.2.1)", "pytest-xdist (1.18.2)", "pytest-pythonpath (0.7.2)", "pytest-cov (2.5.1)", "pytest-flake8 (1.0.0)", "requests", "tornado (>=4.1,<5.0)", "tox", "webob", "webtest", "wheel", "anyjson", "zconfig", "Flask (>=0.8)", "blinker (>=1.1)", "Flask-Login (>=0.2.0)", "blinker (>=1.1)", "sanic (>=0.7.0)", "aiohttp"] +aiohttp = ["aiohttp (>=3.5)"] +beam = ["apache-beam (>=2.12)"] +bottle = ["bottle (>=0.12.13)"] +celery = ["celery (>=3)"] +django = ["django (>=1.8)"] +falcon = ["falcon (>=1.4)"] +flask = ["flask (>=0.11)", "blinker (>=1.1)"] +pyspark = ["pyspark (>=2.4.4)"] +rq = ["rq (>=0.6)"] +sanic = ["sanic (>=0.8)"] +sqlalchemy = ["sqlalchemy (>=1.2)"] +tornado = ["tornado (>=5)"] + +[package.dependencies] +certifi = "*" +urllib3 = ">=1.10.0" [[package]] -category = "main" -description = "Python 2 and 3 compatibility utilities" name = "six" +version = "1.15.0" +description = "Python 2 and 3 compatibility utilities" +category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" -version = "1.15.0" [[package]] -category = "main" -description = "Database Abstraction Library" name = "sqlalchemy" +version = "1.3.18" +description = "Database Abstraction Library" +category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -version = "1.3.18" [package.extras] mssql = ["pyodbc"] @@ -434,16 +448,12 @@ postgresql_psycopg2cffi = ["psycopg2cffi"] pymysql = ["pymysql"] [[package]] -category = "main" -description = "Various utility functions for SQLAlchemy." name = "sqlalchemy-utils" +version = "0.36.8" +description = "Various utility functions for SQLAlchemy." +category = "main" optional = false python-versions = "*" -version = "0.36.8" - -[package.dependencies] -SQLAlchemy = ">=1.0" -six = "*" [package.extras] anyjson = ["anyjson (>=0.3.3)"] @@ -460,51 +470,67 @@ test_all = ["anyjson (>=0.3.3)", "arrow (>=0.3.4)", "Babel (>=1.3)", "colour (>= timezone = ["python-dateutil"] url = ["furl (>=0.4.1)"] +[package.dependencies] +six = "*" +SQLAlchemy = ">=1.0" + [[package]] -category = "main" -description = "Python Library for Tom's Obvious, Minimal Language" name = "toml" +version = "0.10.1" +description = "Python Library for Tom's Obvious, Minimal Language" +category = "main" optional = false python-versions = "*" -version = "0.10.1" [[package]] -category = "main" -description = "Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed." name = "tornado" +version = "6.0.4" +description = "Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed." +category = "main" optional = false python-versions = ">= 3.5" -version = "6.0.4" [[package]] -category = "dev" -description = "Measures the displayed width of unicode strings in a terminal" -name = "wcwidth" +name = "urllib3" +version = "1.22" +description = "HTTP library with thread-safe connection pooling, file post, and more." +category = "main" optional = false python-versions = "*" -version = "0.2.5" + +[package.extras] +secure = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "certifi", "ipaddress"] +socks = ["PySocks (>=1.5.6,<1.5.7 || >1.5.7,<2.0)"] [[package]] +name = "wcwidth" +version = "0.2.5" +description = "Measures the displayed width of unicode strings in a terminal" category = "dev" -description = "Backport of pathlib-compatible object wrapper for zip files" -marker = "python_version < \"3.8\"" +optional = false +python-versions = "*" + +[[package]] name = "zipp" +version = "3.1.0" +description = "Backport of pathlib-compatible object wrapper for zip files" +category = "dev" optional = false python-versions = ">=3.6" -version = "3.1.0" +marker = "python_version < \"3.8\"" [package.extras] docs = ["sphinx", "jaraco.packaging (>=3.2)", "rst.linker (>=1.9)"] testing = ["jaraco.itertools", "func-timeout"] [metadata] -content-hash = "85007d56f9403f04c2356f02fe49fd367772d2a2bcb98632e24267795ec17743" lock-version = "1.0" python-versions = ">=3.7" +content-hash = "077918cd6cab8d29d3e235617a01802e145a967ae6470f5f7fb9c29b47216b15" [metadata.files] alembic = [ - {file = "alembic-1.4.0.tar.gz", hash = "sha256:2df2519a5b002f881517693b95626905a39c5faf4b5a1f94de4f1441095d1d26"}, + {file = "alembic-1.4.2.tar.gz", hash = "sha256:035ab00497217628bf5d0be82d664d8713ab13d37b630084da8e1f98facf4dbf"}, ] atomicwrites = [ {file = "atomicwrites-1.4.0-py2.py3-none-any.whl", hash = "sha256:6d1784dea7c0c8d4a5172b6c620f40b6e4cbfdf96d783691f2e1302a7b88e197"}, @@ -845,9 +871,9 @@ pyyaml = [ {file = "PyYAML-5.3.1-cp38-cp38-win_amd64.whl", hash = "sha256:95f71d2af0ff4227885f7a6605c37fd53d3a106fcab511b8860ecca9fcf400ee"}, {file = "PyYAML-5.3.1.tar.gz", hash = "sha256:b8eac752c5e14d3eca0e6dd9199cd627518cb5ec06add0de9d32baeee6fe645d"}, ] -raven = [ - {file = "raven-6.10.0-py2.py3-none-any.whl", hash = "sha256:44a13f87670836e153951af9a3c80405d36b43097db869a36e92809673692ce4"}, - {file = "raven-6.10.0.tar.gz", hash = "sha256:3fa6de6efa2493a7c827472e984ce9b020797d0da16f1db67197bcc23c8fae54"}, +sentry-sdk = [ + {file = "sentry-sdk-0.16.0.tar.gz", hash = "sha256:da06bc3641e81ec2c942f87a0676cd9180044fa3d1697524a0005345997542e2"}, + {file = "sentry_sdk-0.16.0-py2.py3-none-any.whl", hash = "sha256:e80d61af85d99a1222c1a3e2a24023618374cd50a99673aa7fa3cf920e7d813b"}, ] six = [ {file = "six-1.15.0-py2.py3-none-any.whl", hash = "sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced"}, @@ -901,6 +927,10 @@ tornado = [ {file = "tornado-6.0.4-cp38-cp38-win_amd64.whl", hash = "sha256:c58d56003daf1b616336781b26d184023ea4af13ae143d9dda65e31e534940b9"}, {file = "tornado-6.0.4.tar.gz", hash = "sha256:0fe2d45ba43b00a41cd73f8be321a44936dc1aba233dee979f17a042b83eb6dc"}, ] +urllib3 = [ + {file = "urllib3-1.22-py2.py3-none-any.whl", hash = "sha256:06330f386d6e4b195fbfc736b297f58c5a892e4440e54d294d7004e3a9bbea1b"}, + {file = "urllib3-1.22.tar.gz", hash = "sha256:cc44da8e1145637334317feebd728bd869a35285b93cbb4cca2577da7e62db4f"}, +] wcwidth = [ {file = "wcwidth-0.2.5-py2.py3-none-any.whl", hash = "sha256:beb4802a9cebb9144e99086eff703a642a13d6a0052920003a230f3294bbe784"}, {file = "wcwidth-0.2.5.tar.gz", hash = "sha256:c4d647b99872929fdb7bdcaa4fbe7f01413ed3d98077df798530e5b04f116c83"}, diff --git a/pyproject.toml b/pyproject.toml index db676c9..a775a74 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -8,7 +8,7 @@ repository = "https://github.com/nukesor/sticker-finder" [tool.poetry.dependencies] python = ">=3.7" -raven = "^6" +sentry-sdk = "0.16.0" alembic = "^1" python-telegram-bot = "^12" SQLAlchemy = "^1" diff --git a/stickerfinder/logic/sticker_set.py b/stickerfinder/logic/sticker_set.py index 4d95eca..2b0a132 100644 --- a/stickerfinder/logic/sticker_set.py +++ b/stickerfinder/logic/sticker_set.py @@ -139,7 +139,7 @@ def extract_text(tg_sticker): logger.info(f"Failed to open image {tg_sticker.file_unique_id}") pass except: - sentry.captureException() + sentry.capture_exception(tags={"context": "text_extraction"}) pass return text diff --git a/stickerfinder/logic/tag.py b/stickerfinder/logic/tag.py index 1c312c6..169c3e4 100644 --- a/stickerfinder/logic/tag.py +++ b/stickerfinder/logic/tag.py @@ -254,9 +254,8 @@ def tag_sticker( achievement_message = i18n.t(f"text.tagging.achievements.{len(user.changes)}") tg_chat.send_message(achievement_message) - sentry.captureMessage( + sentry.capture_message( f"User hit {len(user.changes)} changes!", - level="info", extra={ "user": user.username, "user_id": user.id, diff --git a/stickerfinder/sentry.py b/stickerfinder/sentry.py index 2b3b8c2..3d6aaea 100644 --- a/stickerfinder/sentry.py +++ b/stickerfinder/sentry.py @@ -1,12 +1,19 @@ """Simple wrapper around sentry that allows for lazy initilization.""" -from raven import Client +import sentry_sdk +from sentry_sdk import configure_scope + from stickerfinder.config import config +from telegram.error import TimedOut class Sentry(object): - """Sentry wrapper class that allows this app to work without a sentry token. + """Sentry wrapper class. + + This class offers some convenience classes and functions for adding + additional information to sentry calls. - If no token is specified in the config, the messages used for logging are simply not called. + The extra level of abstraction ensures that everything will still work, + if sentry hasn't been initialized. """ initialized = False @@ -15,27 +22,41 @@ def __init__(self): """Construct new sentry wrapper.""" if config["logging"]["sentry_enabled"]: self.initialized = True - self.sentry = Client(config["logging"]["sentry_token"]) + sentry_sdk.init(config["logging"]["sentry_token"],) - def captureMessage(self, *args, **kwargs): + def capture_message(self, message, level="info", tags=None, extra=None): """Capture message with sentry.""" - if self.initialized: - if "tags" not in kwargs: - kwargs["tags"] = {} + if not self.initialized: + return + + with configure_scope() as scope: + if tags is not None: + for key, tag in tags.items(): + scope.set_tag(key, tag) - # Tag it as stickerfinder - kwargs["tags"]["bot"] = "stickerfinder" - self.sentry.captureMessage(*args, **kwargs) + if extra is not None: + for key, extra in extra.items(): + scope.set_extra(key, extra) - def captureException(self, *args, **kwargs): + scope.set_tag("bot", "StickerFinder") + sentry_sdk.capture_message(message, level) + + def capture_exception(self, tags=None, extra=None): """Capture exception with sentry.""" - if self.initialized: - if "tags" not in kwargs: - kwargs["tags"] = {} + if not self.initialized: + return + + with configure_scope() as scope: + if tags is not None: + for key, tag in tags.items(): + scope.set_tag(key, tag) + + if extra is not None: + for key, extra in extra.items(): + scope.set_extra(key, extra) - # Tag it as stickerfinder - kwargs["tags"]["bot"] = "stickerfinder" - self.sentry.captureException(*args, **kwargs) + scope.set_tag("bot", "StickerFinder") + sentry_sdk.capture_exception() sentry = Sentry() diff --git a/stickerfinder/session.py b/stickerfinder/session.py index 6401efc..e7d61d4 100644 --- a/stickerfinder/session.py +++ b/stickerfinder/session.py @@ -17,7 +17,7 @@ from stickerfinder.i18n import i18n -def job_session_wrapper(): +def job_wrapper(): """Create a session, handle permissions and exceptions for jobs.""" def real_decorator(func): @@ -34,7 +34,7 @@ def wrapper(context): # Capture all exceptions from jobs. # We need to handle those inside the jobs traceback.print_exc() - sentry.captureException() + sentry.capture_exception(tags={"handler": "job"}) finally: context.job.enabled = True session.close() @@ -44,7 +44,7 @@ def wrapper(context): return real_decorator -def inline_session_wrapper(): +def inline_query_wrapper(): """Create a session, handle permissions and exceptions.""" def real_decorator(func): @@ -69,7 +69,7 @@ def wrapper(update, context): except Exception as e: if not ignore_exception(e): traceback.print_exc() - sentry.captureException() + sentry.capture_exception(tags={"handler": "inline_query"}) finally: session.close() @@ -79,7 +79,7 @@ def wrapper(update, context): return real_decorator -def callback_session_wrapper(): +def callback_query_wrapper(): """Create a session, handle permissions and exceptions.""" def real_decorator(func): @@ -104,8 +104,11 @@ def wrapper(update, context): except Exception as e: if not ignore_exception(e): traceback.print_exc() - sentry.captureException() + sentry.capture_exception( + tags={"handler": "callback_query",}, + extra={"query": update.callback_query,}, + ) finally: session.close() @@ -114,7 +117,7 @@ def wrapper(update, context): return real_decorator -def session_wrapper( +def message_wrapper( send_message=True, allow_edit=False, admin_only=False, ): """Create a session, handle permissions, handle exceptions and prepare some entities.""" @@ -175,12 +178,13 @@ def wrapper(update, context): except Exception as e: if not ignore_exception(e): traceback.print_exc() - sentry.captureException() - if send_message and message: - session.close() - error_message = i18n.t("text.misc.error") - message.chat.send_message(error_message) - raise + sentry.capture_exception( + tags={"handler": "message",}, + extra={"update": update.to_dict(), "function": func.__name__}, + ) + + error_message = i18n.t("text.misc.error") + message.chat.send_message(error_message) finally: session.close() diff --git a/stickerfinder/stickerfinder.py b/stickerfinder/stickerfinder.py index 4fe8b43..a0ebc86 100644 --- a/stickerfinder/stickerfinder.py +++ b/stickerfinder/stickerfinder.py @@ -54,7 +54,6 @@ from stickerfinder.telegram.callback_handlers import handle_callback_query from stickerfinder.telegram.inline_query import search from stickerfinder.telegram.inline_query.result import handle_chosen_inline_result -from stickerfinder.telegram.error_handler import error_callback logging.basicConfig( @@ -182,6 +181,3 @@ # Inline callback handler dispatcher.add_handler(CallbackQueryHandler(handle_callback_query)) dispatcher.add_handler(ChosenInlineResultHandler(handle_chosen_inline_result)) - - # Error handling - dispatcher.add_error_handler(error_callback) diff --git a/stickerfinder/telegram/callback_handlers/__init__.py b/stickerfinder/telegram/callback_handlers/__init__.py index c4061fd..b4c0aa5 100644 --- a/stickerfinder/telegram/callback_handlers/__init__.py +++ b/stickerfinder/telegram/callback_handlers/__init__.py @@ -2,7 +2,7 @@ from telegram.ext import run_async from stickerfinder.db import get_session -from stickerfinder.session import callback_session_wrapper +from stickerfinder.session import callback_query_wrapper from stickerfinder.helper.callback import CallbackType from stickerfinder.models import Chat @@ -87,7 +87,7 @@ def __init__(self, session, bot, query, user): @run_async -@callback_session_wrapper() +@callback_query_wrapper() def handle_callback_query(bot, update, session, user): """Handle callback queries from inline keyboards.""" context = CallbackContext(session, bot, update.callback_query, user) diff --git a/stickerfinder/telegram/commands/admin.py b/stickerfinder/telegram/commands/admin.py index b08d3dd..1678921 100644 --- a/stickerfinder/telegram/commands/admin.py +++ b/stickerfinder/telegram/commands/admin.py @@ -7,11 +7,11 @@ from stickerfinder.config import config from stickerfinder.models import User, StickerSet, Chat, Sticker -from stickerfinder.session import session_wrapper +from stickerfinder.session import message_wrapper @run_async -@session_wrapper(admin_only=True) +@message_wrapper(admin_only=True) def ban_user(bot, update, session, chat, user): """Send a help text.""" name_to_ban = update.message.text.split(" ", 1)[1].lower() @@ -29,7 +29,7 @@ def ban_user(bot, update, session, chat, user): @run_async -@session_wrapper(admin_only=True) +@message_wrapper(admin_only=True) def unban_user(bot, update, session, chat, user): """Send a help text.""" name_to_unban = update.message.text.split(" ", 1)[1].lower() @@ -51,7 +51,7 @@ def unban_user(bot, update, session, chat, user): @run_async -@session_wrapper(admin_only=True) +@message_wrapper(admin_only=True) def authorize_user(bot, update, session, chat, user): """Send a help text.""" name_to_ban = update.message.text.split(" ", 1)[1].lower() @@ -70,7 +70,7 @@ def authorize_user(bot, update, session, chat, user): @run_async -@session_wrapper(admin_only=True) +@message_wrapper(admin_only=True) def make_admin(bot, update, session, chat, user): """Send a help text.""" identifier = update.message.text.split(" ", 1)[1].lower() @@ -93,7 +93,7 @@ def make_admin(bot, update, session, chat, user): @run_async -@session_wrapper(admin_only=True) +@message_wrapper(admin_only=True) def add_sets(bot, update, session, chat, user): """Get random sticker_set.""" text = update.message.text[9:] @@ -119,7 +119,7 @@ def add_sets(bot, update, session, chat, user): @run_async -@session_wrapper(admin_only=True) +@message_wrapper(admin_only=True) def delete_set(bot, update, session, chat, user): """Delete a specific set.""" name = update.message.text[11:].strip().lower() @@ -134,7 +134,7 @@ def delete_set(bot, update, session, chat, user): @run_async -@session_wrapper(admin_only=True) +@message_wrapper(admin_only=True) def broadcast(bot, update, session, chat, user): """Broadcast a message to all users.""" message = update.message.text.split(" ", 1)[1].strip() @@ -184,7 +184,7 @@ def broadcast(bot, update, session, chat, user): @run_async -@session_wrapper(admin_only=True) +@message_wrapper(admin_only=True) def test_broadcast(bot, update, session, chat, user): """Broadcast a message to all users.""" message = update.message.text.split(" ", 1)[1].strip() @@ -195,7 +195,7 @@ def test_broadcast(bot, update, session, chat, user): @run_async -@session_wrapper(admin_only=True) +@message_wrapper(admin_only=True) def fix_stuff(bot, update, session, chat, user): """Entry point for quick fixes.""" bot.send_message(chat.id, "starting to fix") @@ -226,7 +226,7 @@ def fix_stuff(bot, update, session, chat, user): @run_async -@session_wrapper() +@message_wrapper() def show_sticker(bot, update, session, chat, user): """Show the sticker for the given file id.""" file_id = update.message.text.split(" ", 1)[1].strip() @@ -237,7 +237,7 @@ def show_sticker(bot, update, session, chat, user): @run_async -@session_wrapper() +@message_wrapper() def show_sticker_file_id(bot, update, session, chat, user): """Give the file id for a sticker.""" if update.message.reply_to_message is None: @@ -251,7 +251,7 @@ def show_sticker_file_id(bot, update, session, chat, user): @run_async -@session_wrapper(admin_only=True) +@message_wrapper(admin_only=True) def ban_sticker(bot, update, session, chat, user): """Broadcast a message to all users.""" chat.current_sticker.banned = True @@ -261,7 +261,7 @@ def ban_sticker(bot, update, session, chat, user): @run_async -@session_wrapper(admin_only=True) +@message_wrapper(admin_only=True) def unban_sticker(bot, update, session, chat, user): """Broadcast a message to all users.""" chat.current_sticker.banned = True diff --git a/stickerfinder/telegram/commands/chat.py b/stickerfinder/telegram/commands/chat.py index 9ff0456..09bc1dd 100644 --- a/stickerfinder/telegram/commands/chat.py +++ b/stickerfinder/telegram/commands/chat.py @@ -1,12 +1,12 @@ """Chat related commands.""" from telegram.ext import run_async -from stickerfinder.session import session_wrapper +from stickerfinder.session import message_wrapper from stickerfinder.telegram.keyboard import get_main_keyboard from stickerfinder.logic.tag import send_tagged_count_message @run_async -@session_wrapper() +@message_wrapper() def cancel(bot, update, session, chat, user): """Send a help text.""" if not send_tagged_count_message(session, bot, user, chat): diff --git a/stickerfinder/telegram/commands/maintenance.py b/stickerfinder/telegram/commands/maintenance.py index ea09532..83cb668 100644 --- a/stickerfinder/telegram/commands/maintenance.py +++ b/stickerfinder/telegram/commands/maintenance.py @@ -1,12 +1,12 @@ """Maintenance related commands.""" from telegram.ext import run_async -from stickerfinder.session import session_wrapper +from stickerfinder.session import message_wrapper from stickerfinder.logic.maintenance import check_maintenance_chat, check_newsfeed_chat @run_async -@session_wrapper(admin_only=True) +@message_wrapper(admin_only=True) def flag_chat(bot, update, session, chat, user): """Flag a chat as maintenance or ban chat.""" chat_type = update.message.text.split(" ", 1)[1].strip() @@ -25,7 +25,7 @@ def flag_chat(bot, update, session, chat, user): @run_async -@session_wrapper(admin_only=True) +@message_wrapper(admin_only=True) def start_tasks(bot, update, session, chat, user): """Start the handling of tasks.""" if not chat.is_maintenance and not chat.is_newsfeed: diff --git a/stickerfinder/telegram/commands/misc.py b/stickerfinder/telegram/commands/misc.py index 071574c..33d48a1 100644 --- a/stickerfinder/telegram/commands/misc.py +++ b/stickerfinder/telegram/commands/misc.py @@ -1,5 +1,5 @@ """Misc telegram commands.""" -from stickerfinder.session import session_wrapper +from stickerfinder.session import message_wrapper from stickerfinder.helper.display import ( get_settings_text, get_help_text_and_keyboard, @@ -11,7 +11,7 @@ ) -@session_wrapper() +@message_wrapper() def start(bot, update, session, chat, user): """Send the start text.""" if chat.is_maintenance or chat.is_newsfeed: @@ -27,7 +27,7 @@ def start(bot, update, session, chat, user): ) -@session_wrapper() +@message_wrapper() def send_help_text(bot, update, session, chat, user): """Send the help text.""" text, keyboard = get_help_text_and_keyboard("Search") @@ -36,7 +36,7 @@ def send_help_text(bot, update, session, chat, user): ) -@session_wrapper() +@message_wrapper() def show_settings(bot, update, session, chat, user): """Update the settings message.""" update.message.send_message( diff --git a/stickerfinder/telegram/commands/sticker_set.py b/stickerfinder/telegram/commands/sticker_set.py index 11f7f0b..07cfa0d 100644 --- a/stickerfinder/telegram/commands/sticker_set.py +++ b/stickerfinder/telegram/commands/sticker_set.py @@ -1,7 +1,7 @@ """Sticker set related commands.""" from telegram.ext import run_async -from stickerfinder.session import session_wrapper +from stickerfinder.session import message_wrapper from stickerfinder.models import ( Report, Sticker, @@ -9,7 +9,7 @@ @run_async -@session_wrapper() +@message_wrapper() def report_set(bot, update, session, chat, user): """Report the set of the last sticker send to this chat.""" if ( diff --git a/stickerfinder/telegram/commands/tag.py b/stickerfinder/telegram/commands/tag.py index 42c6911..33f9338 100644 --- a/stickerfinder/telegram/commands/tag.py +++ b/stickerfinder/telegram/commands/tag.py @@ -1,14 +1,14 @@ """Tag related commands.""" from telegram.ext import run_async -from stickerfinder.session import session_wrapper +from stickerfinder.session import message_wrapper from stickerfinder.enum import TagMode from stickerfinder.logic.tag import handle_next, tag_sticker from stickerfinder.models import Sticker @run_async -@session_wrapper() +@message_wrapper() def tag_single(bot, update, session, chat, user): """Tag the last sticker send to this chat.""" # The tag command has been replied to another message @@ -55,7 +55,7 @@ def tag_single(bot, update, session, chat, user): @run_async -@session_wrapper() +@message_wrapper() def replace_single(bot, update, session, chat, user): """Tag the last sticker send to this chat.""" # The replace command has been replied to another message diff --git a/stickerfinder/telegram/commands/usage.py b/stickerfinder/telegram/commands/usage.py index c12231c..9676f8f 100644 --- a/stickerfinder/telegram/commands/usage.py +++ b/stickerfinder/telegram/commands/usage.py @@ -1,12 +1,12 @@ """Sticker usage related commands.""" from telegram.ext import run_async -from stickerfinder.session import session_wrapper +from stickerfinder.session import message_wrapper from stickerfinder.models import StickerUsage, Sticker @run_async -@session_wrapper() +@message_wrapper() def forget_set(bot, update, session, chat, user): """Forget every usage of the set of the previously posted sticker.""" if chat.current_sticker is None: diff --git a/stickerfinder/telegram/error_handler.py b/stickerfinder/telegram/error_handler.py deleted file mode 100644 index b613c9a..0000000 --- a/stickerfinder/telegram/error_handler.py +++ /dev/null @@ -1,34 +0,0 @@ -"""Telegram bot error handling.""" -import traceback -from telegram.error import ( - BadRequest, - NetworkError, - TimedOut, - Unauthorized, -) - -from stickerfinder.sentry import sentry - - -def error_callback(update, context): - """Handle generic errors from telegram.""" - try: - raise context.error - except BadRequest as e: - # It took to long to send the inline query response. - # Probably due to slow network on client side. - if str(e) == "Query_id_invalid": # noqa - return - - traceback.print_exc() - sentry.captureException() - # A user banned the bot Just ignore this. - # This probably happens due to sending a message during maintenance work - except Unauthorized: - pass - - except (TimedOut, NetworkError): - pass - except: - traceback.print_exc() - sentry.captureException() diff --git a/stickerfinder/telegram/inline_query/__init__.py b/stickerfinder/telegram/inline_query/__init__.py index 03620a3..b647f3f 100644 --- a/stickerfinder/telegram/inline_query/__init__.py +++ b/stickerfinder/telegram/inline_query/__init__.py @@ -4,7 +4,7 @@ from telegram.ext import run_async from telegram import InlineQueryResultCachedSticker -from stickerfinder.session import inline_session_wrapper +from stickerfinder.session import inline_query_wrapper from stickerfinder.models import ( InlineQuery, InlineQueryRequest, @@ -17,7 +17,7 @@ @run_async -@inline_session_wrapper() +@inline_query_wrapper() def search(tg_context, update, session, user): """Handle inline queries for sticker search. diff --git a/stickerfinder/telegram/inline_query/search.py b/stickerfinder/telegram/inline_query/search.py index 5bd17fe..e602ba8 100644 --- a/stickerfinder/telegram/inline_query/search.py +++ b/stickerfinder/telegram/inline_query/search.py @@ -193,9 +193,8 @@ def get_matching_stickers(session, context): # We need to know about this, before it happens. duration = end - start if duration.seconds >= 8: - sentry.captureMessage( + sentry.capture_message( f"Query took too long.", - level="info", extra={ "query": context.query, "duration": duration, @@ -219,10 +218,9 @@ def get_matching_sticker_sets(session, context): # If we take more than 10 seconds, the answer will be invalid. # We need to know about this, before it happens. duration = end - start - if duration.seconds >= 9: - sentry.captureMessage( + if duration.seconds >= 8: + sentry.capture_message( f"Query took too long.", - level="info", extra={ "query": context.query, "duration": duration, diff --git a/stickerfinder/telegram/jobs.py b/stickerfinder/telegram/jobs.py index a32bf8d..206933b 100644 --- a/stickerfinder/telegram/jobs.py +++ b/stickerfinder/telegram/jobs.py @@ -4,7 +4,7 @@ from datetime import datetime, timedelta from stickerfinder.config import config -from stickerfinder.session import job_session_wrapper +from stickerfinder.session import job_wrapper from stickerfinder.logic.sticker_set import refresh_stickers from stickerfinder.logic.maintenance import ( distribute_tasks, @@ -21,7 +21,7 @@ @run_async -@job_session_wrapper() +@job_wrapper() def newsfeed_job(context, session): """Send all new sticker to the newsfeed chats.""" # Get all tasks of added sticker sets, which have been @@ -32,7 +32,7 @@ def newsfeed_job(context, session): @run_async -@job_session_wrapper() +@job_wrapper() def free_cache(context, session): """This job removes all inline query cache entries that are older than a specified threshold. @@ -50,7 +50,7 @@ def free_cache(context, session): @run_async -@job_session_wrapper() +@job_wrapper() def maintenance_job(context, session): """Create new maintenance tasks. @@ -114,14 +114,14 @@ def maintenance_job(context, session): @run_async -@job_session_wrapper() +@job_wrapper() def distribute_tasks_job(context, session): """Distribute open tasks to maintenance channels.""" distribute_tasks(context.bot, session) @run_async -@job_session_wrapper() +@job_wrapper() def scan_sticker_sets_job(context, session): """Scan stickers of all sticker sets.""" context.job.enabled = False @@ -159,7 +159,7 @@ def scan_sticker_sets_job(context, session): @run_async -@job_session_wrapper() +@job_wrapper() def cleanup_job(context, session): """Send all new sticker to the newsfeed chats.""" threshold = datetime.now() - timedelta(hours=3) diff --git a/stickerfinder/telegram/message_handlers.py b/stickerfinder/telegram/message_handlers.py index 5995cfe..24d7f12 100644 --- a/stickerfinder/telegram/message_handlers.py +++ b/stickerfinder/telegram/message_handlers.py @@ -4,7 +4,7 @@ Sticker, StickerSet, ) -from stickerfinder.session import session_wrapper +from stickerfinder.session import message_wrapper from stickerfinder.enum import TagMode from stickerfinder.logic.tag import ( handle_next, @@ -18,7 +18,7 @@ ) -@session_wrapper() +@message_wrapper() def handle_private_text(bot, update, session, chat, user): """Read all messages and handle the tagging of stickers.""" # Handle the name of a sticker set to initialize full sticker set tagging @@ -52,7 +52,7 @@ def handle_private_text(bot, update, session, chat, user): return "Sticker tags adjusted." -@session_wrapper() +@message_wrapper() def handle_private_sticker(bot, update, session, chat, user): """Read all stickers. @@ -93,7 +93,7 @@ def handle_private_sticker(bot, update, session, chat, user): ) -@session_wrapper(send_message=False) +@message_wrapper(send_message=False) def handle_group_sticker(bot, update, session, chat, user): """Read all stickers. @@ -146,7 +146,7 @@ def handle_group_sticker(bot, update, session, chat, user): return -@session_wrapper() +@message_wrapper() def handle_edited_messages(bot, update, session, chat, user): """Read edited messages and check whether the user corrected some tags.""" message = update.edited_message