leadguru-jobs 0.637.0__tar.gz → 0.639.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 (64) hide show
  1. {leadguru_jobs-0.637.0 → leadguru_jobs-0.639.0}/PKG-INFO +1 -1
  2. {leadguru_jobs-0.637.0 → leadguru_jobs-0.639.0}/leadguru_jobs.egg-info/PKG-INFO +1 -1
  3. {leadguru_jobs-0.637.0 → leadguru_jobs-0.639.0}/leadguru_jobs.egg-info/SOURCES.txt +1 -2
  4. {leadguru_jobs-0.637.0 → leadguru_jobs-0.639.0}/lgt_jobs/jobs/bot_stats_update.py +2 -10
  5. {leadguru_jobs-0.637.0 → leadguru_jobs-0.639.0}/lgt_jobs/jobs/chat_history.py +3 -6
  6. {leadguru_jobs-0.637.0 → leadguru_jobs-0.639.0}/lgt_jobs/jobs/connect_sources.py +4 -1
  7. {leadguru_jobs-0.637.0 → leadguru_jobs-0.639.0}/lgt_jobs/jobs/inbox_leads.py +6 -2
  8. {leadguru_jobs-0.637.0 → leadguru_jobs-0.639.0}/lgt_jobs/jobs/load_slack_people.py +2 -1
  9. {leadguru_jobs-0.637.0 → leadguru_jobs-0.639.0}/lgt_jobs/jobs/send_slack_message.py +1 -1
  10. {leadguru_jobs-0.637.0 → leadguru_jobs-0.639.0}/lgt_jobs/jobs/update_slack_profile.py +2 -1
  11. {leadguru_jobs-0.637.0 → leadguru_jobs-0.639.0}/lgt_jobs/jobs/workspace_connect.py +3 -1
  12. leadguru_jobs-0.639.0/lgt_jobs/lgt_data/models/base.py +29 -0
  13. {leadguru_jobs-0.637.0 → leadguru_jobs-0.639.0}/lgt_jobs/lgt_data/mongo_repository.py +225 -45
  14. {leadguru_jobs-0.637.0 → leadguru_jobs-0.639.0}/lgt_jobs/runner.py +2 -2
  15. leadguru_jobs-0.639.0/lgt_jobs/services/__init__.py +0 -0
  16. {leadguru_jobs-0.637.0 → leadguru_jobs-0.639.0}/lgt_jobs/simple_job.py +1 -1
  17. leadguru_jobs-0.637.0/lgt_jobs/lgt_common/lgt_logging.py +0 -15
  18. leadguru_jobs-0.637.0/lgt_jobs/lgt_data/model.py +0 -1136
  19. leadguru_jobs-0.637.0/lgt_jobs/lgt_data/models/message_request.py +0 -14
  20. {leadguru_jobs-0.637.0 → leadguru_jobs-0.639.0}/MANIFEST.in +0 -0
  21. {leadguru_jobs-0.637.0 → leadguru_jobs-0.639.0}/README.md +0 -0
  22. {leadguru_jobs-0.637.0 → leadguru_jobs-0.639.0}/leadguru_jobs.egg-info/dependency_links.txt +0 -0
  23. {leadguru_jobs-0.637.0 → leadguru_jobs-0.639.0}/leadguru_jobs.egg-info/not-zip-safe +0 -0
  24. {leadguru_jobs-0.637.0 → leadguru_jobs-0.639.0}/leadguru_jobs.egg-info/requires.txt +0 -0
  25. {leadguru_jobs-0.637.0 → leadguru_jobs-0.639.0}/leadguru_jobs.egg-info/top_level.txt +0 -0
  26. {leadguru_jobs-0.637.0 → leadguru_jobs-0.639.0}/lgt_jobs/__init__.py +0 -0
  27. {leadguru_jobs-0.637.0 → leadguru_jobs-0.639.0}/lgt_jobs/assets/images/arrow.png +0 -0
  28. {leadguru_jobs-0.637.0 → leadguru_jobs-0.639.0}/lgt_jobs/assets/images/firework.png +0 -0
  29. {leadguru_jobs-0.637.0 → leadguru_jobs-0.639.0}/lgt_jobs/assets/images/lock.png +0 -0
  30. {leadguru_jobs-0.637.0 → leadguru_jobs-0.639.0}/lgt_jobs/assets/images/logo.png +0 -0
  31. {leadguru_jobs-0.637.0 → leadguru_jobs-0.639.0}/lgt_jobs/assets/images/mail.png +0 -0
  32. {leadguru_jobs-0.637.0 → leadguru_jobs-0.639.0}/lgt_jobs/basejobs.py +0 -0
  33. {leadguru_jobs-0.637.0 → leadguru_jobs-0.639.0}/lgt_jobs/env.py +0 -0
  34. {leadguru_jobs-0.637.0 → leadguru_jobs-0.639.0}/lgt_jobs/jobs/__init__.py +0 -0
  35. {leadguru_jobs-0.637.0 → leadguru_jobs-0.639.0}/lgt_jobs/jobs/analytics.py +0 -0
  36. {leadguru_jobs-0.637.0 → leadguru_jobs-0.639.0}/lgt_jobs/jobs/mass_message.py +0 -0
  37. {leadguru_jobs-0.637.0 → leadguru_jobs-0.639.0}/lgt_jobs/jobs/send_code.py +0 -0
  38. {leadguru_jobs-0.637.0 → leadguru_jobs-0.639.0}/lgt_jobs/lgt_common/__init__.py +0 -0
  39. {leadguru_jobs-0.637.0 → leadguru_jobs-0.639.0}/lgt_jobs/lgt_common/discord_client/__init__.py +0 -0
  40. {leadguru_jobs-0.637.0 → leadguru_jobs-0.639.0}/lgt_jobs/lgt_common/discord_client/discord_client.py +0 -0
  41. {leadguru_jobs-0.637.0 → leadguru_jobs-0.639.0}/lgt_jobs/lgt_common/discord_client/methods.py +0 -0
  42. {leadguru_jobs-0.637.0 → leadguru_jobs-0.639.0}/lgt_jobs/lgt_common/enums/__init__.py +0 -0
  43. {leadguru_jobs-0.637.0 → leadguru_jobs-0.639.0}/lgt_jobs/lgt_common/enums/slack_errors.py +0 -0
  44. {leadguru_jobs-0.637.0 → leadguru_jobs-0.639.0}/lgt_jobs/lgt_common/helpers.py +0 -0
  45. {leadguru_jobs-0.637.0 → leadguru_jobs-0.639.0}/lgt_jobs/lgt_common/pubsub/__init__.py +0 -0
  46. {leadguru_jobs-0.637.0 → leadguru_jobs-0.639.0}/lgt_jobs/lgt_common/pubsub/messages.py +0 -0
  47. {leadguru_jobs-0.637.0 → leadguru_jobs-0.639.0}/lgt_jobs/lgt_common/pubsub/pubsubfactory.py +0 -0
  48. {leadguru_jobs-0.637.0 → leadguru_jobs-0.639.0}/lgt_jobs/lgt_common/slack_client/__init__.py +0 -0
  49. {leadguru_jobs-0.637.0 → leadguru_jobs-0.639.0}/lgt_jobs/lgt_common/slack_client/methods.py +0 -0
  50. {leadguru_jobs-0.637.0 → leadguru_jobs-0.639.0}/lgt_jobs/lgt_common/slack_client/slack_client.py +0 -0
  51. {leadguru_jobs-0.637.0 → leadguru_jobs-0.639.0}/lgt_jobs/lgt_common/slack_client/web_client.py +0 -0
  52. {leadguru_jobs-0.637.0 → leadguru_jobs-0.639.0}/lgt_jobs/lgt_data/__init__.py +0 -0
  53. {leadguru_jobs-0.637.0 → leadguru_jobs-0.639.0}/lgt_jobs/lgt_data/analytics.py +0 -0
  54. {leadguru_jobs-0.637.0 → leadguru_jobs-0.639.0}/lgt_jobs/lgt_data/engine.py +0 -0
  55. {leadguru_jobs-0.637.0 → leadguru_jobs-0.639.0}/lgt_jobs/lgt_data/enums.py +0 -0
  56. {leadguru_jobs-0.637.0 → leadguru_jobs-0.639.0}/lgt_jobs/lgt_data/helpers.py +0 -0
  57. /leadguru_jobs-0.637.0/lgt_jobs/lgt_data/models/__init__.py → /leadguru_jobs-0.639.0/lgt_jobs/lgt_data/model.py +0 -0
  58. {leadguru_jobs-0.637.0/lgt_jobs/services → leadguru_jobs-0.639.0/lgt_jobs/lgt_data/models}/__init__.py +0 -0
  59. {leadguru_jobs-0.637.0 → leadguru_jobs-0.639.0}/lgt_jobs/main.py +0 -0
  60. {leadguru_jobs-0.637.0 → leadguru_jobs-0.639.0}/lgt_jobs/services/web_client.py +0 -0
  61. {leadguru_jobs-0.637.0 → leadguru_jobs-0.639.0}/lgt_jobs/smtp.py +0 -0
  62. {leadguru_jobs-0.637.0 → leadguru_jobs-0.639.0}/lgt_jobs/templates/new_message.html +0 -0
  63. {leadguru_jobs-0.637.0 → leadguru_jobs-0.639.0}/setup.cfg +0 -0
  64. {leadguru_jobs-0.637.0 → leadguru_jobs-0.639.0}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: leadguru_jobs
