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.
- {leadguru_jobs-0.542.0.dist-info → leadguru_jobs-0.544.0.dist-info}/METADATA +1 -1
- {leadguru_jobs-0.542.0.dist-info → leadguru_jobs-0.544.0.dist-info}/RECORD +14 -15
- lgt_jobs/lgt_common/pubsub/pubsubfactory.py +0 -4
- lgt_jobs/lgt_common/slack_client/methods.py +1 -2
- lgt_jobs/lgt_common/slack_client/slack_client.py +7 -78
- lgt_jobs/lgt_common/slack_client/web_client.py +9 -10
- lgt_jobs/lgt_data/analytics.py +0 -91
- lgt_jobs/lgt_data/engine.py +1 -24
- lgt_jobs/lgt_data/enums.py +0 -13
- lgt_jobs/lgt_data/model.py +4 -51
- lgt_jobs/lgt_data/mongo_repository.py +1 -126
- lgt_jobs/main.py +1 -1
- lgt_jobs/lgt_common/pubsub/command.py +0 -14
- {leadguru_jobs-0.542.0.dist-info → leadguru_jobs-0.544.0.dist-info}/WHEEL +0 -0
- {leadguru_jobs-0.542.0.dist-info → leadguru_jobs-0.544.0.dist-info}/top_level.txt +0 -0
@@ -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=
|
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=
|
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
|
38
|
-
lgt_jobs/lgt_common/slack_client/slack_client.py,sha256=
|
39
|
-
lgt_jobs/lgt_common/slack_client/web_client.py,sha256=
|
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=
|
42
|
-
lgt_jobs/lgt_data/engine.py,sha256=
|
43
|
-
lgt_jobs/lgt_data/enums.py,sha256=
|
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=
|
46
|
-
lgt_jobs/lgt_data/mongo_repository.py,sha256=
|
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.
|
51
|
-
leadguru_jobs-0.
|
52
|
-
leadguru_jobs-0.
|
53
|
-
leadguru_jobs-0.
|
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
|
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)
|
lgt_jobs/lgt_data/analytics.py
CHANGED
@@ -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)
|
lgt_jobs/lgt_data/engine.py
CHANGED
@@ -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
|
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) -> \
|
lgt_jobs/lgt_data/enums.py
CHANGED
@@ -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'
|
lgt_jobs/lgt_data/model.py
CHANGED
@@ -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
|
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
|
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,
|
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]
|
File without changes
|
File without changes
|