leadguru-jobs 0.727.0__tar.gz → 0.729.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (122) hide show
  1. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/PKG-INFO +3 -1
  2. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/leadguru_jobs.egg-info/PKG-INFO +3 -1
  3. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/leadguru_jobs.egg-info/requires.txt +2 -0
  4. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/lgt_common/slack_client/slack_client.py +0 -33
  5. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/smtp.py +21 -7
  6. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/setup.py +3 -1
  7. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/MANIFEST.in +0 -0
  8. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/README.md +0 -0
  9. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/leadguru_jobs.egg-info/SOURCES.txt +0 -0
  10. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/leadguru_jobs.egg-info/dependency_links.txt +0 -0
  11. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/leadguru_jobs.egg-info/not-zip-safe +0 -0
  12. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/leadguru_jobs.egg-info/top_level.txt +0 -0
  13. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/__init__.py +0 -0
  14. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/assets/images/arrow.png +0 -0
  15. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/assets/images/arrow_blue.png +0 -0
  16. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/assets/images/firework.png +0 -0
  17. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/assets/images/lock.png +0 -0
  18. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/assets/images/logo.png +0 -0
  19. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/assets/images/mail.png +0 -0
  20. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/basejobs.py +0 -0
  21. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/env.py +0 -0
  22. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/jobs/__init__.py +0 -0
  23. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/jobs/analytics.py +0 -0
  24. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/jobs/bot_stats_update.py +0 -0
  25. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/jobs/bots_killer.py +0 -0
  26. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/jobs/chat_history.py +0 -0
  27. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/jobs/connect_sources.py +0 -0
  28. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/jobs/inbox_leads.py +0 -0
  29. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/jobs/load_slack_people.py +0 -0
  30. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/jobs/load_slack_users.py +0 -0
  31. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/jobs/mass_message.py +0 -0
  32. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/jobs/send_code.py +0 -0
  33. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/jobs/send_slack_invites.py +0 -0
  34. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/jobs/send_slack_message.py +0 -0
  35. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/jobs/update_slack_profile.py +0 -0
  36. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/jobs/workspace_connect.py +0 -0
  37. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/lgt_common/__init__.py +0 -0
  38. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/lgt_common/discord_client/__init__.py +0 -0
  39. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/lgt_common/discord_client/discord_client.py +0 -0
  40. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/lgt_common/discord_client/methods.py +0 -0
  41. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/lgt_common/enums/__init__.py +0 -0
  42. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/lgt_common/enums/slack_errors.py +0 -0
  43. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/lgt_common/helpers.py +0 -0
  44. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/lgt_common/pubsub/__init__.py +0 -0
  45. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/lgt_common/pubsub/messages.py +0 -0
  46. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/lgt_common/pubsub/pubsubfactory.py +0 -0
  47. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/lgt_common/slack_client/__init__.py +0 -0
  48. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/lgt_common/slack_client/methods.py +0 -0
  49. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/lgt_common/slack_client/web_client.py +0 -0
  50. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/lgt_data/__init__.py +0 -0
  51. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/lgt_data/analytics.py +0 -0
  52. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/lgt_data/engine.py +0 -0
  53. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/lgt_data/enums.py +0 -0
  54. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/lgt_data/helpers.py +0 -0
  55. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/lgt_data/model.py +0 -0
  56. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/lgt_data/models/__init__.py +0 -0
  57. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/lgt_data/models/base.py +0 -0
  58. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/lgt_data/models/boards/__init__.py +0 -0
  59. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/lgt_data/models/boards/board.py +0 -0
  60. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/lgt_data/models/boards/status.py +0 -0
  61. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/lgt_data/models/bots/__init__.py +0 -0
  62. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/lgt_data/models/bots/base_bot.py +0 -0
  63. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/lgt_data/models/bots/bot_info.py +0 -0
  64. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/lgt_data/models/bots/dedicated_bot.py +0 -0
  65. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/lgt_data/models/chat/__init__.py +0 -0
  66. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/lgt_data/models/chat/file.py +0 -0
  67. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/lgt_data/models/chat/grouped_messages.py +0 -0
  68. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/lgt_data/models/chat/message.py +0 -0
  69. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/lgt_data/models/chat/request.py +0 -0
  70. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/lgt_data/models/chat/scheduled_message.py +0 -0
  71. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/lgt_data/models/contacts/__init__.py +0 -0
  72. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/lgt_data/models/contacts/contact.py +0 -0
  73. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/lgt_data/models/external/__init__.py +0 -0
  74. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/lgt_data/models/external/cloud/__init__.py +0 -0
  75. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/lgt_data/models/external/cloud/file.py +0 -0
  76. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/lgt_data/models/external/discord/__init__.py +0 -0
  77. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/lgt_data/models/external/discord/user.py +0 -0
  78. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/lgt_data/models/external/slack/__init__.py +0 -0
  79. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/lgt_data/models/external/slack/timezone.py +0 -0
  80. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/lgt_data/models/external/slack/user.py +0 -0
  81. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/lgt_data/models/external/user_workspace.py +0 -0
  82. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/lgt_data/models/leads/__init__.py +0 -0
  83. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/lgt_data/models/leads/config.py +0 -0
  84. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/lgt_data/models/leads/extended_lead.py +0 -0
  85. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/lgt_data/models/leads/lead.py +0 -0
  86. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/lgt_data/models/leads/message.py +0 -0
  87. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/lgt_data/models/notifications/__init__.py +0 -0
  88. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/lgt_data/models/notifications/notification.py +0 -0
  89. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/lgt_data/models/notifications/notification_settings.py +0 -0
  90. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/lgt_data/models/people/__init__.py +0 -0
  91. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/lgt_data/models/people/people.py +0 -0
  92. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/lgt_data/models/people/profile.py +0 -0
  93. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/lgt_data/models/post/__init__.py +0 -0
  94. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/lgt_data/models/post/message.py +0 -0
  95. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/lgt_data/models/post/post.py +0 -0
  96. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/lgt_data/models/templates/__init__.py +0 -0
  97. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/lgt_data/models/templates/template.py +0 -0
  98. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/lgt_data/models/user/__init__.py +0 -0
  99. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/lgt_data/models/user/feature.py +0 -0
  100. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/lgt_data/models/user/general_settings.py +0 -0
  101. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/lgt_data/models/user/reset_password.py +0 -0
  102. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/lgt_data/models/user/subscription.py +0 -0
  103. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/lgt_data/models/user/typed_field.py +0 -0
  104. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/lgt_data/models/user/user.py +0 -0
  105. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/lgt_data/models/user/user_follow_ups.py +0 -0
  106. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/lgt_data/models/user/user_page.py +0 -0
  107. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/lgt_data/models/user/verification.py +0 -0
  108. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/lgt_data/models/user_leads/__init__.py +0 -0
  109. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/lgt_data/models/user_leads/extended_user_lead.py +0 -0
  110. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/lgt_data/models/user_leads/user_lead.py +0 -0
  111. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/lgt_data/mongo_repository.py +0 -0
  112. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/lgt_data/repositories/__init__.py +0 -0
  113. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/lgt_data/repositories/post/__init__.py +0 -0
  114. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/lgt_data/repositories/post/posts.py +0 -0
  115. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/main.py +0 -0
  116. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/runner.py +0 -0
  117. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/services/__init__.py +0 -0
  118. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/services/k8_manager.py +0 -0
  119. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/services/web_client.py +0 -0
  120. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/simple_job.py +0 -0
  121. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/lgt_jobs/templates/new_message.html +0 -0
  122. {leadguru_jobs-0.727.0 → leadguru_jobs-0.729.0}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: leadguru_jobs
