leadguru-jobs 0.724.0__py3-none-any.whl → 0.725.0__py3-none-any.whl

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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: leadguru_jobs
3
- Version: 0.724.0
3
+ Version: 0.725.0
4
4
  Summary: LGT jobs builds
5
5
  Author-email: developer@leadguru.co
6
6
  Classifier: Development Status :: 5 - Production/Stable
@@ -1,4 +1,4 @@
1
- lgt_jobs/__init__.py,sha256=fQ97ZFeVtbOgODPdB26x7ku45AQPQ8ixeziiCAjNYZM,2451
1
+ lgt_jobs/__init__.py,sha256=NQozhvhEGeXUvyj8kkT-Q5FduKAkQt1bDxlczkjbmQY,2635
2
2
  lgt_jobs/basejobs.py,sha256=LPEclvY6fIG17YMGy9pRK0Q58n62gkI5W1BTK6R2p-c,1234
3
3
  lgt_jobs/env.py,sha256=HHlpQgZrRQMMuPZYhP94A8b29T_10sKRo98mh0_hh3Y,907
4
4
  lgt_jobs/main.py,sha256=zd0TdwFBUXUmFfUw552rPt6Rd_uG-LWEE6wTs8TCxIk,2081
@@ -22,6 +22,7 @@ lgt_jobs/jobs/load_slack_people.py,sha256=RnuHRPvZkAlM9o7i6hQtBBmnN_nu5X6LLZY5eC
22
22
  lgt_jobs/jobs/load_slack_users.py,sha256=d_Hy-MM86OqWdsaLX06n-ovNL6whY1xQz6sv_Ls3C4I,1404
23
23
  lgt_jobs/jobs/mass_message.py,sha256=1mFcBlL2MhzLbj5yrd_NyJc7TXDWCcROAzGDnr0miMU,2035
24
24
  lgt_jobs/jobs/send_code.py,sha256=dIlLPkG3GgGKIEqGiElyzrtdrnJNTL1Ak2V0xnE-WIQ,824
25
+ lgt_jobs/jobs/send_slack_invites.py,sha256=tO4XZ_g-YhLZAhf871qHs4SVd9z9ILRVKVC6cBWlhC0,1850
25
26
  lgt_jobs/jobs/send_slack_message.py,sha256=eiSN-yZ7XJ2WLUTQOkViSYOCYwaEwLry0ldGAcONNsM,1708
26
27
  lgt_jobs/jobs/update_slack_profile.py,sha256=GU28azaNz1zYsCAAF_BShJxLUecQb7AbO5XPgiv7yHg,3654
27
28
  lgt_jobs/jobs/workspace_connect.py,sha256=3uGxI0gTXVloZWxo32uhRmHjVwCGzET2CLUNjN4CcS8,7829
@@ -45,7 +46,7 @@ lgt_jobs/lgt_data/engine.py,sha256=GY8FOl3dl7euKjQRML_H3ophaSTgfQ8ICMRv1NpE2oE,7
45
46
  lgt_jobs/lgt_data/enums.py,sha256=xNE5uIot8yT2Yl6HufTYlPiR0uSJVP2fNbnObL5tsNE,2669
46
47
  lgt_jobs/lgt_data/helpers.py,sha256=S_1P7pnx14dllmen-TzjA9pkKWQr39x8-v6iv7FUYnQ,423
47
48
  lgt_jobs/lgt_data/model.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
48
- lgt_jobs/lgt_data/mongo_repository.py,sha256=02ot-tPDDqjZYjuRwkrH3biKUYBSxmKQaltxhK0IeS8,57939
49
+ lgt_jobs/lgt_data/mongo_repository.py,sha256=KRfnAHzBbPWPHe3gc2L3cNcSv4Qq4yvG_by1Oq41rsE,54763
49
50
  lgt_jobs/lgt_data/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
