leadguru-jobs 0.542.0__py3-none-any.whl → 0.544.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.1
2
2
  Name: leadguru_jobs
3
- Version: 0.542.0
3
+ Version: 0.544.0
4
4
  Summary: LGT jobs builds
5
5
  Author-email: developer@leadguru.co
6
6
  Classifier: Development Status :: 5 - Production/Stable
@@ -1,7 +1,7 @@
1
1
  lgt_jobs/__init__.py,sha256=lrhMUJ7a5YSkYswQkQe981b_w8h8NHyncwfEduXEq6Q,1992
2
2
  lgt_jobs/basejobs.py,sha256=LPEclvY6fIG17YMGy9pRK0Q58n62gkI5W1BTK6R2p-c,1234
3
3
  lgt_jobs/env.py,sha256=cRO03GGvstUjBsv3uYO-iakrOvAk_ZWUP_fnmf21iZQ,789
4
- lgt_jobs/main.py,sha256=OUfuq8INpY54pYwdL3wV8Fy_3oScdMaj5jonUakWytY,1538
4
+ lgt_jobs/main.py,sha256=cK_nkBtJHnUNDbba1WZotqPtI_6OWxiYQkAgco9OAmE,1539
5
5
  lgt_jobs/runner.py,sha256=MZ3_UvfyDSM707UI4uPDntlKKCXkIyN6h95D1i1SoQQ,2125
6
6
  lgt_jobs/simple_job.py,sha256=sta7MP-57iwRewPycmTAc9dvSbocbGjWhb1QYYj7ccA,519
7
7
  lgt_jobs/smtp.py,sha256=Svaq2ghMjGwpPA4J92wVnzrLlVbI2FcM2d4liiAbHLo,1210
@@ -30,24 +30,23 @@ lgt_jobs/lgt_common/discord_client/methods.py,sha256=C46Vq9_-dlvs0nEW6ck8QvAmE_n
30
30
  lgt_jobs/lgt_common/enums/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
31
31
  lgt_jobs/lgt_common/enums/slack_errors.py,sha256=5VNbBaMKya2RIR5uyr3YI8N6Xll9WexItk7uJtoJ4NQ,142
32
32
  lgt_jobs/lgt_common/pubsub/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
33
- lgt_jobs/lgt_common/pubsub/command.py,sha256=tr7J51NGbt6Iq5CTEUyASu3o7KqP-Q64NfKaI1WVC64,278
34
33
  lgt_jobs/lgt_common/pubsub/messages.py,sha256=rm7uKbxwDTWJqsVA8Kee-4YT58bThjCEV2Q0559Lrzg,1397
35
- lgt_jobs/lgt_common/pubsub/pubsubfactory.py,sha256=7HAg_P2sZ6DDJkDyxzc4yI-i38bDSMxySulEGlHUhxc,2441
34
+ lgt_jobs/lgt_common/pubsub/pubsubfactory.py,sha256=rfUDooYuhBQ2pE9FdDxZOpXjbrvlpiiQLCGOtnTFbSg,2204
36
35
  lgt_jobs/lgt_common/slack_client/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
37
- lgt_jobs/lgt_common/slack_client/methods.py,sha256=-PxK8StkJ-dyACHdRRiQlRL2qaG9KEyWB7wo4eh7ifU,1506
38
- lgt_jobs/lgt_common/slack_client/slack_client.py,sha256=C1FwHQW82OS73THwPRF4_AvyDi4QbYLjbI_NDXO8Nwk,15896
39
- lgt_jobs/lgt_common/slack_client/web_client.py,sha256=oZV7oUcSXXngfMI6oXDedlQWePL9b2ClkocqbXNe1ns,6259
36
+ lgt_jobs/lgt_common/slack_client/methods.py,sha256=ctKF_1UHEmSWaRsoGEgMZicVabV7eEufZ7pjxdMAx8g,1455
37
+ lgt_jobs/lgt_common/slack_client/slack_client.py,sha256=6Jgz0ELARcqknL9YBW4yph75E_AUsDGBsoTpcoYNMBQ,13479
38
+ lgt_jobs/lgt_common/slack_client/web_client.py,sha256=JOW-VGYYGqFZgyoqjOZ3t_XUdZAOttETVjVBZUWiUDM,6245
40
39
  lgt_jobs/lgt_data/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