3
- Version: 0.727.0
3
+ Version: 0.729.0
4
4
  Summary: LGT jobs builds
5
5
  Author-email: developer@leadguru.co
6
6
  Classifier: Development Status :: 5 - Production/Stable
@@ -32,11 +32,13 @@ Requires-Dist: mongoengine
32
32
  Requires-Dist: google
33
33
  Requires-Dist: google-cloud-pubsub
34
34
  Requires-Dist: google-cloud-storage
35
+ Requires-Dist: google-cloud-logging
35
36
  Requires-Dist: websockets
36
37
  Requires-Dist: aiohttp
37
38
  Requires-Dist: nameparser
38
39
  Requires-Dist: loguru
39
40
  Requires-Dist: redmail
41
+ Requires-Dist: tenacity
40
42
  Dynamic: author-email
41
43
  Dynamic: classifier
42
44
  Dynamic: requires-dist
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: leadguru_jobs
3
- Version: 0.727.0
3
+ Version: 0.729.0
4
4
  Summary: LGT jobs builds
5
5
  Author-email: developer@leadguru.co
6
6
  Classifier: Development Status :: 5 - Production/Stable
@@ -32,11 +32,13 @@ Requires-Dist: mongoengine
32
32
  Requires-Dist: google
33
33
  Requires-Dist: google-cloud-pubsub
34
34
  Requires-Dist: google-cloud-storage
35
+ Requires-Dist: google-cloud-logging
35
36
  Requires-Dist: websockets
36
37
  Requires-Dist: aiohttp
37
38
  Requires-Dist: nameparser
38
39
  Requires-Dist: loguru
39
40
  Requires-Dist: redmail
41
+ Requires-Dist: tenacity
40
42
  Dynamic: author-email
41
43
  Dynamic: classifier
42
44
  Dynamic: requires-dist
