repos
/
irgramd
/ annotate_shade
telegram, service: Move initial help to service module
Annotate for file /service.py
2022-03-02 E.
1
# irgramd: IRC-Telegram gateway
19:18:03 '
2
# service.py: IRC service/control command handlers
'
3
#
2023-03-29 E.
4
# Copyright (c) 2022,2023 E. Bosch <presidev@AT@gmail.com>
2022-03-02 E.
5
#
19:18:03 '
6
# Use of this source code is governed by a MIT style license that
'
7
# can be found in the LICENSE file included in this project.
'
8
2023-06-25 E.
9
from utils import compact_date, command, HELP
2023-03-18 E.
10
from telethon import utils as tgutils
2022-03-19 E.
11
2023-06-22 E.
12
class service(command):
2022-03-08 E.
13
def __init__(self, settings, telegram):
2022-03-02 E.
14
self.commands = \
2023-06-25 E.
15
{ # Command Handler Arguments Min Max Maxsplit
22:17:22 '
16
'code': (self.handle_command_code, 1, 1, -1),
'
17
'dialog': (self.handle_command_dialog, 1, 2, -1),
'
18
'get': (self.handle_command_get, 2, 2, -1),
'
19
'help': (self.handle_command_help, 0, 1, -1),
'
20
'history': (self.handle_command_history, 1, 3, -1),
'
21
'mark_read': (self.handle_command_mark_read, 1, 1, -1),
2022-03-02 E.
22
}
2022-03-08 E.
23
self.ask_code = settings['ask_code']
21:58:55 '
24
self.tg = telegram
2023-05-04 E.
25
self.irc = telegram.irc
2022-03-19 E.
26
self.tmp_ircnick = None
22:26:56 '
27
2024-10-06 E.
28
def initial_help(self):
22:07:54 '
29
return (
'
30
'Welcome to irgramd service',
'
31
'use /msg {} help'.format(self.irc.service_user.irc_nick),
'
32
'or equivalent in your IRC client',
'
33
'to get help',
'
34
)
'
35
2022-03-08 E.
36
async def handle_command_code(self, code=None, help=None):
21:58:55 '
37
if not help:
'
38
if self.ask_code:
'
39
reply = ('Code will be asked on console',)
'
40
elif code.isdigit():
'
41
try:
'
42
await self.tg.telegram_client.sign_in(code=code)
'
43
except:
'
44
reply = ('Invalid code',)
'
45
else:
'
46
reply = ('Valid code', 'Telegram account authorized')
'
47
await self.tg.continue_auth()
'
48
else: # not isdigit
'
49
reply = ('Code must be numeric',)
'
50
'
51
else: # HELP.brief or HELP.desc (first line)
2023-05-07 E.
52
reply = (' code Enter authorization code',)
2022-03-08 E.
53
if help == HELP.desc: # rest of HELP.desc
21:58:55 '
54
reply += \
'
55
(
'
56
' code <code>',
'
57
'Enter authorization code sent by Telegram to the phone or to',
'
58
'another client connected.',
'
59
'This authorization code usually is only needed the first time',
'
60
'that irgramd connects to Telegram with a given account.',
2022-03-19 E.
61
)
22:26:56 '
62
return reply
'
63
'
64
async def handle_command_dialog(self, command=None, id=None, help=None):
'
65
if not help:
'
66
if command == 'archive':
'
67
pass
'
68
elif command == 'delete':
'
69
pass
'
70
elif command == 'list':
'
71
reply = \
'
72
(
'
73
'Dialogs:',
2023-04-11 E.
74
' {:<11} {:<9} {:<9} {:5} {:<3} {:<4} {:<6} {}'.format(
2022-03-19 E.
75
'Id', 'Unread', 'Mentions', 'Type', 'Pin', 'Arch', 'Last', 'Name'),
22:26:56 '
76
)
'
77
async for dialog in self.tg.telegram_client.iter_dialogs():
2023-03-18 E.
78
id, type = tgutils.resolve_id(dialog.id)
2022-03-19 E.
79
unr = dialog.unread_count
22:26:56 '
80
men = dialog.unread_mentions_count
2023-04-11 E.
81
ty = self.tg.get_entity_type(dialog.entity, format='short')
2022-03-19 E.
82
pin = 'Yes' if dialog.pinned else 'No'
22:26:56 '
83
arch = 'Yes' if dialog.archived else 'No'
2023-05-07 E.
84
last = compact_date(dialog.date, self.tg.timezone)
2023-03-18 E.
85
if id == self.tg.id:
04:12:31 '
86
name_in_irc = self.tmp_ircnick
'
87
else:
2023-12-02 E.
88
name_in_irc = self.tg.get_irc_name_from_telegram_id(id)
19:41:44 '
89
2023-04-11 E.
90
reply += (' {:<11d} {:<9d} {:<9d} {:5} {:<3} {:<4} {:<6} {}'.format(
2022-03-19 E.
91
id, unr, men, ty, pin, arch, last, name_in_irc),
22:26:56 '
92
)
'
93
'
94
else: # HELP.brief or HELP.desc (first line)
2023-05-07 E.
95
reply = (' dialog Manage conversations (dialogs)',)
2022-03-19 E.
96
if help == HELP.desc: # rest of HELP.desc
22:26:56 '
97
reply += \
'
98
(
'
99
' dialog <subcommand> [id]',
'
100
'Manage conversations (dialogs) established in Telegram, the',
'
101
'following subcommands are available:',
2024-04-18 E.
102
# ' archive <id> Archive the dialog specified by id',
23:11:38 '
103
# ' delete <id> Delete the dialog specified by id',
2022-03-19 E.
104
' list Show all dialogs',
2023-05-13 E.
105
)
22:39:42 '
106
return reply
'
107
'
108
async def handle_command_get(self, peer=None, mid=None, help=None):
'
109
if not help:
2023-05-16 E.
110
msg = None
2023-05-13 E.
111
peer_id, reply = self.get_peer_id(peer.lower())
22:39:42 '
112
if reply: return reply
2023-05-16 E.
113
else: reply = ()
2023-05-13 E.
114
2023-11-28 E.
115
# If the ID starts with '=' is absolute ID, not compact ID
21:38:01 '
116
# character '=' is not used by compact IDs
'
117
if mid[0] == '=':
'
118
id = int(mid[1:])
'
119
else:
'
120
id = self.tg.mid.id_to_num_offset(peer_id, mid)
2023-05-16 E.
121
if id is not None:
21:13:51 '
122
msg = await self.tg.telegram_client.get_messages(entity=peer_id, ids=id)
'
123
if msg is not None:
'
124
await self.tg.handle_telegram_message(event=None, message=msg, history=True)
'
125
else:
2023-06-25 E.
126
reply = ('Message not found',)
2023-05-13 E.
127
return reply
22:39:42 '
128
'
129
else: # HELP.brief or HELP.desc (first line)
'
130
reply = (' get Get a message by id and peer',)
'
131
if help == HELP.desc: # rest of HELP.desc
'
132
reply += \
'
133
(
2023-11-28 E.
134
' get <peer> <compact_id|=ID>',
21:38:01 '
135
'Get one message from peer with the compact or absolute ID',
2022-03-08 E.
136
)
21:58:55 '
137
return reply
'
138
'
139
async def handle_command_help(self, help_command=None, help=None):
2022-03-06 E.
140
01:36:51 '
141
start_help = ('*** Telegram Service Help ***',)
'
142
end_help = ('*** End of Help ***',)
'
143
2022-03-08 E.
144
if help == HELP.brief:
2023-05-07 E.
145
help_text = (' help This help',)
2022-03-08 E.
146
elif not help_command or help_command == 'help':
2022-03-06 E.
147
help_text = start_help
01:36:51 '
148
help_text += \
'
149
(
'
150
'This service contains specific Telegram commands that irgramd',
'
151
'cannot map to IRC commands. The following commands are available:',
'
152
)
'
153
for command in self.commands.values():
'
154
handler = command[0]
2022-03-08 E.
155
help_text += await handler(help=HELP.brief)
2022-03-06 E.
156
help_text += \
01:36:51 '
157
(
2023-06-25 E.
158
'The commands begining with ! (exclamation) must be used directly',
22:17:22 '
159
'in channels or chats. The following ! commands are available:',
'
160
)
'
161
for command in self.irc.exclam.commands.values():
'
162
handler = command[0]
'
163
help_text += await handler(help=HELP.brief)
'
164
help_text += \
'
165
(
2022-03-06 E.
166
'If you need more information about a specific command you can use',
01:36:51 '
167
'help <command>',
'
168
)
'
169
help_text += end_help
2023-06-25 E.
170
elif help_command in (all_commands := dict(**self.commands, **self.irc.exclam.commands)).keys():
22:17:22 '
171
handler = all_commands[help_command][0]
2022-03-06 E.
172
help_text = start_help
2022-03-08 E.
173
help_text += await handler(help=HELP.desc)
2022-03-06 E.
174
help_text += end_help
01:36:51 '
175
else:
'
176
help_text = ('help: Unknown command',)
'
177
return help_text
'
178
2023-05-04 E.
179
async def handle_command_history(self, peer=None, limit='10', add_unread=None, help=None):
22:23:04 '
180
if not help:
'
181
async def get_unread(tgt):
'
182
async for dialog in self.tg.telegram_client.iter_dialogs():
'
183
id, type = tgutils.resolve_id(dialog.id)
'
184
if id in self.tg.tid_to_iid.keys():
'
185
name = self.tg.tid_to_iid[id]
'
186
if tgt == name.lower():
'
187
count = dialog.unread_count
'
188
reply = None
'
189
break
'
190
else:
'
191
count = None
'
192
reply = ('Unknown unread',)
'
193
return count, reply
'
194
'
195
def conv_int(num_str):
'
196
if num_str.isdigit():
'
197
n = int(num_str)
'
198
err = None
'
199
else:
'
200
n = None
'
201
err = ('Invalid argument',)
'
202
return n, err
'
203
'
204
tgt = peer.lower()
2023-05-07 E.
205
peer_id, reply = self.get_peer_id(tgt)
2023-05-04 E.
206
if reply: return reply
22:23:04 '
207
'
208
if limit == 'unread':
'
209
add_unread = '0' if add_unread is None else add_unread
'
210
add_unread_int, reply = conv_int(add_unread)
'
211
if reply: return reply
'
212
'
213
li, reply = await get_unread(tgt)
'
214
if reply: return reply
'
215
li += add_unread_int
'
216
elif add_unread is not None:
'
217
reply = ('Wrong number of arguments',)
'
218
return reply
'
219
elif limit == 'all':
'
220
li = None
'
221
else:
'
222
li, reply = conv_int(limit)
'
223
if reply: return reply
'
224
'
225
his = await self.tg.telegram_client.get_messages(peer_id, limit=li)
'
226
for msg in reversed(his):
2023-05-06 E.
227
await self.tg.handle_telegram_message(event=None, message=msg, history=True)
2023-05-04 E.
228
reply = ()
22:23:04 '
229
return reply
'
230
'
231
else: # HELP.brief or HELP.desc (first line)
2023-05-07 E.
232
reply = (' history Get messages from history',)
2023-05-04 E.
233
if help == HELP.desc: # rest of HELP.desc
22:23:04 '
234
reply += \
'
235
(
'
236
' history <peer> [<limit>|all|unread [<plusN>]]',
'
237
'Get last <limit> number of messages already sent to <peer>',
'
238
'(channel or user). If not set <limit> is 10.',
'
239
'Instead of <limit>, "unread" is for messages not marked as read,',
'
240
'optionally <plusN> number of previous messages to the first unread.',
'
241
'Instead of <limit>, "all" is for retrieving all available messages',
'
242
'in <peer>.',
'
243
)
'
244
return reply
2022-03-06 E.
245
2023-05-07 E.
246
async def handle_command_mark_read(self, peer=None, help=None):
23:04:52 '
247
if not help:
'
248
peer_id, reply = self.get_peer_id(peer.lower())
'
249
if reply: return reply
'
250
'
251
await self.tg.telegram_client.send_read_acknowledge(peer_id, clear_mentions=True)
'
252
reply = ('',)
'
253
else: # HELP.brief or HELP.desc (first line)
2023-05-07 E.
254
reply = (' mark_read Mark messages as read',)
2023-05-07 E.
255
if help == HELP.desc: # rest of HELP.desc
23:04:52 '
256
reply += \
'
257
(
'
258
' mark_read <peer>',
'
259
'Mark all messages on <peer> (channel or user) as read, this also will',
2024-08-29 E.
260
'reset the number of mentions to you on <peer>.',
2023-05-07 E.
261
)
23:04:52 '
262
return reply
'
263
'
264
def get_peer_id(self, tgt):
'
265
if tgt in self.irc.users or tgt in self.irc.irc_channels:
'
266
peer_id = self.tg.get_tid(tgt)
'
267
reply = None
'
268
else:
'
269
peer_id = None
'
270
reply = ('Unknown user or channel',)
'
271
return peer_id, reply