41
- lgt_jobs/lgt_data/analytics.py,sha256=Gr-7IzrnHPN9YJlIT6-NqrzVYU39vQUMKCRMsvvM5A4,22869
42
- lgt_jobs/lgt_data/engine.py,sha256=YJYEAj1Z4_XIhPMaoB7bp8x9ponANBzw7gZRrj6c-c4,8600
43
- lgt_jobs/lgt_data/enums.py,sha256=fr5yR5WPilFgWMBtMsYkVy5vsq3bT0t553CCuKtWpXQ,2416
40
+ lgt_jobs/lgt_data/analytics.py,sha256=FJxImuuJw-m4B-eKIddytBy_B19BVsdPEHib-5gNgyo,20172
41
+ lgt_jobs/lgt_data/engine.py,sha256=Rsbz-CApAo_TVDssdjBkv8v_fVOZm_Uh1S6W4fnaEWo,7728
42
+ lgt_jobs/lgt_data/enums.py,sha256=pZz8Xv-44hhhttb01ci4YnMIj7gS1oNnhX24XnuX5UM,2160
44
43
  lgt_jobs/lgt_data/helpers.py,sha256=NDa-V5EYaJfkGoWsmQSwSe6N_jxNxs8tHRQzW1iST6k,480
45
- lgt_jobs/lgt_data/model.py,sha256=ZXJHbsQ-BgH09o9siw5yqKNWqQSymsOQ5HH8nKFeACQ,29312
46
- lgt_jobs/lgt_data/mongo_repository.py,sha256=nX9oh7-Em1amfljkvgbyA4hjaxdOb27ocZM132YmZWQ,49479
44
+ lgt_jobs/lgt_data/model.py,sha256=DDfoWeH6rLWKoZsFJ2tI5Yagj1WlOa0PIJp-GqBIVSA,28112
45
+ lgt_jobs/lgt_data/mongo_repository.py,sha256=6Cv5L90jUPgzTbv5vCjsGSOkeCdzVJf0pTRYHujBnUU,44855
47
46
  lgt_jobs/services/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
48
47
  lgt_jobs/services/web_client.py,sha256=GLWsJkIC8rv6xLFaLwcMm4EwBlVDu0njORwkZqBJaE4,2086
49
48
  lgt_jobs/templates/new_message.html,sha256=BD_E90akmQ1Wf07wtZAjeK_7DUKRmja5HFHVo_AKI24,6994
50
- leadguru_jobs-0.542.0.dist-info/METADATA,sha256=b4X_3y3w-rQ2LBt4K3Ay8vOIJnpAetDZwWRzGfZmcsA,1319
51
- leadguru_jobs-0.542.0.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
52
- leadguru_jobs-0.542.0.dist-info/top_level.txt,sha256=rIuw1DqwbnZyeoarBSC-bYeGOhv9mZBs7_afl9q4_JI,9
53
- leadguru_jobs-0.542.0.dist-info/RECORD,,
49
+ leadguru_jobs-0.544.0.dist-info/METADATA,sha256=r1tD2YPghm4E8ID9f5OBosLGwnywHC-VYLAlBLRwdqA,1319
50
+ leadguru_jobs-0.544.0.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
51
+ leadguru_jobs-0.544.0.dist-info/top_level.txt,sha256=rIuw1DqwbnZyeoarBSC-bYeGOhv9mZBs7_afl9q4_JI,9
52
+ leadguru_jobs-0.544.0.dist-info/RECORD,,
@@ -30,10 +30,6 @@ class PubSubFactory:
30
30
  topic_path = self.get_topic_path(topic_name)
31
31
  self.publisher.api.delete_topic(topic=topic_path)
32
32
 
33
- def delete_subscriber(self, subscriber_name: str, topic_name: str):
34
- subscription_path = self.get_subscription_path(subscriber_name, topic_name)
35
- self.subscriber.api.delete_subscription(subscription=subscription_path)
36
-
37
33
  def create_subscription_if_doesnt_exist(self, subscriber_name, topic_name,
38
34
  ack_deadline_seconds=60) -> pubsub_v1.types.pubsub_gapic_types.Subscription:
39
35
  subscription_path = self.get_subscription_path(subscriber_name, topic_name)
@@ -6,7 +6,6 @@ class SlackMethods:
6
6
  users_list = 'users.list'
7
7
  users_info = 'users.info'
8
8
  users_get_presence = 'users.getPresence'
9
- list_users = "users.list"
10
9
 
11
10
  conversations_join = 'conversations.join'
12
11
  conversations_leave = 'conversations.leave'
@@ -19,7 +18,6 @@ class SlackMethods:
19
18
  chat_delete = 'chat.delete'
20
19
  chat_update = 'chat.update'
21
20
  chat_post_message = 'chat.postMessage'
22
- chat_schedule_message = "chat.scheduleMessage"
23
21
  chat_attachments = "chat.unfurlLink"
24
22
 
25
23
  rtm_connect = 'rtm.connect'
@@ -30,6 +28,7 @@ class SlackMethods:
30
28
  alternative_invite_by_email = 'users.inviteRequests.create'
31
29
 
32
30
  upload_file = 'files.upload'
31
+ files_info = 'files.info'
33
32
  download_file = 'files.download'
34
33
  delete_file = 'files.delete'
35
34
  share_files = 'files.share'
@@ -1,13 +1,12 @@
1
- import requests
2
- import aiohttp
3
1
  import asyncio