@@ -13,8 +13,10 @@ mongoengine
13
13
  google
14
14
  google-cloud-pubsub
15
15
  google-cloud-storage
16
+ google-cloud-logging
16
17
  websockets
17
18
  aiohttp
18
19
  nameparser
19
20
  loguru
20
21
  redmail
22
+ tenacity
@@ -4,7 +4,6 @@ import requests
4
4
  import json
5
5
  import io
6
6
  from urllib import parse
7
- from pyppeteer import launch
8
7
  from requests import Response
9
8
  from websockets.client import WebSocketClientProtocol
10
9
  from lgt_jobs.lgt_common.slack_client.methods import SlackMethods
@@ -214,38 +213,6 @@ class SlackClient:
214
213
  headers = {'User-Agent': user_agent}
215
214
  response = requests.post(f"{self.base_url}{SlackMethods.confirm_email}", data=payload, headers=headers)
216
215
  result = response.json()['ok'] if response.status_code == 200 else False
217
-
218
- print(f"Result is {result}")
219
- if not result:
220
- print("Start pyppeteer")
221
- try:
222
- async def send_code():
223
- print("Launch browser")
224
- browser = await launch(headless=True)
225
- page = await browser.newPage()
226
-
227
- print("Go to Slack")
228
- await page.goto('https://slack.com/signin', waitUntil='networkidle2')
229
-
230
- print("Type email")
231
- await page.waitForSelector('input#signup_email')
232
- await page.type('input#signup_email', email)
233
- await asyncio.sleep(1.324)
234
-
235
- print("Press the button to submit")
236
- button = await page.querySelector('button#submit_btn')
237
- await button.tap()
238
-
239
- print("Wait for the next page")
240
- await page.waitForSelector('input[aria-label="digit 1 of 6"]')
241
-
242
- print("Close the browser")
243
- await browser.close()
244
-
245
- asyncio.run(send_code())
246
- return True
247
- except:
248
- return False
249
216
  return result
250
217
 
251
218
  def confirm_code(self, email: str, code: str, user_agent: str) -> requests.Response:
@@ -1,3 +1,4 @@
1
+ from tenacity import retry, stop_after_attempt, wait_fixed, retry_if_exception_type
1
2
  from abc import ABC
2
3
  from pydantic import BaseModel
3
4
  import logging as log
@@ -13,11 +14,11 @@ gmail = EmailSender(
13
14
  username=smtp_login,
14
15
  password=smtp_password
15
16
  )
17
+
16
18
  """
17
19
  Send email
18
20
  """
19
21
 
20
-
21
22
  class SendMailJobData(BaseBackgroundJobData, BaseModel):
22
23
  html: str
23
24
  subject: str
@@ -31,10 +32,13 @@ class SendMailJob(BaseBackgroundJob, ABC):
31
32
  def job_data_type(self) -> type:
32
33
  return SendMailJobData
33
34
 
34
- def exec(self, data: SendMailJobData):
35
- body_image = {}
36
- for image in data.images:
37
- body_image[f'IMAGE_{ImageName(image.value).name}'] = f'lgt_jobs/assets/images/{image.value}'
35
+ @retry(
36
+ stop=stop_after_attempt(3),
37
+ wait=wait_fixed(5),
38
+ retry=retry_if_exception_type(Exception),
39
+ reraise=True
40
+ )
41
+ def send_email(self, data: SendMailJobData, body_images_map: dict):
38
42
  with gmail:
39
43
  if not gmail.is_alive:
40
44
  gmail.connect()
@@ -43,6 +47,16 @@ class SendMailJob(BaseBackgroundJob, ABC):
43
47
  receivers=[data.recipient],
44
48
  subject=data.subject,
45
49
  html=data.html,
46
- body_images=body_image
50
+ body_images=body_images_map
47
51
  )
48
- log.info('email message has been sent')
52
+ log.info('email message has been sent')
53
+
54
+ def exec(self, data: SendMailJobData):
55
+ body_images_map = {
56
+ f'IMAGE_{ImageName(image.value).name}': f'lgt_jobs/assets/images/{image.value}'
57
+ for image in data.images
58
+ }
59
+ try:
60
+ self.send_email(data, body_images_map)
61
+ except Exception as e:
62
+ log.error(f"Failed to send email after retries: {e}")
@@ -36,11 +36,13 @@ install_requires = [
36
36
  'google',
37
37
  'google-cloud-pubsub',
38
38
  'google-cloud-storage',
39
+ 'google-cloud-logging',
39
40
  'websockets',
40
41
  'aiohttp',
41
42
  'nameparser',
42
43
  'loguru',
43
- 'redmail'
44
+ 'redmail',
45
+ 'tenacity'
44
46
  ]
45
47
 
46
48
  setup(name=package_name,