3
- Version: 0.637.0
3
+ Version: 0.639.0
4
4
  Summary: LGT jobs builds
5
5
  Author-email: developer@leadguru.co
6
6
  Classifier: Development Status :: 5 - Production/Stable
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: leadguru_jobs
3
- Version: 0.637.0
3
+ Version: 0.639.0
4
4
  Summary: LGT jobs builds
5
5
  Author-email: developer@leadguru.co
6
6
  Classifier: Development Status :: 5 - Production/Stable
@@ -34,7 +34,6 @@ lgt_jobs/jobs/update_slack_profile.py
34
34
  lgt_jobs/jobs/workspace_connect.py
35
35
  lgt_jobs/lgt_common/__init__.py
36
36
  lgt_jobs/lgt_common/helpers.py
37
- lgt_jobs/lgt_common/lgt_logging.py
38
37
  lgt_jobs/lgt_common/discord_client/__init__.py
39
38
  lgt_jobs/lgt_common/discord_client/discord_client.py
40
39
  lgt_jobs/lgt_common/discord_client/methods.py
@@ -55,7 +54,7 @@ lgt_jobs/lgt_data/helpers.py
55
54
  lgt_jobs/lgt_data/model.py
56
55
  lgt_jobs/lgt_data/mongo_repository.py
57
56
  lgt_jobs/lgt_data/models/__init__.py