4
- import websockets
2
+ import aiohttp
3
+ import requests
5
4
  import json
6
5
  import io
7
6
  from urllib import parse
8
7
  from requests import Response
9
8
  from websockets.client import WebSocketClientProtocol
10
- from .methods import SlackMethods
9
+ from lgt_jobs.lgt_common.slack_client.methods import SlackMethods
11
10
 
12
11
 
13
12
  class SlackClient:
@@ -78,6 +77,10 @@ class SlackClient:
78
77
  return requests.post(f"{self.base_url}{SlackMethods.share_files}", data=payload,
79
78
  headers=self.headers, cookies=self.cookies).json()
80
79
 
80
+ def get_file_info(self, file_id: str):
81
+ return requests.get(url=f"{self.base_url}{SlackMethods.files_info}",
82
+ cookies=self.cookies, headers=self.headers, params={'file': file_id}).json()
83
+
81
84
  def get_profile(self, user_id: str = None):
82
85
  url = f'{self.base_url}{SlackMethods.profile_get}'
83
86
  payload = {}
@@ -165,10 +168,6 @@ class SlackClient:
165
168
  url = f'{self.base_url}{SlackMethods.conversations_replies}?{self.__ts_payload(channel, id)}'
166
169
  return requests.get(url=url, cookies=self.cookies).json()
167
170
 
168
- def get_presense(self, user: str = None):
169
- url = f'{self.base_url}{SlackMethods.users_get_presence}?{self.__presense_payload(user)}'
170
- return requests.get(url=url, cookies=self.cookies).json()
171
-
172
171
  def post_message(self, channel: str, text: str):
173
172
  import uuid
