From 9e11f0e5aab21e4f8eef565338099a189fa037d5 Mon Sep 17 00:00:00 2001 From: Roman Cattaneo Date: Thu, 18 Jul 2024 17:42:09 +0200 Subject: [PATCH 01/11] Remove discontinued textile collection service --- src/trashbot.py | 34 +++++++++++++--------------------- 1 file changed, 13 insertions(+), 21 deletions(-) diff --git a/src/trashbot.py b/src/trashbot.py index 8471852..9adc1ae 100644 --- a/src/trashbot.py +++ b/src/trashbot.py @@ -37,6 +37,9 @@ CURRENT_VERSION = "1.1.0" WhatsNew = { + "2.0.0": [ + "Removed deprecated query for discontinued textile %s collection. Bring your old cloths to the normal collection station." % E_textile, + ], "1.2.0": ["Use `/next %s` as a shortcut to query paper collections directly" % E_paper, "Deprecated textile %s collection dates" % E_textile, @@ -121,20 +124,17 @@ def nextCommand(update, context): nextDates = queryCollectionAPI("cardboard", context.user_data) update.message.reply_text(nextDates) return - textile = len(re.findall(r'[' + E_textile + ']', update.message.text)) - if textile > 0: - nextDates = queryCollectionAPI("textile", context.user_data) - update.message.reply_text(nextDates) - return - keyboard = [[InlineKeyboardButton(E_paper, callback_data='paper'), - InlineKeyboardButton(E_cardboard, callback_data='cardboard'), - InlineKeyboardButton(E_textile, callback_data='textile')], - - [InlineKeyboardButton("Cargo %s" % E_tram, - callback_data='cargotram'), - InlineKeyboardButton("E - %s" % E_tram, - callback_data='etram')]] + keyboard = [ + [ + InlineKeyboardButton(E_paper, callback_data='paper'), + InlineKeyboardButton(E_cardboard, callback_data='cardboard'), + ], + [ + InlineKeyboardButton("Cargo %s" % E_tram, callback_data='cargotram'), + InlineKeyboardButton("E - %s" % E_tram, callback_data='etram') + ] + ] reply_markup = InlineKeyboardMarkup(keyboard) @@ -146,18 +146,10 @@ def queryCollectionAPI(choice, user_data): name = { "paper": "paper collection %s" % E_paper, "cardboard": "cardboard collection %s" % E_cardboard, - "textile": "textile collection %s" % E_textile, "cargotram": "cargo tram %s" % E_tram, "etram": "E-tram %s" % E_tram } - if choice == "textile": - textileException = "The city of Zurich stopped textile collections in "\ - "favor of an increased number of collection stations. You can also "\ - "bring your old cloths to Cargo-Tram %s.\n\n"\ - "For more information (in German) visit erz.ch/textilien." % E_tram - return textileException - zip = user_data.get('zip_code', 'undefined') limit = user_data.get('queryLimit', "1") today = datetime.today().strftime('%Y-%m-%d') From e56da859a8f31e3d0ae9784d1ed3442d4dfefe89 Mon Sep 17 00:00:00 2001 From: Roman Cattaneo Date: Thu, 18 Jul 2024 17:45:38 +0200 Subject: [PATCH 02/11] Fix typos --- src/trashbot.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/trashbot.py b/src/trashbot.py index 9adc1ae..4ac5a39 100644 --- a/src/trashbot.py +++ b/src/trashbot.py @@ -39,6 +39,7 @@ WhatsNew = { "2.0.0": [ "Removed deprecated query for discontinued textile %s collection. Bring your old cloths to the normal collection station." % E_textile, + "Fixed some typos", ], "1.2.0": ["Use `/next %s` as a shortcut to query paper collections directly" % E_paper, @@ -155,18 +156,18 @@ def queryCollectionAPI(choice, user_data): today = datetime.today().strftime('%Y-%m-%d') baseurl = "http://openerz.metaodi.ch/api/calendar.json" - openerz = "%s?sort=date&types=%s&zip=%s&start=%s" % (baseurl, choice, + openERZ = "%s?sort=date&types=%s&zip=%s&start=%s" % (baseurl, choice, zip, today) - openerz += "&limit=0" if limit == "none" else "&limit=%s" % limit + openERZ += "&limit=0" if limit == "none" else "&limit=%s" % limit - with urllib.request.urlopen(openerz) as url: + with urllib.request.urlopen(openERZ) as url: data = json.loads(url.read().decode()) count = data['_metadata']['total_count'] if count == 0: notFound = "I couldn't find any %s in your area %s "\ "(zip code = %s).\n\n"\ "Please note: Especially in December you might see no this "\ - "message if the new year's data isn't publically available "\ + "message if the new year's data isn't publicly available "\ "yet.\n\n"\ "If you think your zip code is wrong, use /start to "\ "configure a new one." % (E_cry, name[query.data], zip) @@ -245,7 +246,7 @@ def handleQueryLimit(update, context): context.user_data["queryLimit"] = query.data reply = "" if query.data == "none": - reply = "Removed query limit - showing all remaining colletion dates "\ + reply = "Removed query limit - showing all remaining collection dates "\ "for each query in the future." else: reply = "Query limit is set to %s now." % query.data @@ -356,7 +357,7 @@ def trashbot(token): if __name__ == '__main__': - logger.info("Parsing configfile") + logger.info("Parsing configuration file") config = configparser.ConfigParser() config.read("../config.ini") From ddd57c0edb1bb2f8cc74b38dc1f27c7aa0815927 Mon Sep 17 00:00:00 2001 From: Roman Cattaneo Date: Thu, 18 Jul 2024 18:33:01 +0200 Subject: [PATCH 03/11] Fix python version, ignore standard path for venv --- .gitignore | 1 + .tool-versions | 1 + 2 files changed, 2 insertions(+) create mode 100644 .tool-versions diff --git a/.gitignore b/.gitignore index 0c9b1dd..dff2cc3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ # python venv venv +.venv # config file with settings config.ini diff --git a/.tool-versions b/.tool-versions new file mode 100644 index 0000000..63bf8f7 --- /dev/null +++ b/.tool-versions @@ -0,0 +1 @@ +python 3.6.15 From fb0bb0af9eefe753a8daa085cb6d86c7fc11b4e3 Mon Sep 17 00:00:00 2001 From: Roman Cattaneo Date: Thu, 18 Jul 2024 20:40:24 +0200 Subject: [PATCH 04/11] Add missing WhatsNew, update python to 3.8 --- .tool-versions | 2 +- src/trashbot.py | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/.tool-versions b/.tool-versions index 63bf8f7..090e624 100644 --- a/.tool-versions +++ b/.tool-versions @@ -1 +1 @@ -python 3.6.15 +python 3.8.19 diff --git a/src/trashbot.py b/src/trashbot.py index 4ac5a39..00a49f3 100644 --- a/src/trashbot.py +++ b/src/trashbot.py @@ -34,13 +34,16 @@ E_wave = "\U0001F44B" CHOOSE, HANDLE_LIMIT, ZIPCODE = range(3) -CURRENT_VERSION = "1.1.0" +CURRENT_VERSION = "2.0.0" WhatsNew = { "2.0.0": [ "Removed deprecated query for discontinued textile %s collection. Bring your old cloths to the normal collection station." % E_textile, "Fixed some typos", ], + "1.2.1": [ + "Update to current version of openERZ API", + ], "1.2.0": ["Use `/next %s` as a shortcut to query paper collections directly" % E_paper, "Deprecated textile %s collection dates" % E_textile, From 0fb9b1fa9f0730855ad53e6d8d82a8aca19c1032 Mon Sep 17 00:00:00 2001 From: Roman Cattaneo Date: Thu, 18 Jul 2024 20:53:12 +0200 Subject: [PATCH 05/11] Update ReadMe with new install instructions --- ReadMe.md | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/ReadMe.md b/ReadMe.md index bf64d69..0123e5e 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -11,7 +11,12 @@ Visit [https://t.me/zh_trashbot](https://t.me/zh_trashbot) or use `@zh_trashbot` You don't need to deploy the bot to use it. For using the bot, just follow the link above. If - for whatever reason - you want to deploy (a copy of) this bot, you will need to: - clone this repository, -- create a virtual environment (use python 3.6 or later), -- install the dependencies (into your virtual environment): `pip install -r requirements.txt`, -- copy `config.ini.example` to `config.ini`, get a [Telegram bot token](https://core.telegram.org/bots#creating-a-new-bot) and configure it in `config.ini`, +- install [asdf-vm](https://asdf-vm.com) and [asdf-python](https://github.com/asdf-community/asdf-python) to manage the python version, +- run `asdf global python system` to use the system's python version (if installed) outside this project, +- run `asdf install` to install the configured python version, +- run `python -m venv .venv/` to create the virtual environment, +- run `source .venv/bin/activate` to activate the virtual environment, +- run `pip install -r requirements.txt` to install the dependencies, +- copy `config.ini.example` to `config.ini`, +- get a [Telegram bot token](https://core.telegram.org/bots#creating-a-new-bot) and configure it in `config.ini`, - run `python trashbot.py` from within the `src/` folder (or submit a PR to fix the fact that we currently have a hard-coded relative path to the config file) From 21563bddb8a4b51e1de3b23202f8ca72e2aabbe3 Mon Sep 17 00:00:00 2001 From: Roman Cattaneo Date: Thu, 18 Jul 2024 21:08:10 +0200 Subject: [PATCH 06/11] Fix: name resolution when no collection is found --- src/trashbot.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/trashbot.py b/src/trashbot.py index 00a49f3..a375d59 100644 --- a/src/trashbot.py +++ b/src/trashbot.py @@ -173,7 +173,7 @@ def queryCollectionAPI(choice, user_data): "message if the new year's data isn't publicly available "\ "yet.\n\n"\ "If you think your zip code is wrong, use /start to "\ - "configure a new one." % (E_cry, name[query.data], zip) + "configure a new one." % (E_cry, name[choice], zip) return notFound nextDate = "" From 54bbd8b4769677c45b872bebf600b329f178a7e1 Mon Sep 17 00:00:00 2001 From: Roman Cattaneo Date: Thu, 18 Jul 2024 21:24:24 +0200 Subject: [PATCH 07/11] Add Code Spell Check configuration --- ReadMe.md | 4 ++++ cspell.config.yaml | 15 +++++++++++++++ 2 files changed, 19 insertions(+) create mode 100644 cspell.config.yaml diff --git a/ReadMe.md b/ReadMe.md index 0123e5e..fc5e2b0 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -20,3 +20,7 @@ You don't need to deploy the bot to use it. For using the bot, just follow the l - copy `config.ini.example` to `config.ini`, - get a [Telegram bot token](https://core.telegram.org/bots#creating-a-new-bot) and configure it in `config.ini`, - run `python trashbot.py` from within the `src/` folder (or submit a PR to fix the fact that we currently have a hard-coded relative path to the config file) + +## VSCode setup + +Recommended extensions are Python language support and Code Spell Checker. diff --git a/cspell.config.yaml b/cspell.config.yaml new file mode 100644 index 0000000..5bdf2fd --- /dev/null +++ b/cspell.config.yaml @@ -0,0 +1,15 @@ +version: "0.2" +ignorePaths: + - .venv +dictionaryDefinitions: [] +dictionaries: [] +words: + - trashbot + - venv + - Züri +ignoreWords: + - cargotram + - etram + - levelname + - tada +import: [] From 9ab5bb36fc6b62d9f959ead9319f3de29e36e5ec Mon Sep 17 00:00:00 2001 From: Roman Cattaneo Date: Thu, 18 Jul 2024 21:24:40 +0200 Subject: [PATCH 08/11] Remove extra empty lines at end of file --- .gitignore | 1 - config.ini.example | 1 - 2 files changed, 2 deletions(-) diff --git a/.gitignore b/.gitignore index dff2cc3..c294751 100644 --- a/.gitignore +++ b/.gitignore @@ -9,4 +9,3 @@ config.ini src/trashbot_data ideas.md - diff --git a/config.ini.example b/config.ini.example index 03e21ef..4496118 100644 --- a/config.ini.example +++ b/config.ini.example @@ -1,3 +1,2 @@ [api.telegram.org] token = Your-telegram-bot-token-here - From 528f40d0d5125ee360eeb9b86574bf4fb3cf5ea6 Mon Sep 17 00:00:00 2001 From: Roman Cattaneo Date: Thu, 18 Jul 2024 22:09:08 +0200 Subject: [PATCH 09/11] Use ruff as linter & formatter --- .gitignore | 3 + ReadMe.md | 2 +- requirements.txt | 1 + src/trashbot.py | 269 +++++++++++++++++++++++++++-------------------- 4 files changed, 159 insertions(+), 116 deletions(-) diff --git a/.gitignore b/.gitignore index c294751..e74983e 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,9 @@ venv .venv +# ruff (linter / formatter) cache +.ruff_cache + # config file with settings config.ini diff --git a/ReadMe.md b/ReadMe.md index fc5e2b0..a45f3f4 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -23,4 +23,4 @@ You don't need to deploy the bot to use it. For using the bot, just follow the l ## VSCode setup -Recommended extensions are Python language support and Code Spell Checker. +Recommended extensions are [ruff](https://marketplace.visualstudio.com/items?itemName=charliermarsh.ruff) and [Code Spell Checker](https://marketplace.visualstudio.com/items?itemName=streetsidesoftware.code-spell-checker). diff --git a/requirements.txt b/requirements.txt index 4a7eb4f..41dbc9d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,5 +4,6 @@ cryptography==3.1.1 decorator==4.4.2 pycparser==2.20 python-telegram-bot==12.8 +ruff==0.5.3 six==1.15.0 tornado==6.0.4 diff --git a/src/trashbot.py b/src/trashbot.py index a375d59..65d1671 100644 --- a/src/trashbot.py +++ b/src/trashbot.py @@ -5,61 +5,75 @@ import logging import re import urllib.request - from datetime import datetime + from telegram import InlineKeyboardButton, InlineKeyboardMarkup -from telegram.ext import CallbackQueryHandler, CommandHandler,\ - ConversationHandler, Filters, MessageHandler, PicklePersistence, Updater +from telegram.ext import ( + CallbackQueryHandler, + CommandHandler, + ConversationHandler, + Filters, + MessageHandler, + PicklePersistence, + Updater, +) # configure logger logging.basicConfig( - format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', - level=logging.INFO) + format="%(asctime)s - %(name)s - %(levelname)s - %(message)s", level=logging.INFO +) logger = logging.getLogger(__name__) # emojis -E_blush = "\U0001F60A" -E_broom = "\U0001F9F9" -E_calendar = "\U0001F4C5" -E_cardboard = "\U0001F4E6" -E_cry = "\U0001F62D" -E_disappointed = "\U0001F61E" +E_blush = "\U0001f60a" +E_broom = "\U0001f9f9" +E_calendar = "\U0001f4c5" +E_cardboard = "\U0001f4e6" +E_cry = "\U0001f62d" +E_disappointed = "\U0001f61e" E_gear = "\U00002699" -E_grin = "\U0001F604" -E_paper = "\U0001F4F0" -E_tada = "\U0001F389" -E_textile = "\U0001F455" -E_tram = "\U0001F68B" -E_unsure = "\U0001F615" -E_wave = "\U0001F44B" +E_grin = "\U0001f604" +E_paper = "\U0001f4f0" +E_tada = "\U0001f389" +E_textile = "\U0001f455" +E_tram = "\U0001f68b" +E_unsure = "\U0001f615" +E_wave = "\U0001f44b" + CHOOSE, HANDLE_LIMIT, ZIPCODE = range(3) CURRENT_VERSION = "2.0.0" WhatsNew = { "2.0.0": [ - "Removed deprecated query for discontinued textile %s collection. Bring your old cloths to the normal collection station." % E_textile, + "Removed deprecated query for discontinued textile %s collection. Bring your old cloths to the normal collection station." + % E_textile, "Fixed some typos", ], "1.2.1": [ "Update to current version of openERZ API", ], - "1.2.0": - ["Use `/next %s` as a shortcut to query paper collections directly" % E_paper, + "1.2.0": [ + "Use `/next %s` as a shortcut to query paper collections directly" % E_paper, "Deprecated textile %s collection dates" % E_textile, - "Minor code cleanups"], - "1.1.0": - ["Use /configure %s to set a query limit and see more the one collection date" % E_gear, - "What's new messages %s" % E_grin, - "Various text improvements", - "Some code cleanup"]} + "Minor code cleanups", + ], + "1.1.0": [ + "Use /configure %s to set a query limit and see more the one collection date" + % E_gear, + "What's new messages %s" % E_grin, + "Various text improvements", + "Some code cleanup", + ], +} def newerVersionExists(userVersion): (major, minor, patch) = userVersion.split(".") (cMajor, cMinor, cPatch) = CURRENT_VERSION.split(".") - return major < cMajor or (major == cMajor and ( - minor < cMinor or (minor == cMinor and patch < cPatch))) + return major < cMajor or ( + major == cMajor and (minor < cMinor or (minor == cMinor and patch < cPatch)) + ) def setDefaultUserData(context, key, value): @@ -77,9 +91,11 @@ def startCommand(update, context): setDefaultUserData(context, "queryLimit", "1") setDefaultUserData(context, "version", CURRENT_VERSION) - reply = "Waste collection in Zurich occurs on different days depending "\ - "on you zip code.\n\n"\ + reply = ( + "Waste collection in Zurich occurs on different days depending " + "on you zip code.\n\n" "Please share your 4 digit zip code with me." + ) update.message.reply_text(reply) return ZIPCODE @@ -91,15 +107,19 @@ def zipHandler(update, context): if len(zips) == 1: zip_code = zips[0] - context.user_data['zip_code'] = zip_code - msg = "Thank you! Setting your zip code to %s.\n\n"\ + context.user_data["zip_code"] = zip_code + msg = ( + "Thank you! Setting your zip code to %s.\n\n" "Now try /next to check for waste collection dates." % zip_code + ) update.message.reply_text(msg) return ConversationHandler.END - reply = "I'm sorry, I didn't get that %s\nPlease either share "\ - "your 4 digit zip code or write /cancel to abort the "\ + reply = ( + "I'm sorry, I didn't get that %s\nPlease either share " + "your 4 digit zip code or write /cancel to abort the " "conversation." % E_disappointed + ) update.message.reply_text(reply) return ZIPCODE @@ -110,20 +130,22 @@ def helpCommand(update, context): def nextCommand(update, context): - if 'zip_code' not in context.user_data: - reply = "Hang on!\n\n"\ - "I need to know where you live before I can look up the "\ - "calendar %s for you. Please use /start to configure your zip "\ + if "zip_code" not in context.user_data: + reply = ( + "Hang on!\n\n" + "I need to know where you live before I can look up the " + "calendar %s for you. Please use /start to configure your zip " "code." % E_calendar + ) update.message.reply_text(reply) return - paper = len(re.findall(r'[' + E_paper + ']', update.message.text)) + paper = len(re.findall(r"[" + E_paper + "]", update.message.text)) if paper > 0: nextDates = queryCollectionAPI("paper", context.user_data) update.message.reply_text(nextDates) return - cardboard = len(re.findall(r'[' + E_cardboard + ']', update.message.text)) + cardboard = len(re.findall(r"[" + E_cardboard + "]", update.message.text)) if cardboard > 0: nextDates = queryCollectionAPI("cardboard", context.user_data) update.message.reply_text(nextDates) @@ -131,19 +153,20 @@ def nextCommand(update, context): keyboard = [ [ - InlineKeyboardButton(E_paper, callback_data='paper'), - InlineKeyboardButton(E_cardboard, callback_data='cardboard'), + InlineKeyboardButton(E_paper, callback_data="paper"), + InlineKeyboardButton(E_cardboard, callback_data="cardboard"), ], [ - InlineKeyboardButton("Cargo %s" % E_tram, callback_data='cargotram'), - InlineKeyboardButton("E - %s" % E_tram, callback_data='etram') - ] + InlineKeyboardButton("Cargo %s" % E_tram, callback_data="cargotram"), + InlineKeyboardButton("E - %s" % E_tram, callback_data="etram"), + ], ] reply_markup = InlineKeyboardMarkup(keyboard) update.message.reply_text( - 'What do you want to throw away?', reply_markup=reply_markup) + "What do you want to throw away?", reply_markup=reply_markup + ) def queryCollectionAPI(choice, user_data): @@ -151,35 +174,37 @@ def queryCollectionAPI(choice, user_data): "paper": "paper collection %s" % E_paper, "cardboard": "cardboard collection %s" % E_cardboard, "cargotram": "cargo tram %s" % E_tram, - "etram": "E-tram %s" % E_tram + "etram": "E-tram %s" % E_tram, } - zip = user_data.get('zip_code', 'undefined') - limit = user_data.get('queryLimit', "1") - today = datetime.today().strftime('%Y-%m-%d') + zip = user_data.get("zip_code", "undefined") + limit = user_data.get("queryLimit", "1") + today = datetime.today().strftime("%Y-%m-%d") baseurl = "http://openerz.metaodi.ch/api/calendar.json" - openERZ = "%s?sort=date&types=%s&zip=%s&start=%s" % (baseurl, choice, - zip, today) + openERZ = "%s?sort=date&types=%s&zip=%s&start=%s" % (baseurl, choice, zip, today) openERZ += "&limit=0" if limit == "none" else "&limit=%s" % limit with urllib.request.urlopen(openERZ) as url: data = json.loads(url.read().decode()) - count = data['_metadata']['total_count'] + count = data["_metadata"]["total_count"] if count == 0: - notFound = "I couldn't find any %s in your area %s "\ - "(zip code = %s).\n\n"\ - "Please note: Especially in December you might see no this "\ - "message if the new year's data isn't publicly available "\ - "yet.\n\n"\ - "If you think your zip code is wrong, use /start to "\ + notFound = ( + "I couldn't find any %s in your area %s " + "(zip code = %s).\n\n" + "Please note: Especially in December you might see no this " + "message if the new year's data isn't publicly available " + "yet.\n\n" + "If you think your zip code is wrong, use /start to " "configure a new one." % (E_cry, name[choice], zip) + ) return notFound nextDate = "" - for result in data['result']: - date = datetime.strptime( - result['date'], "%Y-%m-%d").strftime('%a, %b %d %Y') + for result in data["result"]: + date = datetime.strptime(result["date"], "%Y-%m-%d").strftime( + "%a, %b %d %Y" + ) nextDate += "\t\U00002022 %s\n" % date return "Next %s in your area:\n%s" % (name[choice], nextDate) @@ -205,14 +230,20 @@ def cancelCommand(update, context): def configureCommand(update, context): - opts = [[InlineKeyboardButton("Query limit", callback_data="queryLimit"), - InlineKeyboardButton("Cancel", callback_data="cancel")]] + opts = [ + [ + InlineKeyboardButton("Query limit", callback_data="queryLimit"), + InlineKeyboardButton("Cancel", callback_data="cancel"), + ] + ] - queryLimit = context.user_data.get('queryLimit', "1") - current = "Your current settings look like this:\n\n"\ - "\t\U00002022 Query limit: %s\n\n"\ - "What do you want to configure? If these settings look just fine, "\ + queryLimit = context.user_data.get("queryLimit", "1") + current = ( + "Your current settings look like this:\n\n" + "\t\U00002022 Query limit: %s\n\n" + "What do you want to configure? If these settings look just fine, " "use the cancel button." % (queryLimit) + ) update.message.reply_text(current, reply_markup=InlineKeyboardMarkup(opts)) @@ -224,18 +255,22 @@ def chooseSetting(update, context): query.answer() if query.data == "queryLimit": - keyboard = [[InlineKeyboardButton("1", callback_data="1"), - InlineKeyboardButton("2", callback_data="2"), - InlineKeyboardButton("5", callback_data="5"), - InlineKeyboardButton("all", callback_data="none")]] - text = "Okay, let's set the query limit. How many collections do you "\ + keyboard = [ + [ + InlineKeyboardButton("1", callback_data="1"), + InlineKeyboardButton("2", callback_data="2"), + InlineKeyboardButton("5", callback_data="5"), + InlineKeyboardButton("all", callback_data="none"), + ] + ] + text = ( + "Okay, let's set the query limit. How many collections do you " "want to see per query?" - query.edit_message_text(text=text, - reply_markup=InlineKeyboardMarkup(keyboard)) + ) + query.edit_message_text(text=text, reply_markup=InlineKeyboardMarkup(keyboard)) return HANDLE_LIMIT elif query.data == "cancel": - query.edit_message_text( - text="Keeping your settings as is. %s" % E_blush) + query.edit_message_text(text="Keeping your settings as is. %s" % E_blush) return ConversationHandler.END query.edit_message_text(text="I'm sorry, I can't find this setting.") @@ -249,8 +284,10 @@ def handleQueryLimit(update, context): context.user_data["queryLimit"] = query.data reply = "" if query.data == "none": - reply = "Removed query limit - showing all remaining collection dates "\ + reply = ( + "Removed query limit - showing all remaining collection dates " "for each query in the future." + ) else: reply = "Query limit is set to %s now." % query.data @@ -259,35 +296,41 @@ def handleQueryLimit(update, context): def settingsCommand(update, context): - zip = context.user_data.get('zip_code', 'undefined') - limit = context.user_data.get('queryLimit', "1") - reply = "Züri Trash Bot stores only very few settings.\n"\ - "Currently, the bot knows the following about you:\n\n"\ - "\t\U00002022 zip code: %s\n"\ - "\t\U00002022 query limit: %s\n\n"\ - "If you want to change your zip-code, use /start to configure a new "\ - "one.\n\n"\ - "Use /configure to change any other setting.\n\n"\ + zip = context.user_data.get("zip_code", "undefined") + limit = context.user_data.get("queryLimit", "1") + reply = ( + "Züri Trash Bot stores only very few settings.\n" + "Currently, the bot knows the following about you:\n\n" + "\t\U00002022 zip code: %s\n" + "\t\U00002022 query limit: %s\n\n" + "If you want to change your zip-code, use /start to configure a new " + "one.\n\n" + "Use /configure to change any other setting.\n\n" "Use /clear to remove all user data mentioned above." % (zip, limit) + ) update.message.reply_text(reply) def clearCommand(update, context): context.user_data.clear() - reply = "%s All user data cleared!\n\n"\ - "You will need to use /start again to configure your zip "\ + reply = ( + "%s All user data cleared!\n\n" + "You will need to use /start again to configure your zip " "code." % E_broom + ) update.message.reply_text(reply) def aboutCommand(update, context): - text = "Züri Trash Bot is an open-source project, see "\ - "https://github.com/romanc/zh_trashbot\n\n"\ - "Züri Trash Bot is made possible by\n"\ - "\t\U00002022 https://github.com/python-telegram-bot\n"\ - "\t\U00002022 http://openerz.metaodi.ch\n\n"\ - "Kudos and keep up the nice work! "\ + text = ( + "Züri Trash Bot is an open-source project, see " + "https://github.com/romanc/zh_trashbot\n\n" + "Züri Trash Bot is made possible by\n" + "\t\U00002022 https://github.com/python-telegram-bot\n" + "\t\U00002022 http://openerz.metaodi.ch\n\n" + "Kudos and keep up the nice work! " "This service is provided 'as is', without warranty of any kind.\n" + ) update.message.reply_text(text) @@ -298,22 +341,17 @@ def trashbot(token): updater = Updater(token, persistence=pp, use_context=True) startConversation = ConversationHandler( - entry_points=[CommandHandler('start', startCommand)], - - states={ - ZIPCODE: [MessageHandler(Filters.text & ~Filters.command, - zipHandler)] - }, - - fallbacks=[CommandHandler('cancel', cancelCommand)] + entry_points=[CommandHandler("start", startCommand)], + states={ZIPCODE: [MessageHandler(Filters.text & ~Filters.command, zipHandler)]}, + fallbacks=[CommandHandler("cancel", cancelCommand)], ) configureConversation = ConversationHandler( entry_points=[CommandHandler("configure", configureCommand)], states={ CHOOSE: [CallbackQueryHandler(chooseSetting)], - HANDLE_LIMIT: [CallbackQueryHandler(handleQueryLimit)] + HANDLE_LIMIT: [CallbackQueryHandler(handleQueryLimit)], }, - fallbacks=[CommandHandler('cancel', cancelCommand)] + fallbacks=[CommandHandler("cancel", cancelCommand)], ) myDispatcher = updater.dispatcher @@ -329,8 +367,7 @@ def trashbot(token): myDispatcher.add_handler(CallbackQueryHandler(queryButton)) # echo anything unknown - myDispatcher.add_handler(MessageHandler( - Filters.text & ~Filters.command, echo)) + myDispatcher.add_handler(MessageHandler(Filters.text & ~Filters.command, echo)) userData = pp.get_user_data() chatData = pp.get_chat_data() @@ -341,15 +378,17 @@ def trashbot(token): if newerVersionExists(thisUser.get("version", "1.0.2")): # we have a newer version - text = "Here's what's new in version %s %s\n\n" % ( - CURRENT_VERSION, E_tada) + text = "Here's what's new in version %s %s\n\n" % (CURRENT_VERSION, E_tada) for note in WhatsNew[CURRENT_VERSION]: text = text + ("\t\U00002022 %s\n" % note) # send a what's new message - updater.job_queue.run_once(whatsNewMessage, 2, context={ - "chat_id": chatId, "text": text}, - name="new%s" % str(chatId)) + updater.job_queue.run_once( + whatsNewMessage, + 2, + context={"chat_id": chatId, "text": text}, + name="new%s" % str(chatId), + ) # then, update current version myDispatcher.user_data[chatId]["version"] = CURRENT_VERSION @@ -359,10 +398,10 @@ def trashbot(token): updater.idle() -if __name__ == '__main__': +if __name__ == "__main__": logger.info("Parsing configuration file") config = configparser.ConfigParser() config.read("../config.ini") logger.info("Running Züri Trash Bot") - trashbot(config['api.telegram.org']['token']) + trashbot(config["api.telegram.org"]["token"]) From 74b200bcbd781a9d408eba39235e99ef5612973e Mon Sep 17 00:00:00 2001 From: Roman Cattaneo Date: Fri, 19 Jul 2024 11:24:18 +0200 Subject: [PATCH 10/11] Add pre-commit hook configured to run ruff --- .pre-commit-config.yaml | 18 ++++++++++++++++++ requirements.txt | 9 +++++++++ 2 files changed, 27 insertions(+) create mode 100644 .pre-commit-config.yaml diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..a132b67 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,18 @@ +# See https://pre-commit.com for more information +# See https://pre-commit.com/hooks.html for more hooks +repos: +- repo: https://github.com/pre-commit/pre-commit-hooks + rev: v3.2.0 + hooks: + - id: trailing-whitespace + - id: end-of-file-fixer + - id: check-yaml + - id: check-added-large-files +- repo: https://github.com/astral-sh/ruff-pre-commit + # Ruff version. + rev: v0.5.3 + hooks: + # Run the linter. + - id: ruff + # Run the formatter. + - id: ruff-format diff --git a/requirements.txt b/requirements.txt index 41dbc9d..4d38499 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,9 +1,18 @@ certifi==2020.6.20 cffi==1.14.3 +cfgv==3.4.0 cryptography==3.1.1 decorator==4.4.2 +distlib==0.3.8 +filelock==3.15.4 +identify==2.6.0 +nodeenv==1.9.1 +platformdirs==4.2.2 +pre-commit==3.5.0 pycparser==2.20 python-telegram-bot==12.8 +PyYAML==6.0.1 ruff==0.5.3 six==1.15.0 tornado==6.0.4 +virtualenv==20.26.3 From f0091ca05636a3221b9c7050dfb3810181fc83ca Mon Sep 17 00:00:00 2001 From: Roman Cattaneo Date: Mon, 26 Aug 2024 08:20:08 +0200 Subject: [PATCH 11/11] Updated what's new for v 2.0.0 - added profile picture - updated menu with some emojis --- src/trashbot.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/trashbot.py b/src/trashbot.py index 65d1671..f16bb0e 100644 --- a/src/trashbot.py +++ b/src/trashbot.py @@ -48,6 +48,7 @@ "2.0.0": [ "Removed deprecated query for discontinued textile %s collection. Bring your old cloths to the normal collection station." % E_textile, + "Added profile picture and updated menu", "Fixed some typos", ], "1.2.1": [