58
- lgt_jobs/lgt_data/models/message_request.py
57
+ lgt_jobs/lgt_data/models/base.py
59
58
  lgt_jobs/services/__init__.py
60
59
  lgt_jobs/services/web_client.py
61
60
  lgt_jobs/templates/new_message.html
@@ -1,12 +1,12 @@
1
1
  import random
2
2
  import time
3
3
  from abc import ABC
4
- from datetime import datetime, UTC, timedelta
5
4
  from typing import Optional
6
5
  from lgt_jobs.lgt_common.discord_client.discord_client import DiscordClient
7
6
  from lgt_jobs.lgt_common.slack_client.web_client import SlackWebClient
8
7
  from lgt_jobs.lgt_data.enums import SourceType
9
- from lgt_jobs.lgt_data.model import DedicatedBotModel, Server, Channel, DiscordUser
8
+ from lgt_jobs.lgt_data.models.bots.dedicated_bot import Server, Channel, DedicatedBotModel
9
+ from lgt_jobs.lgt_data.models.external.discord.user import DiscordUser
10
10
  from lgt_jobs.lgt_data.mongo_repository import (DedicatedBotRepository, UserMongoRepository, SlackContactUserRepository,
11
11
  LeadMongoRepository, UserLeadMongoRepository)
12
12
  from pydantic import BaseModel
@@ -33,15 +33,7 @@ class BotStatsUpdateJob(BaseBackgroundJob, ABC):
33
33
  bots_rep = DedicatedBotRepository()
34
34
  users_rep = UserMongoRepository()
35
35
  bot = bots_rep.get_one(id=data.bot_id, include_deleted=True)
36
-
37
36
  user = users_rep.get(bot.user_id)
38
- if user.subscription_expired_at.replace(tzinfo=UTC) < (datetime.now(UTC) - timedelta(7)):
39
- bot.deleted = True
40
- for server in bot.servers:
41
- server.deleted = True
42
- bots_rep.add_or_update(bot)
43
- return
44
-
45
37
  received_messages, filtered_messages = get_bots_aggregated_analytics(bot_ids=[str(bot.id)])
46
38
 
47
39
  if bot.source.source_type == SourceType.DISCORD:
@@ -3,7 +3,9 @@ from abc import ABC
3
3
  from typing import Optional, List
4
4
  import logging as log
5
5
  from lgt_jobs.lgt_common.slack_client.web_client import SlackWebClient
6
- from lgt_jobs.lgt_data.model import ChatMessage, UserContact, DedicatedBotModel
6
+ from lgt_jobs.lgt_data.models.bots.dedicated_bot import DedicatedBotModel
7
+ from lgt_jobs.lgt_data.models.chat.message import ChatMessage
8
+ from lgt_jobs.lgt_data.models.contacts.contact import UserContact
7
9
  from lgt_jobs.lgt_data.mongo_repository import UserMongoRepository, DedicatedBotRepository, UserContactsRepository, \
8
10
  ChatRepository, UserLeadMongoRepository
9
11
  from pydantic import BaseModel
@@ -39,7 +41,6 @@ class LoadChatHistoryJob(BaseBackgroundJob, ABC):
39
41
  return
40
42
  last_message = None
41
43
  last_message_contact = None
42
- last_message_bot = None
43
44
  contacts_groups = self.contacts_repo.find_grouped_actual_contacts(user.id, spam=False, with_chat_only=False)
44
45
  for bot in bots:
45
46
  contacts = contacts_groups.get(bot.source.source_id)
@@ -54,12 +55,10 @@ class LoadChatHistoryJob(BaseBackgroundJob, ABC):
54
55
  continue
55
56
 
56
57
  if not last_message:
57
- last_message_bot = bot
58
58
  last_message = message
59
59
  last_message_contact = contact
60
60
 
61
61
  if message.created_at > last_message.created_at and message.user == contact.sender_id:
62
- last_message_bot = bot
63
62
  last_message = message
64
63
  last_message_contact = contact
65
64
 
@@ -67,8 +66,6 @@ class LoadChatHistoryJob(BaseBackgroundJob, ABC):
67
66
  has_to_be_notified = (not last_notification or (last_message and last_message.created_at > last_notification))
68
67
  if last_message and has_to_be_notified and last_message.user == last_message_contact.sender_id:
69
68
  user.notification_settings.incoming_messages.need_to_notify = True
70
- user.notification_settings.incoming_messages.attributes = [last_message_contact.sender_id,
71
- last_message_bot.source.source_id]
72
69
  UserMongoRepository().set(data.user_id, notification_settings=user.notification_settings.to_dic())
73
70
 
74
71
  def _get_new_messages(self, contact: UserContact, bot: DedicatedBotModel, slack_chat: List[ChatMessage]):
@@ -5,10 +5,13 @@ import logging as log
5
5
  from lgt_jobs.jobs.load_slack_people import LoadSlackPeopleJob, LoadSlackPeopleJobData
6
6
  from lgt_jobs.basejobs import BaseBackgroundJob, BaseBackgroundJobData
7
7
  from lgt_jobs.jobs.bot_stats_update import BotStatsUpdateJob, BotStatsUpdateJobData
8
+ from lgt_jobs.lgt_data.models.base import BaseModel
9
+ from lgt_jobs.lgt_data.models.bots.base_bot import Source
10
+ from lgt_jobs.lgt_data.models.bots.dedicated_bot import DedicatedBotModel, Server
11
+ from lgt_jobs.lgt_data.models.external.slack.user import SlackUser
8
12
  from lgt_jobs.runner import BackgroundJobRunner
