leadguru-jobs 0.276.0__tar.gz → 0.278.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 (41) hide show
  1. {leadguru_jobs-0.276.0 → leadguru_jobs-0.278.0}/PKG-INFO +1 -1
  2. {leadguru_jobs-0.276.0 → leadguru_jobs-0.278.0}/README.md +11 -21
  3. {leadguru_jobs-0.276.0 → leadguru_jobs-0.278.0}/leadguru_jobs.egg-info/PKG-INFO +1 -1
  4. {leadguru_jobs-0.276.0 → leadguru_jobs-0.278.0}/leadguru_jobs.egg-info/SOURCES.txt +0 -1
  5. {leadguru_jobs-0.276.0 → leadguru_jobs-0.278.0}/leadguru_jobs.egg-info/requires.txt +2 -2
  6. {leadguru_jobs-0.276.0 → leadguru_jobs-0.278.0}/lgt_jobs/__init__.py +0 -4
  7. {leadguru_jobs-0.276.0 → leadguru_jobs-0.278.0}/lgt_jobs/jobs/bot_stats_update.py +7 -7
  8. {leadguru_jobs-0.276.0 → leadguru_jobs-0.278.0}/lgt_jobs/jobs/chat_history.py +3 -3
  9. {leadguru_jobs-0.276.0 → leadguru_jobs-0.278.0}/lgt_jobs/jobs/conversation_replied.py +10 -6
  10. {leadguru_jobs-0.276.0 → leadguru_jobs-0.278.0}/lgt_jobs/jobs/inbox_leads.py +4 -7
  11. {leadguru_jobs-0.276.0 → leadguru_jobs-0.278.0}/lgt_jobs/jobs/mass_message.py +11 -5
  12. {leadguru_jobs-0.276.0 → leadguru_jobs-0.278.0}/lgt_jobs/jobs/reactions_added.py +3 -3
  13. {leadguru_jobs-0.276.0 → leadguru_jobs-0.278.0}/lgt_jobs/jobs/reindex_conversation_history.py +0 -2
  14. {leadguru_jobs-0.276.0 → leadguru_jobs-0.278.0}/lgt_jobs/jobs/send_code.py +5 -2
  15. {leadguru_jobs-0.276.0 → leadguru_jobs-0.278.0}/lgt_jobs/jobs/send_slack_message.py +5 -4
  16. leadguru_jobs-0.278.0/lgt_jobs/jobs/update_slack_profile.py +52 -0
  17. {leadguru_jobs-0.276.0 → leadguru_jobs-0.278.0}/lgt_jobs/jobs/user_balance_update.py +2 -3
  18. {leadguru_jobs-0.276.0 → leadguru_jobs-0.278.0}/lgt_jobs/jobs/workspace_connect.py +8 -9
  19. {leadguru_jobs-0.276.0 → leadguru_jobs-0.278.0}/setup.py +2 -2
  20. {leadguru_jobs-0.276.0 → leadguru_jobs-0.278.0}/tests/job_data_test.py +3 -4
  21. leadguru_jobs-0.276.0/lgt_jobs/jobs/update_slack_profile.py +0 -95
  22. leadguru_jobs-0.276.0/lgt_jobs/jobs/user_limits_update.py +0 -62
  23. {leadguru_jobs-0.276.0 → leadguru_jobs-0.278.0}/MANIFEST.in +0 -0
  24. {leadguru_jobs-0.276.0 → leadguru_jobs-0.278.0}/leadguru_jobs.egg-info/dependency_links.txt +0 -0
  25. {leadguru_jobs-0.276.0 → leadguru_jobs-0.278.0}/leadguru_jobs.egg-info/not-zip-safe +0 -0
  26. {leadguru_jobs-0.276.0 → leadguru_jobs-0.278.0}/leadguru_jobs.egg-info/top_level.txt +0 -0
  27. {leadguru_jobs-0.276.0 → leadguru_jobs-0.278.0}/lgt_jobs/basejobs.py +0 -0
  28. {leadguru_jobs-0.276.0 → leadguru_jobs-0.278.0}/lgt_jobs/env.py +0 -0
  29. {leadguru_jobs-0.276.0 → leadguru_jobs-0.278.0}/lgt_jobs/jobs/__init__.py +0 -0
  30. {leadguru_jobs-0.276.0 → leadguru_jobs-0.278.0}/lgt_jobs/jobs/analytics.py +0 -0
  31. {leadguru_jobs-0.276.0 → leadguru_jobs-0.278.0}/lgt_jobs/jobs/archive_leads.py +0 -0
  32. {leadguru_jobs-0.276.0 → leadguru_jobs-0.278.0}/lgt_jobs/jobs/clear_user_analytics.py +0 -0
  33. {leadguru_jobs-0.276.0 → leadguru_jobs-0.278.0}/lgt_jobs/main.py +0 -0
  34. {leadguru_jobs-0.276.0 → leadguru_jobs-0.278.0}/lgt_jobs/runner.py +0 -0
  35. {leadguru_jobs-0.276.0 → leadguru_jobs-0.278.0}/lgt_jobs/services/__init__.py +0 -0
  36. {leadguru_jobs-0.276.0 → leadguru_jobs-0.278.0}/lgt_jobs/services/web_client.py +0 -0
  37. {leadguru_jobs-0.276.0 → leadguru_jobs-0.278.0}/lgt_jobs/simple_job.py +0 -0
  38. {leadguru_jobs-0.276.0 → leadguru_jobs-0.278.0}/lgt_jobs/smtp.py +0 -0
  39. {leadguru_jobs-0.276.0 → leadguru_jobs-0.278.0}/lgt_jobs/templates/new_message_mail_template.html +0 -0
  40. {leadguru_jobs-0.276.0 → leadguru_jobs-0.278.0}/setup.cfg +0 -0
  41. {leadguru_jobs-0.276.0 → leadguru_jobs-0.278.0}/tests/__init__.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: leadguru_jobs
