-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathMyFeedsBot.py
129 lines (107 loc) · 4.91 KB
/
MyFeedsBot.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
import logging
import asyncio
import telepot_adapter
import subscriptions_manager
logging.basicConfig(
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
filename='infolog.log',
level=logging.INFO)
class MyFeedsBot(telepot_adapter.BotAdapter):
def __init__(self, token, update_period=600):
super().__init__(token)
self.logger = logging.getLogger(__name__)
self.start_message = 'Welcome to this feed bot! Try to /add something'
# TODO decide how to configure messages (e.g. "which subreddit would you ...")
self.add_command('add', callback=self.on_add, expectedType=list,
question='What would you like to add?')
self.add_command('list', callback=self.on_list)
self.add_command('start', callback=self.on_start)
self.add_command('remove', callback=self.on_remove,
expectedType=list, question='What would you like to remove?')
# TODO add more/less/update_threshold
self.update_period = update_period
async def on_start(self, chat_id):
await self.send(chat_id, self.start_message)
async def on_add(self, chat_id, sources):
for source in sources:
try:
await self.new_posts(source)
except Exception as e:
print(e)
await self.send(chat_id, f'Cannot get posts from {source}')
threshold = await self.default_threshold(source)
subscriptions_manager.subscribe(chat_id, source, threshold)
await self.on_list(chat_id)
await self.send_updates()
async def on_remove(self, chat_id, sources):
for source in sources:
subscriptions_manager.unsubscribe(chat_id, source)
await self.on_list(chat_id)
async def on_moar(self, chat_id, source):
pass
async def on_less(self, chat_id, source):
pass
async def on_list(self, chat_id):
subscriptions = subscriptions_manager.user_subscriptions(chat_id)
message = 'You are now subscribed to:\n'
message += '\n'.join(
[f'{source}, threshold: {threshold}' for source, threshold in subscriptions])
await self.send(chat_id, message)
def format(self, post):
return repr(post)
def score(self, post):
return 0
async def default_threshold(self, source):
return 0
async def new_posts(self, source):
raise NotImplementedError("You must implement a new_posts method")
async def send_formatted_post(self, chat_id, post):
await self.send(chat_id, self.format(post),
show_keyboard=False, parse_mode="HTML")
async def send_post(self, chat_id, post):
# TODO rate limiting
if subscriptions_manager.already_sent(chat_id, post.id):
return
try:
await self.send_formatted_post(chat_id, post)
except Exception as e:
print(e)
self.logger.error('Failed to send {} to {}'.format(post, chat_id))
self.logger.error(e)
unsub_reasons = [
'chat not found', 'bot was blocked by the user',
'user is deactivated', 'chat not found', 'bot was kicked'
]
if any(reason in str(e) for reason in unsub_reasons):
self.logger.warning('Unsubscribing user {}'.format(chat_id))
for sub, th, pm in subscriptions_manager.user_subscriptions(
chat_id):
subscriptions_manager.unsubscribe(chat_id, sub)
await self.send(80906134, 'Unsibscribing:\n' + str(e))
elif (hasattr(e, 'json')
and 'group chat was upgraded to a supergroup chat' in
e.json['description']):
self.logger.warning('Resubscribing group {}'.format(chat_id))
for sub, th in subscriptions_manager.user_subscriptions(chat_id):
subscriptions_manager.subscribe(
e.json['parameters']['migrate_to_chat_id'], sub, th)
subscriptions_manager.unsubscribe(chat_id, sub)
else:
await self.send(80906134, str(e))
subscriptions_manager.mark_as_sent(chat_id, post.id)
async def send_source_updates(self, source):
subscriptions = subscriptions_manager.get_subscriptions(source)
post_iterator = await self.new_posts(source)
for post in post_iterator:
for chat_id, threshold in subscriptions:
if post.score >= threshold:
await self.send_post(chat_id, post)
async def send_updates(self):
for source in subscriptions_manager.all_sources():
await self.send_source_updates(source)
print("Sent updates")
async def run_feed(self):
print("Running?")
while True:
await self.send_updates()
await asyncio.sleep(self.update_period)