174
173
  payload = {
@@ -179,21 +178,6 @@ class SlackClient:
179
178
  url = f'{self.base_url}{SlackMethods.chat_post_message}'
180
179
  return requests.post(url=url, cookies=self.cookies, headers=self.headers, data=payload).json()
181
180
 
182
- def post_message_schedule(self, channel: str, text: str, post_at: int):
183
- url = (f'{self.base_url}{SlackMethods.chat_schedule_message}?'
184
- f'{self.__post_scheduled_message_payload(channel, text, post_at)}')
185
- return requests.post(url=url, cookies=self.cookies).json()
186
-
187
- def users_list(self, cursor=None, limit: int = 1000):
188
- url = f'{self.base_url}{SlackMethods.users_list}?{self.__token_payload()}'
189
- if cursor:
190
- url += f'&cursor={cursor}'
191
-
192
- if limit:
193
- url += f'&limit={limit}'
194
-
195
- return requests.get(url=url, cookies=self.cookies).json()
196
-
197
181
  def user_info(self, user: str):
198
182
  url = f'{self.base_url}{SlackMethods.users_info}?{self.__user_info_payload(user)}'
199
183
  return requests.get(url=url, cookies=self.cookies).json()
@@ -202,19 +186,6 @@ class SlackClient:
202
186
  url = f'{self.base_url}{SlackMethods.reactions_get}?{self.__get_reactions_payload(channel, id)}'
203
187
  return requests.get(url=url, cookies=self.cookies).json()
204
188
 
205
- def get_attachments(self, channel: str, msg_id: str, url: str):
206
- payload = {
207
- 'token': self.token,
208
- 'channel': channel,
209
- 'client_msg_id': msg_id,
210
- 'url': url
211
- }
212
- url = f'{self.base_url}{SlackMethods.chat_attachments}'
213
- response = requests.post(url=url, cookies=self.cookies, data=payload)
214
- if response.status_code != 200:
215
- return
216
- return response.json().get('attachments')
217
-
218
189
  def check_email(self, email: str, user_agent: str) -> bool:
219
190
  payload = {'email': email}
220
191
  headers = {'User-Agent': user_agent}
@@ -270,23 +241,6 @@ class SlackClient:
270
241
  return requests.post(f"{self.base_url}/{SlackMethods.auth_test}", headers=headers,
271
242
  cookies=self.cookies)
272
243
 
273
- def rtm_connect(self, callback):
274
- loop = asyncio.new_event_loop()
275
- loop.run_until_complete(self.__consumer(callback))
276
- loop.run_forever()
277
-
278
- async def __consumer(self, callback):
279
- url = f'{self.base_url}{SlackMethods.rtm_connect}?{self.__token_payload()}'
280
- response = requests.get(url=url, cookies=self.cookies).json()
281
- web_socket_url = response['url']
282
- async with websockets.connect(uri=web_socket_url) as websocket:
283
- self.socket = websocket
284
- async for message in websocket:
285
- await callback(json.loads(message))
286
-
287
- def __token_payload(self):
288
- return parse.urlencode({'token': self.token})
289
-
290
244
  def __user_info_payload(self, user):
291
245
  payload = {
292
246
  'token': self.token,
@@ -294,15 +248,6 @@ class SlackClient:
294
248
  }
295
249
  return parse.urlencode(payload)
296
250
 
297
- def __post_scheduled_message_payload(self, channel, text, post_at):
298
- payload = {
299
- 'token': self.token,
300
- 'channel': channel,
301
- 'text': text,
302
- 'post_at': post_at
303
- }
304
- return parse.urlencode(payload)
305
-
306
251
  def __update_message_payload(self, channel, id, text, file_ids):
307
252
  payload = {
308
253
  'parse': 'none',
@@ -345,13 +290,6 @@ class SlackClient:
345
290
  }
346
291
  return parse.urlencode(payload)
347
292
 
348
- def __update_profile_payload(self, profile):
349
- payload = {
350
- 'token': self.token,
351
- 'profile': profile
352
- }
353
- return parse.urlencode(payload)
354
-
355
293
  def __channel_payload(self, channel, id=None):
356
294
  payload = {
357
295
  'token': self.token,
@@ -365,15 +303,6 @@ class SlackClient:
365
303
 
366
304
  return parse.urlencode(payload)
367
305
 
368
- def __presense_payload(self, user: str = None):
369
- payload = {
370
- 'token': self.token,
371
- }
372
-
373
- if user:
374
- payload["user"] = user
375
- return parse.urlencode(payload)
376
-
377
306
  def __ts_payload(self, channel: str, id: str):
378
307
  payload = {
379
308
  'token': self.token,
@@ -76,7 +76,6 @@ class SlackFilesClient:
76
76
  blob = bucket.blob(blob_path)
77
77
  blob.upload_from_string(res.content, content_type=mimetype)
78
78
 
79
- blob = bucket.get_blob(blob_path)
80
79
  # valid for 3 days
81
80
  return blob.generate_signed_url(timedelta(3))
82
81
 
@@ -106,9 +105,6 @@ class SlackWebClient:
106
105
  def post_message(self, to, text):
107
106
  return self.client.post_message(to, text)
108
107
 
109
- def user_list(self):
110
- return self.client.users_list()
111
-
112
108
  def channels_list(self):
113
109
  return self.client.get_conversations_list()
114
110
 
@@ -118,12 +114,6 @@ class SlackWebClient:
118
114
  def update_profile(self, profile):
119
115
  return self.client.update_profile(profile)
120
116
 
121
- def channel_join(self, channels):
122
- return self.client.join_channels(channels)
123
-
124
- def channel_leave(self, channels):
125
- return self.client.leave_channels(channels)
126
-
127
117
  def get_reactions(self, channel, id):
128
118
  return self.client.get_reactions(channel, id)
129
119
 
@@ -165,3 +155,12 @@ class SlackWebClient:
165
155
 
166
156
  def get_team_info(self):
167
157
  return self.client.get_team_info()
158
+
159
+ def get_file_info(self, file_id: str):
160
+ return self.client.get_file_info(file_id)
161
+
162
+ def channel_join(self, channels):
163
+ return self.client.join_channels(channels)
164
+
165
+ def channel_leave(self, channels):
166
+ return self.client.leave_channels(channels)
@@ -513,52 +513,6 @@ def get_bots_aggregated_analytics(from_date: datetime = None,
513
513
  return received_messages_dic, filtered_messages_dic
514
514
 
515
515
 
516
- def get_channel_aggregated_analytics(from_date: datetime = None, to_date: datetime = None,
517
- bot_id: Optional[str | ObjectId] = None):
518
- pipeline = [
519
- {
520
- '$match': {
521
- 'extra_ids': {"$in": [str(bot_id)]}
522
- }
523
- },
524
- {
525
- "$group": {
526
- '_id': {
527
- '$arrayElemAt': [
528
- '$attributes', 0
529
- ]
530
- },
531
- 'count': {"$sum": 1}
532
- }
533
- },
534
- {
535
- '$limit': 1000
536
- }
537
- ]
538
-
539
- if from_date:
540
- beginning_of_the_day = datetime(from_date.year, from_date.month, from_date.day, 0, 0, 0, 0)
541
- pipeline.insert(0, {"$match": {"created_at": {"$gte": beginning_of_the_day}}})
542
-
543
- if to_date:
544
- end_of_the_day = datetime(to_date.year, to_date.month, to_date.day, 23, 59, 59, 999)
545
- pipeline.insert(0, {"$match": {"created_at": {"$lte": end_of_the_day}}})
546
-
547
- received_messages = list(db[f'received_messages'].aggregate(pipeline))
548
- filtered_messages = list(db[f'filtered_messages'].aggregate(pipeline))
549
-
550
- received_messages_dic = OrderedDict()
551
- filtered_messages_dic = OrderedDict()
552
-
553
- for item in received_messages:
554
- received_messages_dic[item["_id"]] = item["count"]
555
-
556
- for item in filtered_messages:
557
- filtered_messages_dic[item["_id"]] = item["count"]
558
-
559
- return received_messages_dic, filtered_messages_dic
560
-
561
-
562
516
  def get_users_aggregated_analytics(event_type: str = 'user-lead-extended',
563
517
  from_date: datetime = None,
564
518
  to_date: datetime = None,
@@ -645,51 +599,6 @@ def get_events_leads(email, event, from_date, to_date=None):
645
599
  return list(db[event].find(pipeline))
646
600
 
647
601
 
648
- def get_leads_aggregation(email, event, from_date, to_date=None):
649
- pipeline = get_event_pipeline(email, from_date, to_date)
650
- return list(db[event].aggregate(pipeline))
651
-
652
-
653
- def get_event_pipeline(email, from_date, to_date=None):
654
- pipeline = [
655
- {
656
- "$match": {
657
- 'name': email,
658
- 'created_at': {'$gte': from_date}
659
- }
660
- },
661
- {
662
- '$group': {
663
- '_id': {
664
- '$dateFromParts': {
665
- 'day': {
666
- '$dayOfMonth': '$created_at'
667
- },
668
- 'month': {
669
- '$month': '$created_at'
670
- },
671
- 'year': {
672
- '$year': '$created_at'
673
- }
674
- }
675
- },
676
- 'count': {
677
- '$sum': 1
678
- }
679
- }
680
- },
681
- {
682
- "$sort": {"_id": 1}
683
- }
684
- ]
685
-
686
- if to_date:
687
- end = datetime(to_date.year, to_date.month, to_date.day, 23, 59, 59, tzinfo=tz.tzutc())
688
- pipeline[0]["$match"]["created_at"]['$lte'] = end
689
-
690
- return pipeline
691
-
692
-
693
602
  def get_total_analytic_followup_up_date(from_date, to_date=None):
694
603
  beginning_of_the_day = datetime(from_date.year, from_date.month, from_date.day, 0, 0, 0, 0)
695
604
  end_of_the_day = datetime(to_date.year, to_date.month, to_date.day, 23, 59, 59, 999)
@@ -5,7 +5,7 @@ from datetime import datetime, UTC
5
5
  from bson import ObjectId
6
6
  from mongoengine import connect, Document, DateTimeField, StringField, IntField, ObjectIdField, ListField
7
7
  from typing import Dict, Tuple, Optional
8
- from .mongo_repository import to_object_id, UserMongoRepository
8
+ from .mongo_repository import to_object_id
9
9
 
10
10
  connect(host=os.environ.get('MONGO_CONNECTION_STRING', 'mongodb://127.0.0.1:27017/'), db="lgt_admin", alias="lgt_admin")
11
11
 
@@ -73,29 +73,6 @@ class UserTrackAction(Document):
73
73
  metadata=metadata
74
74
  ).save()
75
75
 
76
- @staticmethod
77
- def get_ws_monitoring_logs(email: str, action_subtype: str, from_date: datetime, to_date: datetime,
78
- source_id=None) -> list[UserTrackAction]:
79
-
80
- pipeline = {'action': {'$regex': f"^monitoring.*{action_subtype}$"}}
81
-
82
- if email:
83
- user = UserMongoRepository().get_by_email(email)
84
- pipeline['user_id'] = to_object_id(user.id)
85
-
86
- if from_date:
87
- start = datetime(from_date.year, from_date.month, from_date.day)
88
- pipeline['created_at__gte'] = start
89
-
90
- if to_date:
91
- end = datetime(to_date.year, to_date.month, to_date.day, 23, 59, 59)
92
- pipeline['created_at__lte'] = end
93
-
94
- if source_id:
95
- pipeline['metadata'] = {'$regex': f"^{source_id}:"}
96
-
97
- return list(UserTrackAction.objects(**pipeline))
98
-
99
76
  @staticmethod
100
77
  def get_global_user_actions(user_id: str = None, from_date: datetime = None,
101
78
  to_date: datetime = None, actions: list = None) -> \
@@ -1,12 +1,6 @@
1
1
  from enum import Enum, IntFlag
2
2
 
3
3
 
4
- class DedicatedBotState(IntFlag):
5
- Operational = 0
6
- Stopped = 1
7
- ScheduledForDeletion = 2
8
-
9
-
10
4
  class UserAccountState(IntFlag):
11
5
  Operational = 0
12
6
  Suspended = 1
@@ -33,13 +27,6 @@ class SourceType(str, Enum):
33
27
  DISCORD = 'discord'
34
28
 
35
29
 
36
- class BotUpdateEventType(str, Enum):
37
- NotDefined = 'NotDefined'
38
- BotAdded = 'BotAdded'
39
- BotDeleted = 'BotDeleted'
40
- BotUpdated = 'BotUpdated'
41
-
42
-
43
30
  class UserAction(str, Enum):
44
31
  PAUSE_SOURCE = 'monitoring.pause.source'
45
32
  UNPAUSE_SOURCE = 'monitoring.unpause.source'
@@ -3,7 +3,7 @@ import copy
3
3
  import json
4
4
  from abc import ABC
5
5
  from datetime import datetime, UTC
6
- from typing import Optional, List, Dict
6
+ from typing import Optional, List
7
7
  from .enums import UserRole, SourceType, FeaturesEnum, FeatureOptions
8
8
  from bson import ObjectId
9
9
 
@@ -290,6 +290,8 @@ class UserModel(BaseModel):
290
290
  self.subscription_expired_at: datetime | None = None
291
291
  self.balance: str | None = None
292
292
  self.subscription_name: str | None = None
293
+ self.subscription_expiration_notified = False
294
+ self.subscription_expiration_warning_notified = False
293
295
 
294
296
  @classmethod
295
297
  def from_dic(cls, dic: dict):
@@ -540,37 +542,6 @@ class BotInfo:
540
542
  return result
541
543
 
542
544
 
543
- class SlackReplyModel(BaseModel):
544
- def __init__(self):
545
- super().__init__()
546
- self.type = None
547
- self.user = None
548
- self.username = None
549
- self.text = None
550
- self.thread_ts = None
551
- self.parent_user_id = None
552
- self.ts = None
553
- self.files = []
554
- self.attachments = []
555
-
556
- @classmethod
557
- def from_slack_response(cls, dic: dict):
558
- if not dic:
559
- return None
560
-
561
- model = cls()
562
- for k, v in dic.items():
563
- setattr(model, k, v)
564
-
565
- js_ticks = int(model.ts.split('.')[0] + model.ts.split('.')[1][3:])
566
- model.created_at = datetime.fromtimestamp(js_ticks / 1000.0)
567
-
568
- if model.files:
569
- model.files = [{"url_private_download": file.get("url_private_download")} for file in model.files]
570
-
571
- return model
572
-
573
-
574
545
  class ChatMessage:
575
546
  bot_id: ObjectId
576
547
  user_id: ObjectId
@@ -657,16 +628,6 @@ class UserLeadModel(LeadModel):
657
628
  result.chat_viewed_at = dic.get('chat_viewed_at')
658
629
  return result
659
630
 
660
- @staticmethod
661
- def from_route(lead: LeadModel):
662
- model_dict = lead.to_dic()
663
- result = UserLeadModel.from_dic(model_dict)
664
- result.order = 0
665
-
666
- result.message = MessageModel.from_dic(model_dict['message'])
667
- result.chat_viewed_at = None
668
- return result
669
-
670
631
 
671
632
  class ExtendedUserLeadModel(UserLeadModel):
672
633
  pass
@@ -892,8 +853,7 @@ class ExtendedSlackMemberInformation(SlackMemberInformation):
892
853
  return model
893
854
 
894
855
  @staticmethod
895
- def to_lead(contact: ExtendedSlackMemberInformation, linkedin_contacts: Dict[str, LinkedinContact] = None) \
896
- -> ExtendedUserLeadModel:
856
+ def to_lead(contact: ExtendedSlackMemberInformation) -> ExtendedUserLeadModel:
897
857
  lead = ExtendedUserLeadModel()
898
858
  lead.id = str(contact.id)
899
859
  lead.created_at = contact.created_at
@@ -936,13 +896,6 @@ class UserTemplateModel(BaseModel):
936
896
  user_id: Optional[ObjectId]
937
897
 
938
898
 
939
- class LinkedinContact(BaseModel):
940
- full_name: str
941
- slack_user: str
942
- title: str
943
- urls: List[dict]
944
-
945
-
946
899
  class CloudFileModel(BaseModel):
947
900
  blob_path: str
948
901
  public_url: str
@@ -7,7 +7,7 @@ from pymongo import MongoClient, UpdateOne
7
7
  from bson.objectid import ObjectId
8
8
  from lgt_jobs.lgt_data.enums import SourceType
9
9
  from lgt_jobs.lgt_data.model import (LeadModel, BaseModel, UserModel, UserResetPasswordModel, BoardModel, BoardedStatus,
10
- DedicatedBotModel, SlackMemberInformation, UserTemplateModel, LinkedinContact,
10
+ DedicatedBotModel, SlackMemberInformation, UserTemplateModel,
11
11
  ExtendedUserLeadModel, UserLeadModel, ExtendedLeadModel, UserContact, ChatMessage,
12
12
  GroupedMessagesModel, UserVerificationModel, UsersPage, Subscription)
13
13
  from datetime import datetime, UTC, timedelta
@@ -153,10 +153,6 @@ class UserLeadMongoRepository(BaseMongoRepository):
153
153
  collection_name = 'user_leads'
154
154
  model = ExtendedUserLeadModel
155
155
 
156
- def get_count(self, user_id, **kwargs):
157
- pipeline = self.__create_leads_filter(user_id, **kwargs)
158
- return self.collection().count_documents(pipeline)
159
-
160
156
  def get_many(self, ids: list, user_id):
161
157
  docs = self.collection().find({"id": {'$in': ids}, 'user_id': to_object_id(user_id)})
162
158
  leads = [ExtendedUserLeadModel.from_dic(lead) for lead in docs]
@@ -292,54 +288,6 @@ class UserLeadMongoRepository(BaseMongoRepository):
292
288
  pipeline["message.dedicated_slack_options.bot_id"] = {"$in": dedicated_bots_ids}
293
289
  return pipeline
294
290
 
295
- def get_unanswered_leads_ids(self, user_id: str, from_date=None):
296
- pipeline = [
297
- {
298
- '$match':
299
- {
300
- 'user_id': to_object_id(user_id)
301
- }
302
- },
303
- {
304
- '$match':
305
- {
306
- 'chat_history': {'$exists': True, '$not': {'$size': 0}}
307
- }
308
- },
309
- {
310
- '$project':
311
- {
312
- 'id': 1,
313
- 'sender_id': "$message.sender_id",
314
- 'last_message': {'$arrayElemAt': ['$chat_history', 0]}
315
- }
316
- },
317
- {
318
- '$addFields':
319
- {
320
- 'is_user_message': {'$ne': ['$sender_id', '$last_message.user']}
321
- }
322
- },
323
- {
324
- '$match':
325
- {
326
- '$and':
327
- [
328
- {'last_message.text': {'$regex': '\\?'}},
329
- {'is_user_message': False}
330
- ]
331
- }
332
- }
333
- ]
334
-
335
- if from_date:
336
- beginning_of_the_day = datetime(from_date.year, from_date.month, from_date.day, 0, 0, 0, 0)
337
- pipeline.insert(0, {"$match": {"created_at": {"$gte": beginning_of_the_day}}})
338
-
339
- data = list(self.collection().aggregate(pipeline))
340
- leads_ids = [item['id'] for item in data]
341
- return leads_ids
342
-
343
291
  def get_daily_analytics_by_workspace(self, user_configs: list,
344
292
  dedicated_only: bool | None,
345
293
  from_date: datetime,
@@ -405,10 +353,6 @@ class UserLeadMongoRepository(BaseMongoRepository):
405
353
 
406
354
  return saved_messages_dic
407
355
 
408
- def get_leads_after(self, action_after: datetime) -> [ExtendedUserLeadModel]:
409
- leads = self.collection().find({'last_action_at': {'$gte': action_after}})
410
- return [ExtendedUserLeadModel.from_dic(lead) for lead in leads]
411
-
412
356
  def add_lead(self, user_id, lead: UserLeadModel) -> None:
413
357
  if not lead.created_at:
414
358
  lead.created_at = datetime.now(UTC)
@@ -429,11 +373,6 @@ class UserLeadMongoRepository(BaseMongoRepository):
429
373
 
430
374
  return ExtendedUserLeadModel.from_dic(self.collection().find_one(pipeline))
431
375
 
432
- def update_same_leads(self, user_id, sender_id: str, **kwargs):
433
- pipeline = {'user_id': to_object_id(user_id), 'message.sender_id': sender_id}
434
- update_dict = {k: v for k, v in kwargs.items() if v is not None}
435
- self.collection().update_many(pipeline, {'$set': update_dict})
436
-
437
376
  def update_leads_order(self, user_id, lead_ids: [str]):
438
377
  pipeline = {'user_id': to_object_id(user_id), 'id': {'$in': lead_ids}}
439
378
  docs = list(self.collection().find(pipeline))
@@ -559,10 +498,6 @@ class LeadMongoRepository(BaseMongoRepository):
559
498
  update_dict = {k: v for k, v in kwargs.items() if v is not None}
560
499
  self.collection().update_one({'id': _id}, {'$set': update_dict}, upsert=False)
561
500
 
562
- def get_count(self, **kwargs):
563
- pipeline = self.__create_leads_filter(**kwargs)
564
- return self.collection().count_documents(pipeline)
565
-
566
501
  def get_list(self, skip, limit, **kwargs):
567
502
  pipeline = self.__create_leads_filter(**kwargs)
568
503
 
@@ -684,10 +619,6 @@ class SpamLeadsMongoRepository(LeadMongoRepository):
684
619
  lead.contact = next(filter(lambda x: x.sender_id == lead.message.sender_id, contacts), None)
685
620
  return leads
686
621
 
687
- def get_count(self, **kwargs):
688
- pipeline = self.__create_leads_filter(**kwargs)
689
- return self.collection().count_documents(pipeline)
690
-
691
622
  def __create_leads_filter(self, **kwargs):
692
623
  pipeline = {"user_id": {'$exists': False}}
693
624
  text = kwargs.get('text', None)
@@ -883,14 +814,6 @@ class DedicatedBotRepository(BaseMongoRepository):
883
814
 
884
815
  collection_name = 'dedicated_bots'
885
816
 
886
- def get_by_user_and_source_id(self, user_id: str, source_id: str) -> Optional[DedicatedBotModel]:
887
- doc = self.collection().find_one({"user_id": ObjectId(f"{user_id}"), "source.source_id": source_id})
888
- return DedicatedBotModel.from_dic(doc)
889
-
890
- def get_by_user_and_active_server_id(self, user_id: str, active_server_id: str) -> Optional[DedicatedBotModel]:
891
- doc = self.collection().find_one({"user_id": ObjectId(f"{user_id}"), "active_servers.id": active_server_id})
892
- return DedicatedBotModel.from_dic(doc)
893
-
894
817
  def add_or_update(self, bot: DedicatedBotModel):
895
818
  bot_dict = bot.to_dic()
896
819
  if '_id' in bot_dict:
@@ -923,25 +846,6 @@ class DedicatedBotRepository(BaseMongoRepository):
923
846
  pipeline = self.__create_bots_filter(**kwargs)
924
847
  return DedicatedBotModel.from_dic(self.collection().find_one(pipeline))
925
848
 
926
- def get_user_bots(self, user_id: str, only_valid: bool = False,
927
- include_deleted: bool = False, include_paused: bool = False, **kwargs) -> List[DedicatedBotModel]:
928
- pipeline = {'user_id': to_object_id(user_id)}
929
- user_name = kwargs.get('user_name')
930
-
931
- if user_name:
932
- pipeline['user_name'] = user_name
933
-
934
- if not include_deleted:
935
- pipeline['deleted'] = False
936
-
937
- if not include_paused:
938
- pipeline['paused'] = False
939
-
940
- if only_valid:
941
- pipeline['invalid_creds'] = False
942
-
943
- return [DedicatedBotModel.from_dic(doc) for doc in self.collection().find(pipeline)]
944
-
945
849
  def delete(self, _id: str):
946
850
  self.collection().update_one({'_id': to_object_id(f"{_id}")}, {"$set": {"deleted": True}})
947
851
 
@@ -1025,26 +929,6 @@ class SlackContactUserRepository(BaseMongoRepository):
1025
929
  pipeline = {"sender_id": user_id}
1026
930
  return SlackMemberInformation.from_dic(self.collection().find_one(pipeline))
1027
931
 
1028
- def get_count_in_workspaces(self):
1029
- pipeline = [
1030
- {
1031
- '$match': {
1032
- 'user': {
1033
- '$ne': 'USLACKBOT'
1034
- }
1035
- }
1036
- }, {
1037
- '$group': {
1038
- '_id': '$workspace',
1039
- 'count': {
1040
- '$sum': 1
1041
- }
1042
- }
1043
- }
1044
- ]
1045
- docs = list(self.collection().aggregate(pipeline))
1046
- return {doc['_id']: doc['count'] for doc in docs}
1047
-
1048
932
 
1049
933
  class UserTemplatesRepository(BaseMongoRepository):
1050
934
  collection_name = "user_templates"
@@ -1071,15 +955,6 @@ class UserTemplatesRepository(BaseMongoRepository):
1071
955
  return self.collection().find_one_and_delete({'_id': to_object_id(id)})
1072
956
 
1073
957
 
1074
- class LinkedinContactRepository(BaseMongoRepository):
1075
- collection_name = "linkedin_contact"
1076
- model = LinkedinContact
1077
-
1078
- def find(self, **kwargs):
1079
- docs = self.collection().find({**kwargs})
1080
- return [LinkedinContact.from_dic(doc) for doc in docs]
1081
-
1082
-
1083
958
  class UserContactsRepository(BaseMongoRepository):
1084
959
  collection_name = 'user_contacts'
1085
960
 
lgt_jobs/main.py CHANGED
@@ -40,7 +40,7 @@ if __name__ == '__main__':
40
40
  client.setup_logging()
41
41
  factory = PubSubFactory(project_id)
42
42
  factory.create_topic_if_doesnt_exist(background_jobs_topic)
43
- factory.create_subscription_if_doesnt_exist(background_jobs_subscriber, background_jobs_topic,600)
43
+ factory.create_subscription_if_doesnt_exist(background_jobs_subscriber, background_jobs_topic, 600)
44
44
  bot_subscription_path = factory.get_subscription_path(background_jobs_subscriber, background_jobs_topic)
45
45
  factory.subscriber.subscribe(bot_subscription_path, callback=run_background_job_with_lock)
46
46
  while True:
@@ -1,14 +0,0 @@
1
- import enum
2
- from typing import Optional
3
- from pydantic import BaseModel, Extra
4
-
5
-
6
- class TelegramCommandType(enum.Enum):
7
- AUTH_VERIFICATION_CODE = 1
8
- HARD_RESET = 1
9
-
10
-
11
- class TelegramCommand(BaseModel, extra=Extra.ignore):
12
- bot_id: str
13
- type: int
14
- data: Optional[str]