3
- Version: 0.276.0
3
+ Version: 0.278.0
4
4
  Summary: LGT jobs builds
5
5
  Author-email: developer@leadguru.co
6
6
  Classifier: Development Status :: 5 - Production/Stable
@@ -1,48 +1,38 @@
1
1
  ## Some example on how to publish messages for testing purposes
2
2
 
3
3
 
4
- ### 1. Load Slack Chat history
4
+ ### Load Slack Chat history
5
5
  ``gcloud pubsub topics publish local-background-worker --message='{ "job_type": "LoadChatHistoryJob", "data": { "user_id": "5d9db09e3710ae3ec4b4592f" } }'``
6
6
 
7
- ### 2. Restart BOTS
7
+ ### Restart BOTS
8
8
  ``gcloud pubsub topics publish local-background-worker --message='{ "job_type": "RestartBotsJob", "data": { "bots": [] }}'``
9
9
 
10
- ### 3. Update BOTS credentials
10
+ ### Update BOTS credentials
11
11
  ``gcloud pubsub topics publish local-background-worker --message='{ "job_type": "BotsCredentialsUpdateJob", "data": { "bot_name": "mitrixdataprocessing" }}'``
12
12
 
13
- ### 4. Update User BOT credentials
14
- ``gcloud pubsub topics publish local-background-worker --message='{ "job_type": "UserBotsCredentialsUpdateJob", "data": { "user_id": "5d9db09e3710ae3ec4b4592f", "bot_name": "mitrixdataprocessing" }}'``
15
-
16
- ### 5. Update user slack profile
13
+ ### Update user slack profile
17
14
  ``gcloud pubsub topics publish local-background-worker --message='{ "job_type": "UpdateUserSlackProfileJob", "data": { "user_id": "5d9db09e3710ae3ec4b4592f", "bot_name": "mitrixdataprocessing" }}'``
18
15
 
19
- ### 6. Restart slack dedicated bots
20
- ``gcloud pubsub topics publish local-background-worker --message='{ "job_type": "RestartDedicatedBotsJob", "data": { "user_id": "5f354dd91554d906e44fadf6" }}'``
21
-
22
- ### 7. Update emotions
16
+ ### Update emotions
23
17
  ``gcloud pubsub topics publish local-background-worker --message='{ "job_type": "ReactionAddedJob", "data": { "message_id": "4f6258b5-75f5-49b4-b288-3e21921b1895", "ts": "1625480670.035200" }}'``
24
18
 
25
- ### 8. Update conversation history
19
+ ### Update conversation history
26
20
  ``gcloud pubsub topics publish local-background-worker --message='{ "job_type": "ConversationRepliedJob", "data": { "message_id": "4f6258b5-75f5-49b4-b288-3e21921b1895", "ts": "1625480670.035200" }}'``
27
21
 
28
- ### 9. Bot status update
29
- ``gcloud pubsub topics publish local-background-worker --message='{ "job_type": "BotStatsUpdateJob", "data": { "bot_name": "mitrixdataprocessing" }}'``
30
- ``gcloud pubsub topics publish local-background-worker --message='{ "job_type": "BotStatsUpdateJob", "data": { "dedicated_bot_id": "60d9ab815b22e55e41da81da" }}'``
31
-
32
- ### 10. update stats
33
- ``gcloud pubsub topics publish local-background-worker --message='{"job_type": "UpdateUserDataUsageJob", "data": {"dedicated_bot_id": null, "filtered": false, "bot_name": "kotlinlang", "channel_id": "C0B8M7BUY", "message": "For changes from the server you would need a web socket."}}'``
22
+ ### Bot status update
23
+ ``gcloud pubsub topics publish local-background-worker --message='{ "job_type": "BotStatsUpdateJob", "data": { "bot_id": "60d9ab815b22e55e41da81da" }}'``
34
24
 
35
- ### 11. update users feed
25
+ ### Update users feed
36
26
  ``
37
27
  gcloud pubsub topics publish local-background-worker --message='{"job_type": "UpdateUserFeedJob", "data": {"lead_id": "61767a9 3bb463584e0658e1a", "bot_name": "gophers", "dedicated_bot_id": null}}'
38
28
  ``
39
29
 
40
- ### 12. update users balances
30
+ ### Update users balances
41
31
  ``
42
32
  gcloud pubsub topics publish local-background-worker --message='{"job_type": "UpdateUserBalanceJob", "data": {"user_id": "60a6a9a59ef97dc902180512"}}'
43
33
  ``
44
34
 
45
- ### 13. Clear User analytics
35
+ ### Clear User analytics
46
36
  ``