50
51
  lgt_jobs/lgt_data/models/base.py,sha256=YaiceCaaF45snOLx-bQoYJ1aTWrfgMQeHWjAaRnzGKE,592
51
52
  lgt_jobs/lgt_data/models/boards/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -108,7 +109,7 @@ lgt_jobs/services/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU
108
109
  lgt_jobs/services/k8_manager.py,sha256=bXpka9psIQ5UJ6QG_e4xolmE_3gtmNrzzZeL03bJ62I,995
109
110
  lgt_jobs/services/web_client.py,sha256=oMyWJxwGeIe3f40fPT7xcisjDg3BhA3Ipf8dr1jVT-Y,1549
110
111
  lgt_jobs/templates/new_message.html,sha256=dZl8UmdAOOMq4nidvAgMFroSrTV7Pw0RWt2yLp_2idg,6989
111
- leadguru_jobs-0.724.0.dist-info/METADATA,sha256=HL0s6RKqssyN7LZdE1t2lkFZ70wcyIBPpA-qWNck3xg,1399
112
- leadguru_jobs-0.724.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
113
- leadguru_jobs-0.724.0.dist-info/top_level.txt,sha256=rIuw1DqwbnZyeoarBSC-bYeGOhv9mZBs7_afl9q4_JI,9
114
- leadguru_jobs-0.724.0.dist-info/RECORD,,
112
+ leadguru_jobs-0.725.0.dist-info/METADATA,sha256=c6qwlQOg87kjWjPc87vZigeNg_M6yPBDholW0VKR9Mk,1399
113
+ leadguru_jobs-0.725.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
114
+ leadguru_jobs-0.725.0.dist-info/top_level.txt,sha256=rIuw1DqwbnZyeoarBSC-bYeGOhv9mZBs7_afl9q4_JI,9
115
+ leadguru_jobs-0.725.0.dist-info/RECORD,,
lgt_jobs/__init__.py CHANGED
@@ -16,6 +16,7 @@ from .simple_job import (SimpleTestJob, SimpleTestJobData)
16
16
  from .jobs.load_slack_people import (LoadSlackPeopleJob, LoadSlackPeopleJobData)
17
17
  from .jobs.load_slack_users import LoadSlackUsersJob, LoadSlackUsersJobData
18
18
  from .jobs.bots_killer import BotsKillerJob, BotsKillerData
19
+ from .jobs.send_slack_invites import SendSlackInvitesJob, SendSlackInvitesJobData
19
20
 