9
13
  from lgt_jobs.lgt_data.engine import UserTrackAction
10
14
  from lgt_jobs.lgt_data.enums import SourceType, UserAction, StatusConnection
11
- from lgt_jobs.lgt_data.model import BaseModel, DedicatedBotModel, Server, Source, SlackUser
12
15
  from lgt_jobs.lgt_data.mongo_repository import DedicatedBotRepository, UserMongoRepository
13
16
 
14
17
 
@@ -1,8 +1,10 @@
1
1
  from abc import ABC
2
2
  import logging as log
3
3
  from lgt_jobs.lgt_common.slack_client.web_client import SlackWebClient
4
- from lgt_jobs.lgt_data.model import UserModel, DedicatedBotModel, SlackMemberInformation
5
- from lgt_jobs.lgt_data.models.message_request import MessageRequest
4
+ from lgt_jobs.lgt_data.models.bots.dedicated_bot import DedicatedBotModel
5
+ from lgt_jobs.lgt_data.models.chat.request import MessageRequest
6
+ from lgt_jobs.lgt_data.models.people.people import SlackMemberInformation
7
+ from lgt_jobs.lgt_data.models.user.user import UserModel
6
8
  from lgt_jobs.lgt_data.mongo_repository import UserMongoRepository, DedicatedBotRepository, \
7
9
  SlackContactUserRepository, UserContactsRepository, MessageRequestsRepository
8
10
  from pydantic import BaseModel
@@ -84,6 +86,8 @@ class InboxLeadsJob(BaseBackgroundJob, ABC):
84
86
  if not sender_request:
85
87
  log.info(f"[InboxLeadsJob]: New message request from {sender_id} for user: {user.email}")
86
88
  requests_repo.upsert(user.id, sender_id, message_request)
89
+ user.notification_settings.inbox.need_to_notify = True
90
+ UserMongoRepository().set(user.id, notification_settings=user.notification_settings.to_dic())
87
91
 
88
92
  @staticmethod
89
93
  def create_people(slack_profile: dict, dedicated_bot: DedicatedBotModel):
@@ -1,7 +1,8 @@
1
1
  from abc import ABC
2
2
  from lgt_jobs.lgt_common.enums.slack_errors import SlackErrors
3
3
  from lgt_jobs.lgt_common.slack_client.slack_client import SlackClient
4
- from lgt_jobs.lgt_data.model import Source, SlackMemberInformation
4
+ from lgt_jobs.lgt_data.models.bots.base_bot import Source
5
+ from lgt_jobs.lgt_data.models.people.people import SlackMemberInformation
5
6
  from lgt_jobs.lgt_data.mongo_repository import DedicatedBotRepository, SlackContactUserRepository
6
7
  import logging as log
7
8
  from pydantic import BaseModel
@@ -3,7 +3,7 @@ from abc import ABC
3
3
  from typing import Optional
4
4
  import logging as log
5
5
  from lgt_jobs.lgt_common.slack_client.web_client import SlackWebClient
6
- from lgt_jobs.lgt_data.model import ChatMessage
6
+ from lgt_jobs.lgt_data.models.chat.message import ChatMessage
7
7
  from lgt_jobs.lgt_data.mongo_repository import DedicatedBotRepository, UserContactsRepository, ChatRepository
8
8
  from pydantic import BaseModel
9
9
  from lgt_jobs.basejobs import BaseBackgroundJobData, BaseBackgroundJob
@@ -2,7 +2,8 @@ from abc import ABC
2
2
  from lgt_jobs.lgt_common.slack_client.slack_client import SlackClient
3
3
  from lgt_jobs.lgt_common.slack_client.web_client import SlackFilesClient
4
4
  from lgt_jobs.lgt_data.enums import SourceType
5
- from lgt_jobs.lgt_data.model import Profile, SlackUser
5
+ from lgt_jobs.lgt_data.models.external.slack.user import SlackUser
6
+ from lgt_jobs.lgt_data.models.people.profile import Profile
6
7
  from lgt_jobs.lgt_data.mongo_repository import UserMongoRepository, DedicatedBotRepository
7
8
  from pydantic import BaseModel
8
9
  from lgt_jobs.basejobs import BaseBackgroundJobData, BaseBackgroundJob
@@ -4,7 +4,9 @@ import requests
4
4
  from lgt_jobs.lgt_common.helpers import update_credentials
5
5
  from lgt_jobs.lgt_common.slack_client.web_client import SlackWebClient
6
6
  from lgt_jobs.lgt_data.enums import StatusConnection, SourceType
7
- from lgt_jobs.lgt_data.model import UserWorkspace, SlackUser, DedicatedBotModel
7
+ from lgt_jobs.lgt_data.models.bots.dedicated_bot import DedicatedBotModel
8
+ from lgt_jobs.lgt_data.models.external.slack.user import SlackUser
9
+ from lgt_jobs.lgt_data.models.external.user_workspace import UserWorkspace
8
10
  from lgt_jobs.lgt_data.mongo_repository import UserMongoRepository, DedicatedBotRepository
9
11
  from lgt_jobs.basejobs import BaseBackgroundJobData, BaseBackgroundJob
10
12
  from lgt_jobs.jobs.bot_stats_update import BotStatsUpdateJob, BotStatsUpdateJobData
