aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorclarkzjw <[email protected]>2023-02-23 21:46:27 -0800
committerclarkzjw <[email protected]>2023-02-23 21:46:27 -0800
commita9fb6f252553ae49a2ba372434073824babe31e4 (patch)
tree77d53a16f1d7565f6da6490d2cad4e4321995549
parentcbfde03e620188d80213a8b15a4dffdb8948b257 (diff)
downloadswarm2fediverse-a9fb6f252553ae49a2ba372434073824babe31e4.tar.gz
bot: support changing default toot visibility
-rw-r--r--bot.py22
-rw-r--r--callback.py21
-rw-r--r--command.py32
-rw-r--r--config.py2
-rw-r--r--dbstore/peewee_store.py34
-rw-r--r--prompt/string.py5
6 files changed, 91 insertions, 25 deletions
diff --git a/bot.py b/bot.py
index aea62af..1d59f9e 100644
--- a/bot.py
+++ b/bot.py
@@ -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
61from prompt.string import PROMPT_CHOOSE_ACTION 63from 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,
diff --git a/command.py b/command.py
index b12483a..f124e2a 100644
--- a/command.py
+++ b/command.py
@@ -2,7 +2,9 @@ from telegram import Update
2from telegram.constants import ParseMode 2from telegram.constants import ParseMode
3from telegram.error import BadRequest 3from telegram.error import BadRequest
4from telegram.ext import ContextTypes, ConversationHandler 4from telegram.ext import ContextTypes, ConversationHandler
5from dbstore.peewee_store import get_user_access_key, get_user_home_instance, delete_user_by_id 5from dbstore.peewee_store import get_user_access_key, get_user_home_instance, delete_user_by_id, update_user_visibility
6from dbstore.peewee_store import get_user_by_id
7from dbstore.peewee_store import TOOT_VISIBILITY_PRIVATE, TOOT_VISIBILITY_UNLISTED, TOOT_VISIBILITY_PUBLIC
6from config import * 8from 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
53async def toggle_visibility_command(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None: 55async 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
69async 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
57async def cancel_command(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int: 83async def cancel_command(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int:
diff --git a/config.py b/config.py
index 9b52205..0fae9b1 100644
--- a/config.py
+++ b/config.py
@@ -12,7 +12,7 @@ ENCRYPT_KEY = config["DEFAULT"]["ENCRYPT_KEY"]
12 12
13MEDIA_GROUP_TIMEOUT = 3 13MEDIA_GROUP_TIMEOUT = 3
14 14
15FEDI_LOGIN, WAIT_LOCATION, LOCATION_SEARCH_KEYWORD, LOCATION_CONFIRMATION, ADD_MEDIA, ADD_COMMENT = range(6) 15FEDI_LOGIN, WAIT_VISIBILITY, WAIT_LOCATION, LOCATION_SEARCH_KEYWORD, LOCATION_CONFIRMATION, ADD_MEDIA, ADD_COMMENT = range(7)
16 16
17MAIN_MENU = ReplyKeyboardMarkup([ 17MAIN_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
28def 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
35def 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
28def get_user_by_state(state: str) -> dict: 53def 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
81with db.connection_context():
82 db.create_tables([User, Location])
83
84
85def get_poi_by_fsq_id(fsq_id) -> dict: 107def 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
134with 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:"
43PROMPT_LIST_NO_RESULT = "You are not linked with any Fediverse account yet. \n\n Input <code>/login</code> to login." 42PROMPT_LIST_NO_RESULT = "You are not linked with any Fediverse account yet. \n\n Input <code>/login</code> to login."
44PROMPT_LOGOUT = "Choose Fediverse account to logout" 43PROMPT_LOGOUT = "Choose Fediverse account to logout"
45PROMPT_LOGOUT_SUCCESS = "Successfully logged out from Fediverse account" 44PROMPT_LOGOUT_SUCCESS = "Successfully logged out from Fediverse account"
46PROMPT_TOGGLE_VIS = "Choose visibility of your checkins on Fediverse" 45PROMPT_TOGGLE_VIS = "Change default toot visibility of your checkins on Fediverse.\n<b>Current</b>: {}"
47 46
48CALLBACK_SKIP = "Skip" 47CALLBACK_SKIP = "Skip"
Powered by cgit v1.2.3 (git 2.41.0)