diff options
author | clarkzjw <[email protected]> | 2023-02-23 21:46:27 -0800 |
---|---|---|
committer | clarkzjw <[email protected]> | 2023-02-23 21:46:27 -0800 |
commit | a9fb6f252553ae49a2ba372434073824babe31e4 (patch) | |
tree | 77d53a16f1d7565f6da6490d2cad4e4321995549 | |
parent | cbfde03e620188d80213a8b15a4dffdb8948b257 (diff) | |
download | swarm2fediverse-a9fb6f252553ae49a2ba372434073824babe31e4.tar.gz |
bot: support changing default toot visibility
-rw-r--r-- | bot.py | 22 | ||||
-rw-r--r-- | callback.py | 21 | ||||
-rw-r--r-- | command.py | 32 | ||||
-rw-r--r-- | config.py | 2 | ||||
-rw-r--r-- | dbstore/peewee_store.py | 34 | ||||
-rw-r--r-- | prompt/string.py | 5 |
6 files changed, 91 insertions, 25 deletions
@@ -42,6 +42,7 @@ from command import ( | |||
42 | help_command, | 42 | help_command, |
43 | tos_command, | 43 | tos_command, |
44 | toggle_visibility_command, | 44 | toggle_visibility_command, |
45 | callback_toggle_visibility, | ||
45 | logout_command, | 46 | logout_command, |
46 | list_command | 47 | list_command |
47 | ) | 48 | ) |
@@ -55,7 +56,8 @@ from config import ( | |||
55 | ADD_COMMENT, | 56 | ADD_COMMENT, |
56 | BOT_TOKEN, | 57 | BOT_TOKEN, |
57 | BOT_SCOPE, | 58 | BOT_SCOPE, |
58 | MAIN_MENU | 59 | MAIN_MENU, |
60 | WAIT_VISIBILITY | ||
59 | ) | 61 | ) |
60 | 62 | ||
61 | from prompt.string import PROMPT_CHOOSE_ACTION | 63 | from prompt.string import PROMPT_CHOOSE_ACTION |
@@ -161,13 +163,27 @@ async def main() -> None: | |||
161 | 163 | ||
162 | # register handlers | 164 | # register handlers |
163 | application.add_handler(CommandHandler("tos", tos_command)) | 165 | application.add_handler(CommandHandler("tos", tos_command)) |
164 | application.add_handler(CommandHandler("vis", toggle_visibility_command)) | 166 | visibility_conversation_handler = ConversationHandler( |
167 | entry_points=[ | ||
168 | CommandHandler("vis", toggle_visibility_command) | ||
169 | ], | ||
170 | states={ | ||
171 | WAIT_VISIBILITY: [ | ||
172 | CallbackQueryHandler(callback_toggle_visibility) | ||
173 | ]}, | ||
174 | fallbacks=[CommandHandler("cancel", cancel_command)], | ||
175 | per_message=False, | ||
176 | allow_reentry=True, | ||
177 | ) | ||
178 | |||
165 | application.add_handler(CommandHandler("logout", logout_command)) | 179 | application.add_handler(CommandHandler("logout", logout_command)) |
166 | application.add_handler(CommandHandler("list", list_command)) | 180 | application.add_handler(CommandHandler("list", list_command)) |
167 | application.add_handler(CommandHandler("Help", help_command)) | 181 | application.add_handler(CommandHandler("Help", help_command)) |
168 | application.add_handler(checkin_handler) | ||
169 | application.add_handler(TypeHandler(type=FediLoginCallbackUpdate, callback=process_oauth_login_callback)) | 182 | application.add_handler(TypeHandler(type=FediLoginCallbackUpdate, callback=process_oauth_login_callback)) |
170 | 183 | ||
184 | application.add_handler(visibility_conversation_handler, 2) | ||
185 | application.add_handler(checkin_handler, 1) | ||
186 | |||
171 | # Pass webhook settings to telegram | 187 | # Pass webhook settings to telegram |
172 | await application.bot.set_webhook(url=f"{BOT_DOMAIN}{TELEGRAM_WEBHOOK_URL}") | 188 | await application.bot.set_webhook(url=f"{BOT_DOMAIN}{TELEGRAM_WEBHOOK_URL}") |
173 | 189 | ||
diff --git a/callback.py b/callback.py index 1abef5e..cb6a8d3 100644 --- a/callback.py +++ b/callback.py | |||
@@ -60,7 +60,7 @@ async def process_media_group(context: CallbackContext): | |||
60 | 60 | ||
61 | with db.connection_context(): | 61 | with db.connection_context(): |
62 | u = User.get(User.telegram_user_id == context.user_data["user_id"]) | 62 | u = User.get(User.telegram_user_id == context.user_data["user_id"]) |
63 | content_type = "text/markdown" if u.home_instance_type == "pleroma" else "text/plain" | 63 | content_type = "text/markdown" if u.home_instance_type == "pleroma" else None |
64 | 64 | ||
65 | for media_dict in context.job.data: | 65 | for media_dict in context.job.data: |
66 | if len(media_id) >= 4: | 66 | if len(media_id) >= 4: |
@@ -124,11 +124,11 @@ async def callback_location_sharing(update: Update, context: ContextTypes.DEFAUL | |||
124 | poi = query_poi_by_fsq_id(context.user_data.get("fsq_id")) | 124 | poi = query_poi_by_fsq_id(context.user_data.get("fsq_id")) |
125 | content = generate_toot_text(poi["name"], poi["locality"], poi["region"], poi["latitude"], poi["longitude"]) | 125 | content = generate_toot_text(poi["name"], poi["locality"], poi["region"], poi["latitude"], poi["longitude"]) |
126 | 126 | ||
127 | with db.connection_context(): | 127 | u = get_user_by_id(str(update.effective_user.id)) |
128 | u = User.get(User.telegram_user_id == update.effective_user.id) | 128 | content_type = "text/markdown" if u["home_instance_type"] == "pleroma" else None |
129 | content_type = "text/markdown" if u.home_instance_type == "pleroma" else "text/plain" | 129 | |
130 | status = get_mastodon_client(update.effective_user.id).status_post(content, | 130 | status = get_mastodon_client(update.effective_user.id).status_post(content, |
131 | visibility=TOOT_VISIBILITY_PRIVATE, | 131 | visibility=u["tool_visibility"], |
132 | content_type=content_type, | 132 | content_type=content_type, |
133 | media_ids=[]) | 133 | media_ids=[]) |
134 | 134 | ||
@@ -208,12 +208,11 @@ async def _process_location_selection(context: ContextTypes.DEFAULT_TYPE) -> int | |||
208 | content = generate_toot_text(poi_name, "", "", context.user_data.get("latitude"), | 208 | content = generate_toot_text(poi_name, "", "", context.user_data.get("latitude"), |
209 | context.user_data.get("longitude")) | 209 | context.user_data.get("longitude")) |
210 | 210 | ||
211 | with db.connection_context(): | 211 | u = get_user_by_id(context.user_data["user_id"]) |
212 | u = User.get(User.telegram_user_id == context.user_data["user_id"]) | 212 | content_type = "text/markdown" if u["home_instance_type"] == "pleroma" else None |
213 | content_type = "text/markdown" if u.home_instance_type == "pleroma" else "text/plain" | ||
214 | 213 | ||
215 | status = get_mastodon_client(context.user_data["user_id"]).status_post(content, | 214 | status = get_mastodon_client(context.user_data["user_id"]).status_post(content, |
216 | visibility=TOOT_VISIBILITY_PRIVATE, | 215 | visibility=u["toot_visibility"], |
217 | content_type=content_type, | 216 | content_type=content_type, |
218 | media_ids=[]) | 217 | media_ids=[]) |
219 | 218 | ||
@@ -268,7 +267,7 @@ async def callback_add_comment(update: Update, context: ContextTypes.DEFAULT_TYP | |||
268 | 267 | ||
269 | with db.connection_context(): | 268 | with db.connection_context(): |
270 | u = User.get(User.telegram_user_id == context.user_data["user_id"]) | 269 | u = User.get(User.telegram_user_id == context.user_data["user_id"]) |
271 | content_type = "text/markdown" if u.home_instance_type == "pleroma" else "text/plain" | 270 | content_type = "text/markdown" if u.home_instance_type == "pleroma" else None |
272 | 271 | ||
273 | comment = update.effective_message.text | 272 | comment = update.effective_message.text |
274 | get_mastodon_client(update.effective_user.id).status_update(id=context.user_data.get(KEY_TOOT_STATUS_ID), | 273 | get_mastodon_client(update.effective_user.id).status_update(id=context.user_data.get(KEY_TOOT_STATUS_ID), |
@@ -329,7 +328,7 @@ async def callback_add_media(update: Update, context: CallbackContext): | |||
329 | 328 | ||
330 | with db.connection_context(): | 329 | with db.connection_context(): |
331 | u = User.get(User.telegram_user_id == context.user_data["user_id"]) | 330 | u = User.get(User.telegram_user_id == context.user_data["user_id"]) |
332 | content_type = "text/markdown" if u.home_instance_type == "pleroma" else "text/plain" | 331 | content_type = "text/markdown" if u.home_instance_type == "pleroma" else None |
333 | 332 | ||
334 | mastodon_client.status_update(status=status_content, | 333 | mastodon_client.status_update(status=status_content, |
335 | id=status_id, | 334 | id=status_id, |
@@ -2,7 +2,9 @@ from telegram import Update | |||
2 | from telegram.constants import ParseMode | 2 | from telegram.constants import ParseMode |
3 | from telegram.error import BadRequest | 3 | from telegram.error import BadRequest |
4 | from telegram.ext import ContextTypes, ConversationHandler | 4 | from telegram.ext import ContextTypes, ConversationHandler |
5 | from dbstore.peewee_store import get_user_access_key, get_user_home_instance, delete_user_by_id | 5 | from dbstore.peewee_store import get_user_access_key, get_user_home_instance, delete_user_by_id, update_user_visibility |
6 | from dbstore.peewee_store import get_user_by_id | ||
7 | from dbstore.peewee_store import TOOT_VISIBILITY_PRIVATE, TOOT_VISIBILITY_UNLISTED, TOOT_VISIBILITY_PUBLIC | ||
6 | from config import * | 8 | from config import * |
7 | 9 | ||
8 | 10 | ||
@@ -50,8 +52,32 @@ async def logout_command(update: Update, context: ContextTypes.DEFAULT_TYPE) -> | |||
50 | await update.message.reply_text(PROMPT_LOGOUT_SUCCESS, parse_mode=ParseMode.HTML, reply_markup=LOGIN_MENU) | 52 | await update.message.reply_text(PROMPT_LOGOUT_SUCCESS, parse_mode=ParseMode.HTML, reply_markup=LOGIN_MENU) |
51 | 53 | ||
52 | 54 | ||
53 | async def toggle_visibility_command(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None: | 55 | async def toggle_visibility_command(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int: |
54 | await update.message.reply_text(PROMPT_TOGGLE_VIS, parse_mode=ParseMode.HTML, reply_markup=MAIN_MENU) | 56 | visibility_menu = InlineKeyboardMarkup([ |
57 | [InlineKeyboardButton("Private", callback_data=TOOT_VISIBILITY_PRIVATE)], | ||
58 | [InlineKeyboardButton("Unlisted", callback_data=TOOT_VISIBILITY_UNLISTED)], | ||
59 | [InlineKeyboardButton("Public", callback_data=TOOT_VISIBILITY_PUBLIC)] | ||
60 | ]) | ||
61 | |||
62 | user = get_user_by_id(str(update.effective_user.id)) | ||
63 | await update.message.reply_text(PROMPT_TOGGLE_VIS.format(user["toot_visibility"]), | ||
64 | parse_mode=ParseMode.HTML, | ||
65 | reply_markup=visibility_menu) | ||
66 | return WAIT_VISIBILITY | ||
67 | |||
68 | |||
69 | async def callback_toggle_visibility(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int: | ||
70 | query = update.callback_query | ||
71 | await query.answer() | ||
72 | |||
73 | if query.data not in [TOOT_VISIBILITY_PRIVATE, TOOT_VISIBILITY_UNLISTED, TOOT_VISIBILITY_PUBLIC]: | ||
74 | await query.edit_message_text(text="Invalid visibility", | ||
75 | reply_markup=MAIN_MENU) | ||
76 | return ConversationHandler.END | ||
77 | |||
78 | update_user_visibility(str(update.effective_user.id), query.data) | ||
79 | await query.edit_message_text(text=f"Default visibility changed to {query.data}") | ||
80 | return ConversationHandler.END | ||
55 | 81 | ||
56 | 82 | ||
57 | async def cancel_command(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int: | 83 | async def cancel_command(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int: |
@@ -12,7 +12,7 @@ ENCRYPT_KEY = config["DEFAULT"]["ENCRYPT_KEY"] | |||
12 | 12 | ||
13 | MEDIA_GROUP_TIMEOUT = 3 | 13 | MEDIA_GROUP_TIMEOUT = 3 |
14 | 14 | ||
15 | FEDI_LOGIN, WAIT_LOCATION, LOCATION_SEARCH_KEYWORD, LOCATION_CONFIRMATION, ADD_MEDIA, ADD_COMMENT = range(6) | 15 | FEDI_LOGIN, WAIT_VISIBILITY, WAIT_LOCATION, LOCATION_SEARCH_KEYWORD, LOCATION_CONFIRMATION, ADD_MEDIA, ADD_COMMENT = range(7) |
16 | 16 | ||
17 | MAIN_MENU = ReplyKeyboardMarkup([ | 17 | MAIN_MENU = ReplyKeyboardMarkup([ |
18 | [KeyboardButton(text="Check-in here", request_location=True)], | 18 | [KeyboardButton(text="Check-in here", request_location=True)], |
diff --git a/dbstore/peewee_store.py b/dbstore/peewee_store.py index f10627b..c8d9c22 100644 --- a/dbstore/peewee_store.py +++ b/dbstore/peewee_store.py | |||
@@ -25,6 +25,31 @@ class User(BaseModel): | |||
25 | toot_visibility = CharField(max_length=128, default=TOOT_VISIBILITY_PRIVATE) | 25 | toot_visibility = CharField(max_length=128, default=TOOT_VISIBILITY_PRIVATE) |
26 | 26 | ||
27 | 27 | ||
28 | def update_user_visibility(telegram_user_id: str, visibility: str) -> int: | ||
29 | with db.connection_context(): | ||
30 | return User.update(toot_visibility=visibility).where( | ||
31 | User.telegram_user_id == telegram_user_id | ||
32 | ).execute() | ||
33 | |||
34 | |||
35 | def get_user_by_id(telegram_user_id: str) -> dict: | ||
36 | with db.connection_context(): | ||
37 | try: | ||
38 | user = User.get(User.telegram_user_id == telegram_user_id) | ||
39 | return { | ||
40 | "telegram_user_id": user.telegram_user_id, | ||
41 | "access_key": user.access_key, | ||
42 | "home_instance": user.home_instance, | ||
43 | "home_instance_type": user.home_instance_type, | ||
44 | "state": user.state, | ||
45 | "client_id": user.client_id, | ||
46 | "client_secret": user.client_secret, | ||
47 | "toot_visibility": user.toot_visibility, | ||
48 | } | ||
49 | except DoesNotExist: | ||
50 | return {} | ||
51 | |||
52 | |||
28 | def get_user_by_state(state: str) -> dict: | 53 | def get_user_by_state(state: str) -> dict: |
29 | with db.connection_context(): | 54 | with db.connection_context(): |
30 | try: | 55 | try: |
@@ -33,6 +58,7 @@ def get_user_by_state(state: str) -> dict: | |||
33 | "telegram_user_id": user.telegram_user_id, | 58 | "telegram_user_id": user.telegram_user_id, |
34 | "access_key": user.access_key, | 59 | "access_key": user.access_key, |
35 | "home_instance": user.home_instance, | 60 | "home_instance": user.home_instance, |
61 | "home_instance_type": user.home_instance_type, | ||
36 | "state": user.state, | 62 | "state": user.state, |
37 | "client_id": user.client_id, | 63 | "client_id": user.client_id, |
38 | "client_secret": user.client_secret, | 64 | "client_secret": user.client_secret, |
@@ -78,10 +104,6 @@ class Location(BaseModel): | |||
78 | longitude = CharField(max_length=128) | 104 | longitude = CharField(max_length=128) |
79 | 105 | ||
80 | 106 | ||
81 | with db.connection_context(): | ||
82 | db.create_tables([User, Location]) | ||
83 | |||
84 | |||
85 | def get_poi_by_fsq_id(fsq_id) -> dict: | 107 | def get_poi_by_fsq_id(fsq_id) -> dict: |
86 | with db.connection_context(): | 108 | with db.connection_context(): |
87 | try: | 109 | try: |
@@ -107,3 +129,7 @@ def create_or_update_poi(poi: dict) -> int: | |||
107 | latitude=poi["latitude"], | 129 | latitude=poi["latitude"], |
108 | longitude=poi["longitude"], | 130 | longitude=poi["longitude"], |
109 | ).on_conflict_replace().execute() | 131 | ).on_conflict_replace().execute() |
132 | |||
133 | |||
134 | with db.connection_context(): | ||
135 | db.create_tables([User, Location]) | ||
diff --git a/prompt/string.py b/prompt/string.py index b7aeff1..2fe13f6 100644 --- a/prompt/string.py +++ b/prompt/string.py | |||
@@ -34,8 +34,7 @@ PROMPT_HELP = "Available commands:" \ | |||
34 | "You can use this command to login to multiple Fediverse accounts" \ | 34 | "You can use this command to login to multiple Fediverse accounts" \ |
35 | "\n`/list` - list current linked Fediverse accounts" \ | 35 | "\n`/list` - list current linked Fediverse accounts" \ |
36 | "\n`/logout [number]` - logout from specified Fediverse account, default logout from all" \ | 36 | "\n`/logout [number]` - logout from specified Fediverse account, default logout from all" \ |
37 | "\n`/vis public|private|unlisted [number]` - " \ | 37 | "\n`/vis` - toggle visibility of your checkins on specified instances, default=private" \ |
38 | "toggle visibility of your checkins on specified instances, default=private" \ | ||
39 | "\n`/tos` - show ToS message" \ | 38 | "\n`/tos` - show ToS message" \ |
40 | "\n`/cancel` - cancel current operation during checkins" | 39 | "\n`/cancel` - cancel current operation during checkins" |
41 | 40 | ||
@@ -43,6 +42,6 @@ PROMPT_LIST = "You are linked with the following Fediverse accounts:" | |||
43 | PROMPT_LIST_NO_RESULT = "You are not linked with any Fediverse account yet. \n\n Input <code>/login</code> to login." | 42 | PROMPT_LIST_NO_RESULT = "You are not linked with any Fediverse account yet. \n\n Input <code>/login</code> to login." |
44 | PROMPT_LOGOUT = "Choose Fediverse account to logout" | 43 | PROMPT_LOGOUT = "Choose Fediverse account to logout" |
45 | PROMPT_LOGOUT_SUCCESS = "Successfully logged out from Fediverse account" | 44 | PROMPT_LOGOUT_SUCCESS = "Successfully logged out from Fediverse account" |
46 | PROMPT_TOGGLE_VIS = "Choose visibility of your checkins on Fediverse" | 45 | PROMPT_TOGGLE_VIS = "Change default toot visibility of your checkins on Fediverse.\n<b>Current</b>: {}" |
47 | 46 | ||
48 | CALLBACK_SKIP = "Skip" | 47 | CALLBACK_SKIP = "Skip" |