-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsholis_bot.py
234 lines (190 loc) · 8.08 KB
/
sholis_bot.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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
"""
The python bot.
It gets the commands from the chats and processes them. As data structure is uses the
ShoppingList class. To get the images it imports google_images_download. If you
encounter any problems please visit my fork
https://github.com/therealpeterpython/google-images-download.
therealpeterpython - [email protected]
2019
"""
import telegram
from telegram.ext import Updater, Filters, CommandHandler, MessageHandler
import logging
from google_images_download import google_images_download
from sholis import ShoppingList
import pickle
import os
config = {"path_lists": "./shopping_lists", "path_images":"./images", "path_token":"./token"}
# Download an image
def download_images(query):
print("download_images")
arguments = {"keywords": query,
"limit":1,
"thumbnail_only": True,
"output_directory":config["path_images"]
}
response = google_images_download.googleimagesdownload()
try:
path = response.download(arguments)[0][query][0]
return path
except FileNotFoundError:
pass
# Load or create a shopping list
def load(bot, chat_id):
print("load chat_id: {}".format(chat_id))
load_path = os.path.join(config["path_lists"], str(chat_id))
if not os.path.isfile(load_path): # create or load?
slist = ShoppingList()
save(chat_id, slist)
msg = "I've created a new shopping list for you!"
bot.send_message(chat_id=chat_id, text=msg)
else:
with open(load_path, "rb") as fp:
slist = pickle.load(fp)
return slist
# Save a shopping list
def save(chat_id, slist):
print("save chat_id: {}".format(chat_id))
os.makedirs(config["path_lists"], exist_ok=True)
save_path = os.path.join(config["path_lists"], str(chat_id))
with open(save_path, "wb") as fp:
pickle.dump(slist, fp)
# Start the bot
def start(bot, update):
print("start chat_id: {}".format(update.message.chat_id))
help(bot, update)
# Add on or more comma or newline seperated items
def add_item(bot, update):
print("add_item chat_id: {}".format(update.message.chat_id))
chat_id = update.message.chat_id
text = update.message.text
try:
items = text[text.index(" ")+1:]
except ValueError:
msg = "There was no item to add!"
bot.send_message(chat_id=chat_id, text=msg)
return
items = [item.strip() for item in items.replace("\n", ",").split(",") if item.strip()] # convert newline to comma and split
if not items:
msg = "There was no item to add!"
bot.send_message(chat_id=chat_id, text=msg)
return
slist = load(bot, chat_id)
slist.add_items(items)
save(chat_id, slist)
msg = "I've added the items for you!"
bot.send_message(chat_id=chat_id, text=msg)
# Remove one or more items
def remove_items(bot, update, args):
print("remove_items chat_id: {}".format(update.message.chat_id))
chat_id = update.message.chat_id
slist = load(bot, chat_id)
try:
positions = [int(index) for l in args for index in l.split(",") if index] # split at commas and cast to int
print(positions)
except ValueError:
msg = "Please use the item ids!"
bot.send_message(chat_id=chat_id, text=msg)
return
slist.remove_items(positions)
save(chat_id, slist)
if not len(args):
msg = "Nothing to delete!"
else:
msg = "I've removed that for you!"
bot.send_message(chat_id=chat_id, text=msg)
# Remove all items
def remove_all(bot, update, args):
print("remove_all chat_id: {}".format(update.message.chat_id))
chat_id = update.message.chat_id
if len(args) == 1 and args[0] == "clear":
slist = load(bot, chat_id)
slist.remove_all()
save(chat_id, slist)
msg = "I've cleared the list for you!"
bot.send_message(chat_id=chat_id, text=msg)
else:
msg = "If you want to clear the entire list, enter the command and the word 'clear'!"
bot.send_message(chat_id=chat_id, text=msg)
# Show the list
def view_list(bot, update):
print("view_list chat_id: {}".format(update.message.chat_id))
chat_id = update.message.chat_id
slist = load(bot, chat_id)
if not slist.empty():
bot.send_message(chat_id=chat_id, text=slist.pprint_basic(), disable_web_page_preview=True)
else:
bot.send_message(chat_id=chat_id, text="There are no elements in your list!")
# Show the list with timestamps
def view_times(bot, update):
print("view_times chat_id: {}".format(update.message.chat_id))
chat_id = update.message.chat_id
slist = load(bot, chat_id)
if not slist.empty():
bot.send_message(chat_id=chat_id, text=slist.pprint_full(), disable_web_page_preview=True)
else:
bot.send_message(chat_id=chat_id, text="There are no elements in your list!")
# Download an image
def image(bot, update, args):
print("image chat_id: {}".format(update.message.chat_id))
chat_id = update.message.chat_id
items = load(bot, chat_id).get_items()
for arg in args:
try:
arg = items[int(arg)]
except ValueError:
pass
try:
path = download_images(arg)
if path:
bot.send_message(chat_id=chat_id, text=arg, disable_web_page_preview=True)
bot.send_photo(chat_id=chat_id, photo=open(path, 'rb'))
else:
bot.send_message(chat_id=chat_id, text="Cant find an image for '{}' you :(".format(arg))
except UnicodeDecodeError:
bot.send_message(chat_id=chat_id, text="Umlauts for images are not supported yet!")
raise
def all_images(bot, update):
print("all_images chat_id: {}".format(update.message.chat_id))
chat_id = update.message.chat_id
items = load(bot, chat_id).get_items()
image(bot, update, list(range(len(items))))
# Writes the help
def help(bot, update):
print("help chat_id: {}".format(update.message.chat_id))
help_msg = 'I am your shopping list bot: Sholibo!\n'
help_msg += 'There are six commands to control me:\n'
help_msg += '(1) With /add <name> you can add multiple comma or newline seperated items to your list,\n'
help_msg += '(2) With /list you get an enumeration of your items,\n'
help_msg += '(3) With /remove <number> you can remove items of your list,\n'
help_msg += '(4) With /clear clear you delete the full list (be carefull),\n'
help_msg += '(5) With /whatis <number> you get an image of the product,\n'
help_msg += '(6) With /help you get this help again.\n\n'
help_msg += 'Have fun shopping!'
bot.send_message(chat_id=update.message.chat_id, text=help_msg)
# Main, register all the handels and start the polling
def main():
# Logging the warnings and errors
logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', level=logging.INFO)
# Get the bot token
with open(config["path_token"], "r") as fp:
token = fp.read()
# Get the updater, dispatcher and bot
updater = Updater(token=token)
dispatcher = updater.dispatcher
# Add handler
dispatcher.add_handler(CommandHandler('start', start))
dispatcher.add_handler(CommandHandler('add', add_item))
dispatcher.add_handler(CommandHandler('list', view_list))
dispatcher.add_handler(CommandHandler('times', view_times))
dispatcher.add_handler(CommandHandler('remove', remove_items, pass_args=True))
dispatcher.add_handler(CommandHandler('clear', remove_all, pass_args=True))
dispatcher.add_handler(CommandHandler('whatis', image, pass_args=True))
dispatcher.add_handler(CommandHandler('whatiseverything', all_images))
dispatcher.add_handler(CommandHandler('help', help))
print("I am ready! :)")
# Get the updates
updater.start_polling()
updater.idle()
print("Bye bye")
if __name__ == "__main__": main()