├── README.md
├── data
├── custom_message.xlsx
├── history.xlsx
├── list_publish.xlsx
├── publish_on.xlsx
├── search_product.xlsx
├── search_result.xlsx
├── setting.xlsx
├── short_url.xlsx
└── support_dev.xlsx
├── main.py
├── publish.py
├── requirements.txt
└── search_products.py
/README.md:
--------------------------------------------------------------------------------
1 |
Amacapy
2 | Amacapy is a program that focuses on web scraping amazon.com, amazon.es and amazon.it. The data extracted are the price, title and URL of the products searched, then with the help of a Telegram bot created with Bot Father, these are published in a certain time.
3 |
4 |
5 |
6 |
7 |
8 | Old version
9 | Libraries and technologies used:
10 | Python 3.10.1.
11 | Beautifulsoup4 v4.11.1 and Requests v2.28.1 (For the web scraping)
12 | Flet v0.3.2. (For the graphical interface)
13 | Pandas v1.5.2. (For saving and manipulating information from xlsx files)
14 | Pyshorteners v1.0.1. (To shorten the links of the publications)
15 |
16 |
17 | How to use Amacapy?
18 | 1. Create a bot with BotFather.
19 | 1.1. Start a new conversation with the BotFather in Telegram.
20 | 1.2. Send /newbot to create a new Telegram bot.
21 | 1.3. When asked, enter a name for the bot.
22 | 1.4. Give the Telegram bot a unique username.
23 | 1.5. Copy and save the Telegram bot's access token for later steps.
24 |
25 |
26 | 2. Install the necessary libraries. You can do it in the following way:
27 | 2.1. Open the terminal in the path of the Amacapy program.
28 | 2.2. Type: pip install -r requirements.txt.
29 | 2.3. Wait for the installation to finish.
30 |
31 | 3. Open the "main.py" file containing the main program.
32 |
33 | 4. Add your data (amazon id, telegram token, chat id) in the configuration.
34 | 4.1. Amazon ID: Your amazon affiliates tag.
35 | 4.2. Telegram Token: It is the token obtained when creating the telegram bot with Bot Father.
36 | 4.3. Chat ID: The name of the Telegram channel or Telegram group. Make sure the chat ID has no symbols or special characters.
37 | Example:
38 |
39 |
40 | 5. Search products.
41 | 5.1. You can place the direct URL of a product or enter the keyword of the product you want to search for.
42 | 5.2. Select Amazon region.
43 | 5.3. Activate or deactivate quick search. (Optional).
44 | 5.4. Press Enter in the search bar or click on the search symbol to start retrieving products.
45 | Example:
46 |
47 |
48 | 6. Search results.
49 | 6.1. Modify the title or price of the products only by editing the text field.
50 | 6.2. Select in "Check" the products you want to publish.
51 | 6.3.Click on the button "Add to publish" to add them to the list of products to be published.
52 | Example:
53 |
54 |
55 | 7. Publication list.
56 | 7.1. Verify name and price of the products to be published.
57 | 7.2. Add how often (in minutes) you want the products to be published on Telegram.
58 | 7.3. Press the Telegram button to start publishing. While it is posting, you cannot do other things in the program unless you press the "stop" button.
59 | Example:
60 |
61 |
62 | 7. History of published products.
63 | 7.1. You can see the URL, title, price and publication date of the product.
64 | Example:
65 |
66 |
67 | 8. Modify the text displayed in the Telegram post (Optional).
68 | 8.1. Go to "Settings" and click on the "Modify publication message" button located in other options.
69 | Example:
70 |
71 |
72 |
73 | 9.Add link shortener (Optional).
74 | 9.1. Go to "Settings" and click on the "Modify Short URL" button located in other options.
75 | 9.2. Select between Tinyurl, Is.gd and Da.gd.
76 | Example:
77 |
78 |
79 | 10. Supporting the developer.
80 | 10.1. Activating the option that allows you to publish 1 product with the amazon affiliate tag of the Amacapy developer. It is published every 5 products published. (option enabled by default, you can disable it manually).
81 | Example:
82 |
83 |
84 |
85 | Where are the data stored? (Do not manually delete or modify these files)
86 | 1. The configuration is stored in the file: setting.xlsx.
87 | 2. The search_product.xlsx file stores the data entered in the search screen (product keyword and Amazon region).
88 | 3. The search result is stored in the file: search_result.xlsx.
89 | 4. Products added to the publication list are stored in: list_publish.xlsx.
90 | 5. The publish_on.xlsx file stores the products that are being published.
91 | 6. The history.xlsx file stores the products that have been published, including their publication date.
92 | 7. The custom Telegram post message is stored in the file custom_message.xlsx.
93 | 8. The link shortener data is stored in the file: short_url.xlsx.
94 | 9. The support_dev.xlsx file stores whether or not the developer will be supported by the affiliate link.
95 |
96 |
97 | Thank you for using the program, you can support me through Paypal.
98 | You can contact me on Telegram.
99 |
100 |
101 |
102 |
--------------------------------------------------------------------------------
/data/custom_message.xlsx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sulasoft/Amacapy-Bot-Telegram-Amazon-Affiliates/59044c2d107df836161a073215e959e60664486f/data/custom_message.xlsx
--------------------------------------------------------------------------------
/data/history.xlsx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sulasoft/Amacapy-Bot-Telegram-Amazon-Affiliates/59044c2d107df836161a073215e959e60664486f/data/history.xlsx
--------------------------------------------------------------------------------
/data/list_publish.xlsx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sulasoft/Amacapy-Bot-Telegram-Amazon-Affiliates/59044c2d107df836161a073215e959e60664486f/data/list_publish.xlsx
--------------------------------------------------------------------------------
/data/publish_on.xlsx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sulasoft/Amacapy-Bot-Telegram-Amazon-Affiliates/59044c2d107df836161a073215e959e60664486f/data/publish_on.xlsx
--------------------------------------------------------------------------------
/data/search_product.xlsx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sulasoft/Amacapy-Bot-Telegram-Amazon-Affiliates/59044c2d107df836161a073215e959e60664486f/data/search_product.xlsx
--------------------------------------------------------------------------------
/data/search_result.xlsx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sulasoft/Amacapy-Bot-Telegram-Amazon-Affiliates/59044c2d107df836161a073215e959e60664486f/data/search_result.xlsx
--------------------------------------------------------------------------------
/data/setting.xlsx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sulasoft/Amacapy-Bot-Telegram-Amazon-Affiliates/59044c2d107df836161a073215e959e60664486f/data/setting.xlsx
--------------------------------------------------------------------------------
/data/short_url.xlsx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sulasoft/Amacapy-Bot-Telegram-Amazon-Affiliates/59044c2d107df836161a073215e959e60664486f/data/short_url.xlsx
--------------------------------------------------------------------------------
/data/support_dev.xlsx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sulasoft/Amacapy-Bot-Telegram-Amazon-Affiliates/59044c2d107df836161a073215e959e60664486f/data/support_dev.xlsx
--------------------------------------------------------------------------------
/main.py:
--------------------------------------------------------------------------------
1 | import flet as ft
2 | from flet import Page, Text, Row, TextField, ElevatedButton, Checkbox, Column, Container, IconButton, Theme
3 | import time
4 | from time import sleep
5 | import requests
6 | import io
7 | from io import open
8 | import webbrowser
9 | import pandas as pd
10 | from pandas import ExcelWriter
11 | from datetime import datetime
12 | from multiprocessing import Process
13 | import search_products
14 | import publish
15 | from os import remove
16 |
17 |
18 | # Starting the scripts that will search for products on Amazon and post on Telegram.
19 | def script_search_products():
20 | search_products.enable(True)
21 |
22 | def script_publish():
23 | publish.enable(True)
24 |
25 |
26 |
27 | if __name__ == '__main__':
28 |
29 | processes_search_product = []
30 | processes_publish_product = []
31 | for i in range(0, 500):
32 | processes_search_product.append(Process(target=script_search_products))
33 | processes_publish_product.append(Process(target=script_publish))
34 |
35 | # thread_search_product = Process(target=script_search_products)
36 | # thread_publish_product = Process(target=script_publish)
37 |
38 | def main(page: ft.Page):
39 |
40 | # Defining the program title and design
41 | page.window_maximizable = True
42 | page.title = "Amacapy 2.0"
43 | page.vertical_alignment = "center"
44 | page.horizontal_alignment = "center"
45 | page.window_width = 720
46 | page.window_height = 680
47 | page.window_resizable = True
48 | page.theme_mode = ft.ThemeMode.DARK
49 |
50 |
51 |
52 |
53 | title_amacapy = Text(
54 | value="Amacapy",
55 | size=30,
56 | color="white",
57 | weight="bold",
58 | italic=True,
59 | )
60 | page.add(title_amacapy)
61 |
62 | def main_interface():
63 |
64 | # This function will display the screen with the list of products that will be ready to be published.
65 | def page_publish(self):
66 | try:
67 | # We read the file where the product data is stored
68 | verify_list_publish = pd.read_excel('data/list_publish.xlsx', header = 0)
69 |
70 | except:
71 | sleep(2)
72 | try:
73 | # We read the file where the product data is stored
74 | verify_list_publish = pd.read_excel('data/list_publish.xlsx', header = 0)
75 | except:
76 | remove('data/list_publish.xlsx')
77 | update_list_publish_data = pd.DataFrame(columns = ['title', 'price', 'currency', 'url'])
78 | with ExcelWriter('data/list_publish.xlsx') as writer:
79 | update_list_publish_data.to_excel(writer, 'Sheet', index=False)
80 |
81 | title_list_publish = verify_list_publish['title'].values
82 | price_list_publish = verify_list_publish['price'].values
83 | currency_list_publish = verify_list_publish['currency'].values
84 | url_list_publish = verify_list_publish['url'].values
85 |
86 | # Title that will appear in the publish products view.
87 | title_head_list_publish = Text(
88 | value="Products to Publish",
89 | size=20,
90 | color="white",
91 | weight="bold",
92 | italic=True,
93 | )
94 |
95 | all_results = ft.Column(scroll="always", expand=True)
96 |
97 | # The file is checked for stored data to be able to display it on the screen.
98 | if len(verify_list_publish) > 0:
99 | currency = f"({currency_list_publish[0]})"
100 |
101 | for i in range(len(verify_list_publish)):
102 |
103 | all_results.controls.append(
104 | ft.Row(spacing=28, run_spacing=5, controls=[
105 | Text(f"{i+1}. "),
106 | ft.IconButton(on_click=view_url_list_publish, data = i, icon="remove_red_eye_rounded", icon_size=20),
107 | ft.TextField(value=title_list_publish[i], label = i, on_blur=change_title_publish, text_align="start", keyboard_type = "text", width=250, height = 50, text_size=12, content_padding = 10),
108 | ft.TextField(value=price_list_publish[i], label = i, on_blur=change_price_publish, text_align="start", keyboard_type = "number", width=70, height = 50, text_size=12, content_padding = 10),
109 | ft.IconButton(on_click=delete_product_button, data = i, icon="delete_forever_rounded", icon_size=20),
110 | ], alignment="center", vertical_alignment = "center")
111 |
112 | )
113 |
114 | # If the file has no data, then a message that there are no products is displayed.
115 | else:
116 | currency = ''
117 | all_results.controls.append(
118 | ft.Row(spacing=40, run_spacing=10, controls=[
119 | Text("You have not yet added articles for publication")
120 | ], alignment="center", vertical_alignment = "center")
121 |
122 | )
123 |
124 | page.clean() # We clean the screen before adding a new one.
125 | page.add(
126 | ft.Container(height = 50, content= title_head_list_publish, alignment=ft.alignment.center),
127 | ft.Divider(height=1, color="black"),
128 | ft.Row(spacing=1, controls=[
129 | Text('N°', color="white", width=55, text_align="center"),
130 | Text('View', color="white", width=60, text_align="center"),
131 | Text('Product Title', color="white", width=290, text_align="center"),
132 | Text(f'Price {currency}', color="white", width=80, text_align="center"),
133 | Text('Del',width=80, text_align="center", color="white"),
134 | ],
135 | alignment="center", vertical_alignment = "center"),
136 | ft.Divider(height=1, color="black"),
137 | ft.Container(width= 650, height= 348, content=all_results),
138 | ft.Container(width= 650, height= 40, content=ft.Row(controls=[
139 | ft.ElevatedButton("Delete All", icon="delete_rounded", on_click=delete_all_products_publish)
140 | ],
141 | alignment="end", vertical_alignment = "start")
142 | ),
143 | ft.Row(controls=[
144 | Text('Publish every', width=90, text_align="start",color="white"),
145 | minutes_publish,
146 | Text('on', width=20, text_align="start", color="white"),
147 | ft.ElevatedButton('Telegram' ,icon="telegram_rounded", on_click=publish_on_telegram),
148 | ],
149 | alignment="center", vertical_alignment = "center"),
150 | ft.Container(content= ft.Row(controls=list_all_button_menu,
151 | alignment="center", vertical_alignment = "end"),
152 | height = 50
153 | )
154 | )
155 |
156 | # The same process is repeated as in the page_publish function
157 | # But in this case to see the history of published products.
158 | def page_history(self):
159 | # The file that stores the history of published products is read.
160 | verify_history = pd.read_excel('data/history.xlsx', header = 0)
161 |
162 | date_history = verify_history['date'].values
163 | title_history = verify_history['title'].values
164 | price_history = verify_history['price'].values
165 | url_history = verify_history['url'].values
166 | platform_history = verify_history['platform'].values
167 |
168 | # Title that will appear in the history view.
169 | title_list_history = Text(
170 | value="History of published products",
171 | size=20,
172 | color="white",
173 | weight="bold",
174 | italic=True,
175 | )
176 |
177 | all_results = ft.Column(scroll="always", expand=True)
178 |
179 | # The file is checked for stored data to be able to display it on the screen.
180 | if len(verify_history) > 0:
181 |
182 | for i in range(len(verify_history)):
183 | new_date = date_history[i]
184 | new_date = pd.to_datetime(new_date)
185 | new_date = datetime.strftime(new_date, '%Y-%m-%d')
186 |
187 | all_results.controls.append(
188 | ft.Row(spacing=28, run_spacing=5, controls=[
189 | Text(f"{i+1}. "),
190 | ft.IconButton(on_click=view_url_history, data = i, icon="remove_red_eye_rounded", icon_size=20),
191 | ft.TextField(value=title_history[i], read_only = True, text_align="start", keyboard_type = "text", width=250, height = 50, text_size=12, content_padding = 10),
192 | ft.Text(color="white", value=price_history[i], width=80, text_align="center"),
193 | ft.Text(color="white", value=platform_history[i]),
194 | ft.Text(color="white", value=new_date)
195 | ], alignment="center", vertical_alignment = "center")
196 |
197 | )
198 | # If the file has no data, then a message that there are no products is displayed.
199 | else:
200 | currency = ''
201 | all_results.controls.append(
202 | ft.Row(spacing=40, run_spacing=10, controls=[
203 | Text("You have not yet added articles for publication", color="white")
204 | ], alignment="center", vertical_alignment = "center")
205 |
206 | )
207 | # The view is cleaned before adding another one.
208 | page.clean()
209 | page.add(
210 | ft.Container(height = 50, content= title_list_history, alignment=ft.alignment.center),
211 | ft.Divider(height=1, color="black"),
212 | ft.Row(spacing=10, controls=[
213 | Text('N°', width=20, text_align="center", color="white"),
214 | Text('View', width=80, text_align="center", color="white"),
215 | Text('Product Title', width=270, text_align="center", color="white"),
216 | Text(f'Price', width=95, text_align="center", color="white"),
217 | Text(f'Platform', width=65, text_align="center",color="white"),
218 | Text(f'Date', width=100, text_align="center", color="white")
219 | ],
220 | alignment="center", vertical_alignment = "center"),
221 | ft.Divider(height=1, color="black"),
222 | ft.Container(width= 710, height= 408, content=all_results),
223 | ft.Container(width= 710, height= 40, content=ft.Row(controls=[
224 | ft.ElevatedButton("Delete All", icon="delete_rounded", on_click=delete_all_history)
225 | ],
226 | alignment="end", vertical_alignment = "start")
227 | ),
228 | ft.Container(content= ft.Row(controls=list_all_button_menu,
229 | alignment="center", vertical_alignment = "end"),
230 | height = 50
231 | )
232 | )
233 |
234 | # Function to stop the publication of products
235 | def stop_publish_on(e):
236 |
237 | # To read the data contained in the file that stores the products to be published.
238 | verify_publish_on = pd.read_excel('data/publish_on.xlsx', header = 0)
239 |
240 | # To remove the data from the file of the products to be published.
241 | update_publish_on = pd.DataFrame(columns = ['title', 'price', 'url', 'min', 'telegram'])
242 |
243 | # This loop will check if the file still has data. If it has data, it will proceed to delete it.
244 | while len(verify_publish_on) !=0:
245 | try:
246 | with ExcelWriter('data/publish_on.xlsx') as writer:
247 | update_publish_on.to_excel(writer, 'Sheet', index=False)
248 |
249 | processes_publish_product[0].kill()
250 | processes_publish_product.pop(0)
251 |
252 | except Exception as e:
253 | print('Error: ' + str(e))
254 | sleep(1)
255 | with ExcelWriter('data/publish_on.xlsx') as writer:
256 | update_publish_on.to_excel(writer, 'Sheet', index=False)
257 |
258 | processes_publish_product[0].kill()
259 | processes_publish_product.pop(0)
260 |
261 |
262 | # The file is rechecked to see if it still has data.
263 | verify_publish_on = pd.read_excel('data/publish_on.xlsx', header = 0)
264 | sleep(1)
265 |
266 | # The function that displays the products to be published is called
267 | page_publish(1)
268 |
269 | # This function will show when products are being published.
270 | def page_publish_on(e):
271 |
272 | # To read the data contained in the file that stores the products to be published.
273 | verify_publish_on = pd.read_excel('data/publish_on.xlsx', header = 0)
274 |
275 | if len(verify_publish_on) == 0:
276 | pass
277 | else:
278 | processes_publish_product[0].start()
279 | page.clean()
280 |
281 | # Text that will display the message "Publishing products..."
282 | publish_text = Text(
283 | value=f"Publishing products...",
284 | size=15,
285 | color="white",
286 | italic=False,
287 | )
288 |
289 | # Text with the number of products still to be released
290 | yet_publish_text = Text(
291 | value=f"{len(verify_publish_on)} to publish",
292 | size=15,
293 | color="white",
294 | italic=False,
295 | )
296 | page.add(
297 | ft.Container(content= ft.Column(controls=[
298 | ft.Row(alignment="center", controls=[publish_text]),
299 | yet_publish_text,
300 | press_button_publish_on_stop
301 | ], horizontal_alignment = "center", alignment="center"),
302 | height= 520
303 |
304 |
305 | ),
306 | ft.Container(content= ft.Row(controls=list_all_button_menu,
307 | alignment="center", vertical_alignment = "end"),
308 | height = 100
309 | )
310 | )
311 |
312 |
313 | # As long as there are products to be published, the screen will be updated.
314 | while len(verify_publish_on) !=0 and processes_publish_product[0].is_alive():
315 | verify_publish_on = pd.read_excel('data/publish_on.xlsx', header = 0)
316 | publish_text = Text(
317 | value=f"Publishing products...",
318 | size=15,
319 | color="white",
320 | italic=False,
321 | )
322 | yet_publish_text = Text(
323 | value=f"{len(verify_publish_on)} to publish",
324 | size=15,
325 | color="white",
326 | italic=False,
327 | )
328 | page.clean()
329 | page.add(
330 | ft.Container(content= ft.Column(controls=[
331 | ft.Row(alignment="center", controls=[publish_text]),
332 | yet_publish_text,
333 | press_button_publish_on_stop
334 | ], horizontal_alignment = "center", alignment="center"),
335 | height= 520
336 |
337 |
338 | ),
339 | ft.Container(content= ft.Row(controls=list_all_button_menu,
340 | alignment="center", vertical_alignment = "end"),
341 | height = 100
342 | )
343 | )
344 | sleep(5)
345 | verify_publish_on = pd.read_excel('data/publish_on.xlsx', header = 0)
346 |
347 | # When there are no more products to be published, it will call the function that displays the products to be published.
348 | else:
349 | if processes_publish_product[0].is_alive():
350 | processes_publish_product[0].kill()
351 | processes_publish_product.pop(0)
352 | page_publish(1)
353 |
354 | # Function that adds the products to the file that will store the products that will be published.
355 | def publish_on_telegram(e):
356 | # To check the list of products to be published
357 | verify_list_publish = pd.read_excel('data/list_publish.xlsx', header = 0)
358 | title_publish = verify_list_publish['title'].values
359 | price_publish = verify_list_publish['price'].values
360 | url_publish = verify_list_publish['url'].values
361 |
362 | # To obtain how often the products will be published.
363 | minutes = minutes_publish.value
364 |
365 | # They will be used to save the data stored in list_publish.xlsx and add them to publish_on.xlsx
366 | # (this file stores the products that will be published).
367 | title_publish_on = []
368 | price_publish_on = []
369 | url_publish_on = []
370 | minutes_publish_on = []
371 | telegram_publish_on = []
372 |
373 | for i in range(len(verify_list_publish)):
374 | title_publish_on.append(title_publish[i])
375 | price_publish_on.append(price_publish[i])
376 | url_publish_on.append(url_publish[i])
377 | minutes_publish_on.append(minutes)
378 | telegram_publish_on.append('yes')
379 |
380 |
381 | add_history = {'title': title_publish_on, 'price': price_publish_on, 'url': url_publish_on, 'min': minutes_publish_on,'telegram':telegram_publish_on}
382 |
383 | update_publish_on = pd.DataFrame(add_history, columns = ['title', 'price', 'url', 'min', 'telegram'])
384 |
385 | with ExcelWriter('data/publish_on.xlsx') as writer:
386 | update_publish_on.to_excel(writer, 'Sheet', index=False)
387 |
388 | page_publish_on(1)
389 |
390 | # Function to change the message that will be displayed in Telegram posts.
391 | def change_custom_message(e):
392 | verify_custom_message = pd.read_excel('data/custom_message.xlsx', header = 0)
393 | before_title_message = verify_custom_message['before_title'].values
394 | original_price_message = verify_custom_message['original_price'].values
395 | sale_price_message = verify_custom_message['sale_price'].values
396 | currency_message = verify_custom_message['currency'].values
397 | url_message = verify_custom_message['url'].values
398 |
399 | label_message = e.control.label
400 | add_custom_message = {}
401 |
402 | if 'Before' in label_message:
403 | before_title_message = [form_before_title_message.value]
404 |
405 | elif 'Sale' in label_message:
406 | sale_price_message = [form_sale_price_message.value]
407 |
408 | elif 'Original' in label_message:
409 | original_price_message = [form_original_price_message.value]
410 |
411 | elif 'Currency' in label_message:
412 | currency_message = [form_currency_message.value]
413 |
414 | elif 'URL' in label_message:
415 | url_message = [form_url_message.value]
416 |
417 | else:
418 | pass
419 |
420 | add_custom_message['before_title'] = before_title_message
421 | add_custom_message['original_price'] = original_price_message
422 | add_custom_message['sale_price'] = sale_price_message
423 | add_custom_message['currency'] = currency_message
424 | add_custom_message['url'] = url_message
425 |
426 | update_custom_message = pd.DataFrame(add_custom_message, columns = ['before_title', 'original_price', 'sale_price', 'currency', 'url'])
427 | with ExcelWriter('data/custom_message.xlsx') as writer:
428 | update_custom_message.to_excel(writer, 'Sheet', index=False)
429 |
430 | # Function that will show the screen where the message of the products published in Telegram can be modified.
431 | def custom_message(e):
432 | verify_custom_message = pd.read_excel('data/custom_message.xlsx', header = 0)
433 | before_title_message = verify_custom_message['before_title'].values
434 | original_price_message = verify_custom_message['original_price'].values
435 | sale_price_message = verify_custom_message['sale_price'].values
436 | currency_message = verify_custom_message['currency'].values
437 | url_message = verify_custom_message['url'].values
438 |
439 | if len(verify_custom_message) != 0:
440 | form_before_title_message.value = before_title_message[0]
441 | form_sale_price_message.value = sale_price_message[0]
442 | form_original_price_message.value = original_price_message[0]
443 | form_currency_message.value = currency_message[0]
444 | form_url_message.value = url_message[0]
445 |
446 | title_custom_message = Text(
447 | value="Modify the publication message",
448 | size=20,
449 | color="white",
450 | weight="bold",
451 | italic=True,
452 | )
453 |
454 | page.clean()
455 | page.add(
456 | ft.Container(height = 50, content= title_custom_message, alignment=ft.alignment.center),
457 | ft.Divider(height=1, color="black"),
458 | ft.Container(height= 449, content=ft.Column(controls=[
459 | form_before_title_message,
460 | form_sale_price_message,
461 | form_original_price_message,
462 | form_currency_message,
463 | form_url_message
464 | ],
465 | alignment="center")),
466 |
467 | ft.Container(content= ft.Row(controls=list_all_button_menu,
468 | alignment="center", vertical_alignment = "end"),
469 | height = 100
470 | )
471 | )
472 |
473 | # Function to delete product in the list of products to be published.
474 | def delete_product_button(e):
475 | id_number = e.control.data
476 |
477 | verify_list_publish = pd.read_excel('data/list_publish.xlsx', header = 0)
478 |
479 | title_publish = verify_list_publish['title'].values
480 | price_publish = verify_list_publish['price'].values
481 | currency_publish = verify_list_publish['currency'].values
482 | url_publish = verify_list_publish['url'].values
483 |
484 | new_title_publish = []
485 | new_price_publish = []
486 | new_currency_publish = []
487 | new_url_publish = []
488 |
489 | for i in range(len(verify_list_publish)):
490 | if i == id_number:
491 | pass
492 | else:
493 | new_title_publish.append(title_publish[i])
494 | new_price_publish.append(price_publish[i])
495 | new_currency_publish.append(currency_publish[i])
496 | new_url_publish.append(url_publish[i])
497 |
498 | list_publish_data = {}
499 |
500 | list_publish_data['title'] = new_title_publish
501 | list_publish_data['price'] = new_price_publish
502 | list_publish_data['currency'] = new_currency_publish
503 | list_publish_data['url'] = new_url_publish
504 |
505 | list_publish_data = pd.DataFrame(list_publish_data, columns = ['title', 'price', 'currency', 'url'])
506 |
507 | with ExcelWriter('data/list_publish.xlsx') as writer:
508 | list_publish_data.to_excel(writer, 'Sheet', index=False)
509 | page_publish(0)
510 |
511 | # Function to change Amazon ID
512 | def change_amazon_id(e):
513 | new_amazon_id = e.control.value
514 |
515 | verify_setting = pd.read_excel('data/setting.xlsx', header = 0)
516 | amazon_id = verify_setting['amazon_id'].values
517 | telegram_token = verify_setting['telegram_token'].values
518 | chat_id = verify_setting['chat_id'].values
519 |
520 | if len(verify_setting) > 0:
521 | amazon_id = new_amazon_id
522 |
523 | if pd.isnull(telegram_token[0]):
524 | telegram_token = ''
525 | else:
526 | telegram_token = telegram_token[0]
527 |
528 | if pd.isnull(chat_id[0]):
529 | chat_id = ''
530 | else:
531 | chat_id = chat_id[0]
532 |
533 | else:
534 | amazon_id = new_amazon_id
535 | telegram_token = ''
536 | chat_id = ''
537 |
538 | setting_data = {}
539 | setting_data['amazon_id'] = [amazon_id]
540 | setting_data['telegram_token'] = [telegram_token]
541 | setting_data['chat_id'] = [chat_id]
542 |
543 | setting_data = pd.DataFrame(setting_data, columns = ['amazon_id', 'telegram_token', 'chat_id'])
544 | with ExcelWriter('data/setting.xlsx') as writer:
545 | setting_data.to_excel(writer, 'Sheet', index=False)
546 |
547 | # Function to change telegram token
548 | def change_telegram_token(e):
549 | new_telegram_token = e.control.value
550 |
551 | verify_setting = pd.read_excel('data/setting.xlsx', header = 0)
552 | amazon_id = verify_setting['amazon_id'].values
553 | telegram_token = verify_setting['telegram_token'].values
554 | chat_id = verify_setting['chat_id'].values
555 |
556 | if len(verify_setting) > 0:
557 | telegram_token = new_telegram_token
558 |
559 | if pd.isnull(amazon_id[0]):
560 | amazon_id = ''
561 | else:
562 | amazon_id = amazon_id[0]
563 |
564 | if pd.isnull(chat_id[0]):
565 | chat_id = ''
566 | else:
567 | chat_id = chat_id[0]
568 |
569 | else:
570 | amazon_id = ''
571 | telegram_token = new_telegram_token
572 | chat_id = ''
573 |
574 | setting_data = {}
575 | setting_data['amazon_id'] = [amazon_id]
576 | setting_data['telegram_token'] = [telegram_token]
577 | setting_data['chat_id'] = [chat_id]
578 |
579 | setting_data = pd.DataFrame(setting_data, columns = ['amazon_id', 'telegram_token', 'chat_id'])
580 | with ExcelWriter('data/setting.xlsx') as writer:
581 | setting_data.to_excel(writer, 'Sheet', index=False)
582 |
583 | # Function to change chat ID
584 | def change_chat_id(e):
585 | new_chat_id = e.control.value
586 |
587 | verify_setting = pd.read_excel('data/setting.xlsx', header = 0)
588 | amazon_id = verify_setting['amazon_id'].values
589 | telegram_token = verify_setting['telegram_token'].values
590 | chat_id = verify_setting['chat_id'].values
591 |
592 | if len(verify_setting) > 0:
593 | chat_id = new_chat_id
594 |
595 | if pd.isnull(amazon_id[0]):
596 | amazon_id = ''
597 | else:
598 | amazon_id = amazon_id[0]
599 |
600 | if pd.isnull(telegram_token[0]):
601 | telegram_token = ''
602 | else:
603 | telegram_token = telegram_token[0]
604 |
605 | else:
606 | amazon_id = ''
607 | telegram_token = ''
608 | chat_id = new_chat_id
609 |
610 | setting_data = {}
611 | setting_data['amazon_id'] = [amazon_id]
612 | setting_data['telegram_token'] = [telegram_token]
613 | setting_data['chat_id'] = [chat_id]
614 |
615 | setting_data = pd.DataFrame(setting_data, columns = ['amazon_id', 'telegram_token', 'chat_id'])
616 | with ExcelWriter('data/setting.xlsx') as writer:
617 | setting_data.to_excel(writer, 'Sheet', index=False)
618 |
619 | # Function to change the title of the products that appear in the list of products to be published.
620 | def change_title_publish(e):
621 | new_title = e.control.value # Stores the text of the form that is being modified.
622 | id_number = e.control.label # Stores the label number of the text field being modified so that it can be identified.
623 |
624 | verify_list_publish = pd.read_excel('data/list_publish.xlsx', header = 0)
625 |
626 | title_publish = verify_list_publish['title'].values
627 | price_publish = verify_list_publish['price'].values
628 | currency_publish = verify_list_publish['currency'].values
629 | url_publish = verify_list_publish['url'].values
630 |
631 | title_publish[id_number] = new_title
632 |
633 | list_publish_data = {}
634 |
635 | list_publish_data['title'] = title_publish
636 | list_publish_data['price'] = price_publish
637 | list_publish_data['currency'] = currency_publish
638 | list_publish_data['url'] = url_publish
639 |
640 | list_publish_data = pd.DataFrame(list_publish_data, columns = ['title', 'price', 'currency', 'url'])
641 |
642 | try:
643 | with ExcelWriter('data/list_publish.xlsx') as writer:
644 | list_publish_data.to_excel(writer, 'Sheet', index=False)
645 | except:
646 | sleep(1)
647 | with ExcelWriter('data/list_publish.xlsx') as writer:
648 | list_publish_data.to_excel(writer, 'Sheet', index=False)
649 |
650 |
651 | # Function to change the price of the products that appear in the list of products to be published.
652 | def change_price_publish(e):
653 | new_price = e.control.value # Stores the text of the form that is being modified.
654 | id_number = e.control.label # Stores the label number of the text field being modified so that it can be identified.
655 |
656 | verify_list_publish = pd.read_excel('data/list_publish.xlsx', header = 0)
657 |
658 | title_publish = verify_list_publish['title'].values
659 | price_publish = verify_list_publish['price'].values
660 | currency_publish = verify_list_publish['currency'].values
661 | url_publish = verify_list_publish['url'].values
662 |
663 | price_publish[id_number] = new_price
664 |
665 | list_publish_data = {}
666 |
667 | list_publish_data['title'] = title_publish
668 | list_publish_data['price'] = price_publish
669 | list_publish_data['currency'] = currency_publish
670 | list_publish_data['url'] = url_publish
671 |
672 | list_publish_data = pd.DataFrame(list_publish_data, columns = ['title', 'price', 'currency', 'url'])
673 |
674 | try:
675 | with ExcelWriter('data/list_publish.xlsx') as writer:
676 | list_publish_data.to_excel(writer, 'Sheet', index=False)
677 | except:
678 | sleep(1)
679 | with ExcelWriter('data/list_publish.xlsx') as writer:
680 | list_publish_data.to_excel(writer, 'Sheet', index=False)
681 |
682 | # Function to change the title of the products that appear in the list of found products.
683 | def change_title_result(e):
684 | new_title = e.control.value # Stores the text of the form that is being modified.
685 | id_number = e.control.label # Stores the label number of the text field being modified so that it can be identified.
686 |
687 | verify_search_result = pd.read_excel('data/search_result.xlsx', header = 0)
688 |
689 | title_result = verify_search_result['title'].values
690 | price_result = verify_search_result['price'].values
691 | currency_result = verify_search_result['currency'].values
692 | check_result = verify_search_result['check'].values
693 | url_result = verify_search_result['url'].values
694 |
695 | title_result[id_number] = new_title
696 |
697 | search_result_data = {}
698 |
699 | search_result_data['title'] = title_result
700 | search_result_data['price'] = price_result
701 | search_result_data['currency'] = currency_result
702 | search_result_data['check'] = check_result
703 | search_result_data['url'] = url_result
704 |
705 | search_result_data = pd.DataFrame(search_result_data, columns = ['title', 'price', 'currency', 'check', 'url'])
706 |
707 | try:
708 | with ExcelWriter('data/search_result.xlsx') as writer:
709 | search_result_data.to_excel(writer, 'Sheet', index=False)
710 | except:
711 | sleep(1)
712 | with ExcelWriter('data/search_result.xlsx') as writer:
713 | search_result_data.to_excel(writer, 'Sheet', index=False)
714 |
715 | # Function to change the price of the products that appear in the list of found products.
716 | def change_price_result(e):
717 | new_price = e.control.value # Stores the text of the form that is being modified.
718 | id_number = e.control.label # Stores the label number of the text field being modified so that it can be identified.
719 |
720 | verify_search_result = pd.read_excel('data/search_result.xlsx', header = 0)
721 | title_result = verify_search_result['title'].values
722 | price_result = verify_search_result['price'].values
723 | currency_result = verify_search_result['currency'].values
724 | check_result = verify_search_result['check'].values
725 | url_result = verify_search_result['url'].values
726 |
727 | price_result[id_number] = new_price
728 |
729 | search_result_data = {}
730 |
731 | search_result_data['title'] = title_result
732 | search_result_data['price'] = price_result
733 | search_result_data['currency'] = currency_result
734 | search_result_data['check'] = check_result
735 | search_result_data['url'] = url_result
736 |
737 | search_result_data = pd.DataFrame(search_result_data, columns = ['title', 'price', 'currency', 'check', 'url'])
738 |
739 | try:
740 | with ExcelWriter('data/search_result.xlsx') as writer:
741 | search_result_data.to_excel(writer, 'Sheet', index=False)
742 | except:
743 | sleep(1)
744 | with ExcelWriter('data/search_result.xlsx') as writer:
745 | search_result_data.to_excel(writer, 'Sheet', index=False)
746 |
747 | # Function that enables and disables application development support
748 | def support_development(e):
749 | verify_status_support = pd.read_excel('data/support_dev.xlsx', header = 0)
750 | status = e.control.value
751 | support_data = {}
752 |
753 | if status:
754 | switch_supp_dev.label = 'Supporting Development On 😊'
755 | support_data['sup_tag'] = ['amla02-20']
756 | support_data['sup_dev'] = ['yes']
757 |
758 | else:
759 | switch_supp_dev.label = 'Supporting Development Off 😢'
760 | support_data['sup_tag'] = ['amla02-20']
761 | support_data['sup_dev'] = ['no']
762 |
763 | update_status_support = pd.DataFrame(support_data, columns = ['sup_tag', 'sup_dev'])
764 |
765 | with ExcelWriter('data/support_dev.xlsx') as writer:
766 | update_status_support.to_excel(writer, 'Sheet', index=False)
767 |
768 | page.update()
769 |
770 | # Function that will add the products to the list of products to be published.
771 | def add_to_publish(self):
772 |
773 | # The data stored in the searched products is checked.
774 | verify_search_result = pd.read_excel('data/search_result.xlsx', header = 0)
775 | # To be stored in the following variables:
776 | title_result = verify_search_result['title'].values
777 | price_result = verify_search_result['price'].values
778 | currency_result = verify_search_result['currency'].values
779 | check_result = verify_search_result['check'].values
780 | url_result = verify_search_result['url'].values
781 |
782 | # The data stored in the list of products to be published are checked.
783 | verify_list_publish = pd.read_excel('data/list_publish.xlsx', header = 0)
784 | # It will be stored in the following variables:
785 | title_publish = verify_list_publish['title'].values
786 | price_publish = verify_list_publish['price'].values
787 | currency_publish = verify_list_publish['currency'].values
788 | url_publish = verify_list_publish['url'].values
789 |
790 | count = 0 # Counter to be used to identify each item stored in the lists obtained from the Excel files.
791 |
792 | # The new variables will store the existing data in the list of products to be published and products found,
793 | # and will also store the new data to be added.
794 | new_title_result = []
795 | new_price_result = []
796 | new_currency_result = []
797 | new_check_result = []
798 | new_url_result = []
799 |
800 | new_title_publish = []
801 | new_price_publish = []
802 | new_currency_publish = []
803 | new_url_publish = []
804 |
805 | # It is verified that the file with the data of the products to be published has information.
806 | if len(verify_list_publish) > 0:
807 | # By means of a loop, the current information of the products to be published is stored in the new variables.
808 | for i in range(len(verify_list_publish)):
809 | new_title_publish.append(title_publish[i])
810 | new_price_publish.append(price_publish[i])
811 | new_currency_publish.append(currency_publish[i])
812 | new_url_publish.append(url_publish[i])
813 |
814 | # It is verified that the file with the data of the products to be published has information.
815 | if len(verify_search_result) > 0:
816 | # Through this loop we can check the products that have been selected to be published.
817 | # This information is stored in search_result.xlsx
818 | for check_status in check_result:
819 | # Products stored in the search_result.xlsx document that contain
820 | # the value "no" in the check field will be stored in the new found products variables.
821 | if check_status == 'no':
822 | new_title_result.append(title_result[count])
823 | new_price_result.append(price_result[count])
824 | new_currency_result.append(currency_result[count])
825 | new_check_result.append(check_result[count])
826 | new_url_result.append(url_result[count])
827 | # On the other hand, if they have the value "yes", they will be stored in the variables
828 | # that will be used to store the information in the list_publish.xlsx document.
829 | else:
830 | new_title_publish.append(title_result[count])
831 | new_price_publish.append(price_result[count])
832 | new_currency_publish.append(currency_result[count])
833 | new_url_publish.append(url_result[count])
834 |
835 | count+=1
836 |
837 | list_publish_data = {}
838 | list_publish_data['title'] = new_title_publish
839 | list_publish_data['price'] = new_price_publish
840 | list_publish_data['currency'] = new_currency_publish
841 | list_publish_data['url'] = new_url_publish
842 |
843 | list_publish_data = pd.DataFrame(list_publish_data, columns = ['title', 'price', 'currency', 'url'])
844 |
845 | with ExcelWriter('data/list_publish.xlsx') as writer:
846 | list_publish_data.to_excel(writer, 'Sheet', index=False)
847 |
848 | search_result_data = {}
849 |
850 | search_result_data['title'] = new_title_result
851 | search_result_data['price'] = new_price_result
852 | search_result_data['currency'] = new_currency_result
853 | search_result_data['check'] = new_check_result
854 | search_result_data['url'] = new_url_result
855 |
856 | search_result_data = pd.DataFrame(search_result_data, columns = ['title', 'price', 'currency', 'check', 'url'])
857 |
858 | with ExcelWriter('data/search_result.xlsx') as writer:
859 | search_result_data.to_excel(writer, 'Sheet', index=False)
860 |
861 | page_search_result(0)
862 | else:
863 | pass
864 |
865 | # Function to delete the products added in the search result.
866 | def select_all_search_result(e):
867 | # The data stored in the searched products is checked.
868 | verify_search_result = pd.read_excel('data/search_result.xlsx', header = 0)
869 |
870 | # To be stored in the following variables:
871 | title_result = verify_search_result['title'].values
872 | price_result = verify_search_result['price'].values
873 | currency_result = verify_search_result['currency'].values
874 | check_result = verify_search_result['check'].values
875 | url_result = verify_search_result['url'].values
876 |
877 | status_select = e.control.text
878 |
879 | # For all products to be selected, "yes" must be placed in the "check" column.
880 | new_check_values = []
881 | for i in range(len(verify_search_result)):
882 | if 'Unselect' in status_select:
883 | new_check_values.append('no')
884 | else:
885 | new_check_values.append('yes')
886 |
887 | update_data = {}
888 | update_data['title'] = title_result
889 | update_data['price'] = price_result
890 | update_data['currency'] = currency_result
891 | update_data['check'] = new_check_values
892 | update_data['url'] = url_result
893 |
894 | search_result_data = pd.DataFrame(update_data, columns = ['title', 'price', 'currency', 'check', 'url'])
895 |
896 | with ExcelWriter('data/search_result.xlsx') as writer:
897 | search_result_data.to_excel(writer, 'Sheet', index=False)
898 | sleep(1)
899 | page_search_result(1)
900 |
901 |
902 | # Function to delete the products added in the history.
903 | def delete_all_history(self):
904 | history_data = pd.DataFrame(columns = ['date', 'title', 'price', 'url', 'platform'])
905 |
906 | with ExcelWriter('data/history.xlsx') as writer:
907 | history_data.to_excel(writer, 'Sheet', index=False)
908 | sleep(1)
909 | page_history(1)
910 |
911 | # Function to delete the products added in the search result.
912 | def delete_all_search_result(self):
913 | search_result_data = pd.DataFrame(columns = ['title', 'price', 'currency', 'check', 'url'])
914 |
915 | with ExcelWriter('data/search_result.xlsx') as writer:
916 | search_result_data.to_excel(writer, 'Sheet', index=False)
917 | sleep(1)
918 | page_search_result(1)
919 |
920 | # Function to delete the products added to the list of products to be published.
921 | def delete_all_products_publish(self):
922 | list_publish_data = pd.DataFrame(columns = ['title', 'price', 'currency', 'url'])
923 |
924 | with ExcelWriter('data/list_publish.xlsx') as writer:
925 | list_publish_data.to_excel(writer, 'Sheet', index=False)
926 | sleep(1)
927 | page_publish(1)
928 |
929 | # Function to select the products shown in the search result that will be added to the list of products to be published.
930 | def check_button(e):
931 | e.control.selected = not e.control.selected
932 | e.control.update()
933 |
934 | verify_search_result = pd.read_excel('data/search_result.xlsx', header = 0)
935 | title_result = verify_search_result['title'].values
936 | price_result = verify_search_result['price'].values
937 | currency_result = verify_search_result['currency'].values
938 | check_result = verify_search_result['check'].values
939 | url_result = verify_search_result['url'].values
940 |
941 | if e.control.selected == False:
942 | pass
943 | else:
944 | check_result[e.control.data] = 'yes'
945 |
946 | if e.control.selected == True:
947 | pass
948 | else:
949 | check_result[e.control.data] = 'no'
950 |
951 | search_result_data = {}
952 | search_result_data['title'] = title_result
953 | search_result_data['price'] = price_result
954 | search_result_data['currency'] = currency_result
955 | search_result_data['check'] = check_result
956 | search_result_data['url'] = url_result
957 |
958 |
959 | search_result_data = pd.DataFrame(search_result_data, columns = ['title', 'price', 'currency', 'check', 'url'])
960 | try:
961 | with ExcelWriter('data/search_result.xlsx') as writer:
962 | search_result_data.to_excel(writer, 'Sheet', index=False)
963 | except:
964 | sleep(1)
965 | with ExcelWriter('data/search_result.xlsx') as writer:
966 | search_result_data.to_excel(writer, 'Sheet', index=False)
967 |
968 |
969 | # Function to open the URL of the products added in the list of products to be published.
970 | def view_url_list_publish(e):
971 | try:
972 | verify_list_publish = pd.read_excel('data/list_publish.xlsx', header = 0)
973 | title_publish = verify_list_publish['title'].values
974 | url_publish = verify_list_publish['url'].values
975 | except:
976 | sleep(1)
977 | verify_list_publish = pd.read_excel('data/list_publish.xlsx', header = 0)
978 | title_publish = verify_list_publish['title'].values
979 | url_publish = verify_list_publish['url'].values
980 |
981 | webbrowser.open(url_publish[e.control.data])
982 |
983 | # Function to open the URL of the products added in the history of published products.
984 | def view_url_history(e):
985 | try:
986 | verify_history = pd.read_excel('data/history.xlsx', header = 0)
987 | url_history = verify_history['url'].values
988 |
989 | except:
990 | sleep(1)
991 | verify_history = pd.read_excel('data/history.xlsx', header = 0)
992 | url_history = verify_history['url'].values
993 |
994 | webbrowser.open(url_history[e.control.data])
995 |
996 | # Function to open the URL of the products added in the search result.
997 | def view_url_search_result(e):
998 | try:
999 | verify_search_result = pd.read_excel('data/search_result.xlsx', header = 0)
1000 | title_result = verify_search_result['title'].values
1001 | url_result = verify_search_result['url'].values
1002 | except:
1003 | sleep(1)
1004 | verify_search_result = pd.read_excel('data/search_result.xlsx', header = 0)
1005 | title_result = verify_search_result['title'].values
1006 | url_result = verify_search_result['url'].values
1007 |
1008 | webbrowser.open(url_result[e.control.data])
1009 |
1010 | # Function that displays the search result page.
1011 | def page_search_result(self):
1012 |
1013 | verify_search_result = pd.read_excel('data/search_result.xlsx', header = 0)
1014 |
1015 | title_result = verify_search_result['title'].values
1016 | price_result = verify_search_result['price'].values
1017 | currency_result = verify_search_result['currency'].values
1018 | check_result = verify_search_result['check'].values
1019 | url_result = verify_search_result['url'].values
1020 |
1021 | all_results = ft.Column(scroll="always", expand=True)
1022 |
1023 | show_price_0 = switch_show_price_0.value
1024 |
1025 | if 'no' in check_result:
1026 | select_products = ft.ElevatedButton(text = "Select All", icon="check_box_outlined", on_click=select_all_search_result)
1027 | else:
1028 | select_products = ft.ElevatedButton(text = "Unselect All", icon="check_box_outline_blank_rounded", on_click=select_all_search_result)
1029 |
1030 | check = []
1031 |
1032 | if show_price_0:
1033 | switch_show_price_0.label = 'Showing all products found'
1034 | if len(verify_search_result) > 0:
1035 | currency = f"({currency_result[0]})"
1036 | for c in check_result:
1037 | if c == 'yes':
1038 | check.append(True)
1039 | else:
1040 | check.append(False)
1041 |
1042 | for i in range(len(check_result)):
1043 |
1044 | all_results.controls.append(
1045 | ft.Row(spacing=28, run_spacing=5, controls=[
1046 | Text(f"{i+1}. "),
1047 | ft.IconButton(on_click=view_url_search_result, data = i, icon="remove_red_eye_rounded", icon_size=20),
1048 | ft.TextField(value=title_result[i], label = i, on_blur=change_title_result, text_align="start", keyboard_type = "text", width=250, height = 50, text_size=12, content_padding = 10),
1049 | ft.TextField(value=price_result[i], label = i, on_blur=change_price_result, text_align="start", keyboard_type = "number", width=70, height = 50, text_size=12, content_padding = 10),
1050 | ft.IconButton(on_click=check_button, data = i, icon="check_box_outline_blank_rounded", selected=check[i], selected_icon="check_box_rounded", icon_size=20),
1051 | ], alignment="center", vertical_alignment = "center")
1052 | )
1053 |
1054 |
1055 | else:
1056 | currency = ''
1057 | all_results.controls.append(
1058 | ft.Row(spacing=40, run_spacing=10, controls=[
1059 | Text("You have not yet searched for products")
1060 | ], alignment="center", vertical_alignment = "center")
1061 | )
1062 |
1063 | else:
1064 | switch_show_price_0.label = 'Hiding unpriced products'
1065 | if len(verify_search_result) > 0:
1066 | currency = f"({currency_result[0]})"
1067 | for i in range(len(verify_search_result)):
1068 | if check_result[i] == 'yes':
1069 | check.append(True)
1070 | else:
1071 | check.append(False)
1072 |
1073 | if price_result[i] == 0:
1074 | pass
1075 | else:
1076 | all_results.controls.append(
1077 | ft.Row(spacing=28, run_spacing=5, controls=[
1078 | Text(f"{i+1}. "),
1079 | ft.IconButton(on_click=view_url_search_result, data = i, icon="remove_red_eye_rounded", icon_size=20),
1080 | ft.TextField(value=title_result[i], label = i, on_blur=change_title_result, text_align="start", keyboard_type = "text", width=250, height = 50, text_size=12, content_padding = 10),
1081 | ft.TextField(value=price_result[i], label = i, on_blur=change_price_result, text_align="start", keyboard_type = "number", width=70, height = 50, text_size=12, content_padding = 10),
1082 | ft.IconButton(on_click=check_button, data = i, icon="check_box_outline_blank_rounded", selected=check[i], selected_icon="check_box_rounded", icon_size=20),
1083 | ], alignment="center", vertical_alignment = "center")
1084 | )
1085 | else:
1086 | currency = ''
1087 | all_results.controls.append(
1088 | ft.Row(spacing=40, run_spacing=10, controls=[
1089 | Text("You have not yet searched for products")
1090 | ], alignment="center", vertical_alignment = "center")
1091 | )
1092 |
1093 |
1094 | page.clean()
1095 | title_search_result = Text(
1096 | value="Search Result",
1097 | size=20,
1098 | color="white",
1099 | weight="bold",
1100 | italic=True,
1101 | )
1102 |
1103 | page.add(
1104 | ft.Container(height = 50, content= title_search_result, alignment=ft.alignment.center),
1105 | ft.Divider(height=1, color="black"),
1106 | ft.Row(spacing=1, controls=[
1107 | Text('N°', width=55, text_align="center"),
1108 | Text('View', width=60, text_align="center"),
1109 | Text('Product Title', width=290, text_align="center"),
1110 | Text(f'Price {currency}', width=80, text_align="center"),
1111 | Text('Check',width=80, text_align="center"),
1112 | ],
1113 | alignment="center", vertical_alignment = "center"),
1114 | ft.Divider(height=1, color="black"),
1115 | ft.Container(height= 358, content=all_results),
1116 | ft.Row(controls=[
1117 | ft.ElevatedButton("Add to Publish", icon="add_circle_outline_rounded", on_click=add_to_publish),
1118 | ft.ElevatedButton("Delete All", icon="delete_rounded", on_click=delete_all_search_result),
1119 | select_products
1120 | ],
1121 | alignment="center", vertical_alignment = "start"),
1122 | ft.Row(controls=[switch_show_price_0], alignment="center", vertical_alignment = "start"),
1123 | ft.Container(content= ft.Row(controls=list_all_button_menu,
1124 | alignment="center", vertical_alignment = "end"),
1125 | height = 50
1126 | )
1127 | )
1128 |
1129 | def stop_search_product(e):
1130 | processes_search_product[0].kill()
1131 |
1132 | processes_search_product.pop(0)
1133 | # To read the data contained in the file that stores the products to be searched.
1134 | verify_search_product = pd.read_excel('data/search_product.xlsx', header = 0)
1135 |
1136 | # The data in the file that stores the search requests is deleted so that it does not continue searching.
1137 | delete_product_data = pd.DataFrame(columns = ['title', 'region', 'pub'])
1138 |
1139 | # This loop will check if the file still has data. If it has data, it will proceed to delete it.
1140 | while len(verify_search_product) !=0:
1141 | try:
1142 | with ExcelWriter('data/search_product.xlsx') as writer:
1143 | delete_product_data.to_excel(writer, 'Sheet', index=False)
1144 | except:
1145 | sleep(1)
1146 | with ExcelWriter('data/search_product.xlsx') as writer:
1147 | delete_product_data.to_excel(writer, 'Sheet', index=False)
1148 |
1149 | # The file is rechecked to see if it still has data.
1150 | verify_search_product = pd.read_excel('data/search_product.xlsx', header = 0)
1151 | sleep(1)
1152 |
1153 | # The function that displays the main is called
1154 | page_main(1)
1155 |
1156 |
1157 | # Function to change the data of the products to be searched.
1158 | def change_search_product(e):
1159 | search_text = search_form.value # Stores the data entered in the product search field.
1160 | region = select_region.value # Stores the selected Amazon region.
1161 | quick_search = switch_quick_search.value
1162 |
1163 | if quick_search:
1164 | quick_search = 'yes'
1165 | else:
1166 | quick_search = 'no'
1167 |
1168 | search_product_data = {}
1169 |
1170 | search_product_data['title'] = [search_text]
1171 | search_product_data['region'] = [region]
1172 | search_product_data['pub'] = ['no'] # It is saved as 'no', to identify that the product has not been selected for publication.
1173 | search_product_data['quick'] = [quick_search]
1174 |
1175 | search_product_data = pd.DataFrame(search_product_data, columns = ['title', 'region', 'pub', 'quick'])
1176 |
1177 | verify_status_support = pd.read_excel('data/support_dev.xlsx', header = 0)
1178 | sup_tag = verify_status_support['sup_tag'].values
1179 | sup_dev = verify_status_support['sup_dev'].values
1180 |
1181 | support_data = {}
1182 |
1183 | if 'com' in region:
1184 | sup_tag = 'amla02-20'
1185 | else:
1186 | sup_tag = 'amla07-21'
1187 |
1188 | support_data['sup_tag'] = [sup_tag]
1189 | support_data['sup_dev'] = sup_dev
1190 |
1191 | update_status_support = pd.DataFrame(support_data, columns = ['sup_tag', 'sup_dev'])
1192 | try:
1193 | with ExcelWriter('data/support_dev.xlsx') as writer:
1194 | update_status_support.to_excel(writer, 'Sheet', index=False)
1195 | except:
1196 | sleep(1)
1197 | with ExcelWriter('data/support_dev.xlsx') as writer:
1198 | update_status_support.to_excel(writer, 'Sheet', index=False)
1199 |
1200 | try:
1201 | with ExcelWriter('data/search_product.xlsx') as writer:
1202 | search_product_data.to_excel(writer, 'Sheet', index=False)
1203 | except:
1204 | sleep(1)
1205 | with ExcelWriter('data/search_product.xlsx') as writer:
1206 | search_product_data.to_excel(writer, 'Sheet', index=False)
1207 |
1208 |
1209 | def search_products(e):
1210 | change_search_product(e)
1211 | sleep(1)
1212 | try:
1213 | verify_search_product = pd.read_excel('data/search_product.xlsx', header = 0)
1214 | except:
1215 | sleep(2)
1216 | verify_search_product = pd.read_excel('data/search_product.xlsx', header = 0)
1217 | count_progress = 0
1218 |
1219 | if len(verify_search_product) == 0:
1220 | pass
1221 | else:
1222 | processes_search_product[0].start()
1223 |
1224 | page.clean()
1225 | searching_text = Text(
1226 | value="Searching...",
1227 | size=15,
1228 | color="white",
1229 | italic=False,
1230 | )
1231 | progress_bar = ft.ProgressBar(width=400)
1232 | page.add(
1233 | ft.Container(content= ft.Column(controls=[
1234 | title_amacapy,
1235 | ft.Row(alignment="center", controls=[searching_text]),
1236 | progress_bar,
1237 | press_button_search_stop
1238 | ], horizontal_alignment = "center", alignment="center"),
1239 | height= 520
1240 |
1241 |
1242 | ),
1243 | ft.Container(content= ft.Row(controls=list_all_button_menu,
1244 | alignment="center", vertical_alignment = "end"),
1245 | height = 100
1246 | )
1247 | )
1248 |
1249 |
1250 |
1251 | while len(verify_search_product) !=0: # and processes_search_product[0].is_alive():
1252 | try:
1253 | verify_search_product = pd.read_excel('data/search_product.xlsx', header = 0)
1254 | except:
1255 | sleep(2)
1256 | verify_search_product = pd.read_excel('data/search_product.xlsx', header = 0)
1257 | sleep(0.5)
1258 | progress_bar.value = count_progress * 0.01
1259 | count_progress+=1
1260 | page.clean()
1261 | page.add(
1262 | ft.Container(content= ft.Column(controls=[
1263 | title_amacapy,
1264 | ft.Row(alignment="center", controls=[searching_text]),
1265 | progress_bar,
1266 | press_button_search_stop
1267 | ], horizontal_alignment = "center", alignment="center"),
1268 | height= 520
1269 |
1270 |
1271 | ),
1272 | ft.Container(content= ft.Row(controls=list_all_button_menu,
1273 | alignment="center", vertical_alignment = "end"),
1274 | height = 100
1275 | )
1276 | )
1277 |
1278 | else:
1279 | if processes_search_product[0].is_alive():
1280 | processes_search_product[0].kill()
1281 | processes_search_product.pop(0)
1282 |
1283 | search_form.value = ''
1284 | page_search_result(1)
1285 |
1286 | # Function that displays the main page.
1287 | def page_main(e):
1288 | page.clean()
1289 | button_search = IconButton(on_click=search_products, icon="search_rounded")
1290 | page.add(
1291 | ft.Container(content= ft.Column(controls=[
1292 | title_amacapy,
1293 | ft.Row(alignment="center", controls=[search_form,
1294 | button_search]),
1295 | select_region,
1296 | ft.Row(alignment="center", controls=[switch_quick_search])
1297 | ], horizontal_alignment = "center", alignment="center"),
1298 | height= 520
1299 |
1300 |
1301 | ),
1302 | ft.Container(content= ft.Row(controls=list_all_button_menu,
1303 | alignment="center", vertical_alignment = "end"),
1304 | height = 100
1305 | )
1306 | )
1307 |
1308 | # Function that displays the setting page.
1309 | def page_settings(self):
1310 | self.page.clean()
1311 | self.title_settings = Text(
1312 | value="Settings",
1313 | size=20,
1314 | color="white",
1315 | weight="bold",
1316 | italic=True,
1317 | )
1318 | verify_status_support = pd.read_excel('data/support_dev.xlsx', header = 0)
1319 | sup_dev = verify_status_support['sup_dev'].values
1320 |
1321 | if sup_dev[0] == 'yes':
1322 | switch_supp_dev.value = True
1323 | switch_supp_dev.label = 'Supporting Development On 😊'
1324 | elif sup_dev[0] == 'no':
1325 | switch_supp_dev.value = False
1326 | switch_supp_dev.label = 'Supporting Development Off 😢'
1327 | else:
1328 | support_data = {}
1329 | support_data['sup_tag'] = ['dsuaz']
1330 | support_data['sup_dev'] = ['yes']
1331 | update_status_support = pd.DataFrame(support_data, columns = ['sup_tag', 'sup_dev'])
1332 | switch_supp_dev.value = True
1333 | switch_supp_dev.label = 'Supporting Development On 😊'
1334 |
1335 | with ExcelWriter('data/support_dev.xlsx') as writer:
1336 | update_status_support.to_excel(writer, 'Sheet', index=False)
1337 |
1338 |
1339 | verify_setting = pd.read_excel('data/setting.xlsx', header = 0)
1340 | amazon_id = verify_setting['amazon_id'].values
1341 | telegram_token = verify_setting['telegram_token'].values
1342 | chat_id = verify_setting['chat_id'].values
1343 |
1344 | if len(verify_setting) > 0:
1345 | if pd.isnull(amazon_id[0]):
1346 | form_amazon_id.value = ''
1347 | else:
1348 | form_amazon_id.value = amazon_id[0]
1349 |
1350 | if pd.isnull(telegram_token[0]):
1351 | form_telegram_token.value = ''
1352 | else:
1353 | form_telegram_token.value = telegram_token[0]
1354 |
1355 | if pd.isnull(chat_id[0]):
1356 | form_chat_id.value = ''
1357 | else:
1358 | form_chat_id.value = chat_id[0]
1359 |
1360 | else:
1361 | form_amazon_id.value = ''
1362 | form_telegram_token.value = ''
1363 | form_chat_id.value = ''
1364 |
1365 | self.page.add(
1366 | ft.Container(height = 50, content= self.title_settings, alignment=ft.alignment.center),
1367 | ft.Divider(height=1, color="black"),
1368 | ft.Container(content= ft.Column(alignment="center", controls=[
1369 | ft.Text(value="Add your Amazon ID"),
1370 | form_amazon_id,
1371 | ft.Divider(height=30, color="transparent"),
1372 | ft.Text(value="Add your Telegram data"),
1373 | form_telegram_token,
1374 | form_chat_id,
1375 | ft.Divider(height=30, color="transparent"),
1376 | ft.Text(value="Other options"),
1377 | press_button_custom_message,
1378 | button_select_short_url],
1379 | horizontal_alignment = "center"),
1380 | height= 449
1381 | ),
1382 | ft.Container(content= ft.Row(controls=list_all_button_menu,
1383 | alignment="center", vertical_alignment = "end"),
1384 | height = 100
1385 | )
1386 | )
1387 |
1388 | def select_short_url(e):
1389 | short_url_label = e.control.label
1390 | short_url_value = e.control.value
1391 |
1392 | if 'Tinyurl' in short_url_label:
1393 | if short_url_value == True:
1394 | short_url = 'tinyurl'
1395 | else:
1396 | short_url = 'no'
1397 | elif 'Is.gd' in short_url_label:
1398 | if short_url_value == True:
1399 | short_url = 'isgd'
1400 | else:
1401 | short_url = 'no'
1402 | elif 'Da.gd' in short_url_label:
1403 | if short_url_value == True:
1404 | short_url = 'dagd'
1405 | else:
1406 | short_url = 'no'
1407 | else:
1408 | short_url = 'no'
1409 |
1410 | short_url_data = [short_url]
1411 | update_short_url = pd.DataFrame(short_url_data, columns = ['short_url'])
1412 | with ExcelWriter('data/short_url.xlsx') as writer:
1413 | update_short_url.to_excel(writer, 'Sheet', index=False)
1414 |
1415 | page_short_url(1)
1416 |
1417 | # Function to display the menu with the short url.
1418 | def page_short_url(e):
1419 | verify_short_url = pd.read_excel('data/short_url.xlsx', header = 0)
1420 | short_url = verify_short_url['short_url'].values
1421 |
1422 | if short_url[0] == 'tinyurl':
1423 | switch_tinyurl_short_url.value = True
1424 | switch_isgd_short_url.value = False
1425 | switch_dagd_short_url.value = False
1426 | elif short_url[0] == 'isgd':
1427 | switch_tinyurl_short_url.value = False
1428 | switch_isgd_short_url.value = True
1429 | switch_dagd_short_url.value = False
1430 | elif short_url[0] == 'dagd':
1431 | switch_tinyurl_short_url.value = False
1432 | switch_isgd_short_url.value = False
1433 | switch_dagd_short_url.value = True
1434 | else:
1435 | switch_tinyurl_short_url.value = False
1436 | switch_isgd_short_url.value = False
1437 | switch_dagd_short_url.value = False
1438 |
1439 | title_settings = Text(
1440 | value="Settings",
1441 | size=20,
1442 | color="white",
1443 | weight="bold",
1444 | italic=True,
1445 | )
1446 |
1447 | page.clean()
1448 |
1449 | page.add(
1450 | ft.Container(height = 50, content= title_settings, alignment=ft.alignment.center),
1451 | ft.Divider(height=1, color="black"),
1452 | ft.Container(content= ft.Column(alignment="center",
1453 | controls=[ft.Row(controls=[Text(value='Select Short URL', size=16)], alignment="center"),
1454 | ft.Row(controls=[switch_tinyurl_short_url,
1455 | switch_isgd_short_url,
1456 | switch_dagd_short_url
1457 | ], alignment="center")
1458 | ],
1459 | horizontal_alignment = "center"),
1460 | width=400, height= 449
1461 | ),
1462 | ft.Container(content= ft.Row(controls=list_all_button_menu,
1463 | alignment="center", vertical_alignment = "end"),
1464 | height = 100
1465 | )
1466 | )
1467 |
1468 | def urls_support(e):
1469 | url = e.control.text
1470 |
1471 | if 'Paypal' in url:
1472 | url = 'https://paypal.me/davidsulbaran'
1473 | elif 'GitHub' in url:
1474 | url = 'https://github.com/sulasoft'
1475 | elif 'sulasoft' in url:
1476 | url = 'https://sulasoft.com'
1477 | elif 'Telegram' in url:
1478 | url = 'https://t.me/+xzxygFLwEmI1NzVh'
1479 | else:
1480 | url = 'https://www.linkedin.com/in/david-sulbarán-azócar-180768244/'
1481 |
1482 | webbrowser.open(url)
1483 |
1484 | def page_support(e):
1485 | page.clean()
1486 | title_support = Text(
1487 | value="Support",
1488 | size=20,
1489 | color="white",
1490 | weight="bold",
1491 | italic=True,
1492 | )
1493 | verify_status_support = pd.read_excel('data/support_dev.xlsx', header = 0)
1494 | sup_dev = verify_status_support['sup_dev'].values
1495 |
1496 | if sup_dev[0] == 'yes':
1497 | switch_supp_dev.value = True
1498 | switch_supp_dev.label = 'Supporting Development On 😊'
1499 | elif sup_dev[0] == 'no':
1500 | switch_supp_dev.value = False
1501 | switch_supp_dev.label = 'Supporting Development Off 😢'
1502 | else:
1503 | support_data = {}
1504 | support_data['sup_tag'] = ['dsuaz']
1505 | support_data['sup_dev'] = ['yes']
1506 | update_status_support = pd.DataFrame(support_data, columns = ['sup_tag', 'sup_dev'])
1507 | switch_supp_dev.value = True
1508 | switch_supp_dev.label = 'Supporting Development On 😊'
1509 |
1510 | with ExcelWriter('data/support_dev.xlsx') as writer:
1511 | update_status_support.to_excel(writer, 'Sheet', index=False)
1512 |
1513 | page.add(
1514 | ft.Container(height = 50, content= title_support, alignment=ft.alignment.center),
1515 | ft.Divider(height=1, color="black"),
1516 | ft.Container(width=650, height = 449, content= ft.Column(alignment="center", controls=[
1517 | ft.Row(controls=[
1518 | ft.Text(value= "You can support the development by sharing a link to the developer's affiliate tag.")
1519 | ], alignment="center", vertical_alignment = "center"),
1520 | ft.Row(controls=[
1521 | switch_supp_dev, button_info_supp
1522 | ], alignment="center", vertical_alignment = "center"),
1523 | ft.Divider(height=60, color="transparent"),
1524 | ft.Row(controls=[
1525 | ft.Text(value="You can also contribute monetarily \n I would be very grateful ❤️", text_align ='center')
1526 | ], alignment="center", vertical_alignment = "center"),
1527 | ft.Row(controls=[
1528 | ft.Text(value = "USDT \n Address", text_align ='center', size = 12, weight='bold'),
1529 | usdt_address,
1530 | ft.Text(value = "Tron (TRC20) \n Network", size = 10)
1531 | ], alignment="center", vertical_alignment = "center"),
1532 | ft.Row(controls=[
1533 | paypal_button
1534 | ], alignment="center", vertical_alignment = "center"),
1535 | ft.Divider(height=60, color="transparent"),
1536 | ft.Row(controls=[
1537 | ft.Text(value="My contact networks", text_align ='center')
1538 | ], alignment="center", vertical_alignment = "center"),
1539 | ft.Row(controls=[
1540 | github_button, linkedin_button, sulasoftcom_button, telegram_channel_button
1541 | ], alignment="center", vertical_alignment = "center"),
1542 | ft.Row(controls=[
1543 | ft.Text(value="Thank you! 😊", text_align ='center')
1544 | ], alignment="center", vertical_alignment = "center")])
1545 | ),
1546 | ft.Container(content= ft.Row(controls=list_all_button_menu,
1547 | alignment="center", vertical_alignment = "end"),
1548 | height = 100
1549 | )
1550 | )
1551 |
1552 | switch_quick_search = ft.Switch(label = 'Quick search', value=True)
1553 | search_form = TextField(label="Search...", width=400, height = 50, on_submit=search_products, text_align="start", keyboard_type = "text", text_size=12, content_padding = 10)
1554 | select_region = ft.RadioGroup(content=ft.Row(alignment="center", controls=[
1555 | ft.Text("Amazon "),
1556 | ft.Radio(value=".com", label=".com"),
1557 | ft.Radio(value=".es", label=".es"),
1558 | ft.Radio(value=".it", label=".it"),
1559 | ft.Radio(value=".in", label=".in")]), value = ".com")
1560 |
1561 | minutes_publish = TextField(value='0', label = 'Minutes', text_align="start", keyboard_type = "text", width=70, height = 50, text_size=12, content_padding = 10)
1562 | press_button_publish_on_stop = ft.ElevatedButton("Stop", icon="stop_circle_rounded", on_click=stop_publish_on)
1563 | press_button_search_stop = ft.ElevatedButton("Stop", icon="stop_circle_rounded", on_click=stop_search_product)
1564 |
1565 | # To know if a product has been selected or not
1566 | check_status = False
1567 |
1568 | # Menu
1569 | press_button_main = IconButton(on_click=page_main, icon="home_rounded", tooltip= 'Home')
1570 | press_button_list_result = IconButton(on_click=page_search_result, icon="format_list_numbered_rounded", tooltip= 'Search Result')
1571 | press_button_list_publish = IconButton(on_click=page_publish, icon="checklist_rounded", tooltip= 'Products to Publish')
1572 | press_button_history = IconButton(on_click=page_history, icon="history_rounded", tooltip= 'History')
1573 | press_button_setting = IconButton(on_click=page_settings, icon="settings_rounded", tooltip= 'Settings')
1574 | press_button_info = IconButton(on_click=page_support, icon="info_rounded", tooltip= "Support")
1575 | list_all_button_menu = [press_button_main, press_button_list_result, press_button_list_publish, press_button_history, press_button_setting, press_button_info]
1576 |
1577 | # Settings form
1578 | form_amazon_id = TextField(label="Amazon ID", text_align="center", on_blur=change_amazon_id, width=400, height = 45, text_size=13)
1579 | form_telegram_token = TextField(label="Telegram Token", text_align="center", on_blur=change_telegram_token, width=400, height = 45, text_size=13)
1580 | form_chat_id = TextField(label="Chat ID Example: yourchatid", text_align="center", on_blur=change_chat_id, width=400, height = 45, text_size=13)
1581 |
1582 | # For modify message displayed in Telegram
1583 | switch_tinyurl_short_url = ft.Switch(label= 'Tinyurl', on_change=select_short_url)
1584 | switch_isgd_short_url = ft.Switch(label= 'Is.gd',on_change=select_short_url)
1585 | switch_dagd_short_url = ft.Switch(label= 'Da.gd',on_change=select_short_url)
1586 | button_select_short_url = ft.ElevatedButton("Modify Short URL", icon="edit_rounded", on_click=page_short_url)
1587 | press_button_custom_message = ft.ElevatedButton("Modify publication message", icon="edit_rounded", on_click=custom_message)
1588 | form_before_title_message = TextField(label="Before Title Message", text_align="center", on_blur=change_custom_message, width=400, height = 45, text_size=13)
1589 | form_sale_price_message = TextField(label="Sale Price Message", text_align="center", on_blur=change_custom_message, width=400, height = 45, text_size=13)
1590 | form_original_price_message = TextField(label="Original Price Message", text_align="center", on_blur=change_custom_message, width=400, height = 45, text_size=13)
1591 | form_currency_message = TextField(label="Currency ($, €)", text_align="center", on_blur=change_custom_message, width=400, height = 45, text_size=13)
1592 | form_url_message = TextField(label="URL Message", text_align="center", on_blur=change_custom_message, width=400, height = 45, text_size=13)
1593 |
1594 |
1595 | # To support or not to support development
1596 | usdt_address = ft.TextField(value='TJajbMu8Q1xPG38VzGHQTKT4Wo2T3x4nUR', read_only = True, text_align="start", keyboard_type = "text", width=300, height = 50, text_size=12, content_padding = 10)
1597 | switch_supp_dev = ft.Switch(on_change=support_development)
1598 | paypal_button = ft.ElevatedButton(text= "Paypal", icon = 'paypal',on_click=urls_support)
1599 | github_button = ft.TextButton(text = "GitHub", on_click=urls_support)
1600 | sulasoftcom_button = ft.TextButton(text = "sulasoft.com", on_click=urls_support)
1601 | linkedin_button = ft.TextButton(text = "Linkedin", on_click=urls_support)
1602 | telegram_channel_button = ft.TextButton(text = "Telegram", icon = 'telegram', on_click=urls_support)
1603 | button_info_supp = ft.IconButton(icon="info_rounded", tooltip= "1 out of 6 published products contains the developer's amazon affiliates tag.")
1604 |
1605 | # Switch to view or not the products with price 0
1606 | switch_show_price_0 = ft.Switch(on_change=page_search_result, value=True)
1607 |
1608 |
1609 | page.add(
1610 | ft.Row(page_main(0))
1611 | )
1612 |
1613 | main_interface()
1614 |
1615 | ft.app(target=main)
1616 |
--------------------------------------------------------------------------------
/publish.py:
--------------------------------------------------------------------------------
1 | import time
2 | from time import sleep
3 | import requests
4 | from threading import Thread
5 | import threading
6 | from bs4 import BeautifulSoup
7 | from pyshorteners import Shortener
8 | import pandas as pd
9 | from pandas import ExcelWriter
10 | from datetime import datetime
11 |
12 |
13 | def enable(e):
14 | status_script = e
15 | if status_script:
16 | # To keep the program active waiting for requests.
17 | status_publish = True
18 |
19 | count_products = 0
20 |
21 | # To know if URL shorteners will be used or not.
22 | verify_short_url = pd.read_excel('data/short_url.xlsx', header = 0)
23 | url_short = verify_short_url['short_url'].values
24 | sleep(1)
25 |
26 | # To verify program development support data.
27 | verify_support_dev = pd.read_excel('data/support_dev.xlsx', header = 0)
28 | sup_tag = verify_support_dev['sup_tag'].values
29 | sup_dev = verify_support_dev['sup_dev'].values
30 |
31 | sup_tag = sup_tag[0]
32 | sup_dev = sup_dev[0]
33 |
34 | while status_publish:
35 | try:
36 | # It is confirmed that there are products added to be published.
37 | verify_publish = pd.read_excel('data/publish_on.xlsx', header = 0)
38 |
39 |
40 | if len(verify_publish) > 0:
41 | title_publish = verify_publish['title'].values
42 | price_publish = verify_publish['price'].values
43 | url_publish = verify_publish['url'].values
44 | min_publish = verify_publish['min'].values
45 | telegram_publish = verify_publish['telegram'].values
46 |
47 | # To get the configuration data, such as Telegram Token and Chat ID.
48 | verify_setting = pd.read_excel('data/setting.xlsx', header = 0)
49 | telegram_token = verify_setting['telegram_token'].values
50 | chat_id = verify_setting['chat_id'].values
51 |
52 | # To obtain the data stored with the custom message for the publications.
53 | verify_custom_message = pd.read_excel('data/custom_message.xlsx', header = 0)
54 | before_title_message = verify_custom_message['before_title'].values
55 | original_price_message = verify_custom_message['original_price'].values
56 | sale_price_message = verify_custom_message['sale_price'].values
57 | currency_message = verify_custom_message['currency'].values
58 | url_message = verify_custom_message['url'].values
59 |
60 | for i in range(len(verify_publish)):
61 | sleep(2)
62 | # Check again that there are products to be published.
63 | new_verify_publish = pd.read_excel('data/publish_on.xlsx', header = 0)
64 |
65 | if len(new_verify_publish) > 0:
66 |
67 | new_url_publish = url_publish[i]
68 |
69 | # When the published products counter reaches 3, a product will be published with the developer's affiliate tag.
70 | # This will only happen if the user has the option activated to support the development of the program.
71 | if count_products == 5 and 'yes' in sup_dev:
72 | headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36', 'referer': f'https://google.com',}
73 |
74 | try:
75 | req = requests.get(url_publish[i], headers=headers, timeout=10)
76 |
77 | soup = BeautifulSoup(req.text, "html.parser")
78 |
79 | product_link = soup.find('link', rel='canonical').get('href') + '/&tag=' + sup_tag
80 |
81 | except:
82 |
83 | req = requests.get(url_publish[i], headers=headers, timeout=10)
84 |
85 | soup = BeautifulSoup(req.text, "html.parser")
86 |
87 | product_link = soup.find('link', rel='canonical').get('href') + '/&tag=' + sup_tag
88 |
89 | try:
90 | new_url_publish = Shortener().tinyurl.short(product_link)
91 | except:
92 | sleep(3)
93 | new_url_publish = Shortener().tinyurl.short(product_link)
94 | pass
95 |
96 | print('Thank you! 😊')
97 | count_products = 0
98 | else:
99 | count_products += 1
100 |
101 |
102 | # To verify if any url shortener will be used.
103 | try:
104 | if url_short[0] == 'tinyurl':
105 | new_url_publish = Shortener().tinyurl.short(new_url_publish)
106 | elif url_short[0] == 'isgd':
107 | new_url_publish = Shortener().isgd.short(new_url_publish)
108 | elif url_short[0] == 'dagd':
109 | new_url_publish = Shortener().dagd.short(new_url_publish)
110 | else:
111 | pass
112 | except:
113 | sleep(3)
114 | if url_short[0] == 'tinyurl':
115 | new_url_publish = Shortener().tinyurl.short(new_url_publish)
116 | elif url_short[0] == 'isgd':
117 | new_url_publish = Shortener().isgd.short(new_url_publish)
118 | elif url_short[0] == 'dagd':
119 | new_url_publish = Shortener().dagd.short(new_url_publish)
120 | else:
121 | pass
122 |
123 | # It will publish on Telegram the products that were selected to be published.
124 | if 'yes' in telegram_publish[i]:
125 | try:
126 | requests.post('https://api.telegram.org/bot' + telegram_token[0] + "/sendMessage",
127 | data = {'chat_id' : f'@{chat_id[0]}',
128 | 'text':
129 | before_title_message[0] + ' ' + title_publish[i] + '\n \n' + sale_price_message[0] + ' ' + str(price_publish[i]) + ' ' + currency_message[0] + '\n' + original_price_message[0] + ' ' + str(round(price_publish[i] + (price_publish[i]*30/100 ), 2)) + ' ' + currency_message[0] + '\n' + url_message[0] + ' ' + new_url_publish
130 | })
131 | except:
132 | sleep(10)
133 | requests.post('https://api.telegram.org/bot' + telegram_token[0] + "/sendMessage",
134 | data = {'chat_id' : f'@{chat_id[0]}',
135 | 'text':
136 | before_title_message[0] + ' ' + title_publish[i] + '\n \n' + sale_price_message[0] + ' ' + str(price_publish[i]) + ' ' + currency_message[0] + '\n' + original_price_message[0] + ' ' + str(round(price_publish[i] + (price_publish[i]*30/100 ), 2)) + ' ' + currency_message[0] + '\n' + url_message[0] + ' ' + new_url_publish
137 | })
138 |
139 |
140 | # It will save the current date.
141 | date_publish = datetime.now()
142 |
143 | try:
144 | # To remove the published product from the list of requests.
145 | verify_publish = pd.read_excel('data/publish_on.xlsx', header = 0)
146 | verify_publish = verify_publish.drop(0)
147 | update_publish_data = pd.DataFrame(verify_publish, columns = ['title', 'price', 'url', 'min', 'telegram'])
148 |
149 | with ExcelWriter('data/publish_on.xlsx') as writer:
150 | update_publish_data.to_excel(writer, 'Sheet', index=False)
151 | except:
152 | try:
153 | sleep(3)
154 | # To remove the published product from the list of requests.
155 | verify_publish = pd.read_excel('data/publish_on.xlsx', header = 0)
156 | verify_publish = verify_publish.drop(0)
157 | update_publish_data = pd.DataFrame(verify_publish, columns = ['title', 'price', 'url', 'min', 'telegram'])
158 |
159 | with ExcelWriter('data/publish_on.xlsx') as writer:
160 | update_publish_data.to_excel(writer, 'Sheet', index=False)
161 | except:
162 | update_publish_data = pd.DataFrame(columns = ['title', 'price', 'url', 'min', 'telegram'])
163 |
164 | with ExcelWriter('data/publish_on.xlsx') as writer:
165 | update_publish_data.to_excel(writer, 'Sheet', index=False)
166 |
167 | # To check the list of products to be published
168 | verify_list_publish = pd.read_excel('data/list_publish.xlsx', header = 0)
169 | title_publish = verify_list_publish['title'].values
170 | price_publish = verify_list_publish['price'].values
171 | url_publish = verify_list_publish['url'].values
172 |
173 | # They will be used to save the data stored in list_publish.xlsx and add them to publish_on.xlsx
174 | # (this file stores the products that will be published).
175 | title_publish_on = []
176 | price_publish_on = []
177 | url_publish_on = []
178 | minutes_publish_on = []
179 | telegram_publish_on = []
180 |
181 | for i in range(len(verify_list_publish)):
182 | title_publish_on.append(title_publish[i])
183 | price_publish_on.append(price_publish[i])
184 | url_publish_on.append(url_publish[i])
185 | minutes_publish_on.append(min_publish[i])
186 | telegram_publish_on.append('yes')
187 |
188 |
189 | add_history = {'title': title_publish_on, 'price': price_publish_on, 'url': url_publish_on, 'min': minutes_publish_on,'telegram':telegram_publish_on}
190 |
191 | update_publish_on = pd.DataFrame(add_history, columns = ['title', 'price', 'url', 'min', 'telegram'])
192 |
193 | with ExcelWriter('data/publish_on.xlsx') as writer:
194 | update_publish_on.to_excel(writer, 'Sheet', index=False)
195 |
196 | # To remove the published product from the list of requests.
197 | verify_publish = pd.read_excel('data/publish_on.xlsx', header = 0)
198 | verify_publish = verify_publish.drop(0)
199 |
200 | # To remove the published product from the list of products to be published.
201 | try:
202 | verify_list_publish = pd.read_excel('data/list_publish.xlsx', header = 0)
203 | verify_list_publish = verify_list_publish.drop(0)
204 | update_list_publish_data = pd.DataFrame(verify_list_publish, columns = ['title', 'price', 'currency', 'url'])
205 |
206 | with ExcelWriter('data/list_publish.xlsx') as writer:
207 | update_list_publish_data.to_excel(writer, 'Sheet', index=False)
208 | except:
209 | try:
210 | sleep(3)
211 | verify_list_publish = pd.read_excel('data/list_publish.xlsx', header = 0)
212 | verify_list_publish = verify_list_publish.drop(0)
213 | update_list_publish_data = pd.DataFrame(verify_list_publish, columns = ['title', 'price', 'currency', 'url'])
214 |
215 | with ExcelWriter('data/list_publish.xlsx') as writer:
216 | update_list_publish_data.to_excel(writer, 'Sheet', index=False)
217 | except:
218 | update_list_publish_data = pd.DataFrame(columns = ['title', 'price', 'currency', 'url'])
219 | with ExcelWriter('data/list_publish.xlsx') as writer:
220 | update_list_publish_data.to_excel(writer, 'Sheet', index=False)
221 |
222 | # To add the published product to the history.
223 | try:
224 | verify_history = pd.read_excel('data/history.xlsx', header = 0)
225 | add_history = {'date': date_publish.today(), 'title': title_publish[i], 'price': price_publish[i], 'url': url_publish[i], 'platform': 'Telegram'}
226 | add_history = pd.DataFrame(add_history, index=[0])
227 |
228 | verify_history = pd.concat([verify_history, add_history], axis=0)
229 | update_history_data = pd.DataFrame(verify_history, columns = ['date', 'title', 'price', 'url', 'platform'])
230 |
231 | with ExcelWriter('data/history.xlsx') as writer:
232 | update_history_data.to_excel(writer, 'Sheet', index=False)
233 | except:
234 | try:
235 | sleep(3)
236 | verify_history = pd.read_excel('data/history.xlsx', header = 0)
237 | add_history = {'date': date_publish.today(), 'title': title_publish[i], 'price': price_publish[i], 'url': url_publish[i], 'platform': 'Telegram'}
238 | add_history = pd.DataFrame(add_history, index=[0])
239 |
240 | verify_history = pd.concat([verify_history, add_history], axis=0)
241 | update_history_data = pd.DataFrame(verify_history, columns = ['date', 'title', 'price', 'url', 'platform'])
242 |
243 | with ExcelWriter('data/history.xlsx') as writer:
244 | update_history_data.to_excel(writer, 'Sheet', index=False)
245 |
246 | except:
247 | update_history_data = pd.DataFrame(columns = ['date', 'title', 'price', 'url', 'platform'])
248 |
249 | with ExcelWriter('data/history.xlsx') as writer:
250 | update_history_data.to_excel(writer, 'Sheet', index=False)
251 |
252 | sleep(float(min_publish[i])*60)
253 |
254 | else:
255 | break
256 |
257 | else:
258 | # If there are no requests, it will wait for a new one.
259 | print('Waiting for publish...')
260 | sleep(1)
261 | status_script = False
262 |
263 |
264 | except Exception as e:
265 | print('Error ' + str(e))
266 |
267 |
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | beautifulsoup4==4.11.1
2 | flet==0.3.2
3 | pandas==1.5.2
4 | pyshorteners==1.0.1
5 | requests==2.28.1
6 | openpyxl==3.0.10
--------------------------------------------------------------------------------
/search_products.py:
--------------------------------------------------------------------------------
1 | import time
2 | from time import sleep
3 | import requests
4 | from threading import Thread
5 | import threading
6 | from bs4 import BeautifulSoup
7 | from pyshorteners import Shortener
8 | import pandas as pd
9 | from pandas import ExcelWriter
10 | import re
11 |
12 |
13 | def enable(e):
14 | status_script = e
15 | if status_script:
16 | status_search = True
17 | status_settings = True
18 | # To verify that the user has already added their publishing data: amazon id, telegram token and chat id.
19 | # If he has not added them, it will not perform the search and will show error.
20 | while status_settings:
21 | verify_setting = pd.read_excel('data/setting.xlsx', header = 0)
22 | setting_amazon_id = verify_setting['amazon_id'].values
23 | setting_telegram_token = verify_setting['telegram_token'].values
24 | setting_chat_id = verify_setting['chat_id'].values
25 |
26 | if len(setting_amazon_id) == 1 and len(setting_telegram_token) == 1 and len(setting_chat_id) == 1:
27 | amazon_id = setting_amazon_id[0]
28 | telegram_token = setting_telegram_token[0]
29 | chatid = setting_chat_id[0]
30 | status_settings = False
31 | else:
32 | print('Add your Amazon ID, Telegram Token and Chat ID in the Settings tab.')
33 | sleep(2)
34 |
35 |
36 | # So that the program is always active waiting for requests to perform searches.
37 | while status_search:
38 |
39 | verify_search_product = pd.read_excel('data/search_product.xlsx', header = 0)
40 |
41 | title_product = verify_search_product['title'].values
42 | region_product = verify_search_product['region'].values
43 | publish_product = verify_search_product['pub'].values
44 | quick_search = verify_search_product['quick'].values
45 |
46 | if len(verify_search_product) > 0 and not pd.isnull(title_product[0]):
47 |
48 | keyword = title_product[0]
49 | region = region_product[0]
50 |
51 | headers = []
52 | headers.append({'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36', 'referer': f'https://google{region}',})
53 | headers.append({'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36', 'referer':f'https://google{region}',})
54 |
55 | headers = headers[1]
56 |
57 | if region == '.com':
58 | currency = 'USD'
59 | elif region =='.in':
60 | currency = 'Rs'
61 | else:
62 | currency = 'EUR'
63 |
64 | # When the person enters the specific URL of a product, the program will scrape that web page.
65 | if keyword.startswith("http"):
66 |
67 | print(f'Searching...{keyword}')
68 |
69 | try:
70 | # Lists that will store the data obtained from the entered URL.
71 | new_title_result = []
72 | new_price_result = []
73 | new_currency_result = []
74 | new_check_result = []
75 | new_url_result = []
76 |
77 | url = keyword
78 |
79 | req = requests.get(url, headers=headers, timeout=10)
80 |
81 | soup = BeautifulSoup(req.text, "html.parser")
82 |
83 | product_title = soup.find('span', id="productTitle").text.strip()
84 |
85 | product_price = 0
86 |
87 | # The price of the product is searched for in different classes, if not found
88 | # the price of the product is set to 0.
89 | for k in range(0, 5):
90 | if headers != headers[1]:
91 | headers = headers[0]
92 | else:
93 | headers = headers[1]
94 | try:
95 | req = requests.get(url, headers=headers, timeout=10)
96 | sleep(3)
97 | soup = BeautifulSoup(req.text, "html.parser")
98 |
99 | try:
100 | product_stock = soup.find_all('span', class_="a-size-medium a-color-price")
101 | if len(product_stock) != 0:
102 | for n in product_stock:
103 | stock = n.text.strip()
104 | if 'out of stock' in stock:
105 | product_stock = 'no'
106 | break
107 | elif 'agotado' in stock:
108 | product_stock = 'no'
109 | break
110 | elif 'indisponível' in stock:
111 | product_stock = 'no'
112 | break
113 | elif 'No disponible' in stock:
114 | product_stock = 'no'
115 | break
116 | elif 'Non disponibile' in stock:
117 | product_stock = 'no'
118 | break
119 | elif 'unavailable' in stock:
120 | product_stock = 'no'
121 | else:
122 | pass
123 | except:
124 | pass
125 |
126 | if product_stock == 'no':
127 | break
128 |
129 |
130 | product_price = soup.find_all('span', class_="a-price a-text-price a-size-medium apexPriceToPay")
131 | print(product_price)
132 | if len(product_price) == 0:
133 | product_price = soup.find_all(class_="olpWrapper a-size-small")
134 | if len(product_price) == 0:
135 | product_price = soup.find_all('span', id="color_name_0_price")
136 |
137 | if len(product_price) == 0:
138 | product_price = soup.find_all('span', class_="a-size-base a-color-price")
139 |
140 | if len(product_price) == 0 or len(product_price) >= 2:
141 |
142 | try:
143 | product_price = soup.find('span', class_="a-offscreen").text.strip()
144 | except:
145 | product_price = '0'
146 | else:
147 | product_price = soup.find('span', class_="a-size-base a-color-price").text.strip()
148 | print(product_price)
149 | if len(product_price) > 6:
150 | product_price = '0'
151 | else:
152 | break
153 | else:
154 | product_price = soup.find('span', id="color_name_0_price").text.strip()
155 | # Method used to clean some data including price and other characters.
156 | all_price = ''
157 | for i in product_price:
158 | if '$' in all_price:
159 | all_price = ''
160 | all_price = f'{i}'
161 |
162 | else:
163 | all_price = f'{all_price}{i}'
164 | product_price = all_price
165 | break
166 | else:
167 | product_price = soup.find_all('span', class_="olpWrapper a-size-small")
168 | for i in product_price:
169 | product_price = i.text.strip()
170 | break
171 | all_price = ''
172 | for i in product_price:
173 | if '$' in all_price:
174 | all_price = ''
175 | all_price = f'{i}'
176 |
177 | else:
178 | all_price = f'{all_price}{i}'
179 | product_price = all_price
180 | break
181 |
182 | else:
183 | product_price = soup.find_all('span', class_="a-price a-text-price a-size-medium apexPriceToPay")
184 | for i in product_price:
185 | product_price = i.find('span', class_="a-offscreen").text.strip()
186 | break
187 |
188 | break
189 |
190 |
191 | except Exception as e:
192 | print(str(e))
193 | product_price = "0"
194 | pass
195 |
196 |
197 | if product_stock == 'no':
198 | pass
199 | else:
200 | # Sometimes the program does not get the price, so it assigns these values.
201 | # If this is the case, then the value of the variable "product_price" is changed to 0.
202 | try:
203 |
204 | if product_price == '':
205 | product_price = '0'
206 | elif 'US$' in product_price:
207 | new_currency_result.append('USD')
208 | product_price = product_price.replace('US$', '')
209 | elif '$' in product_price:
210 | new_currency_result.append('USD')
211 | product_price = product_price.replace('$', '')
212 | elif '€' in product_price:
213 | new_currency_result.append('EUR')
214 | product_price = product_price.replace('€', '')
215 | else:
216 | check_price = float(product_price)
217 |
218 | if len(new_currency_result) == 0:
219 | if '.com' in keyword:
220 | new_currency_result.append('USD')
221 | elif '.in' in keyword:
222 | new_currency_result.append('Rs')
223 | else:
224 | new_currency_result.append('EUR')
225 | except Exception as e:
226 | print(str(e))
227 | product_price = '0'
228 | pass
229 | # These methods are used to clean the data obtained.
230 | # To remove currency symbols and change commas to dots.
231 | if product_price != 0 and ',' in product_price or product_price != '0' and ',' in product_price:
232 | product_price = product_price.replace(',' , '.')
233 |
234 | product_price = float(product_price)
235 |
236 | # The original link is modified by adding the amazon affiliates tag.
237 | product_link = f'{keyword}&tag={amazon_id}'
238 |
239 | new_title_result.append(product_title)
240 | new_price_result.append(product_price)
241 | new_check_result.append('no')
242 | new_url_result.append(product_link)
243 |
244 | search_result_data = {}
245 |
246 | search_result_data['title'] = new_title_result
247 | search_result_data['price'] = new_price_result
248 | search_result_data['currency'] = new_currency_result
249 | search_result_data['check'] = new_check_result
250 | search_result_data['url'] = new_url_result
251 |
252 | search_result_data = pd.DataFrame(search_result_data, columns = ['title', 'price', 'currency', 'check', 'url'])
253 |
254 | print('Product price: ', product_price)
255 |
256 | with ExcelWriter('data/search_result.xlsx') as writer:
257 | search_result_data.to_excel(writer, 'Sheet', index=False)
258 |
259 | search_product_data = pd.DataFrame(columns = ['title', 'region', 'pub', 'quick'])
260 |
261 | with ExcelWriter('data/search_product.xlsx') as writer:
262 | search_product_data.to_excel(writer, 'Sheet', index=False)
263 |
264 | except Exception as e:
265 | print(str(e))
266 |
267 | # The products will be searched on Amazon through a keyword entered.
268 | else:
269 | count_product = 0
270 | try:
271 | print(f'Searching... {keyword} on amazon{region}')
272 |
273 | # The Amazon URL is modified with the selected region and the keyword of the product to be searched.
274 | url = f'https://www.amazon{region}/s?k={keyword}'
275 |
276 | req = requests.get(url, headers=headers, timeout=10)
277 |
278 | sleep(3)
279 |
280 | soup = BeautifulSoup(req.text, "html.parser")
281 |
282 | # Search for products through different classes
283 | products_list = soup.find_all('div', class_="s-result-item s-asin sg-col-0-of-12 sg-col-16-of-20 sg-col s-widget-spacing-small sg-col-12-of-16")
284 |
285 | if len(products_list) == 0:
286 | products_list = soup.find_all('div', class_="sg-col-4-of-12 s-result-item s-asin sg-col-4-of-16 sg-col s-widget-spacing-small sg-col-4-of-20")
287 | if len(products_list) == 0:
288 | products_list = soup.find_all(class_='s-card-container s-overflow-hidden aok-relative puis-include-content-margin puis s-latency-cf-section s-card-border')
289 | if len(products_list) == 0:
290 | products_list = soup.find_all(class_='sg-col-4-of-24 sg-col-4-of-12 s-result-item s-asin sg-col-4-of-16 sg-col s-widget-spacing-small sg-col-4-of-20')
291 |
292 | # Lists that will store product data.
293 | titles_products = []
294 | urls_products = []
295 | prices_products = []
296 | currency_products = []
297 | check_products = []
298 |
299 | # To select each product that is stored in the list of found products.
300 | for product in products_list:
301 |
302 | print("--------------------------------------------------------------")
303 |
304 | product_title = product.find_all('span', class_="a-size-base-plus a-color-base a-text-normal")
305 |
306 | if len(product_title) <= 0:
307 | product_title = product.find_all('h2', class_="a-size-mini a-spacing-none a-color-base s-line-clamp-2")
308 |
309 | if len(product_title) <= 0:
310 | product_title = product.find('span', class_="a-size-base-plus a-color-base a-text-normal").text.strip()
311 | else:
312 | product_title = product.find('h2', class_="a-size-mini a-spacing-none a-color-base s-line-clamp-2").text.strip()
313 | else:
314 | product_title = product.find('span', class_="a-size-base-plus a-color-base a-text-normal").text.strip()
315 |
316 | print(product_title)
317 |
318 | # The link is modified to add the amazon affiliates tag.
319 | product_link = 'https://amazon' + region + product.find('a', class_='a-link-normal s-no-outline').get('href') + '&tag='+ amazon_id
320 |
321 | print('Link: ', product_link)
322 |
323 | product_price = product.find('span', class_="a-price-whole")
324 |
325 | """
326 | If the product does not show a price, it may be a variable product,
327 | so the product is accessed directly to try to find its price.
328 | """
329 | if product_price is None and 'no' in quick_search:
330 |
331 | try:
332 | for i in range(0, 3):
333 | if headers != headers[1]:
334 | headers = headers[0]
335 | else:
336 | headers = headers[1]
337 |
338 | new_req = requests.get(product_link, headers=headers, timeout=10)
339 | new_soup = BeautifulSoup(new_req.text, "html.parser")
340 | product_stock = new_soup.find_all('span', class_="a-size-medium a-color-price")
341 |
342 | if len(product_stock) != 0:
343 | for n in product_stock:
344 | stock = n.text.strip()
345 | if 'out of stock' in stock:
346 | product_stock = 'no'
347 | break
348 | elif 'agotado' in stock:
349 | product_stock = 'no'
350 | break
351 | elif 'indisponível' in stock:
352 | product_stock = 'no'
353 | break
354 | elif 'No disponible' in stock:
355 | product_stock = 'no'
356 | break
357 |
358 | elif 'Non disponibile' in stock:
359 | product_stock = 'no'
360 | break
361 | elif 'unavailable' in stock:
362 | product_stock = 'no'
363 | break
364 | else:
365 | pass
366 |
367 | if product_stock == 'no':
368 | break
369 |
370 | product_price = new_soup.find_all('span', class_="a-price a-text-price a-size-medium apexPriceToPay")
371 | if len(product_price) == 0:
372 | product_price = new_soup.find_all(class_="a-button a-button-selected a-button-thumbnail a-button-toggle")
373 | if len(product_price) == 0:
374 | product_price = new_soup.find_all(class_="swatch-list-item-text inline-twister-swatch reduced-text-swatch-width a-declarative desktop-configurator-dim-row-0")
375 | if len(product_price) == 0:
376 | product_price = new_soup.find_all('span', id="color_name_0_price")
377 | if len(product_price) == 0:
378 | product_price = new_soup.find_all('span', class_="a-size-base a-color-price")
379 | if len(product_price) == 0 or len(product_price) >= 2:
380 | product_price = '0'
381 | else:
382 | product_price = new_soup.find('span', class_="a-size-base a-color-price").text.strip()
383 | if len(product_price) > 6:
384 | product_price = '0'
385 | else:
386 | break
387 | else:
388 | product_price = new_soup.find('span', id="color_name_0_price").text.strip()
389 | # Method used to clean some data including price and other characters.
390 | all_price = ''
391 | for i in product_price:
392 | if '$' in all_price:
393 | all_price = ''
394 | all_price = f'{i}'
395 |
396 | else:
397 | all_price = f'{all_price}{i}'
398 | product_price = all_price
399 | break
400 | else:
401 | product_price = new_soup.find_all(class_="swatch-list-item-text inline-twister-swatch reduced-text-swatch-width a-declarative desktop-configurator-dim-row-0")
402 | for i in product_price:
403 | product_price = i.text.strip()
404 | break
405 | all_price = ''
406 | for i in product_price:
407 | if '$' in all_price:
408 | all_price = ''
409 | all_price = f'{i}'
410 |
411 | else:
412 | all_price = f'{all_price}{i}'
413 | product_price = all_price
414 | break
415 | else:
416 | product_price = new_soup.find_all('span', class_="a-button a-button-selected a-button-thumbnail a-button-toggle")
417 | for i in product_price:
418 | product_price = i.text.strip()
419 | break
420 | all_price = ''
421 | for i in product_price:
422 | if '$' in all_price:
423 | all_price = ''
424 | all_price = f'{i}'
425 |
426 | else:
427 | all_price = f'{all_price}{i}'
428 | product_price = all_price
429 | break
430 | else:
431 | product_price = new_soup.find_all('span', class_="a-price a-text-price a-size-medium apexPriceToPay")
432 | for i in product_price:
433 | product_price = i.find('span', class_="a-offscreen").text.strip()
434 | break
435 | break
436 |
437 | if product_stock == 'no':
438 | pass
439 | else:
440 | # Sometimes the program does not get the price, so it assigns these values.
441 | # If this is the case, then the value of the variable "product_price" is changed to 0.
442 | try:
443 | if product_price == '':
444 | product_price = '0'
445 | elif 'US$' in product_price:
446 | product_price = product_price.replace('US$' , '')
447 | elif '$' in product_price:
448 |
449 | product_price = product_price.replace('$' , '')
450 | elif '€' in product_price:
451 | product_price = product_price.replace('€' , '')
452 | else:
453 | check_price = float(product_price)
454 |
455 | except Exception as e:
456 | print(str(e))
457 | product_price = '0'
458 |
459 | print('Product Price: ' + str(product_price))
460 |
461 | # These methods are used to clean the data obtained.
462 | # To remove currency symbols and change commas to dots.
463 | if product_price != 0 and ',' in product_price:
464 | product_price = product_price.replace(',' , '.')
465 |
466 | if 'US$' in product_price:
467 | product_price = product_price.replace('US$' , '')
468 | elif '$' in product_price:
469 | product_price = product_price.replace('$' , '')
470 | elif '€' in product_price:
471 | product_price = product_price.replace('€' , '')
472 | else:
473 | pass
474 |
475 | # The data found are added to the lists.
476 | titles_products.append(product_title)
477 | urls_products.append(product_link)
478 | currency_products.append(currency)
479 | check_products.append('no')
480 | prices_products.append(product_price)
481 |
482 | except Exception as e:
483 | print(str(e))
484 |
485 | try:
486 | product_price = new_soup.find_all('span', class_="olp-message a-color-price")
487 | if len(product_price) == 0:
488 | product_price = new_soup.find_all('span', id="color_name_0_price")
489 | if len(product_price) == 0:
490 | product_price = new_soup.find('span', class_="a-offscreen").text.strip()
491 | else:
492 | product_price = new_soup.find('span', id="color_name_0_price").text.strip()
493 | # Method used to clean some data including price and other characters.
494 | all_price = ''
495 | for i in product_price:
496 | if '$' in all_price:
497 | all_price = ''
498 | all_price = f'{i}'
499 | new_currency_result.append('USD')
500 | else:
501 | all_price = f'{all_price}{i}'
502 | product_price = all_price
503 | else:
504 | product_price = new_soup.find('span', class_="a-size-base a-color-price").text.strip()
505 |
506 |
507 | except Exception as e:
508 | print(str(e))
509 | product_price = "0"
510 |
511 | # The data found are added to the lists.
512 | titles_products.append(product_title)
513 | urls_products.append(product_link)
514 | currency_products.append(currency)
515 | check_products.append('no')
516 | prices_products.append(product_price)
517 |
518 |
519 | else:
520 | try:
521 | product_price = product.find('span', class_="a-price-whole").text.strip()
522 |
523 | product_price = product_price.replace('.' , '')
524 | product_price = product_price.replace(',' , '.')
525 | product_price = float(product_price)
526 | except Exception as e:
527 | print(str(e))
528 | product_price = 0
529 | pass
530 |
531 | # The data found are added to the lists.
532 | titles_products.append(product_title)
533 | urls_products.append(product_link)
534 | currency_products.append(currency)
535 | check_products.append('no')
536 | prices_products.append(product_price)
537 |
538 |
539 | # The data is added to the file "search_results.xlsx" which will store the search results.
540 | search_result_data = {}
541 | search_result_data['title'] = titles_products
542 | search_result_data['price'] = prices_products
543 | search_result_data['currency'] = currency_products
544 | search_result_data['check'] = check_products
545 | search_result_data['url'] = urls_products
546 |
547 | search_result_data = pd.DataFrame(search_result_data, columns = ['title', 'price', 'currency', 'check', 'url'])
548 |
549 | with ExcelWriter('data/search_result.xlsx') as writer:
550 | search_result_data.to_excel(writer, 'Sheet', index=False)
551 |
552 | # The data in the file that stores the search requests is deleted so that it does not continue searching.
553 | delete_product_data = pd.DataFrame(columns = ['title', 'region', 'pub', 'quick'])
554 |
555 | with ExcelWriter('data/search_product.xlsx') as writer:
556 | delete_product_data.to_excel(writer, 'Sheet', index=False)
557 |
558 | except Exception as e:
559 | print(str(e))
560 |
561 | else:
562 | # When there are no requests, the following message will be displayed.
563 | for i in range(3):
564 | sleep(2)
565 | print(f'Waiting for request...{i}')
566 | status_script = False
567 |
568 |
569 |
570 |
571 |
--------------------------------------------------------------------------------