47
37
  gcloud pubsub topics publish local-background-worker --message='{"job_type": "ClearUserAnalyticsJob", "data": {"user_id": "60a6a9a59ef97dc902180512"}}'
48
38
  ``
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: leadguru-jobs
3
- Version: 0.276.0
3
+ Version: 0.278.0
4
4
  Summary: LGT jobs builds
5
5
  Author-email: developer@leadguru.co
6
6
  Classifier: Development Status :: 5 - Production/Stable
@@ -30,7 +30,6 @@ lgt_jobs/jobs/send_code.py
30
30
  lgt_jobs/jobs/send_slack_message.py
31
31
  lgt_jobs/jobs/update_slack_profile.py
32
32
  lgt_jobs/jobs/user_balance_update.py
33
- lgt_jobs/jobs/user_limits_update.py
34
33
  lgt_jobs/jobs/workspace_connect.py
35
34
  lgt_jobs/services/__init__.py
36
35
  lgt_jobs/services/web_client.py
@@ -1,8 +1,8 @@
1
1
  loguru
2
2
  pydantic
3
3
  cachetools>=3.1.0
4
- leadguru-common==0.317.0
5
- leadguru-data==0.324.0
4
+ leadguru-common==0.320.0
5
+ leadguru-data==0.327.0
6
6
  wheel
7
7
  setuptools
8
8
  twine
@@ -4,7 +4,6 @@ from .jobs.user_balance_update import UpdateUserBalanceJob, UpdateUserBalanceJob
4
4
  from .jobs.conversation_replied import ConversationRepliedJob, ConversationRepliedJobData
5
5
  from .jobs.reactions_added import ReactionAddedJobData, ReactionAddedJob
6
6
  from .jobs.send_slack_message import SendSlackMessageJob, SendSlackMessageJobData
7
- from .jobs.user_limits_update import UpdateUserDataUsageJob, UpdateUserDataUsageJobData
8
7
  from .jobs.analytics import (TrackAnalyticsJob, TrackAnalyticsJobData)
9
8
  from .jobs.archive_leads import (ArchiveLeadsJob, ArchiveLeadsJobData)
10
9
  from .jobs.bot_stats_update import (BotStatsUpdateJob, BotStatsUpdateJobData)
