-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathTooGoodToGo.py
More file actions
189 lines (170 loc) · 9.92 KB
/
TooGoodToGo.py
File metadata and controls
189 lines (170 loc) · 9.92 KB
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
import json
from _thread import start_new_thread
import time
from datetime import datetime, timezone
from telebot import TeleBot, types
from tgtg import TgtgClient
class TooGoodToGo:
users_login_data = {}
users_settings_data = {}
available_items_favorites = {}
connected_clients = {}
client = TgtgClient
def __init__(self, bot_token):
self.bot = TeleBot(bot_token)
self.read_users_login_data_from_txt()
self.read_users_settings_data_from_txt()
self.read_available_items_favorites_from_txt()
start_new_thread(self.get_available_items_per_user, ())
self.bot.set_my_commands([
types.BotCommand("/info", "favorite bags that currently available"),
types.BotCommand("/login", "log in with your mail"),
types.BotCommand("/settings", "set when you want to be notified"),
types.BotCommand("/help", "short explanation"),
])
def send_message(self, telegram_user_id, message):
self.bot.send_message(telegram_user_id, text=message)
def send_message_with_link(self, telegram_user_id, message, item_id):
self.bot.send_message(telegram_user_id, text=message, reply_markup=types.InlineKeyboardMarkup(
keyboard=[
[
types.InlineKeyboardButton(
text="Open in app 📱",
callback_data="open_app",
url="https://share.toogoodtogo.com/item/" + item_id
)
],
]
)
)
def read_users_login_data_from_txt(self):
with open('users_login_data.txt', 'r') as file:
data = file.read()
self.users_login_data = json.loads(data)
def save_users_login_data_to_txt(self):
with open('users_login_data.txt', 'w') as file:
file.write(json.dumps(self.users_login_data))
def read_users_settings_data_from_txt(self):
with open('users_settings_data.txt', 'r') as file:
data = file.read()
self.users_settings_data = json.loads(data)
def save_users_settings_data_to_txt(self):
with open('users_settings_data.txt', 'w') as file:
file.write(json.dumps(self.users_settings_data))
def read_available_items_favorites_from_txt(self):
with open('available_items_favorites.txt', 'r') as file:
data = file.read()
self.available_items_favorites = json.loads(data)
def save_available_items_favorites_to_txt(self):
with open('available_items_favorites.txt', 'w') as file:
file.write(json.dumps(self.available_items_favorites))
def add_user(self, telegram_user_id, credentials):
self.users_login_data[telegram_user_id] = credentials
self.save_users_login_data_to_txt()
self.users_settings_data[telegram_user_id] = {'sold_out': 0,
'new_stock': 1,
'stock_reduced': 0,
'stock_increased': 0}
self.save_users_settings_data_to_txt()
# Get the credentials
def new_user(self, telegram_user_id, email):
client = TgtgClient(email=email)
credentials = client.get_credentials()
self.add_user(telegram_user_id, credentials)
self.send_message(telegram_user_id, "✅ You are now logged in!")
# Looks if the user is already logged in
def find_credentials_by_telegramUserID(self, user_id):
for key in self.users_login_data.keys():
if user_id == key:
return self.users_login_data[key]
# Checks if a connection already exists, or if it has to be created initially.
def connect(self, user_id):
if user_id in self.connected_clients.keys():
self.client = self.connected_clients[user_id]
else:
user_credentials = self.find_credentials_by_telegramUserID(user_id)
self.client = TgtgClient(access_token=user_credentials["access_token"],
refresh_token=user_credentials["refresh_token"],
cookie=user_credentials["cookie"])
self.connected_clients[user_id] = self.client
time.sleep(3)
def get_favourite_items(self):
favourite_items = self.client.get_items()
return favourite_items
# /info command
def send_available_favourite_items_for_one_user(self, user_id):
self.connect(user_id)
favourite_items = self.get_favourite_items()
available_items = []
for item in favourite_items:
if item['items_available'] > 0:
item_id = item['item']['item_id']
store_name = "🍽 " + str(item['store']['store_name'])
store_address_line = "🧭 " + str(item['store']['store_location']['address']['address_line'])
store_price = "💰 " + str(int(item['item']["price_including_taxes"]["minor_units"]) / 100)
store_items_available = "🥡 " + str(item['items_available'])
text = "{0}\n{1}\n{2}\n{3}\n⏰ {4} - {5}".format(store_name, store_address_line,
store_price, store_items_available, str(
datetime.strptime(item['pickup_interval']['start'],
"%Y-%m-%dT%H:%M:%SZ").astimezone(
timezone.utc).strftime("%a %d.%m at %H:%M")), str(
datetime.strptime(item['pickup_interval']['end'], '%Y-%m-%dT%H:%M:%SZ').astimezone(
timezone.utc).strftime("%a %d.%m at %H:%M")))
self.send_message_with_link(user_id, text, item_id)
available_items.append(item)
if len(available_items) == 0:
self.send_message(user_id, "Currently all your favorites are sold out 😕")
# Loop through all users and see if the number has changed
def get_available_items_per_user(self):
while True:
try:
temp_available_items = {}
for key in self.users_login_data.keys():
self.connect(key)
time.sleep(1)
available_items = self.get_favourite_items()
for item in available_items:
status = "null"
item_id = item['item']['item_id']
if item_id in self.available_items_favorites.keys() and not item_id in temp_available_items.keys():
old_items_available = int(self.available_items_favorites[item_id]['items_available'])
new_items_available = int(item['items_available'])
if new_items_available == 0 and old_items_available > 0: # Sold out (x -> 0)
status = "sold_out"
elif old_items_available == 0 and new_items_available > 0: # New Bag available (0 -> x)
status = "new_stock"
elif old_items_available > new_items_available: # Reduced stock available (x -> x-1)
status = "stock_reduced"
elif old_items_available < new_items_available: # Increased stock available (x -> x-1)
status = "stock_increased"
if not status == "null":
temp_available_items[item_id] = status
self.available_items_favorites[item_id] = item
if item_id in temp_available_items and \
self.users_settings_data[key][temp_available_items[item_id]] == 1:
saved_status = temp_available_items[item_id]
store_name = "🍽 " + str(item['store']['store_name'])
store_address_line = "🧭 " + str(item['store']['store_location']['address']['address_line'])
store_price = "💰 " + str(int(item['item']["price_including_taxes"]["minor_units"]) / 100)
store_items_available = "🥡 " + str(item['items_available'])
if saved_status == "sold_out":
text = store_name \
+ "\n" + store_address_line \
+ "\n" + store_price \
+ "\n" + store_items_available
else:
text = "{0}\n{1}\n{2}\n{3}\n⏰ {4} - {5}".format(store_name, store_address_line,
store_price, store_items_available, str(
datetime.strptime(item['pickup_interval']['start'],
"%Y-%m-%dT%H:%M:%SZ").astimezone(
timezone.utc).strftime("%a %d.%m at %H:%M")), str(
datetime.strptime(item['pickup_interval']['end'],
'%Y-%m-%dT%H:%M:%SZ').astimezone(
timezone.utc).strftime("%a %d.%m at %H:%M")))
text += "\n" + saved_status
print(saved_status + " Telegram USER_ID: " + key + "\n" + text)
self.send_message_with_link(key, text, item_id)
self.save_available_items_favorites_to_txt()
time.sleep(60)
except Exception as err:
print(f"Unexpected {err=}, {type(err)=}")