20
21
  jobs_map = {
21
22
  "SimpleTestJob": SimpleTestJob,
@@ -29,7 +30,8 @@ jobs_map = {
29
30
  "ConnectSourceJob": ConnectSourceJob,
30
31
  "LoadSlackPeopleJob": LoadSlackPeopleJob,
31
32
  "BotsKillerJob": BotsKillerJob,
32
- "LoadSlackUsersJob": LoadSlackUsersJob
33
+ "LoadSlackUsersJob": LoadSlackUsersJob,
34
+ "SendSlackInvitesJob": SendSlackInvitesJob
33
35
  }
34
36
  __all__ = [
35
37
  # Jobs
@@ -46,6 +48,7 @@ __all__ = [
46
48
  LoadSlackPeopleJob,
47
49
  LoadSlackUsersJob,
48
50
  BotsKillerJob,
51
+ SendSlackInvitesJob,
49
52
 
50
53
  # module classes
51
54
  BackgroundJobRunner,
@@ -64,6 +67,7 @@ __all__ = [
64
67
  LoadSlackPeopleJobData,
65
68
  LoadSlackUsersJobData,
66
69
  BotsKillerData,
70
+ SendSlackInvitesJobData,
67
71
  # mapping
68
72
  jobs_map
69
73
  ]
@@ -0,0 +1,45 @@
1
+ from abc import ABC
2
+ from lgt_jobs.lgt_common.slack_client.web_client import SlackWebClient
3
+ from pydantic import BaseModel
4
+ from lgt_jobs.basejobs import BaseBackgroundJobData, BaseBackgroundJob
5
+ from lgt_jobs.lgt_data.enums import SourceType
6
+ from lgt_jobs.lgt_data.mongo_repository import DedicatedBotRepository, UserMongoRepository
7
+
8
+ """
9
+ Send Slack Code
10
+ """
11
+
12
+
13
+ class SendSlackInvitesJobData(BaseBackgroundJobData, BaseModel):
14
+ emails: list[str]
15
+ email_to_invite: str
16
+
17
+
18
+ class SendSlackInvitesJob(BaseBackgroundJob, ABC):
19
+ @property
20
+ def job_data_type(self) -> type:
21
+ return SendSlackInvitesJobData
22
+
23
+ def exec(self, data: SendSlackInvitesJobData):
24
+ print('[SendSlackInvitesJob]: Start...')
25
+ users = UserMongoRepository().get_users(emails=data.emails)
26
+ bots = DedicatedBotRepository().get_all(user_ids=[user.id for user in users],
27
+ source_type=SourceType.SLACK,
28
+ only_valid=True,
29
+ include_paused=True,
30
+ include_deleted=True)
31
+ used_sources = {}
32
+ count = 0
33
+ for bot in bots:
34
+ if not used_sources.get(bot.source.source_id):
35
+ used_sources[bot.source.source_id] = None
36
+ try:
37
+ client = SlackWebClient(bot.token, bot.cookies)
38
+ resp = client.send_slack_invite_to_workspace(data.email_to_invite)
39
+ print(f'Sent invite to {bot.source.source_name}. Count is {count}. Response: {resp.content}')
40
+ count += 1
41
+ except:
42
+ print(f'Error to sent invite to {bot.source.source_name}')
43
+
44
+
45
+ print(f'[SendSlackInvitesJob]: STOP...User were invited to {count} workspaces.')
@@ -1,5 +1,4 @@
1
1
  import os
2
- import re
3
2
  from typing import List, Optional
4
3
  import pymongo
5
4
  from dateutil import tz
@@ -70,6 +69,23 @@ class UserMongoRepository(BaseMongoRepository):
70
69
  collection_name = 'users'
71
70
  model = UserModel
72
71
 
72
+ def get_inactive_users(self):
73
+ pipeline = [
74
+ {'$lookup': {'from': 'user_track_action', 'as': 'last_action', 'let': {'id': '$_id' }, 'pipeline':
75
+ [
76
+ {'$match': {'$expr': {'$eq': ['$user_id', '$$id']}}},
77
+ {'$sort': {'created_at': -1}},
78
+ {'$project': {'created_at': 1}},
79
+ {'$limit': 1}
80
+ ]}},
81
+ {'$addFields': {'last_action_date': {'$first': '$last_action.created_at'}}},
82
+ {'$lookup': {'as': 'subscription', 'from': 'subscriptions', 'foreignField': '_id', 'localField': 'subscription_id'}},
83
+ {'$addFields': {'period': {'$first': '$subscription.disable_bots_period'}}},
84
+ {'$match': {'$expr': {'$lte': ['$last_action_date', {'$dateSubtract': {'startDate': '$$NOW', 'unit': 'day', 'amount': '$period'}}]}}},
85
+ {'$project': {'_id': 1}}]
86
+
87
+ return {doc['_id']: None for doc in self.collection().aggregate(pipeline)}
88
+
73
89
  def get(self, _id):
74
90
  return UserModel.from_dic(self.collection().find_one({'_id': to_object_id(_id)}))
75
91
 
@@ -94,6 +110,7 @@ class UserMongoRepository(BaseMongoRepository):
94
110
  has_new_replies = kwargs.get('has_new_replies')
95
111
  has_new_reactions = kwargs.get('has_new_reactions')
96
112
  min_days = kwargs.get('min_days_soon_subscription_expiration', 3)
113
+ emails = kwargs.get('emails')
97
114
 
98
115
  if subscription_expired:
99
116
  pipeline['subscription_expired_at'] = {'$lte': datetime.now(UTC)}
@@ -129,6 +146,9 @@ class UserMongoRepository(BaseMongoRepository):
129
146
  if users_ids is not None:
130
147
  pipeline['_id'] = {'$in': [to_object_id(_id) for _id in users_ids]}
131
148
 
149
+ if emails is not None:
150
+ pipeline['email'] = {'$in': emails}
151
+
132
152
  if name is not None:
133
153
  pipeline['user_name'] = {"$regex": name, "$options": 'i'}
134
154
 
@@ -682,95 +702,6 @@ class LeadMongoRepository(BaseMongoRepository):
682
702
  update_dict = {k: v for k, v in kwargs.items() if v is not None}
683
703
  self.collection().update_one({'id': _id}, {'$set': update_dict}, upsert=False)
684
704
 
685
- def get_list(self, skip, limit, **kwargs):
686
- pipeline = self.__create_leads_filter(**kwargs)
687
-
688
- sort_field = kwargs.get('sort_field', 'created_at')
689
- sort_direction = kwargs.get('sort_direction', 'ASCENDING')
690
- sort_direction = pymongo.ASCENDING if sort_direction == 'ASCENDING' else pymongo.DESCENDING
691
-
692
- leads = self.collection().find(pipeline).sort([(sort_field, sort_direction)]).skip(skip).limit(limit)
693
- return [LeadModel.from_dic(lead) for lead in leads]
694
-
695
- def __create_leads_filter(self, **kwargs):
696
- pipeline: dict = {"hidden": False}
697
-
698
- from_date: datetime = kwargs.get('from_date')
699
- to_date: datetime = kwargs.get('to_date')
700
-
701
- country = kwargs.get('country')
702
- user_id = kwargs.get('user_id')
703
- tags = kwargs.get('tags')
704
- text = kwargs.get('text')
705
- stop_words = kwargs.get('stop_words')
706
- exclude_leads = kwargs.get('exclude_leads')
707
- exclude_senders = kwargs.get('exclude_senders')
708
- sender_ids = kwargs.get('sender_ids')
709
- configs = kwargs.get('config')
710
- bots_names = kwargs.get('bots_names')
711
- locations = kwargs.get('locations')
712
- publication_text = kwargs.get('publication_text')
713
-
714
- pipeline['message.profile.display_name'] = {
715
- "$ne": "Slackbot"
716
- }
717
-
718
- if from_date or to_date:
719
- pipeline['created_at'] = {}
720
-
721
- if from_date:
722
- start = from_date.astimezone(tz.tzutc())
723
- pipeline['created_at']['$gte'] = start
724
-
725
- if to_date:
726
- end = to_date.astimezone(tz.tzutc())
727
- pipeline['created_at']['$lte'] = end
728
-
729
- if locations and len(locations) > 0:
730
- pipeline['message.locations'] = {"$in": locations}
731
-
732
- if country:
733
- pipeline["message.slack_options.country"] = re.compile(country, re.IGNORECASE)
734
-
735
- if user_id:
736
- pipeline["$or"] = [
737
- {"message.dedicated_slack_options": {"$exists": False}},
738
- {"message.dedicated_slack_options": None},
739
- {"message.dedicated_slack_options.user_id": f"{user_id}"},
740
- ]
741
- else:
742
- pipeline["user_id"] = {'$exists': False}
743
-
744
- if stop_words:
745
- pipeline['full_message_text'] = {'$regex': f'^(?!.*({stop_words})).*$', '$options': 'i'}
746
- elif text:
747
- pipeline['$text'] = {'$search': text}
748
-
749
- if publication_text:
750
- pipeline['message.message'] = {'$regex': publication_text, '$options': 'i'}
751
-
752
- if tags:
753
- pipeline["tags"] = {"$elemMatch": {"$in": tags}}
754
-
755
- if exclude_leads:
756
- pipeline['id'] = {'$nin': exclude_leads}
757
-
758
- if exclude_senders:
759
- pipeline['message.sender_id'] = {'$nin': exclude_senders}
760
-
761
- if sender_ids:
762
- pipeline['message.sender_id'] = {'$in': sender_ids}
763
-
764
- if configs:
765
- pipeline["message.configs.id"] = {"$not": {"$elemMatch": {"$nin": configs}}}
766
-
767
- if bots_names is not None:
768
- pipeline['message.name'] = {'$in': bots_names}
769
-
770
- pipeline['message.profile.real_name'] = {'$ne': 'Slackbot'}
771
-
772
- return pipeline
773
-
774
705
  def get_per_day(self, date: datetime):
775
706
  start_day = datetime(date.year, date.month, date.day, 0, 0, 0, tzinfo=tz.tzutc())
776
707
  end_day = datetime(date.year, date.month, date.day, 23, 59, 59, tzinfo=tz.tzutc())
@@ -778,35 +709,6 @@ class LeadMongoRepository(BaseMongoRepository):
778
709
  return [LeadModel.from_dic(x) for x in docs]
779
710
 
780
711
 
781
- class SpamLeadsMongoRepository(LeadMongoRepository):
782
- pass
783
-
784
- def __init__(self):
785
- self.collection_name = 'spam_leads'
786
-
787
- def get_list(self, skip, limit, sort_field: str = 'created_at', sort_direction: str = 'ASCENDING', **kwargs):
788
- pipeline = self.__create_leads_filter(**kwargs)
789
- sort_direction = pymongo.ASCENDING if sort_direction == 'ASCENDING' else pymongo.DESCENDING
790
- docs = self.collection().find(pipeline).sort([(sort_field, sort_direction)]).skip(skip).limit(limit)
791
- leads = [ExtendedLeadModel.from_dic(doc) for doc in docs]
792
- senders = [lead.message.sender_id for lead in leads]
793
- contacts = SlackContactUserRepository().find(users=senders)
794
- for lead in leads:
795
- lead.contact = next(filter(lambda x: x.sender_id == lead.message.sender_id, contacts), None)
796
- return leads
797
-
798
- def __create_leads_filter(self, **kwargs):
799
- pipeline = {"user_id": {'$exists': False}}
800
- text = kwargs.get('text', None)
801
- stop_words = kwargs.get('stop_words', None)
802
- if stop_words:
803
- pipeline['full_message_text'] = {'$regex': f'^(?!.*({stop_words})).*$', '$options': 'i'}
804
- elif text:
805
- pipeline['$text'] = {'$search': text}
806
-
807
- return pipeline
808
-
809
-
810
712
  class SpamUserLeadsMongoRepository(UserLeadMongoRepository):
811
713
  pass
812
714
 
@@ -1023,6 +925,7 @@ class DedicatedBotRepository(BaseMongoRepository):
1023
925
  invalid_creds = kwargs.get('invalid_creds')
1024
926
  sort_by = kwargs.get('sort_by')
1025
927
  deactivated_from = kwargs.get('deactivated_from')
928
+ user_ids = kwargs.get('user_ids')
1026
929
 
1027
930
  if deactivated_from:
1028
931
  pipeline['deactivated_at'] = {'$gte': deactivated_from}
@@ -1066,6 +969,9 @@ class DedicatedBotRepository(BaseMongoRepository):
1066
969
  if sort_by:
1067
970
  pipeline[sort_by] = {'$exists': True}
1068
971
 
972
+ if user_ids is not None:
973
+ pipeline["user_id"] = {'$in': [to_object_id(_id) for _id in user_ids]}
974
+
1069
975
  return pipeline
1070
976
 
1071
977