@@ -0,0 +1,29 @@
1
+ import copy
2
+ from abc import ABC
3
+ from datetime import datetime, UTC
4
+
5
+
6
+ class DictionaryModel(ABC):
7
+ @classmethod
8
+ def from_dic(cls, dic: dict):
9
+ if not dic:
10
+ return None
11
+
12
+ model = cls()
13
+ for k, v in dic.items():
14
+ setattr(model, k, v)
15
+
16
+ if '_id' in dic:
17
+ setattr(model, 'id', dic['_id'])
18
+
19
+ return model
20
+
21
+ def to_dic(self):
22
+ result = copy.deepcopy(self.__dict__)
23
+ return result
24
+
25
+
26
+ class BaseModel(DictionaryModel):
27
+ def __init__(self):
28
+ self.id = None
29
+ self.created_at = datetime.now(UTC)
@@ -6,14 +6,30 @@ from dateutil import tz
6
6
  from pymongo import MongoClient, UpdateOne
7
7
  from bson.objectid import ObjectId
8
8
  from lgt_jobs.lgt_data.enums import SourceType
9
- from lgt_jobs.lgt_data.model import (LeadModel, BaseModel, UserModel, UserResetPasswordModel, BoardModel, BoardedStatus,
10
- DedicatedBotModel, SlackMemberInformation, UserTemplateModel,
11
- ExtendedUserLeadModel, UserLeadModel, ExtendedLeadModel, UserContact, ChatMessage,
12
- GroupedMessagesModel, UserVerificationModel, UsersPage, Subscription,
13
- ScheduledMessage)
14
9
  from datetime import datetime, UTC, timedelta
15
10
  from collections import OrderedDict
16
- from lgt_jobs.lgt_data.models.message_request import MessageRequest
11
+
12
+ from lgt_jobs.lgt_data.models.base import BaseModel
13
+ from lgt_jobs.lgt_data.models.boards.board import BoardModel
14
+ from lgt_jobs.lgt_data.models.boards.status import BoardedStatus
15
+ from lgt_jobs.lgt_data.models.bots.dedicated_bot import DedicatedBotModel
16
+ from lgt_jobs.lgt_data.models.chat.grouped_messages import GroupedMessagesModel
17
+ from lgt_jobs.lgt_data.models.chat.message import ChatMessage
18
+ from lgt_jobs.lgt_data.models.chat.scheduled_message import ScheduledMessage
19
+ from lgt_jobs.lgt_data.models.chat.request import MessageRequest
20
+ from lgt_jobs.lgt_data.models.contacts.contact import UserContact
21
+ from lgt_jobs.lgt_data.models.leads.extended_lead import ExtendedLeadModel
22
+ from lgt_jobs.lgt_data.models.leads.lead import LeadModel
23
+ from lgt_jobs.lgt_data.models.people.people import SlackMemberInformation
24
+ from lgt_jobs.lgt_data.models.templates.template import UserTemplateModel
25
+ from lgt_jobs.lgt_data.models.user.reset_password import UserResetPasswordModel
26
+ from lgt_jobs.lgt_data.models.user.subscription import Subscription
27
+ from lgt_jobs.lgt_data.models.user.user import UserModel
28
+ from lgt_jobs.lgt_data.models.user.user_follow_ups import UserFollowUps
29
+ from lgt_jobs.lgt_data.models.user.user_page import UsersPage
30
+ from lgt_jobs.lgt_data.models.user.verification import UserVerificationModel
31
+ from lgt_jobs.lgt_data.models.user_leads.extended_user_lead import ExtendedUserLeadModel
32
+ from lgt_jobs.lgt_data.models.user_leads.user_lead import UserLeadModel
17
33
 
18
34
  client = MongoClient(os.environ.get('MONGO_CONNECTION_STRING', 'mongodb://127.0.0.1:27017/'))
19
35
 
@@ -73,6 +89,10 @@ class UserMongoRepository(BaseMongoRepository):
73
89
  connected_slack_email = kwargs.get('connected_slack_email')
74
90
  soon_subscription_expiration = kwargs.get('soon_subscription_expiration')
75
91
  has_new_message = kwargs.get('has_new_message')
92
+ has_new_message_request = kwargs.get('has_new_message_request')
93
+ has_deactivated_sources = kwargs.get('has_deactivated_sources')
94
+ has_new_replies = kwargs.get('has_new_replies')
95
+ has_new_reactions = kwargs.get('has_new_reactions')
76
96
  min_days = kwargs.get('min_days_soon_subscription_expiration', 3)
77
97
 
78
98
  if subscription_expired:
@@ -87,6 +107,22 @@ class UserMongoRepository(BaseMongoRepository):
87
107
  pipeline['notification_settings.incoming_messages.enabled'] = True
88
108
  pipeline['notification_settings.incoming_messages.need_to_notify'] = True
89
109
 
110
+ if has_new_message_request:
111
+ pipeline['notification_settings.inbox.enabled'] = True
112
+ pipeline['notification_settings.inbox.need_to_notify'] = True
113
+
114
+ if has_deactivated_sources:
115
+ pipeline['notification_settings.source_deactivation.enabled'] = True
116
+ pipeline['notification_settings.source_deactivation.need_to_notify'] = True
117
+
118
+ if has_new_replies:
119
+ pipeline['notification_settings.bulk_replies.enabled'] = True
120
+ pipeline['notification_settings.bulk_replies.need_to_notify'] = True
121
+
122
+ if has_new_reactions:
123
+ pipeline['notification_settings.bulk_reactions.enabled'] = True
124
+ pipeline['notification_settings.bulk_reactions.need_to_notify'] = True
125
+
90
126
  if connected_slack_email:
91
127
  pipeline['slack_users.email'] = connected_slack_email
92
128
 
