Skip to content

Commit 09c1984

Browse files
committed
Add /library_versions
Admin only command.
1 parent c81140d commit 09c1984

File tree

2 files changed

+43
-9
lines changed

2 files changed

+43
-9
lines changed

README.md

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,25 +4,26 @@
44
## What this does
55
This is a telegram bot that attempts to create URL hacks that help people read news sites with user hostile designs.
66

7-
Add the bot to a group chat and make it an admin so it can see all messages. Or talk to it in pm.
7+
Add the bot to a group chat and make it an admin so it can see all messages. Or talk to it in Private Chat.
88

99
Regular users can use the bot as follows:
1010
* Post messages as usual. The bot will silently detect and remember the most recent link it sees.
11-
When you know that the the most recent link needs to get the bot treatment you say `/include`.
11+
When the most recent link needs the bot treatment, say `/include`.
1212
Immediately and from now on the bot will attempt to post a list of bypass links for all urls from that domain.
1313
You can also send `/include` as a reply to a message to target the domain in that message even if it isn't the most recent one anymore. Or you can add domains manually with `/include domain.tld`.
1414
Messages with multiple links are treated as though only the first link exists, even if the first link needs no action and a subsequent one does.
1515
* `/list` will show all the domains the bot is set to act on.
16-
* `/remove domain.tld` to remove one.
16+
* `/remove domain.tld` to remove domain.
1717
* Reply to a bot message with `/delete` and the bot will delete that message and your `/delete` message too (if it can) to keep things tidy.
18-
Only works on bot messages less than 48 hours old (telegram restriction) or less than 10 bot messages ago (bot restriction).
18+
Only works on bot messages less than 48 hours old (telegram restriction) and less than 10 bot messages ago (bot restriction).
1919

2020
Additionally, users can request a google translate version of the most recent link by sending `/translate`.
2121
`/translate` defaults to english but will also accept a list of ISO-639-1 language codes. For example `/translate en fr es` will produce 3 translate links.
2222

2323
As a bot admin you have some commands that only you can run:
2424
`/data` - Show all the stored data for the chat where you sent the command from.
25-
`/data clear <key>` - delete all the data in `<key>`.
25+
`/data clear <key>` - Delete all the data in `<key>`.
26+
`/library_versions` - Show the versions of all installed libraries and highlight any that are out of date.
2627
If the bot throws an exception it will send it to you in a private message.
2728
The bot will spit out log messages at the info level when messages come in or out. It does not attempt to permanently save these logs anywhere.
2829
Data stored by the bot (like the list of domains to bypass) lives in `data/bot.persist`.
@@ -32,8 +33,8 @@ Ideally new versions of the bot will be backward compatible with the existing `d
3233
But just in case, the list of domains to bypass can be exported per group with the `/export` command. This will create a simple text file with the domains listed in it. The filename will be `{chat_id}_urls_backup.txt`.
3334
To import this list back into the bot you just upload a text file with the exact filename to match the chat you're in. You can even forward the message from `/export` back into the chat and not have to download the file.
3435

35-
Anyone can check the running version of the bot as well as the latest version available (if not the same) by sending `/version`.
36-
You can also run `/start` to find the chat_id to use for this filename, and your user_id to use in the list of admins.
36+
Anyone can check the running version of the bot as well as the latest version available (if not the same) by using `/version`, but `/library_versons` is admin only.
37+
Anyone can also run `/start` to find the chat_id to use for this filename, and their user_id to use in the list of admins.
3738

3839
## Setup
3940
Clone this repo and `cd` into it.

bot.py

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
'''Telegram bot that (primarily) attempts to perform url hacks to get around paywalls'''
22

33

4-
__version__ = '2.3.1'
4+
__version__ = '2.4.0'
55

66

77
import asyncio
@@ -25,6 +25,7 @@
2525
from urlextract import URLExtract
2626

2727
from data.secrets import LIST_OF_ADMINS, TOKEN # If it crashed here it's because you didn't create secrets.py correctly (or at all). Or you didn't pass docker run -v /full/path/to/data/:/home/botuser/data/
28+
import subprocess
2829

2930

3031
logging.basicConfig(format='%(asctime)s - %(levelname)s %(message)s', level=logging.INFO)
@@ -117,6 +118,37 @@ async def chat_data(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
117118
await say(html.escape(text), update, context)
118119

119120

121+
@log
122+
@send_typing_action
123+
async def library_versions(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
124+
'''Show installed library versions and the latest available versions online'''
125+
126+
installed_result = subprocess.run(['pip', 'list', '--format=columns'], capture_output=True, text=True)
127+
outdated_result = subprocess.run(['pip', 'list', '--outdated', '--format=columns'], capture_output=True, text=True)
128+
129+
installed_libraries = installed_result.stdout.splitlines()
130+
outdated_libraries = outdated_result.stdout.splitlines()
131+
132+
outdated_dict = {line.split()[0]: line.split()[2] for line in outdated_libraries[2:]}
133+
134+
response = [installed_libraries[0]] # Headers
135+
for line in installed_libraries[2:]:
136+
lib_name = line.split()[0]
137+
if lib_name in outdated_dict:
138+
response.append(f"{line} (latest: {outdated_dict[lib_name]})")
139+
else:
140+
response.append(line)
141+
142+
further_instructions = ''
143+
if outdated_dict:
144+
further_instructions = "To update all outdated libraries, run:\n<code>pip list --outdated | awk 'NR>2 {print $1}' | xargs -n1 pip install -U</code>"
145+
146+
text = html.escape("\n".join(response))
147+
148+
if text:
149+
await say(f'<pre>{text}</pre>{further_instructions}', update, context)
150+
151+
120152
# internal bot helper stuff
121153
async def say(text: str, update: Update, context: ContextTypes.DEFAULT_TYPE) -> int | None:
122154
'''Send text to channel'''
@@ -236,7 +268,7 @@ async def wayback(url: str, client: httpx.AsyncClient) -> str | None:
236268
archive_org_url = r.json().get('archived_snapshots', {}).get('closest', {}).get('url')
237269
if archive_org_url:
238270
return archive_org_url
239-
271+
240272
except httpx.TimeoutException:
241273
pass
242274

@@ -581,6 +613,7 @@ async def post_init(application: Application) -> None:
581613

582614
application.add_handler(CommandHandler('start', start))
583615
application.add_handler(CommandHandler('version', version))
616+
application.add_handler(CommandHandler('library_versions', library_versions, filters=filters.User(user_id=LIST_OF_ADMINS)))
584617
application.add_handler(CommandHandler('translate', translate))
585618
application.add_handler(CommandHandler('include', include))
586619
application.add_handler(CommandHandler('remove', remove))

0 commit comments

Comments
 (0)