From 867a96ac3fa5ec76c79d40862bbf0d781a135b14 Mon Sep 17 00:00:00 2001 From: dbrennand <52419383+dbrennand@users.noreply.github.com> Date: Thu, 2 Jun 2022 10:03:25 +0100 Subject: [PATCH 01/17] refactor: remove pipfiles --- Pipfile | 18 --- Pipfile.lock | 358 --------------------------------------------------- 2 files changed, 376 deletions(-) delete mode 100644 Pipfile delete mode 100644 Pipfile.lock diff --git a/Pipfile b/Pipfile deleted file mode 100644 index 83ee6f4..0000000 --- a/Pipfile +++ /dev/null @@ -1,18 +0,0 @@ -[[source]] -name = "pypi" -url = "https://pypi.org/simple" -verify_ssl = true - -[dev-packages] -black = "*" - -[packages] -reader = {extras = ["search"], version = "*"} -loguru = "*" -python-telegram-bot = "*" - -[requires] -python_version = "3.9" - -[pipenv] -allow_prereleases = true diff --git a/Pipfile.lock b/Pipfile.lock deleted file mode 100644 index a3f0b2c..0000000 --- a/Pipfile.lock +++ /dev/null @@ -1,358 +0,0 @@ -{ - "_meta": { - "hash": { - "sha256": "e981e263b5499a4a001ebf08a53dc921be40b76ae7d649c2ab6a7ac0e0050d80" - }, - "pipfile-spec": 6, - "requires": { - "python_version": "3.9" - }, - "sources": [ - { - "name": "pypi", - "url": "https://pypi.org/simple", - "verify_ssl": true - } - ] - }, - "default": { - "apscheduler": { - "hashes": [ - "sha256:3bb5229eed6fbbdafc13ce962712ae66e175aa214c69bed35a06bffcf0c5e244", - "sha256:e8b1ecdb4c7cb2818913f766d5898183c7cb8936680710a4d3a966e02262e526" - ], - "version": "==3.6.3" - }, - "beautifulsoup4": { - "hashes": [ - "sha256:4c98143716ef1cb40bf7f39a8e3eec8f8b009509e74904ba3a7b315431577e35", - "sha256:84729e322ad1d5b4d25f805bfa05b902dd96450f43842c4e99067d5e1369eb25", - "sha256:fff47e031e34ec82bf17e00da8f592fe7de69aeea38be00523c04623c04fb666" - ], - "version": "==4.9.3" - }, - "certifi": { - "hashes": [ - "sha256:1a4995114262bffbc2413b159f2a1a480c969de6e6eb13ee966d470af86af59c", - "sha256:719a74fb9e33b9bd44cc7f3a8d94bc35e4049deebe19ba7d8e108280cfd59830" - ], - "version": "==2020.12.5" - }, - "chardet": { - "hashes": [ - "sha256:0d6f53a15db4120f2b08c94f11e7d93d2c911ee118b6b30a04ec3ee8310179fa", - "sha256:f864054d66fd9118f2e67044ac8981a54775ec5b67aed0441892edb553d21da5" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==4.0.0" - }, - "colorama": { - "hashes": [ - "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b", - "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2" - ], - "markers": "sys_platform == 'win32'", - "version": "==0.4.4" - }, - "feedparser": { - "hashes": [ - "sha256:1b00a105425f492f3954fd346e5b524ca9cef3a4bbf95b8809470e9857aa1074", - "sha256:f596c4b34fb3e2dc7e6ac3a8191603841e8d5d267210064e94d4238737452ddd" - ], - "markers": "python_version >= '3.6'", - "version": "==6.0.2" - }, - "idna": { - "hashes": [ - "sha256:b307872f855b18632ce0c21c5e45be78c0ea7ae4c15c828c20788b26921eb3f6", - "sha256:b97d804b1e9b523befed77c48dacec60e6dcb0b5391d57af6a65a312a90648c0" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==2.10" - }, - "iso8601": { - "hashes": [ - "sha256:8aafd56fa0290496c5edbb13c311f78fa3a241f0853540da09d9363eae3ebd79", - "sha256:e7e1122f064d626e17d47cd5106bed2c620cb38fe464999e0ddae2b6d2de6004" - ], - "version": "==0.1.14" - }, - "loguru": { - "hashes": [ - "sha256:b28e72ac7a98be3d28ad28570299a393dfcd32e5e3f6a353dec94675767b6319", - "sha256:f8087ac396b5ee5f67c963b495d615ebbceac2796379599820e324419d53667c" - ], - "index": "pypi", - "version": "==0.5.3" - }, - "python-telegram-bot": { - "hashes": [ - "sha256:467b0f149bf4d0b9b638530c9a887dd0d6e64da1d5603cfe6eee839671ca1496", - "sha256:4c1fdc3dab192bf1f754ccd0692511976b38e2c6ad75010e30844a19c0193c90" - ], - "index": "pypi", - "version": "==13.4.1" - }, - "pytz": { - "hashes": [ - "sha256:83a4a90894bf38e243cf052c8b58f381bfe9a7a483f6a9cab140bc7f702ac4da", - "sha256:eb10ce3e7736052ed3623d49975ce333bcd712c7bb19a58b9e2089d4057d0798" - ], - "version": "==2021.1" - }, - "reader": { - "extras": [ - "search" - ], - "hashes": [ - "sha256:7b8e381b258bf89bd1884b01198047a707849bf16f2a63c9b060cedf17170621", - "sha256:9f78e257e0b37c327acd3c095c1ac9de7400b7e9779e751ad7a9b21fa4701b87" - ], - "index": "pypi", - "version": "==1.15" - }, - "requests": { - "hashes": [ - "sha256:27973dd4a904a4f13b263a19c866c13b92a39ed1c964655f025f3f8d3d75b804", - "sha256:c210084e36a42ae6b9219e00e48287def368a26d03a048ddad7bfee44f75871e" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==2.25.1" - }, - "sgmllib3k": { - "hashes": [ - "sha256:7868fb1c8bfa764c1ac563d3cf369c381d1325d36124933a726f29fcdaa812e9" - ], - "version": "==1.0.0" - }, - "six": { - "hashes": [ - "sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259", - "sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==1.15.0" - }, - "soupsieve": { - "hashes": [ - "sha256:052774848f448cf19c7e959adf5566904d525f33a3f8b6ba6f6f8f26ec7de0cc", - "sha256:c2c1c2d44f158cdbddab7824a9af8c4f83c76b1e23e049479aa432feb6c4c23b" - ], - "markers": "python_version >= '3.0'", - "version": "==2.2.1" - }, - "tornado": { - "hashes": [ - "sha256:0a00ff4561e2929a2c37ce706cb8233b7907e0cdc22eab98888aca5dd3775feb", - "sha256:0d321a39c36e5f2c4ff12b4ed58d41390460f798422c4504e09eb5678e09998c", - "sha256:1e8225a1070cd8eec59a996c43229fe8f95689cb16e552d130b9793cb570a288", - "sha256:20241b3cb4f425e971cb0a8e4ffc9b0a861530ae3c52f2b0434e6c1b57e9fd95", - "sha256:25ad220258349a12ae87ede08a7b04aca51237721f63b1808d39bdb4b2164558", - "sha256:33892118b165401f291070100d6d09359ca74addda679b60390b09f8ef325ffe", - "sha256:33c6e81d7bd55b468d2e793517c909b139960b6c790a60b7991b9b6b76fb9791", - "sha256:3447475585bae2e77ecb832fc0300c3695516a47d46cefa0528181a34c5b9d3d", - "sha256:34ca2dac9e4d7afb0bed4677512e36a52f09caa6fded70b4e3e1c89dbd92c326", - "sha256:3e63498f680547ed24d2c71e6497f24bca791aca2fe116dbc2bd0ac7f191691b", - "sha256:548430be2740e327b3fe0201abe471f314741efcb0067ec4f2d7dcfb4825f3e4", - "sha256:6196a5c39286cc37c024cd78834fb9345e464525d8991c21e908cc046d1cc02c", - "sha256:61b32d06ae8a036a6607805e6720ef00a3c98207038444ba7fd3d169cd998910", - "sha256:6286efab1ed6e74b7028327365cf7346b1d777d63ab30e21a0f4d5b275fc17d5", - "sha256:65d98939f1a2e74b58839f8c4dab3b6b3c1ce84972ae712be02845e65391ac7c", - "sha256:66324e4e1beede9ac79e60f88de548da58b1f8ab4b2f1354d8375774f997e6c0", - "sha256:6c77c9937962577a6a76917845d06af6ab9197702a42e1346d8ae2e76b5e3675", - "sha256:70dec29e8ac485dbf57481baee40781c63e381bebea080991893cd297742b8fd", - "sha256:7250a3fa399f08ec9cb3f7b1b987955d17e044f1ade821b32e5f435130250d7f", - "sha256:748290bf9112b581c525e6e6d3820621ff020ed95af6f17fedef416b27ed564c", - "sha256:7da13da6f985aab7f6f28debab00c67ff9cbacd588e8477034c0652ac141feea", - "sha256:8f959b26f2634a091bb42241c3ed8d3cedb506e7c27b8dd5c7b9f745318ddbb6", - "sha256:9de9e5188a782be6b1ce866e8a51bc76a0fbaa0e16613823fc38e4fc2556ad05", - "sha256:a48900ecea1cbb71b8c71c620dee15b62f85f7c14189bdeee54966fbd9a0c5bd", - "sha256:b87936fd2c317b6ee08a5741ea06b9d11a6074ef4cc42e031bc6403f82a32575", - "sha256:c77da1263aa361938476f04c4b6c8916001b90b2c2fdd92d8d535e1af48fba5a", - "sha256:cb5ec8eead331e3bb4ce8066cf06d2dfef1bfb1b2a73082dfe8a161301b76e37", - "sha256:cc0ee35043162abbf717b7df924597ade8e5395e7b66d18270116f8745ceb795", - "sha256:d14d30e7f46a0476efb0deb5b61343b1526f73ebb5ed84f23dc794bdb88f9d9f", - "sha256:d371e811d6b156d82aa5f9a4e08b58debf97c302a35714f6f45e35139c332e32", - "sha256:d3d20ea5782ba63ed13bc2b8c291a053c8d807a8fa927d941bd718468f7b950c", - "sha256:d3f7594930c423fd9f5d1a76bee85a2c36fd8b4b16921cae7e965f22575e9c01", - "sha256:dcef026f608f678c118779cd6591c8af6e9b4155c44e0d1bc0c87c036fb8c8c4", - "sha256:e0791ac58d91ac58f694d8d2957884df8e4e2f6687cdf367ef7eb7497f79eaa2", - "sha256:e385b637ac3acaae8022e7e47dfa7b83d3620e432e3ecb9a3f7f58f150e50921", - "sha256:e519d64089b0876c7b467274468709dadf11e41d65f63bba207e04217f47c085", - "sha256:e7229e60ac41a1202444497ddde70a48d33909e484f96eb0da9baf8dc68541df", - "sha256:ed3ad863b1b40cd1d4bd21e7498329ccaece75db5a5bf58cd3c9f130843e7102", - "sha256:f0ba29bafd8e7e22920567ce0d232c26d4d47c8b5cf4ed7b562b5db39fa199c5", - "sha256:fa2ba70284fa42c2a5ecb35e322e68823288a4251f9ba9cc77be04ae15eada68", - "sha256:fba85b6cd9c39be262fcd23865652920832b61583de2a2ca907dbd8e8a8c81e5" - ], - "markers": "python_version >= '3.5'", - "version": "==6.1" - }, - "typing-extensions": { - "hashes": [ - "sha256:7cb407020f00f7bfc3cb3e7881628838e69d8f3fcab2f64742a5e76b2f841918", - "sha256:99d4073b617d30288f569d3f13d2bd7548c3a7e4c8de87db09a9d29bb3a4a60c", - "sha256:dafc7639cde7f1b6e1acc0f457842a83e722ccca8eef5270af2d74792619a89f" - ], - "version": "==3.7.4.3" - }, - "tzlocal": { - "hashes": [ - "sha256:643c97c5294aedc737780a49d9df30889321cbe1204eac2c2ec6134035a92e44", - "sha256:e2cb6c6b5b604af38597403e9852872d7f534962ae2954c7f35efcb1ccacf4a4" - ], - "version": "==2.1" - }, - "urllib3": { - "hashes": [ - "sha256:2f4da4594db7e1e110a944bb1b551fdf4e6c136ad42e4234131391e21eb5b0df", - "sha256:e7b021f7241115872f92f43c6508082facffbd1c048e3c6e2bb9c2a157e28937" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' and python_version < '4'", - "version": "==1.26.4" - }, - "win32-setctime": { - "hashes": [ - "sha256:4e88556c32fdf47f64165a2180ba4552f8bb32c1103a2fafd05723a0bd42bd4b", - "sha256:dc925662de0a6eb987f0b01f599c01a8236cb8c62831c22d9cada09ad958243e" - ], - "markers": "sys_platform == 'win32'", - "version": "==1.0.3" - } - }, - "develop": { - "appdirs": { - "hashes": [ - "sha256:7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41", - "sha256:a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128" - ], - "version": "==1.4.4" - }, - "black": { - "hashes": [ - "sha256:1c02557aa099101b9d21496f8a914e9ed2222ef70336404eeeac8edba836fbea" - ], - "index": "pypi", - "version": "==20.8b1" - }, - "click": { - "hashes": [ - "sha256:d2b5255c7c6349bc1bd1e59e08cd12acbbd63ce649f2588755783aa94dfb6b1a", - "sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==7.1.2" - }, - "mypy-extensions": { - "hashes": [ - "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d", - "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8" - ], - "version": "==0.4.3" - }, - "pathspec": { - "hashes": [ - "sha256:86379d6b86d75816baba717e64b1a3a3469deb93bb76d613c9ce79edc5cb68fd", - "sha256:aa0cb481c4041bf52ffa7b0d8fa6cd3e88a2ca4879c533c9153882ee2556790d" - ], - "version": "==0.8.1" - }, - "regex": { - "hashes": [ - "sha256:07ef35301b4484bce843831e7039a84e19d8d33b3f8b2f9aab86c376813d0139", - "sha256:13f50969028e81765ed2a1c5fcfdc246c245cf8d47986d5172e82ab1a0c42ee5", - "sha256:14de88eda0976020528efc92d0a1f8830e2fb0de2ae6005a6fc4e062553031fa", - "sha256:159fac1a4731409c830d32913f13f68346d6b8e39650ed5d704a9ce2f9ef9cb3", - "sha256:18e25e0afe1cf0f62781a150c1454b2113785401ba285c745acf10c8ca8917df", - "sha256:201e2619a77b21a7780580ab7b5ce43835e242d3e20fef50f66a8df0542e437f", - "sha256:360a01b5fa2ad35b3113ae0c07fb544ad180603fa3b1f074f52d98c1096fa15e", - "sha256:39c44532d0e4f1639a89e52355b949573e1e2c5116106a395642cbbae0ff9bcd", - "sha256:3d9356add82cff75413bec360c1eca3e58db4a9f5dafa1f19650958a81e3249d", - "sha256:3d9a7e215e02bd7646a91fb8bcba30bc55fd42a719d6b35cf80e5bae31d9134e", - "sha256:4651f839dbde0816798e698626af6a2469eee6d9964824bb5386091255a1694f", - "sha256:486a5f8e11e1f5bbfcad87f7c7745eb14796642323e7e1829a331f87a713daaa", - "sha256:4b8a1fb724904139149a43e172850f35aa6ea97fb0545244dc0b805e0154ed68", - "sha256:4c0788010a93ace8a174d73e7c6c9d3e6e3b7ad99a453c8ee8c975ddd9965643", - "sha256:4c2e364491406b7888c2ad4428245fc56c327e34a5dfe58fd40df272b3c3dab3", - "sha256:575a832e09d237ae5fedb825a7a5bc6a116090dd57d6417d4f3b75121c73e3be", - "sha256:5770a51180d85ea468234bc7987f5597803a4c3d7463e7323322fe4a1b181578", - "sha256:633497504e2a485a70a3268d4fc403fe3063a50a50eed1039083e9471ad0101c", - "sha256:63f3ca8451e5ff7133ffbec9eda641aeab2001be1a01878990f6c87e3c44b9d5", - "sha256:709f65bb2fa9825f09892617d01246002097f8f9b6dde8d1bb4083cf554701ba", - "sha256:808404898e9a765e4058bf3d7607d0629000e0a14a6782ccbb089296b76fa8fe", - "sha256:882f53afe31ef0425b405a3f601c0009b44206ea7f55ee1c606aad3cc213a52c", - "sha256:8bd4f91f3fb1c9b1380d6894bd5b4a519409135bec14c0c80151e58394a4e88a", - "sha256:8e65e3e4c6feadf6770e2ad89ad3deb524bcb03d8dc679f381d0568c024e0deb", - "sha256:976a54d44fd043d958a69b18705a910a8376196c6b6ee5f2596ffc11bff4420d", - "sha256:a0d04128e005142260de3733591ddf476e4902c0c23c1af237d9acf3c96e1b38", - "sha256:a0df9a0ad2aad49ea3c7f65edd2ffb3d5c59589b85992a6006354f6fb109bb18", - "sha256:a2ee026f4156789df8644d23ef423e6194fad0bc53575534101bb1de5d67e8ce", - "sha256:a59a2ee329b3de764b21495d78c92ab00b4ea79acef0f7ae8c1067f773570afa", - "sha256:b97ec5d299c10d96617cc851b2e0f81ba5d9d6248413cd374ef7f3a8871ee4a6", - "sha256:b98bc9db003f1079caf07b610377ed1ac2e2c11acc2bea4892e28cc5b509d8d5", - "sha256:b9d8d286c53fe0cbc6d20bf3d583cabcd1499d89034524e3b94c93a5ab85ca90", - "sha256:bcd945175c29a672f13fce13a11893556cd440e37c1b643d6eeab1988c8b209c", - "sha256:c66221e947d7207457f8b6f42b12f613b09efa9669f65a587a2a71f6a0e4d106", - "sha256:c782da0e45aff131f0bed6e66fbcfa589ff2862fc719b83a88640daa01a5aff7", - "sha256:cb4ee827857a5ad9b8ae34d3c8cc51151cb4a3fe082c12ec20ec73e63cc7c6f0", - "sha256:d47d359545b0ccad29d572ecd52c9da945de7cd6cf9c0cfcb0269f76d3555689", - "sha256:dc9963aacb7da5177e40874585d7407c0f93fb9d7518ec58b86e562f633f36cd", - "sha256:ea2f41445852c660ba7c3ebf7d70b3779b20d9ca8ba54485a17740db49f46932", - "sha256:f5d0c921c99297354cecc5a416ee4280bd3f20fd81b9fb671ca6be71499c3fdf", - "sha256:f85d6f41e34f6a2d1607e312820971872944f1661a73d33e1e82d35ea3305e14" - ], - "version": "==2021.3.17" - }, - "toml": { - "hashes": [ - "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b", - "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f" - ], - "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==0.10.2" - }, - "typed-ast": { - "hashes": [ - "sha256:07d49388d5bf7e863f7fa2f124b1b1d89d8aa0e2f7812faff0a5658c01c59aa1", - "sha256:14bf1522cdee369e8f5581238edac09150c765ec1cb33615855889cf33dcb92d", - "sha256:240296b27397e4e37874abb1df2a608a92df85cf3e2a04d0d4d61055c8305ba6", - "sha256:36d829b31ab67d6fcb30e185ec996e1f72b892255a745d3a82138c97d21ed1cd", - "sha256:37f48d46d733d57cc70fd5f30572d11ab8ed92da6e6b28e024e4a3edfb456e37", - "sha256:4c790331247081ea7c632a76d5b2a265e6d325ecd3179d06e9cf8d46d90dd151", - "sha256:5dcfc2e264bd8a1db8b11a892bd1647154ce03eeba94b461effe68790d8b8e07", - "sha256:7147e2a76c75f0f64c4319886e7639e490fee87c9d25cb1d4faef1d8cf83a440", - "sha256:7703620125e4fb79b64aa52427ec192822e9f45d37d4b6625ab37ef403e1df70", - "sha256:8368f83e93c7156ccd40e49a783a6a6850ca25b556c0fa0240ed0f659d2fe496", - "sha256:84aa6223d71012c68d577c83f4e7db50d11d6b1399a9c779046d75e24bed74ea", - "sha256:85f95aa97a35bdb2f2f7d10ec5bbdac0aeb9dafdaf88e17492da0504de2e6400", - "sha256:8db0e856712f79c45956da0c9a40ca4246abc3485ae0d7ecc86a20f5e4c09abc", - "sha256:9044ef2df88d7f33692ae3f18d3be63dec69c4fb1b5a4a9ac950f9b4ba571606", - "sha256:963c80b583b0661918718b095e02303d8078950b26cc00b5e5ea9ababe0de1fc", - "sha256:987f15737aba2ab5f3928c617ccf1ce412e2e321c77ab16ca5a293e7bbffd581", - "sha256:9ec45db0c766f196ae629e509f059ff05fc3148f9ffd28f3cfe75d4afb485412", - "sha256:9fc0b3cb5d1720e7141d103cf4819aea239f7d136acf9ee4a69b047b7986175a", - "sha256:a2c927c49f2029291fbabd673d51a2180038f8cd5a5b2f290f78c4516be48be2", - "sha256:a38878a223bdd37c9709d07cd357bb79f4c760b29210e14ad0fb395294583787", - "sha256:b4fcdcfa302538f70929eb7b392f536a237cbe2ed9cba88e3bf5027b39f5f77f", - "sha256:c0c74e5579af4b977c8b932f40a5464764b2f86681327410aa028a22d2f54937", - "sha256:c1c876fd795b36126f773db9cbb393f19808edd2637e00fd6caba0e25f2c7b64", - "sha256:c9aadc4924d4b5799112837b226160428524a9a45f830e0d0f184b19e4090487", - "sha256:cc7b98bf58167b7f2db91a4327da24fb93368838eb84a44c472283778fc2446b", - "sha256:cf54cfa843f297991b7388c281cb3855d911137223c6b6d2dd82a47ae5125a41", - "sha256:d003156bb6a59cda9050e983441b7fa2487f7800d76bdc065566b7d728b4581a", - "sha256:d175297e9533d8d37437abc14e8a83cbc68af93cc9c1c59c2c292ec59a0697a3", - "sha256:d746a437cdbca200622385305aedd9aef68e8a645e385cc483bdc5e488f07166", - "sha256:e683e409e5c45d5c9082dc1daf13f6374300806240719f95dc783d1fc942af10" - ], - "version": "==1.4.2" - }, - "typing-extensions": { - "hashes": [ - "sha256:7cb407020f00f7bfc3cb3e7881628838e69d8f3fcab2f64742a5e76b2f841918", - "sha256:99d4073b617d30288f569d3f13d2bd7548c3a7e4c8de87db09a9d29bb3a4a60c", - "sha256:dafc7639cde7f1b6e1acc0f457842a83e722ccca8eef5270af2d74792619a89f" - ], - "version": "==3.7.4.3" - } - } -} From d16088d90e2876f3d8775f64242d6cfc66396112 Mon Sep 17 00:00:00 2001 From: dbrennand <52419383+dbrennand@users.noreply.github.com> Date: Thu, 2 Jun 2022 10:03:45 +0100 Subject: [PATCH 02/17] refactor: update to Python 3.10 and make database persistent --- Dockerfile | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index dac45c6..4614ec0 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,8 +1,11 @@ -FROM python:3.9-slim +FROM python:3.10-slim # Set working directory WORKDIR /usr/src/app +# Create directory to persist reader database +RUN mkdir -p /data/reader + # Copy all of the projects contents to containers /usr/src/app directory COPY . . From 652bbfe29df7dff1622465dda92c57081f43b083 Mon Sep 17 00:00:00 2001 From: dbrennand <52419383+dbrennand@users.noreply.github.com> Date: Thu, 2 Jun 2022 10:03:59 +0100 Subject: [PATCH 03/17] feat: add pyproject.toml --- pyproject.toml | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 pyproject.toml diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..42325a7 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,20 @@ +[tool.poetry] +name = "rss_feederbot" +version = "1.0.0" +description = "An RSS feed reading Telegram bot" +authors = ["dbrennand <52419383+dbrennand@users.noreply.github.com>"] +license = "MIT" + +[tool.poetry.dependencies] +python = "^3.10" +reader = "^2.12" +loguru = "^0.6.0" +python-telegram-bot = {git = "https://github.com/python-telegram-bot/python-telegram-bot.git"} +emoji = "^1.7.0" + +[tool.poetry.dev-dependencies] +black = "^22.3.0" + +[build-system] +requires = ["poetry-core>=1.0.0"] +build-backend = "poetry.core.masonry.api" From 43bcc3102717e645b1271237eb8089b2593b47f9 Mon Sep 17 00:00:00 2001 From: dbrennand <52419383+dbrennand@users.noreply.github.com> Date: Fri, 3 Jun 2022 16:13:20 +0100 Subject: [PATCH 04/17] chore: update dependencies --- poetry.lock | 664 +++++++++++++++++++++++++++++++++++++++++++++++++ pyproject.toml | 2 +- 2 files changed, 665 insertions(+), 1 deletion(-) create mode 100644 poetry.lock diff --git a/poetry.lock b/poetry.lock new file mode 100644 index 0000000..622811c --- /dev/null +++ b/poetry.lock @@ -0,0 +1,664 @@ +[[package]] +name = "anyio" +version = "3.6.1" +description = "High level compatibility layer for multiple asynchronous event loop implementations" +category = "main" +optional = false +python-versions = ">=3.6.2" + +[package.dependencies] +idna = ">=2.8" +sniffio = ">=1.1" + +[package.extras] +doc = ["packaging", "sphinx-rtd-theme", "sphinx-autodoc-typehints (>=1.2.0)"] +test = ["coverage[toml] (>=4.5)", "hypothesis (>=4.0)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "contextlib2", "uvloop (<0.15)", "mock (>=4)", "uvloop (>=0.15)"] +trio = ["trio (>=0.16)"] + +[[package]] +name = "apscheduler" +version = "3.9.1" +description = "In-process task scheduler with Cron-like capabilities" +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4" + +[package.dependencies] +pytz = "*" +six = ">=1.4.0" +tzlocal = ">=2.0,<3.0.0 || >=4.0.0" + +[package.extras] +asyncio = ["trollius"] +doc = ["sphinx", "sphinx-rtd-theme"] +gevent = ["gevent"] +mongodb = ["pymongo (>=3.0)"] +redis = ["redis (>=3.0)"] +rethinkdb = ["rethinkdb (>=2.4.0)"] +sqlalchemy = ["sqlalchemy (>=0.8)"] +testing = ["pytest", "pytest-cov", "pytest-tornado5", "mock", "pytest-asyncio (<0.6)", "pytest-asyncio"] +tornado = ["tornado (>=4.3)"] +twisted = ["twisted"] +zookeeper = ["kazoo"] + +[[package]] +name = "beautifulsoup4" +version = "4.11.1" +description = "Screen-scraping library" +category = "main" +optional = false +python-versions = ">=3.6.0" + +[package.dependencies] +soupsieve = ">1.2" + +[package.extras] +html5lib = ["html5lib"] +lxml = ["lxml"] + +[[package]] +name = "black" +version = "22.3.0" +description = "The uncompromising code formatter." +category = "dev" +optional = false +python-versions = ">=3.6.2" + +[package.dependencies] +click = ">=8.0.0" +mypy-extensions = ">=0.4.3" +pathspec = ">=0.9.0" +platformdirs = ">=2" +tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} + +[package.extras] +colorama = ["colorama (>=0.4.3)"] +d = ["aiohttp (>=3.7.4)"] +jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"] +uvloop = ["uvloop (>=0.15.2)"] + +[[package]] +name = "cachetools" +version = "5.0.0" +description = "Extensible memoizing collections and decorators" +category = "main" +optional = false +python-versions = "~=3.7" + +[[package]] +name = "certifi" +version = "2022.5.18.1" +description = "Python package for providing Mozilla's CA Bundle." +category = "main" +optional = false +python-versions = ">=3.6" + +[[package]] +name = "charset-normalizer" +version = "2.0.12" +description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." +category = "main" +optional = false +python-versions = ">=3.5.0" + +[package.extras] +unicode_backport = ["unicodedata2"] + +[[package]] +name = "click" +version = "8.1.3" +description = "Composable command line interface toolkit" +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +colorama = {version = "*", markers = "platform_system == \"Windows\""} + +[[package]] +name = "colorama" +version = "0.4.4" +description = "Cross-platform colored terminal text." +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" + +[[package]] +name = "emoji" +version = "1.7.0" +description = "Emoji for Python" +category = "main" +optional = false +python-versions = "*" + +[package.extras] +dev = ["pytest", "coverage", "coveralls"] + +[[package]] +name = "feedparser" +version = "6.0.10" +description = "Universal feed parser, handles RSS 0.9x, RSS 1.0, RSS 2.0, CDF, Atom 0.3, and Atom 1.0 feeds" +category = "main" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +sgmllib3k = "*" + +[[package]] +name = "h11" +version = "0.12.0" +description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1" +category = "main" +optional = false +python-versions = ">=3.6" + +[[package]] +name = "httpcore" +version = "0.14.7" +description = "A minimal low-level HTTP client." +category = "main" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +anyio = ">=3.0.0,<4.0.0" +certifi = "*" +h11 = ">=0.11,<0.13" +sniffio = ">=1.0.0,<2.0.0" + +[package.extras] +http2 = ["h2 (>=3,<5)"] +socks = ["socksio (>=1.0.0,<2.0.0)"] + +[[package]] +name = "httpx" +version = "0.22.0" +description = "The next generation HTTP client." +category = "main" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +certifi = "*" +charset-normalizer = "*" +httpcore = ">=0.14.5,<0.15.0" +rfc3986 = {version = ">=1.3,<2", extras = ["idna2008"]} +sniffio = "*" + +[package.extras] +brotli = ["brotlicffi", "brotli"] +cli = ["click (>=8.0.0,<9.0.0)", "rich (>=10.0.0,<11.0.0)", "pygments (>=2.0.0,<3.0.0)"] +http2 = ["h2 (>=3,<5)"] +socks = ["socksio (>=1.0.0,<2.0.0)"] + +[[package]] +name = "idna" +version = "3.3" +description = "Internationalized Domain Names in Applications (IDNA)" +category = "main" +optional = false +python-versions = ">=3.5" + +[[package]] +name = "iso8601" +version = "1.0.2" +description = "Simple module to parse ISO 8601 dates" +category = "main" +optional = false +python-versions = ">=3.6.2,<4.0" + +[[package]] +name = "loguru" +version = "0.6.0" +description = "Python logging made (stupidly) simple" +category = "main" +optional = false +python-versions = ">=3.5" + +[package.dependencies] +colorama = {version = ">=0.3.4", markers = "sys_platform == \"win32\""} +win32-setctime = {version = ">=1.0.0", markers = "sys_platform == \"win32\""} + +[package.extras] +dev = ["colorama (>=0.3.4)", "docutils (==0.16)", "flake8 (>=3.7.7)", "tox (>=3.9.0)", "pytest (>=4.6.2)", "pytest-cov (>=2.7.1)", "black (>=19.10b0)", "isort (>=5.1.1)", "Sphinx (>=4.1.1)", "sphinx-autobuild (>=0.7.1)", "sphinx-rtd-theme (>=0.4.3)"] + +[[package]] +name = "mypy-extensions" +version = "0.4.3" +description = "Experimental type system extensions for programs checked with the mypy typechecker." +category = "dev" +optional = false +python-versions = "*" + +[[package]] +name = "pathspec" +version = "0.9.0" +description = "Utility library for gitignore style pattern matching of file paths." +category = "dev" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" + +[[package]] +name = "platformdirs" +version = "2.5.2" +description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.extras] +docs = ["furo (>=2021.7.5b38)", "proselint (>=0.10.2)", "sphinx-autodoc-typehints (>=1.12)", "sphinx (>=4)"] +test = ["appdirs (==1.4.4)", "pytest-cov (>=2.7)", "pytest-mock (>=3.6)", "pytest (>=6)"] + +[[package]] +name = "python-telegram-bot" +version = "20.0a0" +description = "We have made you a wrapper you can't refuse" +category = "main" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +APScheduler = ">=3.9.1,<3.10.0" +cachetools = ">=5.0.0,<5.1.0" +httpx = ">=0.22.0,<0.23.0" +pytz = ">=2018.6" +tornado = ">=6.1,<7.0" + +[package.extras] +json = ["ujson (>=4.0.0)"] +passport = ["cryptography (>=3.0,!=3.4,!=3.4.1,!=3.4.2,!=3.4.3)"] +socks = ["httpx"] + +[[package]] +name = "pytz" +version = "2022.1" +description = "World timezone definitions, modern and historical" +category = "main" +optional = false +python-versions = "*" + +[[package]] +name = "pytz-deprecation-shim" +version = "0.1.0.post0" +description = "Shims to make deprecation of pytz easier" +category = "main" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" + +[package.dependencies] +tzdata = {version = "*", markers = "python_version >= \"3.6\""} + +[[package]] +name = "reader" +version = "2.12" +description = "A Python feed reader library." +category = "main" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +beautifulsoup4 = ">=4.5" +feedparser = ">=6" +iso8601 = "*" +requests = ">=2.18" +typing-extensions = "*" + +[package.extras] +app = ["flask (>=0.10)", "humanize", "pyyaml"] +cli = ["click (>=7)", "pyyaml"] +dev = ["tox", "pre-commit", "build", "twine"] +docs = ["sphinx", "sphinx-rtd-theme (>=1.0,<2.0)", "click (>=7)", "sphinx-click", "sphinx-issues", "sphinx-hoverxref", "sphinxcontrib-log-cabinet"] +readtime = ["readtime"] +tests = ["pytest (>=4)", "pytest-randomly", "pytest-subtests", "flaky", "coverage", "pytest-cov", "requests-mock", "requests-wsgi-adapter", "html5lib", "werkzeug", "types-requests", "mypy", "mechanicalsoup", "lxml"] +unstable-plugins = ["requests", "mutagen", "beautifulsoup4", "blinker (>=1.4)"] + +[[package]] +name = "requests" +version = "2.27.1" +description = "Python HTTP for Humans." +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" + +[package.dependencies] +certifi = ">=2017.4.17" +charset-normalizer = {version = ">=2.0.0,<2.1.0", markers = "python_version >= \"3\""} +idna = {version = ">=2.5,<4", markers = "python_version >= \"3\""} +urllib3 = ">=1.21.1,<1.27" + +[package.extras] +socks = ["PySocks (>=1.5.6,!=1.5.7)", "win-inet-pton"] +use_chardet_on_py3 = ["chardet (>=3.0.2,<5)"] + +[[package]] +name = "rfc3986" +version = "1.5.0" +description = "Validating URI References per RFC 3986" +category = "main" +optional = false +python-versions = "*" + +[package.dependencies] +idna = {version = "*", optional = true, markers = "extra == \"idna2008\""} + +[package.extras] +idna2008 = ["idna"] + +[[package]] +name = "sgmllib3k" +version = "1.0.0" +description = "Py3k port of sgmllib." +category = "main" +optional = false +python-versions = "*" + +[[package]] +name = "six" +version = "1.16.0" +description = "Python 2 and 3 compatibility utilities" +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" + +[[package]] +name = "sniffio" +version = "1.2.0" +description = "Sniff out which async library your code is running under" +category = "main" +optional = false +python-versions = ">=3.5" + +[[package]] +name = "soupsieve" +version = "2.3.2.post1" +description = "A modern CSS selector implementation for Beautiful Soup." +category = "main" +optional = false +python-versions = ">=3.6" + +[[package]] +name = "tomli" +version = "2.0.1" +description = "A lil' TOML parser" +category = "dev" +optional = false +python-versions = ">=3.7" + +[[package]] +name = "tornado" +version = "6.1" +description = "Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed." +category = "main" +optional = false +python-versions = ">= 3.5" + +[[package]] +name = "typing-extensions" +version = "4.2.0" +description = "Backported and Experimental Type Hints for Python 3.7+" +category = "main" +optional = false +python-versions = ">=3.7" + +[[package]] +name = "tzdata" +version = "2022.1" +description = "Provider of IANA time zone data" +category = "main" +optional = false +python-versions = ">=2" + +[[package]] +name = "tzlocal" +version = "4.2" +description = "tzinfo object for the local timezone" +category = "main" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +pytz-deprecation-shim = "*" +tzdata = {version = "*", markers = "platform_system == \"Windows\""} + +[package.extras] +devenv = ["black", "pyroma", "pytest-cov", "zest.releaser"] +test = ["pytest-mock (>=3.3)", "pytest (>=4.3)"] + +[[package]] +name = "urllib3" +version = "1.26.9" +description = "HTTP library with thread-safe connection pooling, file post, and more." +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4" + +[package.extras] +brotli = ["brotlicffi (>=0.8.0)", "brotli (>=1.0.9)", "brotlipy (>=0.6.0)"] +secure = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "certifi", "ipaddress"] +socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] + +[[package]] +name = "win32-setctime" +version = "1.1.0" +description = "A small Python utility to set file creation time on Windows" +category = "main" +optional = false +python-versions = ">=3.5" + +[package.extras] +dev = ["pytest (>=4.6.2)", "black (>=19.3b0)"] + +[metadata] +lock-version = "1.1" +python-versions = "^3.10" +content-hash = "33b47fdd3a8cd100885f33f3ce98fbf875dfca0afd1a3ef6533b3f03f571a792" + +[metadata.files] +anyio = [ + {file = "anyio-3.6.1-py3-none-any.whl", hash = "sha256:cb29b9c70620506a9a8f87a309591713446953302d7d995344d0d7c6c0c9a7be"}, + {file = "anyio-3.6.1.tar.gz", hash = "sha256:413adf95f93886e442aea925f3ee43baa5a765a64a0f52c6081894f9992fdd0b"}, +] +apscheduler = [ + {file = "APScheduler-3.9.1-py2.py3-none-any.whl", hash = "sha256:ddc25a0ddd899de44d7f451f4375fb971887e65af51e41e5dcf681f59b8b2c9a"}, + {file = "APScheduler-3.9.1.tar.gz", hash = "sha256:65e6574b6395498d371d045f2a8a7e4f7d50c6ad21ef7313d15b1c7cf20df1e3"}, +] +beautifulsoup4 = [ + {file = "beautifulsoup4-4.11.1-py3-none-any.whl", hash = "sha256:58d5c3d29f5a36ffeb94f02f0d786cd53014cf9b3b3951d42e0080d8a9498d30"}, + {file = "beautifulsoup4-4.11.1.tar.gz", hash = "sha256:ad9aa55b65ef2808eb405f46cf74df7fcb7044d5cbc26487f96eb2ef2e436693"}, +] +black = [ + {file = "black-22.3.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:2497f9c2386572e28921fa8bec7be3e51de6801f7459dffd6e62492531c47e09"}, + {file = "black-22.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5795a0375eb87bfe902e80e0c8cfaedf8af4d49694d69161e5bd3206c18618bb"}, + {file = "black-22.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e3556168e2e5c49629f7b0f377070240bd5511e45e25a4497bb0073d9dda776a"}, + {file = "black-22.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:67c8301ec94e3bcc8906740fe071391bce40a862b7be0b86fb5382beefecd968"}, + {file = "black-22.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:fd57160949179ec517d32ac2ac898b5f20d68ed1a9c977346efbac9c2f1e779d"}, + {file = "black-22.3.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:cc1e1de68c8e5444e8f94c3670bb48a2beef0e91dddfd4fcc29595ebd90bb9ce"}, + {file = "black-22.3.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d2fc92002d44746d3e7db7cf9313cf4452f43e9ea77a2c939defce3b10b5c82"}, + {file = "black-22.3.0-cp36-cp36m-win_amd64.whl", hash = "sha256:a6342964b43a99dbc72f72812bf88cad8f0217ae9acb47c0d4f141a6416d2d7b"}, + {file = "black-22.3.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:328efc0cc70ccb23429d6be184a15ce613f676bdfc85e5fe8ea2a9354b4e9015"}, + {file = "black-22.3.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:06f9d8846f2340dfac80ceb20200ea5d1b3f181dd0556b47af4e8e0b24fa0a6b"}, + {file = "black-22.3.0-cp37-cp37m-win_amd64.whl", hash = "sha256:ad4efa5fad66b903b4a5f96d91461d90b9507a812b3c5de657d544215bb7877a"}, + {file = "black-22.3.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:e8477ec6bbfe0312c128e74644ac8a02ca06bcdb8982d4ee06f209be28cdf163"}, + {file = "black-22.3.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:637a4014c63fbf42a692d22b55d8ad6968a946b4a6ebc385c5505d9625b6a464"}, + {file = "black-22.3.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:863714200ada56cbc366dc9ae5291ceb936573155f8bf8e9de92aef51f3ad0f0"}, + {file = "black-22.3.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10dbe6e6d2988049b4655b2b739f98785a884d4d6b85bc35133a8fb9a2233176"}, + {file = "black-22.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:cee3e11161dde1b2a33a904b850b0899e0424cc331b7295f2a9698e79f9a69a0"}, + {file = "black-22.3.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:5891ef8abc06576985de8fa88e95ab70641de6c1fca97e2a15820a9b69e51b20"}, + {file = "black-22.3.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:30d78ba6bf080eeaf0b7b875d924b15cd46fec5fd044ddfbad38c8ea9171043a"}, + {file = "black-22.3.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ee8f1f7228cce7dffc2b464f07ce769f478968bfb3dd1254a4c2eeed84928aad"}, + {file = "black-22.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6ee227b696ca60dd1c507be80a6bc849a5a6ab57ac7352aad1ffec9e8b805f21"}, + {file = "black-22.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:9b542ced1ec0ceeff5b37d69838106a6348e60db7b8fdd245294dc1d26136265"}, + {file = "black-22.3.0-py3-none-any.whl", hash = "sha256:bc58025940a896d7e5356952228b68f793cf5fcb342be703c3a2669a1488cb72"}, + {file = "black-22.3.0.tar.gz", hash = "sha256:35020b8886c022ced9282b51b5a875b6d1ab0c387b31a065b84db7c33085ca79"}, +] +cachetools = [ + {file = "cachetools-5.0.0-py3-none-any.whl", hash = "sha256:8fecd4203a38af17928be7b90689d8083603073622229ca7077b72d8e5a976e4"}, + {file = "cachetools-5.0.0.tar.gz", hash = "sha256:486471dfa8799eb7ec503a8059e263db000cdda20075ce5e48903087f79d5fd6"}, +] +certifi = [ + {file = "certifi-2022.5.18.1-py3-none-any.whl", hash = "sha256:f1d53542ee8cbedbe2118b5686372fb33c297fcd6379b050cca0ef13a597382a"}, + {file = "certifi-2022.5.18.1.tar.gz", hash = "sha256:9c5705e395cd70084351dd8ad5c41e65655e08ce46f2ec9cf6c2c08390f71eb7"}, +] +charset-normalizer = [ + {file = "charset-normalizer-2.0.12.tar.gz", hash = "sha256:2857e29ff0d34db842cd7ca3230549d1a697f96ee6d3fb071cfa6c7393832597"}, + {file = "charset_normalizer-2.0.12-py3-none-any.whl", hash = "sha256:6881edbebdb17b39b4eaaa821b438bf6eddffb4468cf344f09f89def34a8b1df"}, +] +click = [ + {file = "click-8.1.3-py3-none-any.whl", hash = "sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48"}, + {file = "click-8.1.3.tar.gz", hash = "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e"}, +] +colorama = [ + {file = "colorama-0.4.4-py2.py3-none-any.whl", hash = "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2"}, + {file = "colorama-0.4.4.tar.gz", hash = "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b"}, +] +emoji = [ + {file = "emoji-1.7.0.tar.gz", hash = "sha256:65c54533ea3c78f30d0729288998715f418d7467de89ec258a31c0ce8660a1d1"}, +] +feedparser = [ + {file = "feedparser-6.0.10-py3-none-any.whl", hash = "sha256:79c257d526d13b944e965f6095700587f27388e50ea16fd245babe4dfae7024f"}, + {file = "feedparser-6.0.10.tar.gz", hash = "sha256:27da485f4637ce7163cdeab13a80312b93b7d0c1b775bef4a47629a3110bca51"}, +] +h11 = [ + {file = "h11-0.12.0-py3-none-any.whl", hash = "sha256:36a3cb8c0a032f56e2da7084577878a035d3b61d104230d4bd49c0c6b555a9c6"}, + {file = "h11-0.12.0.tar.gz", hash = "sha256:47222cb6067e4a307d535814917cd98fd0a57b6788ce715755fa2b6c28b56042"}, +] +httpcore = [ + {file = "httpcore-0.14.7-py3-none-any.whl", hash = "sha256:47d772f754359e56dd9d892d9593b6f9870a37aeb8ba51e9a88b09b3d68cfade"}, + {file = "httpcore-0.14.7.tar.gz", hash = "sha256:7503ec1c0f559066e7e39bc4003fd2ce023d01cf51793e3c173b864eb456ead1"}, +] +httpx = [ + {file = "httpx-0.22.0-py3-none-any.whl", hash = "sha256:e35e83d1d2b9b2a609ef367cc4c1e66fd80b750348b20cc9e19d1952fc2ca3f6"}, + {file = "httpx-0.22.0.tar.gz", hash = "sha256:d8e778f76d9bbd46af49e7f062467e3157a5a3d2ae4876a4bbfd8a51ed9c9cb4"}, +] +idna = [ + {file = "idna-3.3-py3-none-any.whl", hash = "sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff"}, + {file = "idna-3.3.tar.gz", hash = "sha256:9d643ff0a55b762d5cdb124b8eaa99c66322e2157b69160bc32796e824360e6d"}, +] +iso8601 = [ + {file = "iso8601-1.0.2-py3-none-any.whl", hash = "sha256:d7bc01b1c2a43b259570bb307f057abc578786ea734ba2b87b836c5efc5bd443"}, + {file = "iso8601-1.0.2.tar.gz", hash = "sha256:27f503220e6845d9db954fb212b95b0362d8b7e6c1b2326a87061c3de93594b1"}, +] +loguru = [ + {file = "loguru-0.6.0-py3-none-any.whl", hash = "sha256:4e2414d534a2ab57573365b3e6d0234dfb1d84b68b7f3b948e6fb743860a77c3"}, + {file = "loguru-0.6.0.tar.gz", hash = "sha256:066bd06758d0a513e9836fd9c6b5a75bfb3fd36841f4b996bc60b547a309d41c"}, +] +mypy-extensions = [ + {file = "mypy_extensions-0.4.3-py2.py3-none-any.whl", hash = "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d"}, + {file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"}, +] +pathspec = [ + {file = "pathspec-0.9.0-py2.py3-none-any.whl", hash = "sha256:7d15c4ddb0b5c802d161efc417ec1a2558ea2653c2e8ad9c19098201dc1c993a"}, + {file = "pathspec-0.9.0.tar.gz", hash = "sha256:e564499435a2673d586f6b2130bb5b95f04a3ba06f81b8f895b651a3c76aabb1"}, +] +platformdirs = [ + {file = "platformdirs-2.5.2-py3-none-any.whl", hash = "sha256:027d8e83a2d7de06bbac4e5ef7e023c02b863d7ea5d079477e722bb41ab25788"}, + {file = "platformdirs-2.5.2.tar.gz", hash = "sha256:58c8abb07dcb441e6ee4b11d8df0ac856038f944ab98b7be6b27b2a3c7feef19"}, +] +python-telegram-bot = [ + {file = "python-telegram-bot-20.0a0.tar.gz", hash = "sha256:a182a3d081071f1ea34833bc68ed7d0843c1fe0d6dca1d260a0e2d253b150f71"}, + {file = "python_telegram_bot-20.0a0-py3-none-any.whl", hash = "sha256:483b2b7d39508cb673b07814284d6c25706890c519d9aa8177becbadd969b4e2"}, +] +pytz = [ + {file = "pytz-2022.1-py2.py3-none-any.whl", hash = "sha256:e68985985296d9a66a881eb3193b0906246245294a881e7c8afe623866ac6a5c"}, + {file = "pytz-2022.1.tar.gz", hash = "sha256:1e760e2fe6a8163bc0b3d9a19c4f84342afa0a2affebfaa84b01b978a02ecaa7"}, +] +pytz-deprecation-shim = [ + {file = "pytz_deprecation_shim-0.1.0.post0-py2.py3-none-any.whl", hash = "sha256:8314c9692a636c8eb3bda879b9f119e350e93223ae83e70e80c31675a0fdc1a6"}, + {file = "pytz_deprecation_shim-0.1.0.post0.tar.gz", hash = "sha256:af097bae1b616dde5c5744441e2ddc69e74dfdcb0c263129610d85b87445a59d"}, +] +reader = [ + {file = "reader-2.12-py3-none-any.whl", hash = "sha256:e5e776266e6563fd06c6ab0c6fb01e7b66f74c38066fe8f577d2dd889fc10543"}, + {file = "reader-2.12.tar.gz", hash = "sha256:f36a2d579c14074fc6ef6e9322de88aaa006debd5edcb08ee42e7ed32661416a"}, +] +requests = [ + {file = "requests-2.27.1-py2.py3-none-any.whl", hash = "sha256:f22fa1e554c9ddfd16e6e41ac79759e17be9e492b3587efa038054674760e72d"}, + {file = "requests-2.27.1.tar.gz", hash = "sha256:68d7c56fd5a8999887728ef304a6d12edc7be74f1cfa47714fc8b414525c9a61"}, +] +rfc3986 = [ + {file = "rfc3986-1.5.0-py2.py3-none-any.whl", hash = "sha256:a86d6e1f5b1dc238b218b012df0aa79409667bb209e58da56d0b94704e712a97"}, + {file = "rfc3986-1.5.0.tar.gz", hash = "sha256:270aaf10d87d0d4e095063c65bf3ddbc6ee3d0b226328ce21e036f946e421835"}, +] +sgmllib3k = [ + {file = "sgmllib3k-1.0.0.tar.gz", hash = "sha256:7868fb1c8bfa764c1ac563d3cf369c381d1325d36124933a726f29fcdaa812e9"}, +] +six = [ + {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, + {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, +] +sniffio = [ + {file = "sniffio-1.2.0-py3-none-any.whl", hash = "sha256:471b71698eac1c2112a40ce2752bb2f4a4814c22a54a3eed3676bc0f5ca9f663"}, + {file = "sniffio-1.2.0.tar.gz", hash = "sha256:c4666eecec1d3f50960c6bdf61ab7bc350648da6c126e3cf6898d8cd4ddcd3de"}, +] +soupsieve = [ + {file = "soupsieve-2.3.2.post1-py3-none-any.whl", hash = "sha256:3b2503d3c7084a42b1ebd08116e5f81aadfaea95863628c80a3b774a11b7c759"}, + {file = "soupsieve-2.3.2.post1.tar.gz", hash = "sha256:fc53893b3da2c33de295667a0e19f078c14bf86544af307354de5fcf12a3f30d"}, +] +tomli = [ + {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, + {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, +] +tornado = [ + {file = "tornado-6.1-cp35-cp35m-macosx_10_9_x86_64.whl", hash = "sha256:d371e811d6b156d82aa5f9a4e08b58debf97c302a35714f6f45e35139c332e32"}, + {file = "tornado-6.1-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:0d321a39c36e5f2c4ff12b4ed58d41390460f798422c4504e09eb5678e09998c"}, + {file = "tornado-6.1-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:9de9e5188a782be6b1ce866e8a51bc76a0fbaa0e16613823fc38e4fc2556ad05"}, + {file = "tornado-6.1-cp35-cp35m-manylinux2010_i686.whl", hash = "sha256:61b32d06ae8a036a6607805e6720ef00a3c98207038444ba7fd3d169cd998910"}, + {file = "tornado-6.1-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:3e63498f680547ed24d2c71e6497f24bca791aca2fe116dbc2bd0ac7f191691b"}, + {file = "tornado-6.1-cp35-cp35m-manylinux2014_aarch64.whl", hash = "sha256:6c77c9937962577a6a76917845d06af6ab9197702a42e1346d8ae2e76b5e3675"}, + {file = "tornado-6.1-cp35-cp35m-win32.whl", hash = "sha256:6286efab1ed6e74b7028327365cf7346b1d777d63ab30e21a0f4d5b275fc17d5"}, + {file = "tornado-6.1-cp35-cp35m-win_amd64.whl", hash = "sha256:fa2ba70284fa42c2a5ecb35e322e68823288a4251f9ba9cc77be04ae15eada68"}, + {file = "tornado-6.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:0a00ff4561e2929a2c37ce706cb8233b7907e0cdc22eab98888aca5dd3775feb"}, + {file = "tornado-6.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:748290bf9112b581c525e6e6d3820621ff020ed95af6f17fedef416b27ed564c"}, + {file = "tornado-6.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:e385b637ac3acaae8022e7e47dfa7b83d3620e432e3ecb9a3f7f58f150e50921"}, + {file = "tornado-6.1-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:25ad220258349a12ae87ede08a7b04aca51237721f63b1808d39bdb4b2164558"}, + {file = "tornado-6.1-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:65d98939f1a2e74b58839f8c4dab3b6b3c1ce84972ae712be02845e65391ac7c"}, + {file = "tornado-6.1-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:e519d64089b0876c7b467274468709dadf11e41d65f63bba207e04217f47c085"}, + {file = "tornado-6.1-cp36-cp36m-win32.whl", hash = "sha256:b87936fd2c317b6ee08a5741ea06b9d11a6074ef4cc42e031bc6403f82a32575"}, + {file = "tornado-6.1-cp36-cp36m-win_amd64.whl", hash = "sha256:cc0ee35043162abbf717b7df924597ade8e5395e7b66d18270116f8745ceb795"}, + {file = "tornado-6.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:7250a3fa399f08ec9cb3f7b1b987955d17e044f1ade821b32e5f435130250d7f"}, + {file = "tornado-6.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:ed3ad863b1b40cd1d4bd21e7498329ccaece75db5a5bf58cd3c9f130843e7102"}, + {file = "tornado-6.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:dcef026f608f678c118779cd6591c8af6e9b4155c44e0d1bc0c87c036fb8c8c4"}, + {file = "tornado-6.1-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:70dec29e8ac485dbf57481baee40781c63e381bebea080991893cd297742b8fd"}, + {file = "tornado-6.1-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:d3f7594930c423fd9f5d1a76bee85a2c36fd8b4b16921cae7e965f22575e9c01"}, + {file = "tornado-6.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:3447475585bae2e77ecb832fc0300c3695516a47d46cefa0528181a34c5b9d3d"}, + {file = "tornado-6.1-cp37-cp37m-win32.whl", hash = "sha256:e7229e60ac41a1202444497ddde70a48d33909e484f96eb0da9baf8dc68541df"}, + {file = "tornado-6.1-cp37-cp37m-win_amd64.whl", hash = "sha256:cb5ec8eead331e3bb4ce8066cf06d2dfef1bfb1b2a73082dfe8a161301b76e37"}, + {file = "tornado-6.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:20241b3cb4f425e971cb0a8e4ffc9b0a861530ae3c52f2b0434e6c1b57e9fd95"}, + {file = "tornado-6.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:c77da1263aa361938476f04c4b6c8916001b90b2c2fdd92d8d535e1af48fba5a"}, + {file = "tornado-6.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:fba85b6cd9c39be262fcd23865652920832b61583de2a2ca907dbd8e8a8c81e5"}, + {file = "tornado-6.1-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:1e8225a1070cd8eec59a996c43229fe8f95689cb16e552d130b9793cb570a288"}, + {file = "tornado-6.1-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:d14d30e7f46a0476efb0deb5b61343b1526f73ebb5ed84f23dc794bdb88f9d9f"}, + {file = "tornado-6.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:8f959b26f2634a091bb42241c3ed8d3cedb506e7c27b8dd5c7b9f745318ddbb6"}, + {file = "tornado-6.1-cp38-cp38-win32.whl", hash = "sha256:34ca2dac9e4d7afb0bed4677512e36a52f09caa6fded70b4e3e1c89dbd92c326"}, + {file = "tornado-6.1-cp38-cp38-win_amd64.whl", hash = "sha256:6196a5c39286cc37c024cd78834fb9345e464525d8991c21e908cc046d1cc02c"}, + {file = "tornado-6.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f0ba29bafd8e7e22920567ce0d232c26d4d47c8b5cf4ed7b562b5db39fa199c5"}, + {file = "tornado-6.1-cp39-cp39-manylinux1_i686.whl", hash = "sha256:33892118b165401f291070100d6d09359ca74addda679b60390b09f8ef325ffe"}, + {file = "tornado-6.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:7da13da6f985aab7f6f28debab00c67ff9cbacd588e8477034c0652ac141feea"}, + {file = "tornado-6.1-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:e0791ac58d91ac58f694d8d2957884df8e4e2f6687cdf367ef7eb7497f79eaa2"}, + {file = "tornado-6.1-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:66324e4e1beede9ac79e60f88de548da58b1f8ab4b2f1354d8375774f997e6c0"}, + {file = "tornado-6.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:a48900ecea1cbb71b8c71c620dee15b62f85f7c14189bdeee54966fbd9a0c5bd"}, + {file = "tornado-6.1-cp39-cp39-win32.whl", hash = "sha256:d3d20ea5782ba63ed13bc2b8c291a053c8d807a8fa927d941bd718468f7b950c"}, + {file = "tornado-6.1-cp39-cp39-win_amd64.whl", hash = "sha256:548430be2740e327b3fe0201abe471f314741efcb0067ec4f2d7dcfb4825f3e4"}, + {file = "tornado-6.1.tar.gz", hash = "sha256:33c6e81d7bd55b468d2e793517c909b139960b6c790a60b7991b9b6b76fb9791"}, +] +typing-extensions = [ + {file = "typing_extensions-4.2.0-py3-none-any.whl", hash = "sha256:6657594ee297170d19f67d55c05852a874e7eb634f4f753dbd667855e07c1708"}, + {file = "typing_extensions-4.2.0.tar.gz", hash = "sha256:f1c24655a0da0d1b67f07e17a5e6b2a105894e6824b92096378bb3668ef02376"}, +] +tzdata = [ + {file = "tzdata-2022.1-py2.py3-none-any.whl", hash = "sha256:238e70234214138ed7b4e8a0fab0e5e13872edab3be586ab8198c407620e2ab9"}, + {file = "tzdata-2022.1.tar.gz", hash = "sha256:8b536a8ec63dc0751342b3984193a3118f8fca2afe25752bb9b7fffd398552d3"}, +] +tzlocal = [ + {file = "tzlocal-4.2-py3-none-any.whl", hash = "sha256:89885494684c929d9191c57aa27502afc87a579be5cdd3225c77c463ea043745"}, + {file = "tzlocal-4.2.tar.gz", hash = "sha256:ee5842fa3a795f023514ac2d801c4a81d1743bbe642e3940143326b3a00addd7"}, +] +urllib3 = [ + {file = "urllib3-1.26.9-py2.py3-none-any.whl", hash = "sha256:44ece4d53fb1706f667c9bd1c648f5469a2ec925fcf3a776667042d645472c14"}, + {file = "urllib3-1.26.9.tar.gz", hash = "sha256:aabaf16477806a5e1dd19aa41f8c2b7950dd3c746362d7e3223dbe6de6ac448e"}, +] +win32-setctime = [ + {file = "win32_setctime-1.1.0-py3-none-any.whl", hash = "sha256:231db239e959c2fe7eb1d7dc129f11172354f98361c4fa2d6d2d7e278baa8aad"}, + {file = "win32_setctime-1.1.0.tar.gz", hash = "sha256:15cf5750465118d6929ae4de4eb46e8edae9a5634350c01ba582df868e932cb2"}, +] diff --git a/pyproject.toml b/pyproject.toml index 42325a7..b40292f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -9,7 +9,7 @@ license = "MIT" python = "^3.10" reader = "^2.12" loguru = "^0.6.0" -python-telegram-bot = {git = "https://github.com/python-telegram-bot/python-telegram-bot.git"} +python-telegram-bot = {version = "20.0a0", allow-prereleases = true} emoji = "^1.7.0" [tool.poetry.dev-dependencies] From 6dd605f38d5cce644d4866f1c9e7424891fa5eec Mon Sep 17 00:00:00 2001 From: dbrennand <52419383+dbrennand@users.noreply.github.com> Date: Fri, 3 Jun 2022 16:14:25 +0100 Subject: [PATCH 05/17] refactor: persist reader database --- Dockerfile | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 4614ec0..c227ecd 100644 --- a/Dockerfile +++ b/Dockerfile @@ -3,8 +3,9 @@ FROM python:3.10-slim # Set working directory WORKDIR /usr/src/app -# Create directory to persist reader database -RUN mkdir -p /data/reader +# Create directory and volume to persist the reader database +RUN mkdir -p /usr/src/app/reader +VOLUME /usr/src/app/reader # Copy all of the projects contents to containers /usr/src/app directory COPY . . From 126c1d300116d7126ccdb29eb78a0929d2556653 Mon Sep 17 00:00:00 2001 From: dbrennand <52419383+dbrennand@users.noreply.github.com> Date: Fri, 3 Jun 2022 16:14:34 +0100 Subject: [PATCH 06/17] feat: add new requirements file --- requirements.txt | Bin 760 -> 11292 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/requirements.txt b/requirements.txt index 51ae2c7bafc798da740df264c1be8512ee2cd814..3b3a33025f9e59982dbc8dc016875e62c3ec4683 100644 GIT binary patch literal 11292 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 literal 760 zcmYLHS#E<+5c7AX9tFgfE+6^m4J!2n1W1BPfC6pP9KNkR!y+^Sz46!{KmLAS@QODS zIHN*|Pc(cF*z-vd;(?Xo9(OqKJZFDGjicd4bbR;744o1AyrK(Zacph<1QAprV!lJ{ zj8(ch^-AKWl}D&(?ss(55s~A-q$dg+peiPpD#MJwsmx|6OmON>rgo!TPBOPDpq~Tp1sQYdxv24kX>|NLM*rq-6 z4VGxhFZGqTZ#FTLp0h1o1f0HFE-k&*mXmwd-}T5+BA(@ho85K6 m-J4a@IhFsmkMy)nVyb>m-=>)IETEG9rh-*72lu~h?^^$P7HyXR From 00b33e803f21022a9e655ab8c434f7f232c0302f Mon Sep 17 00:00:00 2001 From: dbrennand <52419383+dbrennand@users.noreply.github.com> Date: Fri, 3 Jun 2022 16:16:10 +0100 Subject: [PATCH 07/17] chore: update LICENSE year --- LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index 9028fcc..e7f6d7e 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2021 dbrennand +Copyright (c) 2022 dbrennand Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal From ec80a198bda478fc1faf89221d21269ddde670db Mon Sep 17 00:00:00 2001 From: dbrennand <52419383+dbrennand@users.noreply.github.com> Date: Fri, 3 Jun 2022 16:17:16 +0100 Subject: [PATCH 08/17] refactor: remove hashes --- requirements.txt | 161 +++++++++-------------------------------------- 1 file changed, 31 insertions(+), 130 deletions(-) diff --git a/requirements.txt b/requirements.txt index 3b3a330..893f0a8 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,130 +1,31 @@ -anyio==3.6.1; python_full_version >= "3.6.2" and python_version >= "3.7" \ - --hash=sha256:cb29b9c70620506a9a8f87a309591713446953302d7d995344d0d7c6c0c9a7be \ - --hash=sha256:413adf95f93886e442aea925f3ee43baa5a765a64a0f52c6081894f9992fdd0b -apscheduler==3.9.1; python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version < "4" and python_version >= "3.7" \ - --hash=sha256:ddc25a0ddd899de44d7f451f4375fb971887e65af51e41e5dcf681f59b8b2c9a \ - --hash=sha256:65e6574b6395498d371d045f2a8a7e4f7d50c6ad21ef7313d15b1c7cf20df1e3 -beautifulsoup4==4.11.1; python_full_version >= "3.6.0" and python_version >= "3.7" \ - --hash=sha256:58d5c3d29f5a36ffeb94f02f0d786cd53014cf9b3b3951d42e0080d8a9498d30 \ - --hash=sha256:ad9aa55b65ef2808eb405f46cf74df7fcb7044d5cbc26487f96eb2ef2e436693 -cachetools==5.0.0; python_version >= "3.7" and python_version < "4.0" \ - --hash=sha256:8fecd4203a38af17928be7b90689d8083603073622229ca7077b72d8e5a976e4 \ - --hash=sha256:486471dfa8799eb7ec503a8059e263db000cdda20075ce5e48903087f79d5fd6 -certifi==2022.5.18.1; python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version >= "3.7" \ - --hash=sha256:f1d53542ee8cbedbe2118b5686372fb33c297fcd6379b050cca0ef13a597382a \ - --hash=sha256:9c5705e395cd70084351dd8ad5c41e65655e08ce46f2ec9cf6c2c08390f71eb7 -charset-normalizer==2.0.12; python_full_version >= "3.6.0" and python_version >= "3.7" \ - --hash=sha256:2857e29ff0d34db842cd7ca3230549d1a697f96ee6d3fb071cfa6c7393832597 \ - --hash=sha256:6881edbebdb17b39b4eaaa821b438bf6eddffb4468cf344f09f89def34a8b1df -colorama==0.4.4; python_version >= "3.5" and python_full_version < "3.0.0" and sys_platform == "win32" or sys_platform == "win32" and python_version >= "3.5" and python_full_version >= "3.5.0" \ - --hash=sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2 \ - --hash=sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b -emoji==1.7.0 \ - --hash=sha256:65c54533ea3c78f30d0729288998715f418d7467de89ec258a31c0ce8660a1d1 -feedparser==6.0.10; python_version >= "3.7" \ - --hash=sha256:79c257d526d13b944e965f6095700587f27388e50ea16fd245babe4dfae7024f \ - --hash=sha256:27da485f4637ce7163cdeab13a80312b93b7d0c1b775bef4a47629a3110bca51 -h11==0.12.0; python_version >= "3.7" \ - --hash=sha256:36a3cb8c0a032f56e2da7084577878a035d3b61d104230d4bd49c0c6b555a9c6 \ - --hash=sha256:47222cb6067e4a307d535814917cd98fd0a57b6788ce715755fa2b6c28b56042 -httpcore==0.14.7; python_version >= "3.7" \ - --hash=sha256:47d772f754359e56dd9d892d9593b6f9870a37aeb8ba51e9a88b09b3d68cfade \ - --hash=sha256:7503ec1c0f559066e7e39bc4003fd2ce023d01cf51793e3c173b864eb456ead1 -httpx==0.22.0; python_version >= "3.7" \ - --hash=sha256:e35e83d1d2b9b2a609ef367cc4c1e66fd80b750348b20cc9e19d1952fc2ca3f6 \ - --hash=sha256:d8e778f76d9bbd46af49e7f062467e3157a5a3d2ae4876a4bbfd8a51ed9c9cb4 -idna==3.3; python_full_version >= "3.6.2" and python_version >= "3.7" \ - --hash=sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff \ - --hash=sha256:9d643ff0a55b762d5cdb124b8eaa99c66322e2157b69160bc32796e824360e6d -iso8601==1.0.2; python_full_version >= "3.6.2" and python_version < "4.0" and python_version >= "3.7" \ - --hash=sha256:d7bc01b1c2a43b259570bb307f057abc578786ea734ba2b87b836c5efc5bd443 \ - --hash=sha256:27f503220e6845d9db954fb212b95b0362d8b7e6c1b2326a87061c3de93594b1 -loguru==0.6.0; python_version >= "3.5" \ - --hash=sha256:4e2414d534a2ab57573365b3e6d0234dfb1d84b68b7f3b948e6fb743860a77c3 \ - --hash=sha256:066bd06758d0a513e9836fd9c6b5a75bfb3fd36841f4b996bc60b547a309d41c -python-telegram-bot==20.0a0; python_version >= "3.7" \ - --hash=sha256:a182a3d081071f1ea34833bc68ed7d0843c1fe0d6dca1d260a0e2d253b150f71 \ - --hash=sha256:483b2b7d39508cb673b07814284d6c25706890c519d9aa8177becbadd969b4e2 -pytz-deprecation-shim==0.1.0.post0; python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version < "4" and python_version >= "3.7" \ - --hash=sha256:8314c9692a636c8eb3bda879b9f119e350e93223ae83e70e80c31675a0fdc1a6 \ - --hash=sha256:af097bae1b616dde5c5744441e2ddc69e74dfdcb0c263129610d85b87445a59d -pytz==2022.1; python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version < "4" and python_version >= "3.7" \ - --hash=sha256:e68985985296d9a66a881eb3193b0906246245294a881e7c8afe623866ac6a5c \ - --hash=sha256:1e760e2fe6a8163bc0b3d9a19c4f84342afa0a2affebfaa84b01b978a02ecaa7 -reader==2.12; python_version >= "3.7" \ - --hash=sha256:e5e776266e6563fd06c6ab0c6fb01e7b66f74c38066fe8f577d2dd889fc10543 \ - --hash=sha256:f36a2d579c14074fc6ef6e9322de88aaa006debd5edcb08ee42e7ed32661416a -requests==2.27.1; python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version >= "3.7" \ - --hash=sha256:f22fa1e554c9ddfd16e6e41ac79759e17be9e492b3587efa038054674760e72d \ - --hash=sha256:68d7c56fd5a8999887728ef304a6d12edc7be74f1cfa47714fc8b414525c9a61 -rfc3986==1.5.0; python_version >= "3.7" \ - --hash=sha256:a86d6e1f5b1dc238b218b012df0aa79409667bb209e58da56d0b94704e712a97 \ - --hash=sha256:270aaf10d87d0d4e095063c65bf3ddbc6ee3d0b226328ce21e036f946e421835 -sgmllib3k==1.0.0; python_version >= "3.7" \ - --hash=sha256:7868fb1c8bfa764c1ac563d3cf369c381d1325d36124933a726f29fcdaa812e9 -six==1.16.0; python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version < "4" and python_version >= "3.7" \ - --hash=sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254 \ - --hash=sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926 -sniffio==1.2.0; python_full_version >= "3.6.2" and python_version >= "3.7" \ - --hash=sha256:471b71698eac1c2112a40ce2752bb2f4a4814c22a54a3eed3676bc0f5ca9f663 \ - --hash=sha256:c4666eecec1d3f50960c6bdf61ab7bc350648da6c126e3cf6898d8cd4ddcd3de -soupsieve==2.3.2.post1; python_full_version >= "3.6.0" and python_version >= "3.7" \ - --hash=sha256:3b2503d3c7084a42b1ebd08116e5f81aadfaea95863628c80a3b774a11b7c759 \ - --hash=sha256:fc53893b3da2c33de295667a0e19f078c14bf86544af307354de5fcf12a3f30d -tornado==6.1; python_version >= "3.7" \ - --hash=sha256:d371e811d6b156d82aa5f9a4e08b58debf97c302a35714f6f45e35139c332e32 \ - --hash=sha256:0d321a39c36e5f2c4ff12b4ed58d41390460f798422c4504e09eb5678e09998c \ - --hash=sha256:9de9e5188a782be6b1ce866e8a51bc76a0fbaa0e16613823fc38e4fc2556ad05 \ - --hash=sha256:61b32d06ae8a036a6607805e6720ef00a3c98207038444ba7fd3d169cd998910 \ - --hash=sha256:3e63498f680547ed24d2c71e6497f24bca791aca2fe116dbc2bd0ac7f191691b \ - --hash=sha256:6c77c9937962577a6a76917845d06af6ab9197702a42e1346d8ae2e76b5e3675 \ - --hash=sha256:6286efab1ed6e74b7028327365cf7346b1d777d63ab30e21a0f4d5b275fc17d5 \ - --hash=sha256:fa2ba70284fa42c2a5ecb35e322e68823288a4251f9ba9cc77be04ae15eada68 \ - --hash=sha256:0a00ff4561e2929a2c37ce706cb8233b7907e0cdc22eab98888aca5dd3775feb \ - --hash=sha256:748290bf9112b581c525e6e6d3820621ff020ed95af6f17fedef416b27ed564c \ - --hash=sha256:e385b637ac3acaae8022e7e47dfa7b83d3620e432e3ecb9a3f7f58f150e50921 \ - --hash=sha256:25ad220258349a12ae87ede08a7b04aca51237721f63b1808d39bdb4b2164558 \ - --hash=sha256:65d98939f1a2e74b58839f8c4dab3b6b3c1ce84972ae712be02845e65391ac7c \ - --hash=sha256:e519d64089b0876c7b467274468709dadf11e41d65f63bba207e04217f47c085 \ - --hash=sha256:b87936fd2c317b6ee08a5741ea06b9d11a6074ef4cc42e031bc6403f82a32575 \ - --hash=sha256:cc0ee35043162abbf717b7df924597ade8e5395e7b66d18270116f8745ceb795 \ - --hash=sha256:7250a3fa399f08ec9cb3f7b1b987955d17e044f1ade821b32e5f435130250d7f \ - --hash=sha256:ed3ad863b1b40cd1d4bd21e7498329ccaece75db5a5bf58cd3c9f130843e7102 \ - --hash=sha256:dcef026f608f678c118779cd6591c8af6e9b4155c44e0d1bc0c87c036fb8c8c4 \ - --hash=sha256:70dec29e8ac485dbf57481baee40781c63e381bebea080991893cd297742b8fd \ - --hash=sha256:d3f7594930c423fd9f5d1a76bee85a2c36fd8b4b16921cae7e965f22575e9c01 \ - --hash=sha256:3447475585bae2e77ecb832fc0300c3695516a47d46cefa0528181a34c5b9d3d \ - --hash=sha256:e7229e60ac41a1202444497ddde70a48d33909e484f96eb0da9baf8dc68541df \ - --hash=sha256:cb5ec8eead331e3bb4ce8066cf06d2dfef1bfb1b2a73082dfe8a161301b76e37 \ - --hash=sha256:20241b3cb4f425e971cb0a8e4ffc9b0a861530ae3c52f2b0434e6c1b57e9fd95 \ - --hash=sha256:c77da1263aa361938476f04c4b6c8916001b90b2c2fdd92d8d535e1af48fba5a \ - --hash=sha256:fba85b6cd9c39be262fcd23865652920832b61583de2a2ca907dbd8e8a8c81e5 \ - --hash=sha256:1e8225a1070cd8eec59a996c43229fe8f95689cb16e552d130b9793cb570a288 \ - --hash=sha256:d14d30e7f46a0476efb0deb5b61343b1526f73ebb5ed84f23dc794bdb88f9d9f \ - --hash=sha256:8f959b26f2634a091bb42241c3ed8d3cedb506e7c27b8dd5c7b9f745318ddbb6 \ - --hash=sha256:34ca2dac9e4d7afb0bed4677512e36a52f09caa6fded70b4e3e1c89dbd92c326 \ - --hash=sha256:6196a5c39286cc37c024cd78834fb9345e464525d8991c21e908cc046d1cc02c \ - --hash=sha256:f0ba29bafd8e7e22920567ce0d232c26d4d47c8b5cf4ed7b562b5db39fa199c5 \ - --hash=sha256:33892118b165401f291070100d6d09359ca74addda679b60390b09f8ef325ffe \ - --hash=sha256:7da13da6f985aab7f6f28debab00c67ff9cbacd588e8477034c0652ac141feea \ - --hash=sha256:e0791ac58d91ac58f694d8d2957884df8e4e2f6687cdf367ef7eb7497f79eaa2 \ - --hash=sha256:66324e4e1beede9ac79e60f88de548da58b1f8ab4b2f1354d8375774f997e6c0 \ - --hash=sha256:a48900ecea1cbb71b8c71c620dee15b62f85f7c14189bdeee54966fbd9a0c5bd \ - --hash=sha256:d3d20ea5782ba63ed13bc2b8c291a053c8d807a8fa927d941bd718468f7b950c \ - --hash=sha256:548430be2740e327b3fe0201abe471f314741efcb0067ec4f2d7dcfb4825f3e4 \ - --hash=sha256:33c6e81d7bd55b468d2e793517c909b139960b6c790a60b7991b9b6b76fb9791 -typing-extensions==4.2.0; python_version >= "3.7" \ - --hash=sha256:6657594ee297170d19f67d55c05852a874e7eb634f4f753dbd667855e07c1708 \ - --hash=sha256:f1c24655a0da0d1b67f07e17a5e6b2a105894e6824b92096378bb3668ef02376 -tzdata==2022.1; python_version >= "3.7" and python_full_version < "3.0.0" and platform_system == "Windows" or python_full_version >= "3.6.0" and python_version < "4" and python_version >= "3.7" and platform_system == "Windows" \ - --hash=sha256:238e70234214138ed7b4e8a0fab0e5e13872edab3be586ab8198c407620e2ab9 \ - --hash=sha256:8b536a8ec63dc0751342b3984193a3118f8fca2afe25752bb9b7fffd398552d3 -tzlocal==4.2; python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version < "4" and python_version >= "3.7" \ - --hash=sha256:89885494684c929d9191c57aa27502afc87a579be5cdd3225c77c463ea043745 \ - --hash=sha256:ee5842fa3a795f023514ac2d801c4a81d1743bbe642e3940143326b3a00addd7 -urllib3==1.26.9; python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version < "4" and python_version >= "3.7" \ - --hash=sha256:44ece4d53fb1706f667c9bd1c648f5469a2ec925fcf3a776667042d645472c14 \ - --hash=sha256:aabaf16477806a5e1dd19aa41f8c2b7950dd3c746362d7e3223dbe6de6ac448e -win32-setctime==1.1.0; sys_platform == "win32" and python_version >= "3.5" \ - --hash=sha256:231db239e959c2fe7eb1d7dc129f11172354f98361c4fa2d6d2d7e278baa8aad \ - --hash=sha256:15cf5750465118d6929ae4de4eb46e8edae9a5634350c01ba582df868e932cb2 +anyio==3.6.1; python_full_version >= "3.6.2" and python_version >= "3.7" +apscheduler==3.9.1; python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version < "4" and python_version >= "3.7" +beautifulsoup4==4.11.1; python_full_version >= "3.6.0" and python_version >= "3.7" +cachetools==5.0.0; python_version >= "3.7" and python_version < "4.0" +certifi==2022.5.18.1; python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version >= "3.7" +charset-normalizer==2.0.12; python_full_version >= "3.6.0" and python_version >= "3.7" +colorama==0.4.4; python_version >= "3.5" and python_full_version < "3.0.0" and sys_platform == "win32" or sys_platform == "win32" and python_version >= "3.5" and python_full_version >= "3.5.0" +emoji==1.7.0 +feedparser==6.0.10; python_version >= "3.7" +h11==0.12.0; python_version >= "3.7" +httpcore==0.14.7; python_version >= "3.7" +httpx==0.22.0; python_version >= "3.7" +idna==3.3; python_full_version >= "3.6.2" and python_version >= "3.7" +iso8601==1.0.2; python_full_version >= "3.6.2" and python_version < "4.0" and python_version >= "3.7" +loguru==0.6.0; python_version >= "3.5" +python-telegram-bot==20.0a0; python_version >= "3.7" +pytz-deprecation-shim==0.1.0.post0; python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version < "4" and python_version >= "3.7" +pytz==2022.1; python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version < "4" and python_version >= "3.7" +reader==2.12; python_version >= "3.7" +requests==2.27.1; python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version >= "3.7" +rfc3986==1.5.0; python_version >= "3.7" +sgmllib3k==1.0.0; python_version >= "3.7" +six==1.16.0; python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version < "4" and python_version >= "3.7" +sniffio==1.2.0; python_full_version >= "3.6.2" and python_version >= "3.7" +soupsieve==2.3.2.post1; python_full_version >= "3.6.0" and python_version >= "3.7" +tornado==6.1; python_version >= "3.7" +typing-extensions==4.2.0; python_version >= "3.7" +tzdata==2022.1; python_version >= "3.7" and python_full_version < "3.0.0" and platform_system == "Windows" or python_full_version >= "3.6.0" and python_version < "4" and python_version >= "3.7" and platform_system == "Windows" +tzlocal==4.2; python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version < "4" and python_version >= "3.7" +urllib3==1.26.9; python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version < "4" and python_version >= "3.7" +win32-setctime==1.1.0; sys_platform == "win32" and python_version >= "3.5" From 593d2a99deb6db6358440f382bf36ff696ffe44d Mon Sep 17 00:00:00 2001 From: dbrennand <52419383+dbrennand@users.noreply.github.com> Date: Fri, 3 Jun 2022 18:37:45 +0100 Subject: [PATCH 09/17] feat: push version 1.0.0 --- bot.py | 487 ++++++++++++++++++++++++++++++--------------------------- 1 file changed, 257 insertions(+), 230 deletions(-) diff --git a/bot.py b/bot.py index 7705556..e501124 100644 --- a/bot.py +++ b/bot.py @@ -1,253 +1,280 @@ -from reader import make_reader, FeedExistsError, FeedNotFoundError -from contextlib import closing -from telegram import Update -from telegram.ext import Updater, CallbackContext, CommandHandler +from typing import List from loguru import logger +import reader as r import os +import sys +import emoji +import telegram +import telegram.ext +import contextlib +READER_DB_PATH = "/usr/src/app/reader/db.sqlite" +BOT_TOKEN = os.environ["BOT_TOKEN"] +USER_ID = os.environ["USER_ID"] +CHECK_MARK_EMOJI = emoji.emojize(":check_mark_button:", language="alias") +CROSS_MARK_EMOJI = emoji.emojize(":x:", language="alias") +logger.remove() +logger.add( + sys.stderr, + format="{time:YYYY-MM-DD at HH:mm:ss} | {level} | {extra[function]} | {message}", + enqueue=True, +) -class RSS_Feederbot(object): - """ - Class for RSS_Feederbot. + +async def error_handler( + update: telegram.Update, context: telegram.ext.CallbackContext.DEFAULT_TYPE +) -> None: + """Error handler. + + Args: + update (telegram.Update): Object representing the incoming update from Telegram. + context (telegram.ext.CallbackContext.DEFAULT_TYPE): Object representing the callback context. """ + logger.error(f"{CROSS_MARK_EMOJI} {context.error}: {update}") - def __init__(self): - # Create log file that rotates every 10 days - logger.add( - "rss_feederbot_{time}.log", - format="{time:YYYY-MM-DD at HH:mm:ss} | {level} | {message}", - retention="10 days" - ) - # Setup Updater for RSS_Feederbot - self.updater = Updater(token=os.environ["BOT_TOKEN"], use_context=True) - # Create dictionary to compare latest RSS feed(s) entry title - self.feeds_last_entry_title = {} - - def error_handler(self, update: Update, context: CallbackContext) -> None: - """ - Log the error for debugging purposes. - """ - logger.debug(f"Update: {update}\nError: {context.error}.") - - def check_feeds(self, context: CallbackContext) -> None: - """ - Background task to check RSS feed(s) for updates and send to the user on a repeated interval. - """ - # Update RSS feed(s) - logger.debug("Updating RSS feeds.") - # Use Reader object - with closing(make_reader("db.sqlite")) as reader: - reader.update_feeds(workers=10) - # Retrieve all RSS feed(s) - logger.debug("Retrieving RSS feed(s).") - feeds = reader.get_feeds(sort="added") - for feed in feeds: - logger.debug(f"Checking if RSS feed: {feed.title} has updated.") - # Retrieve latest feed entry - latest_entry = list(reader.get_entries(feed=feed, sort="recent"))[0] - # Retrieve last known entry title for feed - feed_last_title = self.feeds_last_entry_title.get(feed.title, None) - # Compare last entry title with latest RSS feed entry's title - # If different, feed has updated - # Update the dictionary and send message a message for the new entry - if latest_entry.title != feed_last_title: - logger.debug( - f"RSS feed: {feed.title} has been updated.\nPrevious entry title was: {feed_last_title} and new entry title is: {latest_entry.title}\nUpdating dictionary with new title and sending update..." - ) - # Create Telegram message string - message = f"[{latest_entry.title}]({latest_entry.link})" - # Update dictionary with new title - self.feeds_last_entry_title[feed.title] = latest_entry.title - # Send Telegram message - context.bot.send_message( - chat_id=self.user_id, text=message, parse_mode="Markdown" - ) - else: - logger.debug( - f"RSS feed: {feed.title} has not been updated. Checking next RSS feed..." - ) - logger.debug("All RSS feeds checked. Waiting for next run...") - - def start(self, update: Update, context: CallbackContext) -> None: - """ - Begin running the background Job to check RSS feed(s) for updates. - - Command args (required): - * Interval: The interval in seconds to run the background Job on. - """ - # Retrieve interval - try: - interval = int(context.args[0]) - logger.debug(f"Interval: {interval}.") - except IndexError as err: - logger.debug(f"Failed to retrieve interval for /start: {err}.") - update.message.reply_text("Provide an interval to /start.") - return - logger.debug( - f"Starting background Job with interval: {interval} to check RSS feed(s) for updates." - ) - # Set user's ID to be used in the background Job - self.user_id = update.message.from_user.id - logger.debug(f"User's ID: {self.user_id}.") - job = context.job_queue.run_repeating(self.check_feeds, interval=interval) - job.run(context.dispatcher) - - def manage_feed(self, update: Update, context: CallbackContext) -> None: - """ - Adds or removes an RSS feed. - - Command args (required): - * Option: Can be either 'Add' or 'Remove'. - * Feed URL: The URL of the RSS feed to add or remove. - """ - # Retrieve option and RSS feed URL - try: - option = context.args[0] - feed_url = context.args[1] - logger.debug(f"Option: {option}, RSS feed URL: {feed_url}.") - except IndexError as err: - logger.debug( - f"Failed to retrieve option and RSS feed URL for /managefeed: {err}." - ) - update.message.reply_text( - "Provide an option and RSS feed URL to /managefeed.\nOption can be either Add or Remove." + +async def check_feeds(context: telegram.ext.CallbackContext.DEFAULT_TYPE) -> None: + """Check for feed updates. + + Args: + context (telegram.ext.CallbackContext.DEFAULT_TYPE): Object representing the callback context. + """ + context_logger = logger.bind(function="check_feeds") + context_logger.info(f"{CHECK_MARK_EMOJI} Checking for feed updates.") + with contextlib.closing(r.make_reader(READER_DB_PATH)) as reader: + reader.update_feeds(workers=10) + context_logger.info(f"{CHECK_MARK_EMOJI} Feeds updated.") + for feed in reader.get_feeds(sort="added"): + context_logger.info(f"{CHECK_MARK_EMOJI} Checking {feed.title}.") + # Get all feed entries + entries = list(reader.get_entries(feed=feed, sort="recent")) + # Get unread feed entries + unread_entires = list( + reader.get_entries(feed=feed, sort="recent", read=False) ) - return - # Use Reader object - with closing(make_reader("db.sqlite")) as reader: - # Check if an RSS feed is being added or removed - if option.lower() == "add": - try: - reader.add_feed(feed_url) - logger.debug(f"Successfully added RSS feed: {feed_url}.") - update.message.reply_text( - f"The RSS feed: {feed_url} was successfully added." - ) - except FeedExistsError as err: - logger.debug( - f"The RSS feed: {feed_url} has already been added: {err}." + entries_count = len(entries) + unread_entires_count = len(unread_entires) + if unread_entires: + # If this is a newly added feed, all of the entries will be unread + # so we need to check if the unread feed entry count is identical to the + # total feed entry count + if unread_entires_count == entries_count: + context_logger.info( + f"{CHECK_MARK_EMOJI} Unread entries identical to total entries for {feed.title}." ) - update.message.reply_text( - f"The RSS feed: {feed_url} has already been added." - ) - elif option.lower() == "remove": - try: - reader.remove_feed(feed_url) - logger.debug(f"Successfully removed RSS feed: {feed_url}.") - update.message.reply_text( - f"The RSS feed: {feed_url} was successfully removed." - ) - except FeedNotFoundError as err: - logger.debug(f"The RSS feed: {feed_url} was not found: {err}.") - update.message.reply_text( - f"The RSS feed: {feed_url} was not found.\nTry adding it using '/managefeed add https://examplefeedurl.com'." + # This is likely a newly added feed so send the last 5 entries + await send_feed_entries(context, feed.title, unread_entires[:5]) + else: + context_logger.info( + f"{CHECK_MARK_EMOJI} {unread_entires_count} new entries for {feed.title}." ) + await send_feed_entries(context, feed.title, unread_entires) + # Mark entries as read + for entry in unread_entires: + reader.mark_entry_as_read(entry) + context_logger.info( + f"{CHECK_MARK_EMOJI} {unread_entires_count} entries marked as read for {feed.title}." + ) else: - logger.debug( - f"The option: {option} provided to /managefeed was invalid." + context_logger.info( + f"{CHECK_MARK_EMOJI} No new entries for {feed.title}." + ) + + +async def send_feed_entries( + context: telegram.ext.CallbackContext.DEFAULT_TYPE, + feed_title: str, + entries: List[r.Entry], +) -> None: + """Send feed entries. + + Args: + context (telegram.ext.CallbackContext.DEFAULT_TYPE): Object representing the callback context. + feed_title (str): The title of the feed. + entries (Iterable[r.Entry]): Feed entries to send. + """ + context_logger = logger.bind(function="send_feed_entries") + context_logger.info( + f"{CHECK_MARK_EMOJI} Sending {len(entries)} entries for {feed_title}." + ) + fmt_entries = [(entry.title, entry.link) for entry in entries] + message = "**{0}**\n\n{1}".format( + feed_title, "\n".join(f"[{title}]({link})" for title, link in fmt_entries) + ).replace("-", "\\") + await context.bot.send_message( + chat_id=USER_ID, + text=message, + parse_mode=telegram.constants.ParseMode.MARKDOWN_V2, + ) + + +async def add_feeds( + update: telegram.Update, context: telegram.ext.CallbackContext.DEFAULT_TYPE +) -> None: + """Add feeds. + + Args: + update (telegram.Update): Object representing the incoming update from Telegram. + context (telegram.ext.CallbackContext.DEFAULT_TYPE): Object representing the callback context. + + Command Args: + url (str): The URL of the feed to add. + """ + context_logger = logger.bind(function="add_feed") + feeds = context.args + context_logger.info(f"{CHECK_MARK_EMOJI} Adding {len(feeds)} feeds.") + with contextlib.closing(r.make_reader(READER_DB_PATH)) as reader: + for feed in feeds: + try: + reader.add_feed(feed) + context_logger.info(f"{CHECK_MARK_EMOJI} Added {feed}.") + await update.message.reply_text(f"{CHECK_MARK_EMOJI} Added {feed}.") + except r.FeedExistsError: + context_logger.error(f"{CROSS_MARK_EMOJI} Feed {feed} already exists.") + await update.message.reply_text( + f"{CROSS_MARK_EMOJI} Feed {feed} already exists." ) - update.message.reply_text( - f"The option: {option} provided was invalid. The option can be either Add or Remove." + + +async def remove_feeds( + update: telegram.Update, context: telegram.ext.CallbackContext.DEFAULT_TYPE +) -> None: + """Remove feeds. + + Args: + update (telegram.Update): Object representing the incoming update from Telegram. + context (telegram.ext.CallbackContext.DEFAULT_TYPE): Object representing the callback context. + + Command Args: + url (str): The URL of the feed to remove. + """ + context_logger = logger.bind(function="remove_feed") + feeds = context.args + context_logger.info(f"{CHECK_MARK_EMOJI} Removing {len(feeds)} feeds.") + with contextlib.closing(r.make_reader(READER_DB_PATH)) as reader: + for feed in feeds: + try: + reader.delete_feed(feed) + context_logger.info(f"{CHECK_MARK_EMOJI} Removed {feed}.") + await update.message.reply_text(f"{CHECK_MARK_EMOJI} Removed {feed}.") + except r.FeedNotFoundError: + context_logger.error(f"{CROSS_MARK_EMOJI} Feed {feed} does not exist.") + await update.message.reply_text( + f"{CROSS_MARK_EMOJI} Feed {feed} does not exist." ) - def show_feeds(self, update: Update, context: CallbackContext) -> None: - """ - Show RSS feed(s) currently being checked for updates. - """ - # Use Reader object - with closing(make_reader("db.sqlite")) as reader: - # Obtain RSS feed(s) currently being checked for updates - feeds = list(reader.get_feeds(sort="added")) - message = f"The following RSS feed(s) are being checked for updates: {[feed.url for feed in feeds]}." - logger.debug(message) - update.message.reply_text(message) - - def change_interval(self, update: Update, context: CallbackContext) -> None: - """ - Alter the interval of the background Job checking for RSS feed(s) updates. - - Command args (required): - * Interval: The interval in seconds to run the background Job on. - """ - # Retrieve interval - try: - interval = int(context.args[0]) - logger.debug(f"Interval: {interval}.") - except IndexError as err: - logger.debug(f"Failed to retrieve interval for /changeinterval: {err}.") - update.message.reply_text("Provide an interval to /changeinterval.") - return - # Remove the previous background Job - try: - logger.debug(f"Attempting to remove previous background Job.") - for job in context.job_queue.jobs(): + +async def change_interval( + update: telegram.Update, context: telegram.ext.CallbackContext.DEFAULT_TYPE +) -> None: + """Change the feed update interval. + + Args: + update (telegram.Update): Object representing the incoming update from Telegram. + context (telegram.ext.CallbackContext.DEFAULT_TYPE): Object representing the callback context. + + Command Args: + interval (int): The interval in seconds to check for feed updates. + """ + context_logger = logger.bind(function="change_interval") + try: + interval = int(context.args[0]) + context_logger.info( + f"{CHECK_MARK_EMOJI} Changing feed(s) job - Interval: {interval}" + ) + jobs = context.job_queue.jobs() + if jobs: + for job in jobs: job.schedule_removal() - logger.debug("Successfully removed previous background Job.") - except: - logger.debug("Failed to remove previous background Job.") - update.message.reply_text( - "Failed to remove previous background Job. Have your ran /start?" - ) - return - # Create a new background Job using provided interval - context.job_queue.run_repeating(self.check_feeds, interval=interval) - logger.debug( - f"Successfully created new background Job with a {interval} second interval." + context.job_queue.run_repeating(check_feeds, interval=interval) + context_logger.info(f"{CHECK_MARK_EMOJI} Changed feed(s) job.") + await update.message.reply_text(f"{CHECK_MARK_EMOJI} Changed feed(s) job.") + else: + context_logger.error(f"{CROSS_MARK_EMOJI} No feed(s) job found.") + await update.message.reply_text(f"{CROSS_MARK_EMOJI} No feed(s) job found.") + except IndexError: + context_logger.error(f"{CROSS_MARK_EMOJI} Interval missing.") + await update.message.reply_text(f"{CROSS_MARK_EMOJI} Interval missing.") + + +async def show_feeds( + update: telegram.Update, context: telegram.ext.CallbackContext.DEFAULT_TYPE +) -> None: + """Show all feeds. + + Args: + update (telegram.Update): Object representing the incoming update from Telegram. + context (telegram.ext.CallbackContext.DEFAULT_TYPE): Object representing the callback context. + """ + context_logger = logger.bind(function="show_feeds") + context_logger.info(f"{CHECK_MARK_EMOJI} Showing all feeds.") + with contextlib.closing(r.make_reader(READER_DB_PATH)) as reader: + feeds = list(reader.get_feeds(sort="added")) + feed_count = len(list(feeds)) + context_logger.info(f"{CHECK_MARK_EMOJI} Found {feed_count} feeds.") + context_logger.info( + f"{CHECK_MARK_EMOJI} {feed_count} feeds: {[feed.url for feed in feeds]}." ) - update.message.reply_text( - f"Successfully created new background Job with a {interval} second interval." + await update.message.reply_text( + f"{CHECK_MARK_EMOJI} {feed_count} feeds: {[feed.url for feed in feeds]}." ) - def show_job(self, update: Update, context: CallbackContext) -> None: - """ - Show currently running background Job(s) checking for RSS feed updates, if any. - """ - jobs = list(context.job_queue.jobs()) - for job in jobs: - logger.debug( - f"Background Job: {job.name} next run is at: {job.next_t.strftime('%m/%d/%Y, %H:%M:%S')}" - ) - update.message.reply_text( - f"Background Job: {job.name} next run is at: {job.next_t.strftime('%m/%d/%Y, %H:%M:%S')}" - ) - def start_bot(self) -> None: - """ - Start RSS_Feederbot. - """ - logger.debug("Starting RSS_Feederbot and registering commands.") - dispatcher = self.updater.dispatcher - # Register error handler - dispatcher.add_error_handler(self.error_handler) - # Register commands - dispatcher.add_handler(CommandHandler("start", self.start, pass_args=True)) - dispatcher.add_handler( - CommandHandler("managefeed", self.manage_feed, pass_args=True) - ) - dispatcher.add_handler( - CommandHandler("showfeed", self.show_feeds) +async def show_job( + update: telegram.Update, context: telegram.ext.CallbackContext.DEFAULT_TYPE +) -> None: + """Show the datetime of the next feed update job. + + Args: + update (telegram.Update): Object representing the incoming update from Telegram. + context (telegram.ext.CallbackContext.DEFAULT_TYPE): Object representing the callback context. + """ + context_logger = logger.bind(function="show_job") + context_logger.info(f"{CHECK_MARK_EMOJI} Showing feed(s) job.") + jobs = context.job_queue.jobs() + for job in jobs: + context_logger.info( + f"{CHECK_MARK_EMOJI} Feed(s) job: {job.name} next run is {job.next_t.strftime('%m/%d/%Y, %H:%M:%S UTC')}." ) - dispatcher.add_handler( - CommandHandler( - "changeinterval", - self.change_interval, - pass_args=True, - pass_job_queue=True, - ) + await update.message.reply_text( + f"{CHECK_MARK_EMOJI} Feed(s) job: {job.name} next run is {job.next_t.strftime('%m/%d/%Y, %H:%M:%S UTC')}" ) - dispatcher.add_handler( - CommandHandler( - "showjob", - self.show_job, - pass_job_queue=True, - ) + + +async def start( + update: telegram.Update, context: telegram.ext.CallbackContext.DEFAULT_TYPE +) -> None: + """Start reading feeds. + + Starts the background job to read feeds on an interval. + + Args: + update (telegram.Update): Object representing the incoming update from Telegram. + context (telegram.ext.CallbackContext.DEFAULT_TYPE): Object representing the callback context. + + Command Args: + interval (int): The interval in seconds to check for feed updates. + """ + context_logger = logger.bind(function="start") + try: + interval = int(context.args[0]) + context_logger.info( + f"{CHECK_MARK_EMOJI} Starting feed(s) job - Interval: {interval}" ) - # Start RSS_Feederbot - self.updater.start_polling() - self.updater.idle() + context.job_queue.run_repeating(check_feeds, interval=interval, first=1) + context_logger.info(f"{CHECK_MARK_EMOJI} Started feed(s) job.") + await update.message.reply_text(f"{CHECK_MARK_EMOJI} Started feed(s) job.") + except IndexError: + context_logger.error(f"{CROSS_MARK_EMOJI} Interval missing.") + await update.message.reply_text(f"{CROSS_MARK_EMOJI} Interval missing.") -if __name__ == "__main__": - __version__ = "0.0.4" - rss_feederbot = RSS_Feederbot() - rss_feederbot.start_bot() +app = telegram.ext.ApplicationBuilder().token(BOT_TOKEN).build() +app.add_error_handler(error_handler) +app.add_handler(telegram.ext.CommandHandler("start", start)) +app.add_handler(telegram.ext.CommandHandler("addfeeds", add_feeds)) +app.add_handler(telegram.ext.CommandHandler("removefeeds", remove_feeds)) +app.add_handler(telegram.ext.CommandHandler("changeinterval", change_interval)) +app.add_handler(telegram.ext.CommandHandler("showfeeds", show_feeds)) +app.add_handler(telegram.ext.CommandHandler("showjob", show_job)) +app.run_polling() From 50b65065cd9c60fd5e283956af86b67abefedf8e Mon Sep 17 00:00:00 2001 From: dbrennand <52419383+dbrennand@users.noreply.github.com> Date: Fri, 3 Jun 2022 18:37:59 +0100 Subject: [PATCH 10/17] docs: update README --- README.md | 65 +++++++++++++++++++++++-------------------------------- 1 file changed, 27 insertions(+), 38 deletions(-) diff --git a/README.md b/README.md index 80870e1..275334a 100644 --- a/README.md +++ b/README.md @@ -1,61 +1,50 @@ -# RSS_Feederbot [Telegram] +# Feederbot -A Telegram bot for reading RSS Feeds. +An Atom, RSS, and JSON feed reading Telegram bot 🤖 -Checks on an interval for RSS feed updates. +Feederbot checks on a user configurable interval for feed updates. -## Setup - -### Normal - -1. Install dependencies from [requirements.txt](requirements.txt) using: `pip install -r requirements.txt` - -2. Set the bot token environment variable: - - PowerShell: `$Env:BOT_TOKEN = "Insert bot token here."` - - Bash: `export BOT_TOKEN="Insert bot token here."` +## Prerequisites -3. Run bot.py. +1. Docker -### Docker +2. Docker Compose -> [!NOTE] -> Run the following commands from inside the project directory. +## Supported Commands -1. `docker build -t rss_feederbot:0.0.4 .` +* `/addfeeds ` - Add feeds. -2. `docker run --rm --name rss_feederbot -e BOT_TOKEN="Insert bot token here." -d -t rss_feederbot:0.0.4` +* `/removefeeds ` - Remove feeds. -## Usage +* `/start ` - Start reading feeds. -Add and remove RSS feeds using the `/managefeed` command: +* `/changeinterval ` - Change the feed update interval. -* Add: `/managefeed add https://examplefeedurl.com` +* `/showfeeds` - Show all feeds. -* Remove: `/managefeed remove https://examplefeedurl.com` +* `/showjob` - Show the datetime of the next feed update job. -Begin checking for RSS feed updates using the `/start` command, providing an interval (in seconds) for how often to check for updates: - -> [!NOTE] -> The example below is every 30 minutes (Highly recommended). - -`/start 1800` - -If you decide that you want to change the interval of how often the bot checks for RSS feed updates, you can use the `/changeinterval` command, providing the new interval (in seconds): +## Setup -> [!NOTE] -> The example below is every hour. +1. Build the container image: -`/changeinterval 3600` + ```bash + docker build -t feederbot:1.0.0 . + ``` -To see the RSS feed(s) currently being checked for updates, use the `/showfeed` command. +2. Run the container: -To see when the bot will next check for RSS feed updates, use the `/showjob` command. + ```bash + # Using the Docker volume for the reader database + docker run -d -t -e BOT_TOKEN="" -e USER_ID="" --name feederbot feederbot:1.0.0 + # Using a bind mount for the reader database + docker run -d -t -e BOT_TOKEN="" -e USER_ID="" -v /path/to/store/db:/usr/src/app/reader --name feederbot feederbot:1.0.0 + ``` ## Authors -- Contributors -* **dbrennand** - *Author* - [dbrennand](https://github.com/dbrennand) +**dbrennand** - *Author* - [dbrennand](https://github.com/dbrennand) ## License + This project is licensed under the MIT License - see the [LICENSE](LICENSE) for details. From 560f03a2154feef8ac2a21c3da69ec3110ad2952 Mon Sep 17 00:00:00 2001 From: dbrennand <52419383+dbrennand@users.noreply.github.com> Date: Fri, 3 Jun 2022 18:39:48 +0100 Subject: [PATCH 11/17] docs(refactor): remove repeating word --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 275334a..7d8bd7d 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,7 @@ Feederbot checks on a user configurable interval for feed updates. ## Authors -- Contributors -**dbrennand** - *Author* - [dbrennand](https://github.com/dbrennand) +[**dbrennand**](https://github.com/dbrennand) - *Author* ## License From 066b8c8ab99b0b14230f274b3c3ed62868f9a94e Mon Sep 17 00:00:00 2001 From: dbrennand <52419383+dbrennand@users.noreply.github.com> Date: Fri, 3 Jun 2022 18:41:30 +0100 Subject: [PATCH 12/17] refactor: clarify comment --- bot.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bot.py b/bot.py index e501124..4b46d61 100644 --- a/bot.py +++ b/bot.py @@ -62,7 +62,7 @@ async def check_feeds(context: telegram.ext.CallbackContext.DEFAULT_TYPE) -> Non context_logger.info( f"{CHECK_MARK_EMOJI} Unread entries identical to total entries for {feed.title}." ) - # This is likely a newly added feed so send the last 5 entries + # This is likely a newly added feed so send the 5 most recent entries await send_feed_entries(context, feed.title, unread_entires[:5]) else: context_logger.info( From 282494ecbcfb2cf1754ad9a1d676fc97dded406f Mon Sep 17 00:00:00 2001 From: dbrennand <52419383+dbrennand@users.noreply.github.com> Date: Sat, 4 Jun 2022 11:10:18 +0100 Subject: [PATCH 13/17] fix: message markdown formatting --- bot.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/bot.py b/bot.py index 4b46d61..96ea19c 100644 --- a/bot.py +++ b/bot.py @@ -1,12 +1,12 @@ from typing import List from loguru import logger import reader as r +import contextlib import os import sys import emoji import telegram import telegram.ext -import contextlib READER_DB_PATH = "/usr/src/app/reader/db.sqlite" BOT_TOKEN = os.environ["BOT_TOKEN"] @@ -98,13 +98,13 @@ async def send_feed_entries( f"{CHECK_MARK_EMOJI} Sending {len(entries)} entries for {feed_title}." ) fmt_entries = [(entry.title, entry.link) for entry in entries] - message = "**{0}**\n\n{1}".format( + msg = "{0}\n\n{1}".format( feed_title, "\n".join(f"[{title}]({link})" for title, link in fmt_entries) - ).replace("-", "\\") + ) await context.bot.send_message( chat_id=USER_ID, - text=message, - parse_mode=telegram.constants.ParseMode.MARKDOWN_V2, + text=msg, + parse_mode="Markdown", ) @@ -200,14 +200,14 @@ async def change_interval( async def show_feeds( update: telegram.Update, context: telegram.ext.CallbackContext.DEFAULT_TYPE ) -> None: - """Show all feeds. + """Show feeds. Args: update (telegram.Update): Object representing the incoming update from Telegram. context (telegram.ext.CallbackContext.DEFAULT_TYPE): Object representing the callback context. """ context_logger = logger.bind(function="show_feeds") - context_logger.info(f"{CHECK_MARK_EMOJI} Showing all feeds.") + context_logger.info(f"{CHECK_MARK_EMOJI} Showing feeds.") with contextlib.closing(r.make_reader(READER_DB_PATH)) as reader: feeds = list(reader.get_feeds(sort="added")) feed_count = len(list(feeds)) From ecda67b27c396214880f1aa0eac6b86694ed3822 Mon Sep 17 00:00:00 2001 From: dbrennand <52419383+dbrennand@users.noreply.github.com> Date: Sat, 4 Jun 2022 11:10:33 +0100 Subject: [PATCH 14/17] docs: alter `/showfeeds` command description --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 7d8bd7d..a087050 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ Feederbot checks on a user configurable interval for feed updates. * `/changeinterval ` - Change the feed update interval. -* `/showfeeds` - Show all feeds. +* `/showfeeds` - Show feeds. * `/showjob` - Show the datetime of the next feed update job. From fbb80dcb8bd07f2cb0cd9b6034d174b470adcaca Mon Sep 17 00:00:00 2001 From: dbrennand <52419383+dbrennand@users.noreply.github.com> Date: Sat, 4 Jun 2022 11:12:14 +0100 Subject: [PATCH 15/17] refactor: rename `name` --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index b40292f..98643d8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,5 +1,5 @@ [tool.poetry] -name = "rss_feederbot" +name = "Feederbot" version = "1.0.0" description = "An RSS feed reading Telegram bot" authors = ["dbrennand <52419383+dbrennand@users.noreply.github.com>"] From 4d8b6c6c54e07ed2c765502b2d6872818e8bb344 Mon Sep 17 00:00:00 2001 From: dbrennand <52419383+dbrennand@users.noreply.github.com> Date: Sat, 4 Jun 2022 11:13:06 +0100 Subject: [PATCH 16/17] docs: remove docker-compose prerequisite --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index a087050..3404964 100644 --- a/README.md +++ b/README.md @@ -8,8 +8,6 @@ Feederbot checks on a user configurable interval for feed updates. 1. Docker -2. Docker Compose - ## Supported Commands * `/addfeeds ` - Add feeds. From a40138b89713e392696606a6ec66e2ebe496a1fe Mon Sep 17 00:00:00 2001 From: dbrennand <52419383+dbrennand@users.noreply.github.com> Date: Sat, 4 Jun 2022 11:14:14 +0100 Subject: [PATCH 17/17] docs: `...` after commands to show multiple feeds can be given --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 3404964..a91318b 100644 --- a/README.md +++ b/README.md @@ -10,9 +10,9 @@ Feederbot checks on a user configurable interval for feed updates. ## Supported Commands -* `/addfeeds ` - Add feeds. +* `/addfeeds ...` - Add feeds. -* `/removefeeds ` - Remove feeds. +* `/removefeeds ...` - Remove feeds. * `/start ` - Start reading feeds.