@@ -106,7 +142,7 @@ class UserMongoRepository(BaseMongoRepository):
106
142
  search = kwargs.get('search')
107
143
  sort_field = kwargs.get('sort_field', 'email')
108
144
  sort_direction = kwargs.get('sort_direction', 'ASCENDING')
109
- sort_direction: int = pymongo.ASCENDING if sort_direction == 'ASCENDING' else pymongo.DESCENDING
145
+ sort_direction = pymongo.ASCENDING if sort_direction == 'ASCENDING' else pymongo.DESCENDING
110
146
  if not include_inactive:
111
147
  match_pipeline['inactive'] = False
112
148
  if email:
@@ -176,6 +212,81 @@ class UserLeadMongoRepository(BaseMongoRepository):
176
212
  collection_name = 'user_leads'
177
213
  model = ExtendedUserLeadModel
178
214
 
215
+ def get_leads_with_follow_ups(self):
216
+ now = datetime.now(UTC)
217
+ this_day = datetime(now.year, now.month, now.day, 21, 00, 00, tzinfo=UTC)
218
+ after_week = this_day + timedelta(7)
219
+ pipeline = [
220
+ {'$match': {'archived': False, 'followup_date': {'$ne': None}}},
221
+ {
222
+ '$lookup': {
223
+ 'from': 'users',
224
+ 'localField': 'user_id',
225
+ 'foreignField': '_id',
226
+ 'as': 'user'
227
+ }
228
+ },
229
+ {
230
+ '$lookup': {
231
+ 'from': 'slack_contact',
232
+ 'localField': 'message.sender_id',
233
+ 'foreignField': 'sender_id',
234
+ 'as': 'contact'
235
+ }
236
+ },
237
+ {'$addFields': {'contact': {'$first': '$contact'}, 'user': {'$first': '$user'}}},
238
+ {
239
+ '$project': {
240
+ 'user_id': 1,
241
+ 'user_email': '$user.email',
242
+ 'notification_settings': '$user.notification_settings',
243
+ 'followup_to': {
244
+ '$cond': {
245
+ 'if': {'$eq': ['$user.notification_settings.follow_ups.type', 'once_a_day']},
246
+ 'then': this_day,
247
+ 'else': after_week
248
+ }
249
+ },
250
+ 'followup_date': 1,
251
+ 'contact': 1,
252
+ 'message.sender_id': 1,
253
+ 'message.source': 1
254
+ }
255
+ },
256
+ {'$group': {'_id': '$user_id', 'leads': {'$push': '$$ROOT'}}},
257
+ {
258
+ '$addFields': {
259
+ 'actual_follow_ups': {
260
+ '$filter': {
261
+ 'input': '$leads',
262
+ 'as': 'lead',
263
+ 'cond': {
264
+ '$and': [
265
+ {'$gte': ['$$lead.followup_date', now]},
266
+ {'$lte': ['$$lead.followup_date', '$$lead.followup_to']}
267
+ ]
268
+ }
269
+ }
270
+ },
271
+ 'overdue_follow_ups': {
272
+ '$filter': {
273
+ 'input': '$leads',
274
+ 'as': 'lead',
275
+ 'cond': {'$lt': ['$$lead.followup_date', now]}
276
+ }
277
+ }
278
+ }
279
+ },
280
+ {
281
+ '$addFields': {
282
+ 'email': {'$first': '$leads.user_email'},
283
+ 'notification_settings': {'$first': '$leads.notification_settings'}}
284
+ },
285
+ {'$match': {'actual_follow_ups': {'$ne': []}}},
286
+ {'$unset': ['leads']}
287
+ ]
288
+ return [UserFollowUps.from_dic(doc) for doc in list(self.collection().aggregate(pipeline))]
289
+
179
290
  def update_source(self, source_id: str, source_data: dict):
180
291
  self.collection().update_many({'message.source.source_id': source_id},
181
292
  {'$set': {'message.source': source_data}})
@@ -222,22 +333,22 @@ class UserLeadMongoRepository(BaseMongoRepository):
222
333
  archived = kwargs.get('archived')
223
334
  from_date = kwargs.get('from_date')
224
335
  to_date = kwargs.get('to_date')
225
- has_followup = kwargs.get('has_followup', None)
226
- followup_to = kwargs.get('followup_to_date', None)
227
- followup_from = kwargs.get('followup_from_date', None)
228
- created_to = kwargs.get('created_to_date', None)
229
- created_from = kwargs.get('created_from_date', None)
230
- sender_ids = kwargs.get('sender_ids', None)
231
- text = kwargs.get('text', None)
232
- stop_words = kwargs.get('stop_words', None)
233
- tags = kwargs.get('tags', None)
234
- configs = kwargs.get('config', None)
235
- bots_names = kwargs.get('bots_names', None)
236
- locations = kwargs.get('locations', None)
237
- with_chat = kwargs.get('with_chat', None)
238
- leads_ids = kwargs.get('leads_ids', None)
239
- exclude_leads = kwargs.get('exclude_leads', None)
240
- exclude_senders = kwargs.get('exclude_senders', None)
336
+ has_followup = kwargs.get('has_followup')
337
+ followup_to = kwargs.get('followup_to_date')
338
+ followup_from = kwargs.get('followup_from_date')
339
+ created_to = kwargs.get('created_to_date')
340
+ created_from = kwargs.get('created_from_date')
341
+ sender_ids = kwargs.get('sender_ids')
342
+ text = kwargs.get('text')
343
+ stop_words = kwargs.get('stop_words')
344
+ tags = kwargs.get('tags')
345
+ configs = kwargs.get('config')
346
+ bots_names = kwargs.get('bots_names')
347
+ locations = kwargs.get('locations')
348
+ with_chat = kwargs.get('with_chat')
349
+ leads_ids = kwargs.get('leads_ids')
350
+ exclude_leads = kwargs.get('exclude_leads')
351
+ exclude_senders = kwargs.get('exclude_senders')
241
352
  deleted = kwargs.get('deleted', False)