@@ -27,7 +26,6 @@ jobs_map = {
27
26
  "TrackAnalyticsJob": TrackAnalyticsJob,
28
27
  "LoadChatHistoryJob": LoadChatHistoryJob,
29
28
  "UpdateUserSlackProfileJob": UpdateUserSlackProfileJob,
30
- "UpdateUserDataUsageJob": UpdateUserDataUsageJob,
31
29
  "ConversationRepliedJob": ConversationRepliedJob,
32
30
  "ReactionAddedJob": ReactionAddedJob,
33
31
  "SendSlackMessageJob": SendSlackMessageJob,
@@ -46,7 +44,6 @@ __all__ = [
46
44
  LoadChatHistoryJob,
47
45
  UpdateUserSlackProfileJob,
48
46
  TrackAnalyticsJob,
49
- UpdateUserDataUsageJob,
50
47
  ConversationRepliedJob,
51
48
  ReactionAddedJob,
52
49
  SendSlackMessageJob,
@@ -67,7 +64,6 @@ __all__ = [
67
64
  LoadChatHistoryJobData,
68
65
  UpdateUserSlackProfileJobData,
69
66
  TrackAnalyticsJobData,
70
- UpdateUserDataUsageJobData,
71
67
  ConversationRepliedJobData,
72
68
  ReactionAddedJobData,
73
69
  SendSlackMessageJobData,
@@ -15,8 +15,7 @@ Update bots statistics
15
15
 
16
16
 
17
17
  class BotStatsUpdateJobData(BaseBackgroundJobData, BaseModel):
18
- dedicated_bot_id: Optional[str]
19
- bot_name: Optional[str]
18
+ bot_id: Optional[str]
20
19
 
21
20
 
22
21
  class BotStatsUpdateJob(BaseBackgroundJob, ABC):
@@ -25,12 +24,13 @@ class BotStatsUpdateJob(BaseBackgroundJob, ABC):
25
24
  return BotStatsUpdateJobData
26
25
 
27
26
  def exec(self, data: BotStatsUpdateJobData):
28
- if data.dedicated_bot_id:
29
- bots_rep = DedicatedBotRepository()
30
- bot = bots_rep.get_by_id(data.dedicated_bot_id)
31
- else:
27
+ bots_rep = DedicatedBotRepository()
28
+ bot = bots_rep.get_by_id(data.bot_id)
29
+ if not bot:
32
30
  bots_rep = BotMongoRepository()
33
- bot = bots_rep.get_by_id(data.bot_name)
31
+ bot = bots_rep.get_by_object_id(data.bot_id)
32
+ if not bot:
33
+ return
34
34
 
35
35
  if not bot.token or not bot.cookies:
36
36
  log.warning(f"[BotStatsUpdateJob]: Bot {bot.id} has no credentials.")
@@ -69,8 +69,8 @@ class LoadChatHistoryJob(BaseBackgroundJob, ABC):
69
69
  lead.last_action_at = last_message.created_at
70
70
  UserLeadMongoRepository().update_lead(lead.user_id, lead.id, last_action_at=last_message.created_at)
71
71
 
72
- has_to_be_notified = not user.new_message_notified_at \
73
- or (last_message and last_message.created_at > user.new_message_notified_at)
72
+ has_to_be_notified = (not user.new_message_notified_at or
73
+ (last_message and last_message.created_at > user.new_message_notified_at))
74
74
 
75
75
  if last_message and has_to_be_notified and last_message.user == last_message_lead.message.sender_id:
76
76
  LoadChatHistoryJob._notify_about_new_messages(user, last_message_lead, data.template_path)
@@ -92,7 +92,7 @@ class LoadChatHistoryJob(BaseBackgroundJob, ABC):
92
92
  def _update_history(user: UserModel, lead: UserLeadModel) -> Optional[SlackHistoryMessageModel]:
93
93
  saved_chat_history = lead.chat_history if lead.chat_history else list()
94
94
 
95
- bot = DedicatedBotRepository().get_by_user_and_name(user.id, lead.message.name)
95
+ bot = DedicatedBotRepository().get_by_user_and_source_id(user.id, lead.message.source.source_id)
96
96
  if not bot or bot.invalid_creds:
97
97
  return None
98
98
 
@@ -28,9 +28,9 @@ class ConversationRepliedJob(BaseBackgroundJob, ABC):
28
28
  if not lead:
29
29
  return
30
30
 
31
- bot = DedicatedBotRepository().get_one(only_valid=True, name=lead.message.name)
32
- if not bot:
33
- log.warning(f"Lead: {lead.id}, no bot to load replies")
31
+ bot = DedicatedBotRepository().get_one(only_valid=True, source_id=lead.message.source.source_id)
32
+ if not bot or bot.invalid_creds:
33
+ log.warning(f"Lead: {lead.id}, no bot with valid creds to load replies")
34
34
  return
35
35
 
36
36
  client = SlackClient(bot.token, bot.cookies)
@@ -49,8 +49,12 @@ class ConversationRepliedJob(BaseBackgroundJob, ABC):
49
49
  reply.username = user_response.get("user").get("real_name")
50
50
  if not reply.attachments and lead.message.urls_in_message:
51
51
  for attachment in lead.message.urls_in_message:
52
- reply.attachments.append(client.get_attachments(
53
- lead.message.channel_id, lead.message.message_id, attachment))
52
+ if attachment:
53
+ attachments = client.get_attachments(lead.message.channel_id,
54
+ lead.message.message_id,
55
+ attachment)
56
+ if attachments:
57
+ reply.attachments.append(attachments)
54
58
  replies.append(reply.to_dic())
55
59
 
56
60
  set_dict = {
@@ -62,4 +66,4 @@ class ConversationRepliedJob(BaseBackgroundJob, ABC):
62
66
  LeadMongoRepository().collection().update_many(pipeline, {"$set": set_dict})
63
67
  UserLeadMongoRepository().collection().update_many(pipeline, {"$set": set_dict})
64
68
  GarbageLeadsMongoRepository().collection().update_many(pipeline, {"$set": set_dict})
65
- SpamLeadsMongoRepository().collection().update_many(pipeline, {"$set": set_dict})
69
+ SpamLeadsMongoRepository().collection().update_many(pipeline, {"$set": set_dict})
@@ -2,7 +2,7 @@ from abc import ABC
2
2
  from lgt.common.python.lgt_logging import log
3
3
  from lgt.common.python.slack_client.web_client import SlackWebClient
4
4
  from lgt_data.enums import DefaultBoards
5
- from lgt_data.model import UserModel, DedicatedBotModel, SlackMemberInformation, UserLeadModel, Source
5
+ from lgt_data.model import UserModel, DedicatedBotModel, SlackMemberInformation, UserLeadModel
6
6
  from lgt_data.mongo_repository import UserLeadMongoRepository, UserMongoRepository, DedicatedBotRepository, \
7
7
  SlackContactUserRepository, BoardsMongoRepository
8
8
  from pydantic import BaseModel
@@ -76,13 +76,10 @@ class InboxLeadsJob(BaseBackgroundJob, ABC):
76
76
 
77
77
  @staticmethod
78
78
  def create_people(slack_profile: dict, dedicated_bot: DedicatedBotModel):
79
- source = Source()
80
- source.source_id = dedicated_bot.workspace_id
81
- source.source_name = dedicated_bot.name
82
- source.source_type = dedicated_bot.type
83
79
  member_info: SlackMemberInformation = SlackMemberInformation.from_slack_response(slack_profile,
84
- dedicated_bot.name, source)
80
+ dedicated_bot.name,
81
+ dedicated_bot.source)
85
82
  SlackContactUserRepository().collection().update_one({"sender_id": member_info.sender_id,
86
- "source.source_id": dedicated_bot.workspace_id},
83
+ "source.source_id": dedicated_bot.source.source_id},
87
84
  {"$set": member_info.to_dic()}, upsert=True)
88
85
  return SlackContactUserRepository().find_one(member_info.sender_id)
@@ -1,9 +1,12 @@
1
1
  import time
2
+ from abc import ABC
2
3
  from random import randint
3
4
  from typing import Optional, Any
4
5
  from lgt.common.python.slack_client.web_client import SlackWebClient
5
6
  from lgt_data.mongo_repository import DedicatedBotRepository
6
7
  from loguru import logger as log
8
+ from pydantic import BaseModel
9
+
7
10
  from ..basejobs import BaseBackgroundJobData, BaseBackgroundJob
8
11
 
9
12
  """
@@ -11,7 +14,7 @@ Send Slack Code
11
14
  """
12
15
 
13
16
 
14
- class SendMassMessageSlackChannelJobData(BaseBackgroundJobData):
17
+ class SendMassMessageSlackChannelJobData(BaseBackgroundJobData, BaseModel):
15
18
  text: str
16
19
  channel_ids: list[str]
17
20
  user_id: str
@@ -19,7 +22,7 @@ class SendMassMessageSlackChannelJobData(BaseBackgroundJobData):
19
22
  source_id: str
20
23
 
21
24
 
22
- class SendMassMessageSlackChannelJob(BaseBackgroundJob):
25
+ class SendMassMessageSlackChannelJob(BaseBackgroundJob, ABC):
23
26
  @property
24
27
  def job_data_type(self) -> type:
25
28
  return SendMassMessageSlackChannelJobData
@@ -27,7 +30,8 @@ class SendMassMessageSlackChannelJob(BaseBackgroundJob):
27
30
  def exec(self, data: SendMassMessageSlackChannelJobData):
28
31
  bot = DedicatedBotRepository().get_by_user_and_source_id(data.user_id, data.source_id)
29
32
  if not bot or bot.invalid_creds:
30
- log.warning(f"Bot not found or not invalid creds, source id:{data.source_id}")
33
+ log.warning(f"[SendMassMessageSlackChannelJob]: "
34
+ f"Bot not found or has invalid creds, source id:{data.source_id}")
31
35
  return
32
36
 
33
37
  slack_client = SlackWebClient(bot.token, bot.cookies)
@@ -39,10 +43,12 @@ class SendMassMessageSlackChannelJob(BaseBackgroundJob):
39
43
  try:
40
44
  post_message_response = slack_client.post_message(to=channel, text=data.text)
41
45
  if not post_message_response['ok']:
42
- log.warning(f"Failed to post message. Attempt {attempts}, bot id {bot.id},"
46
+ log.warning(f"[SendMassMessageSlackChannelJob]: "
47
+ f"Failed to post message. Attempt {attempts}, bot id {bot.id},"
43
48
  f" channel id {channel}. Details {post_message_response}")
44
49
  attempts = 0
45
50
  break
46
51
  except:
47
- log.warning(f"Failed attempt to get clist of channels. Attempt {attempts}, bot id {bot.id}")
52
+ log.warning(f"[SendMassMessageSlackChannelJob]: "
53
+ f"Failed attempt to send message. Attempt {attempts}, bot id {bot.id}")
48
54
  time.sleep(randint(1, 3))
@@ -28,9 +28,9 @@ class ReactionAddedJob(BaseBackgroundJob, ABC):
28
28
  if not lead:
29
29
  return
30
30
 
31
- bot = DedicatedBotRepository().get_one(only_valid=True, name=lead.message.name)
32
- if not bot:
33
- log.warning(f"Lead: {lead.id}, no bot to load reactions")
31
+ bot = DedicatedBotRepository().get_one(only_valid=True, source_id=lead.message.source.source_id)
32
+ if not bot or bot.invalid_creds:
33
+ log.warning(f"Lead: {lead.id}, no bot with valid creds to load reactions")
34
34
  return
35
35
 
36
36
  client = SlackWebClient(bot.token, bot.cookies)
@@ -1,10 +1,8 @@
1
1
  from abc import ABC
2
2
  from typing import List
3
-
4
3
  from lgt_data.model import UserLeadModel
5
4
  from lgt_data.mongo_repository import UserLeadMongoRepository
6
5
  from pydantic import BaseModel
7
-
8
6
  from ..basejobs import BaseBackgroundJobData, BaseBackgroundJob
9
7
 
10
8
  """
@@ -1,6 +1,9 @@
1
+ from abc import ABC
1
2
  from typing import Optional
2
3
  from loguru import logger as log
3
4
  from lgt.common.python.slack_client.web_client import SlackWebClient
5
+ from pydantic import BaseModel
6
+
4
7
  from ..basejobs import BaseBackgroundJobData, BaseBackgroundJob
5
8
 
6
9
  """
@@ -8,13 +11,13 @@ Send Slack Code
8
11
  """
9
12
 
10
13
 
11
- class SendSlackEmailJobData(BaseBackgroundJobData):
14
+ class SendSlackEmailJobData(BaseBackgroundJobData, BaseModel):
12
15
  email: str
13
16
  user_agent: str
14
17
  locale: Optional[str]
15
18
 
16
19
 
17
- class SendSlackEmailJob(BaseBackgroundJob):
20
+ class SendSlackEmailJob(BaseBackgroundJob, ABC):
18
21
  @property
19
22
  def job_data_type(self) -> type:
20
23
  return SendSlackEmailJobData
@@ -1,10 +1,11 @@
1
1
  import datetime
2
+ from abc import ABC
2
3
  from typing import Optional
3
4
  from lgt.common.python.lgt_logging import log
4
- from lgt_data.mongo_repository import DedicatedBotRepository, UserContactsRepository
5
5
  from lgt.common.python.slack_client.web_client import SlackWebClient, SlackMessageConvertService
6
6
  from lgt_data.engine import LeadChat
7
- from lgt_data.mongo_repository import UserMongoRepository, UserLeadMongoRepository
7
+ from lgt_data.mongo_repository import (UserMongoRepository, UserLeadMongoRepository,
8
+ DedicatedBotRepository, UserContactsRepository)
8
9
  from pydantic import BaseModel
9
10
  from ..basejobs import BaseBackgroundJobData, BaseBackgroundJob
10
11
 
@@ -20,7 +21,7 @@ class SendSlackMessageJobData(BaseBackgroundJobData, BaseModel):
20
21
  files_ids: Optional[list]
21
22
 
22
23
 
23
- class SendSlackMessageJob(BaseBackgroundJob):
24
+ class SendSlackMessageJob(BaseBackgroundJob, ABC):
24
25
  @property
25
26
  def job_data_type(self) -> type:
26
27
  return SendSlackMessageJobData
@@ -32,7 +33,7 @@ class SendSlackMessageJob(BaseBackgroundJob):
32
33
  if not lead:
33
34
  return
34
35
 
35
- bot = DedicatedBotRepository().get_by_user_and_name(user.id, lead.message.name)
36
+ bot = DedicatedBotRepository().get_by_user_and_source_id(user.id, lead.message.source.source_id)
36
37
  if not bot or bot.invalid_creds:
37
38
  return
38
39
 
@@ -0,0 +1,52 @@
1
+ from abc import ABC
2
+
3
+ from lgt.common.python.lgt_logging import log
4
+ from lgt.common.python.slack_client.slack_client import SlackClient
5
+ from lgt_data.model import UserModel
6
+ from lgt_data.mongo_repository import UserMongoRepository, DedicatedBotRepository
7
+ from pydantic import BaseModel
8
+ from ..basejobs import BaseBackgroundJobData, BaseBackgroundJob
9
+
10
+ """
11
+ Update Slack User profile
12
+ """
13
+
14
+
15
+ class UpdateUserSlackProfileJobData(BaseBackgroundJobData, BaseModel):
16
+ user_id: str
17
+
18
+
19
+ class UpdateUserSlackProfileJob(BaseBackgroundJob, ABC):
20
+
21
+ @property
22
+ def job_data_type(self) -> type:
23
+ return UpdateUserSlackProfileJobData
24
+
25
+ def exec(self, data: UpdateUserSlackProfileJobData):
26
+ user = UserMongoRepository().get(data.user_id)
27
+ bots = DedicatedBotRepository().get_user_bots(data.user_id)
28
+ for bot in bots:
29
+ if bot.invalid_creds:
30
+ log.warning(
31
+ f'User: {user.email} dedicated bot: {bot.name} credentials are invalid. '
32
+ f'Not able to update user profile')
33
+ continue
34
+
35
+ slack = SlackClient(bot.token, bot.cookies)
36
+ UpdateUserSlackProfileJob.__update_profile(user, slack)
37
+
38
+ @staticmethod
39
+ def __update_profile(user: UserModel, slack: SlackClient):
40
+ try:
41
+ profile_resp = slack.get_profile()
42
+ except:
43
+ log.warning(f"User: {user.email} Bot credentials are not valid")
44
+ return
45
+
46
+ if not profile_resp["ok"]:
47
+ return
48
+
49
+ # try to update user photo
50
+ if user.photo_url:
51
+ photo_resp = slack.update_profile_photo(user.photo_url)
52
+ log.info(f"[PHOTO UPDATE] {photo_resp}")
@@ -1,12 +1,11 @@
1
1
  import datetime
2
+ from abc import ABC
2
3
  from typing import Optional
3
-
4
4
  from lgt_data.engine import UserCreditStatementDocument
5
5
  from lgt_data.enums import UserAccountState
6
6
  from lgt_data.model import UserModel
7
7
  from lgt_data.mongo_repository import UserMongoRepository, to_object_id
8
8
  from pydantic import BaseModel
9
-
10
9
  from ..basejobs import BaseBackgroundJobData, BaseBackgroundJob
11
10
 
12
11
  """
@@ -18,7 +17,7 @@ class UpdateUserBalanceJobData(BaseBackgroundJobData, BaseModel):
18
17
  user_id: Optional[str]
19
18
 
20
19
 
21
- class UpdateUserBalanceJob(BaseBackgroundJob):
20
+ class UpdateUserBalanceJob(BaseBackgroundJob, ABC):
22
21
  @property
23
22
  def job_data_type(self) -> type:
24
23
  return UpdateUserBalanceJobData
@@ -1,3 +1,4 @@
1
+ from abc import ABC
1
2
  from random import randint
2
3
  from time import sleep
3
4
  from typing import Dict
@@ -25,7 +26,7 @@ class ConnectSlackAccountJobData(BaseBackgroundJobData, BaseModel):
25
26
  user_agent: str
26
27
 
27
28
 
28
- class ConnectSlackAccountJob(BaseBackgroundJob):
29
+ class ConnectSlackAccountJob(BaseBackgroundJob, ABC):
29
30
  @property
30
31
  def job_data_type(self) -> type:
31
32
  return ConnectSlackAccountJobData
@@ -105,7 +106,6 @@ class ConnectSlackAccountJob(BaseBackgroundJob):
105
106
  log.info(f'Test token: {test_auth_response.json()}')
106
107
  break
107
108
  log.warning(f'{slack_user.email}: did not get token by url {login_url}. Attempt {counter + 1}')
108
- counter += 1
109
109
 
110
110
  slack_user.cookies = session.cookies.get_dict()
111
111
  slack_user.workspaces = user_workspaces
@@ -117,14 +117,13 @@ class ConnectSlackAccountJob(BaseBackgroundJob):
117
117
 
118
118
  dedicated_bots_repository = DedicatedBotRepository()
119
119
  dedicated_bots = dedicated_bots_repository.get_user_bots(current_user.id)
120
- user_workspaces_map: Dict[str, UserWorkspace] = {workspace.name: workspace
120
+ user_workspaces_map: Dict[str, UserWorkspace] = {workspace.id: workspace
121
121
  for workspace in user_workspaces if workspace.token}
122
- for name, workspace in user_workspaces_map.items():
123
- dedicated_bot = next(filter(lambda x: x.workspace_id == workspace.id
124
- and x.user_name == slack_user.email, dedicated_bots), None)
122
+ for workspace_id, workspace in user_workspaces_map.items():
123
+ dedicated_bot = next(filter(lambda x:
124
+ x.workspace_id == workspace_id and x.user_name == slack_user.email,
125
+ dedicated_bots), None)
125
126
  if dedicated_bot:
126
127
  dedicated_bot = update_credentials(dedicated_bot, workspace.token, slack_user.cookies)
127
128
  dedicated_bots_repository.add_or_update(dedicated_bot)
128
- BackgroundJobRunner.submit(BotStatsUpdateJob,
129
- BotStatsUpdateJobData(dedicated_bot_id=str(dedicated_bot.id),
130
- bot_name=None))
129
+ BackgroundJobRunner.submit(BotStatsUpdateJob, BotStatsUpdateJobData(bot_id=str(dedicated_bot.id)))
@@ -24,8 +24,8 @@ install_requires = [
24
24
  'loguru',
25
25
  'pydantic',
26
26
  'cachetools>=3.1.0',
27
- 'leadguru-common==0.317.0',
28
- 'leadguru-data==0.324.0',
27
+ 'leadguru-common==0.320.0',
28
+ 'leadguru-data==0.327.0',
29
29
  'wheel',
30
30
  'setuptools',
31
31
  'twine',
@@ -1,9 +1,7 @@
1
1
  import json
2
2
  import unittest
3
3
  from datetime import datetime
4
-
5
4
  import pydantic
6
-
7
5
  from lgt_jobs import SimpleTestJob, BackgroundJobRunner, BaseBackgroundJob
8
6
  from lgt_jobs.runner import datetime_converter
9
7
 
@@ -11,7 +9,7 @@ from lgt_jobs.runner import datetime_converter
11
9
  class JobDataTest(unittest.TestCase):
12
10
  def test_can_run_simple_job(self):
13
11
  job_type = SimpleTestJob
14
- data = { "name": "Kiryl", "id": 123 }
12
+ data = {"name": "Kiryl", "id": 123}
15
13
 
16
14
  job = job_type()
17
15
  result = job.run(data)
@@ -32,12 +30,13 @@ class JobDataTest(unittest.TestCase):
32
30
 
33
31
  def test_dump_time(self):
34
32
  now = datetime.now()
33
+
35
34
  class TestModel(pydantic.BaseModel):
36
35
  time: datetime
37
36
 
38
37
  model = TestModel(time=now)
39
38
 
40
- json_str = json.dumps(model.dict(), ensure_ascii=False, default=datetime_converter)
39
+ json_str = json.dumps(model.model_dump(), ensure_ascii=False, default=datetime_converter)
41
40
  model = TestModel(**json.loads(json_str))
42
41
 
43
42
  self.assertEqual(model.time, now)
@@ -1,95 +0,0 @@
1
- from typing import List
2
- from lgt.common.python.lgt_logging import log
3
- from lgt.common.python.slack_client.slack_client import SlackClient
4
- from lgt_data.model import UserBotCredentialsModel, UserModel
5
- from lgt_data.mongo_repository import UserMongoRepository, UserBotCredentialsMongoRepository, DedicatedBotRepository
6
- from pydantic import BaseModel
7
- from ..runner import BackgroundJobRunner
8
- from ..basejobs import BaseBackgroundJobData, BaseBackgroundJob
9
-
10
- """
11
- Update Slack User profile
12
- """
13
-
14
-
15
- class UpdateUserSlackProfileJobData(BaseBackgroundJobData, BaseModel):
16
- user_id: str
17
- bot_name: str
18
-
19
-
20
- class UpdateUserSlackProfileJob(BaseBackgroundJob):
21
- @staticmethod
22
- def __update_profile(user: UserModel, slack: SlackClient) -> bool:
23
- try:
24
- profile_resp = slack.get_profile()
25
- except:
26
- log.warning(f"User: {user.email} Bot credentials are not valid")
27
- return False
28
-
29
- if not profile_resp["ok"]:
30
- return False
31
-
32
- # try to update user photo
33
- if user.photo_url:
34
- photo_resp = slack.update_profile_photo(user.photo_url)
35
- log.info(f"[PHOTO UPDATE] {photo_resp}")
36
-
37
- return True
38
-
39
- @property
40
- def job_data_type(self) -> type:
41
- return UpdateUserSlackProfileJobData
42
-
43
- @staticmethod
44
- def update_all_user_bots_command(data: UpdateUserSlackProfileJobData, bots: List[UserBotCredentialsModel]):
45
- for bot in bots:
46
- BackgroundJobRunner.submit(UpdateUserSlackProfileJob,
47
- UpdateUserSlackProfileJobData(user_id=data.user_id,
48
- bot_name=bot.bot_name))
49
-
50
- UpdateUserSlackProfileJob.update_dedicated_bot_profile(data)
51
-
52
- @staticmethod
53
- def update_dedicated_bot_profile(data: UpdateUserSlackProfileJobData):
54
- user = UserMongoRepository().get(data.user_id)
55
- bots = DedicatedBotRepository().get_user_bots(data.user_id)
56
- for bot in bots:
57
- if bot.invalid_creds:
58
- log.warning(
59
- f'User: {user.email} dedicated bot: {bot.name} credentials are invalid. Not able to update user profile')
60
- continue
61
-
62
- slack = SlackClient(bot.token, bot.cookies)
63
- UpdateUserSlackProfileJob.__update_profile(user, slack)
64
-
65
- @staticmethod
66
- def update_single_user_bots_command(data: UpdateUserSlackProfileJobData, bots: List[UserBotCredentialsModel]):
67
- user = UserMongoRepository().get(data.user_id)
68
- for bot in bots:
69
- if bot.bot_name != data.bot_name:
70
- continue
71
-
72
- if bot.invalid_creds:
73
- log.warning(
74
- f'User: {user.email} bot: {bot.bot_name} credentials are invalid. Not able to update user profile')
75
- continue
76
-
77
- if not bot.user_name or not bot.password:
78
- log.warning(f"User: {user.email} Bot: {bot.bot_name} credentials are not SET")
79
- continue
80
-
81
- slack = SlackClient(bot.token, bot.cookies)
82
- result = UpdateUserSlackProfileJob.__update_profile(user, slack)
83
- if result:
84
- UserBotCredentialsMongoRepository().set(user_id=data.user_id, bot_name=data.bot_name,
85
- slack_profile=user.slack_profile.to_dic())
86
-
87
- if user.slack_profile:
88
- log.info(slack.update_profile(user.slack_profile.to_dic()))
89
-
90
- def exec(self, data: UpdateUserSlackProfileJobData):
91
- bots = UserBotCredentialsMongoRepository().get_bot_credentials(data.user_id)
92
- if data.bot_name == '':
93
- UpdateUserSlackProfileJob.update_all_user_bots_command(data, bots)
94
- else:
95
- UpdateUserSlackProfileJob.update_single_user_bots_command(data, bots)
@@ -1,62 +0,0 @@
1
- from abc import ABC
2
- from datetime import datetime
3
- from typing import List, Optional
4
- from lgt_data.engine import UserCreditStatementDocument
5
- from lgt_data.enums import UserAccountState
6
- from lgt_data.model import UserModel
7
- from lgt_data.mongo_repository import UserMongoRepository, DedicatedBotRepository, to_object_id
8
- from pydantic import BaseModel
9
- from lgt.common.python.lgt_logging import log
10
- from ..basejobs import BaseBackgroundJobData, BaseBackgroundJob
11
-
12
- """
13
- User limits handling
14
- """
15
-
16
-
17
- class UpdateUserDataUsageJobData(BaseBackgroundJobData, BaseModel):
18
- channel_id: str
19
- bot_name: str
20
- filtered: bool
21
- user_ids: List[str]
22
- message: Optional[str]
23
-
24
-
25
- class UpdateUserDataUsageJob(BaseBackgroundJob, ABC):
26
- @property
27
- def job_data_type(self) -> type:
28
- return UpdateUserDataUsageJobData
29
-
30
- @staticmethod
31
- def increment(user_id: str, dedicated_bot_id: str = None, bot_name: str = None, message: str = None):
32
- log.info(f"[UpdateUserDataUsageJob] Updating user: {user_id}")
33
- UserCreditStatementDocument(
34
- user_id=to_object_id(user_id),
35
- created_at=datetime.utcnow(),
36
- balance=-1,
37
- action="lead-filtered",
38
- attributes=[bot_name if bot_name else "", dedicated_bot_id if dedicated_bot_id else "",
39
- message if message else ""]
40
- ).save()
41
-
42
- @staticmethod
43
- def get_users(user_ids: List[str]) -> List[UserModel]:
44
- return UserMongoRepository().get_users(users_ids=user_ids)
45
-
46
- def exec(self, data: UpdateUserDataUsageJobData):
47
- users = self.get_users(data.user_ids)
48
- for user in users:
49
- if user.state == UserAccountState.Suspended.value:
50
- continue
51
-
52
- if user and data.bot_name in user.excluded_workspaces:
53
- continue
54
-
55
- if user and user.excluded_channels and user.excluded_channels.get(data.bot_name) and \
56
- (data.channel_id in user.excluded_channels.get(data.bot_name)):
57
- continue
58
-
59
- dedicated_bot = DedicatedBotRepository().get_by_user_and_name(user.id, data.bot_name)
60
- if dedicated_bot and not dedicated_bot.invalid_creds:
61
- self.increment(f"{user.id}", bot_name=data.bot_name,
62
- dedicated_bot_id=str(dedicated_bot.id), message=data.message)