242
353
 
243
354
  pipeline['message.profile.display_name'] = {
@@ -549,18 +660,17 @@ class LeadMongoRepository(BaseMongoRepository):
549
660
  from_date: datetime = kwargs.get('from_date')
550
661
  to_date: datetime = kwargs.get('to_date')
551
662
 
552
- country = kwargs.get('country', None)
553
- user_id = kwargs.get('user_id', None)
554
- tags = kwargs.get('tags', None)
555
- text = kwargs.get('text', None)
556
- stop_words = kwargs.get('stop_words', None)
557
- exclude_leads = kwargs.get('exclude_leads', None)
558
- exclude_senders = kwargs.get('exclude_senders', None)
559
- excluded_channels = kwargs.get('excluded_channels', None)
560
- sender_ids = kwargs.get('sender_ids', None)
561
- configs = kwargs.get('config', None)
562
- bots_names = kwargs.get('bots_names', None)
563
- locations = kwargs.get('locations', None)
663
+ country = kwargs.get('country')
664
+ user_id = kwargs.get('user_id')
665
+ tags = kwargs.get('tags')
666
+ text = kwargs.get('text')
667
+ stop_words = kwargs.get('stop_words')
668
+ exclude_leads = kwargs.get('exclude_leads')
669
+ exclude_senders = kwargs.get('exclude_senders')
670
+ sender_ids = kwargs.get('sender_ids')
671
+ configs = kwargs.get('config')
672
+ bots_names = kwargs.get('bots_names')
673
+ locations = kwargs.get('locations')
564
674
  publication_text = kwargs.get('publication_text')
565
675
 
566
676
  pipeline['message.profile.display_name'] = {
@@ -610,13 +720,6 @@ class LeadMongoRepository(BaseMongoRepository):
610
720
  if exclude_senders:
611
721
  pipeline['message.sender_id'] = {'$nin': exclude_senders}
612
722
 
613
- if excluded_channels:
614
- pipeline['$and'] = []
615
- for ws, channels in excluded_channels.items():
616
- if channels is not None:
617
- pipeline['$and'].append(
618
- {'$or': [{'message.name': {'$ne': ws}}, {'message.channel_id': {'$nin': channels}}]})
619
-
620
723
  if sender_ids:
621
724
  pipeline['message.sender_id'] = {'$in': sender_ids}
622
725
 
@@ -848,6 +951,9 @@ class DedicatedBotRepository(BaseMongoRepository):
848
951
  kwargs["only_valid"] = only_valid
849
952
  pipeline = self.__create_bots_filter(**kwargs)
850
953
  docs = self.collection().find(pipeline)
954
+ sort_by = kwargs.get('sort_by')
955
+ if sort_by:
956
+ docs = docs.sort({sort_by: 1})
851
957
  return [DedicatedBotModel.from_dic(doc) for doc in docs]
852
958
 
853
959
  def get_source_ids_for_user(self, **kwargs):
@@ -864,7 +970,7 @@ class DedicatedBotRepository(BaseMongoRepository):
864
970
 
865
971
  @staticmethod
866
972
  def __create_bots_filter(**kwargs):
867
- pipeline = {}
973
+ pipeline: dict = {}
868
974
  name = kwargs.get('name')
869
975
  source_type = kwargs.get('source_type', None)
870
976
  user_name = kwargs.get('user_name')
@@ -876,6 +982,8 @@ class DedicatedBotRepository(BaseMongoRepository):
876
982
  source_id = kwargs.get('source_id')
877
983
  server_id = kwargs.get('server_id')
878
984
  active_server_id = kwargs.get('active_server_id')
985
+ invalid_creds = kwargs.get('invalid_creds')
986
+ sort_by = kwargs.get('sort_by')
879
987
 
880
988
  if bot_id:
881
989
  pipeline["_id"] = to_object_id(bot_id)
@@ -904,12 +1012,18 @@ class DedicatedBotRepository(BaseMongoRepository):
904
1012
  if only_valid:
905
1013
  pipeline['invalid_creds'] = False
906
1014
 
1015
+ if invalid_creds is not None:
1016
+ pipeline['invalid_creds'] = invalid_creds
1017
+
907
1018
  if not include_deleted:
908
1019
  pipeline['deleted'] = False
909
1020
 
910
1021
  if not include_paused and source_type == SourceType.DISCORD:
911
1022
  pipeline['paused'] = False
912
1023
 
1024
+ if sort_by:
1025
+ pipeline['sort_by'] = {'$exists': True}
1026
+
913
1027
  return pipeline
914
1028
 
915
1029
 
@@ -1144,15 +1258,59 @@ class ChatRepository(BaseMongoRepository):
1144
1258
 
1145
1259
  if from_date:
1146
1260
  start = datetime(from_date.year, from_date.month, from_date.day, tzinfo=tz.tzutc())
1147
- pipeline['last_action_at']['$gte'] = start
1261
+ pipeline['created_at']['$gte'] = start
1148
1262
 
1149
1263
  if to_date:
1150
1264
  end = datetime(to_date.year, to_date.month, to_date.day, 23, 59, 59, tzinfo=tz.tzutc())
1151
- pipeline['last_action_at']['$lte'] = end
1265
+ pipeline['created_at']['$lte'] = end
1152
1266
 
1153
1267
  return [ChatMessage.from_dic(msg)
1154
1268
  for msg in self.collection().find(pipeline).sort("id", pymongo.ASCENDING)]
1155
1269
 
1270
+ def get_aggregated_list(self, **kwargs):
1271
+ match_pipeline = {}
1272
+ user_id = kwargs.get('user_id')
1273
+ from_date = kwargs.get('from_date')
1274
+ to_date = kwargs.get('to_date')
1275
+ sort_by = kwargs.get('sort_by', 'id')
1276
+ viewed = kwargs.get('viewed')
1277
+
1278
+ if user_id:
1279
+ match_pipeline['user_id'] = to_object_id(user_id)
1280
+
1281
+ if from_date or to_date:
1282
+ match_pipeline['created_at'] = {}
1283
+
1284
+ if viewed is not None:
1285
+ match_pipeline['viewed'] = viewed
1286
+
1287
+ if from_date:
1288
+ start = datetime(from_date.year, from_date.month, from_date.day, tzinfo=tz.tzutc())
1289
+ match_pipeline['created_at']['$gte'] = start
1290
+
1291
+ if to_date:
1292
+ end = datetime(to_date.year, to_date.month, to_date.day, 23, 59, 59, tzinfo=tz.tzutc())
1293
+ match_pipeline['created_at']['$lte'] = end
1294
+
1295
+ pipeline = [
1296
+ {'$match': match_pipeline},
1297
+ {
1298
+ '$lookup': {
1299
+ 'from': 'slack_contact',
1300
+ 'localField': 'sender_id',
1301
+ 'foreignField': 'sender_id',
1302
+ 'as': 'user'
1303
+ }
1304
+ },
1305
+ {
1306
+ '$addFields': {'user': {'$first': '$user'}}
1307
+ },
1308
+ {
1309
+ '$sort': {sort_by: 1}
1310
+ }]
1311
+
1312
+ return self.collection().aggregate(pipeline)
1313
+
1156
1314
  def get_grouped_messages(self, **kwargs):
1157
1315
  match_pipeline = {}
1158
1316
  pipeline = [
@@ -1202,6 +1360,28 @@ class MessageRequestsRepository(BaseMongoRepository):
1202
1360
  self.collection().update_one({'user_id': to_object_id(user_id), 'sender_id': sender_id},
1203
1361
  {'$set': message_request.to_dic()}, upsert=True)
1204
1362
 
1363
+ def get_many(self, user_id: str, viewed: bool = False):
1364
+ pipeline = [
1365
+ {
1366
+ '$match': {'user_id': to_object_id(user_id), 'viewed': viewed}
1367
+ },
1368
+ {
1369
+ '$lookup': {
1370
+ 'from': 'slack_contact',
1371
+ 'localField': 'sender_id',
1372
+ 'foreignField': 'sender_id',
1373
+ 'as': 'user'
1374
+ }
1375
+ },
1376
+ {
1377
+ '$addFields': {'user': {'$first': '$user'}}
1378
+ },
1379
+ {
1380
+ '$sort': {'created_at': 1}
1381
+ }
1382
+ ]
1383
+ return self.collection().aggregate(pipeline)
1384
+
1205
1385
  def find(self, user_id: str, sender_id: str):
1206
1386
  return self.collection().find_one({'user_id': to_object_id(user_id), 'sender_id': sender_id})
1207
1387
 
@@ -2,8 +2,8 @@ import json
2
2
  from datetime import datetime, UTC
3
3
  from lgt_jobs.lgt_common.pubsub.messages import publish_message2_pubsub
4
4
  from lgt_jobs.lgt_data.engine import DelayedJob
5
- from .basejobs import InvalidJobTypeException, BaseBackgroundJobData, BaseBackgroundJob
6
- from .env import background_jobs_topic
5
+ from lgt_jobs.basejobs import InvalidJobTypeException, BaseBackgroundJobData, BaseBackgroundJob
6
+ from lgt_jobs.env import background_jobs_topic
7
7
 
8
8
 
9
9
  def datetime_converter(o):
File without changes
@@ -1,7 +1,7 @@
1
1
  from abc import ABC
2
2
  from typing import Optional
3
3
  from pydantic import BaseModel
4
- from .basejobs import BaseBackgroundJobData, BaseBackgroundJob
4
+ from lgt_jobs.basejobs import BaseBackgroundJobData, BaseBackgroundJob
5
5
 
6
6
 
7
7
  class SimpleTestJobData(BaseBackgroundJobData, BaseModel):
@@ -1,15 +0,0 @@
1
- import sys
2
- from loguru import logger as log
3
-
4
- # log.remove()
5
- # log.add(sys.stdout, format="{time} {name} {level} {message}", level="INFO",
6
- # filter=lambda record: record['level'].name == 'INFO')
7
- # log.add(sys.stderr, format="{time} {name} {level} {message}", level="WARNING",
8
- # filter=lambda record: record['level'].name == 'WARNING')
9
- # log.add(sys.stderr, format="{time} {name} {level} {message}", level="ERROR",
10
- # filter=lambda record: record['level'].name in ['ERROR', 'FATAL', 'CRITICAL'])
11
- #
12
- #
13
- # log.info('Logger has been configured')
14
- #
15
- # log = log