leadguru-jobs 0.542.0__py3-none-any.whl → 0.543.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.543.0.dist-info}/METADATA +1 -1
- {leadguru_jobs-0.542.0.dist-info → leadguru_jobs-0.543.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 +5 -106
- lgt_jobs/lgt_common/slack_client/web_client.py +3 -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.543.0.dist-info}/WHEEL +0 -0
- {leadguru_jobs-0.542.0.dist-info → leadguru_jobs-0.543.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=mbwHaqixC3xCJ0KP9WepxJtwlsJwTSEWQ2O1hx0hjXE,12173
|
38
|
+
lgt_jobs/lgt_common/slack_client/web_client.py,sha256=vAfE6qrT1oTyP35chRsgeH008xtbsNGYdPqMqCdJmlE,6063
|
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.543.0.dist-info/METADATA,sha256=BSC1hi76_fPJxmBt6C__Sd9VpnWH9vfbEV8VWq6d1IU,1319
|
50
|
+
leadguru_jobs-0.543.0.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
51
|
+
leadguru_jobs-0.543.0.dist-info/top_level.txt,sha256=rIuw1DqwbnZyeoarBSC-bYeGOhv9mZBs7_afl9q4_JI,9
|
52
|
+
leadguru_jobs-0.543.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,10 @@
|
|
1
1
|
import requests
|
2
|
-
import aiohttp
|
3
|
-
import asyncio
|
4
|
-
import websockets
|
5
2
|
import json
|
6
3
|
import io
|
7
4
|
from urllib import parse
|
8
5
|
from requests import Response
|
9
6
|
from websockets.client import WebSocketClientProtocol
|
10
|
-
from .methods import SlackMethods
|
7
|
+
from lgt_jobs.lgt_common.slack_client.methods import SlackMethods
|
11
8
|
|
12
9
|
|
13
10
|
class SlackClient:
|
@@ -25,34 +22,6 @@ class SlackClient:
|
|
25
22
|
else:
|
26
23
|
self.cookies = cookies
|
27
24
|
|
28
|
-
def join_channels(self, channels):
|
29
|
-
loop = asyncio.new_event_loop()
|
30
|
-
asyncio.set_event_loop(loop)
|
31
|
-
tasks = asyncio.gather(*[self.join_channel_async(channel) for channel in channels])
|
32
|
-
results = loop.run_until_complete(tasks)
|
33
|
-
loop.close()
|
34
|
-
return results
|
35
|
-
|
36
|
-
def leave_channels(self, channels):
|
37
|
-
loop = asyncio.new_event_loop()
|
38
|
-
asyncio.set_event_loop(loop)
|
39
|
-
tasks = asyncio.gather(*[self.leave_channel_async(channel) for channel in channels])
|
40
|
-
results = loop.run_until_complete(tasks)
|
41
|
-
loop.close()
|
42
|
-
return results
|
43
|
-
|
44
|
-
async def join_channel_async(self, channel):
|
45
|
-
async with aiohttp.ClientSession() as session:
|
46
|
-
url = f'{self.base_url}{SlackMethods.conversations_join}?{self.__channel_payload(channel)}'
|
47
|
-
async with session.post(url=url, cookies=self.cookies) as response:
|
48
|
-
return await response.json()
|
49
|
-
|
50
|
-
async def leave_channel_async(self, channel):
|
51
|
-
async with aiohttp.ClientSession() as session:
|
52
|
-
url = f'{self.base_url}{SlackMethods.conversations_leave}?{self.__channel_payload(channel)}'
|
53
|
-
async with session.post(url=url, cookies=self.cookies) as response:
|
54
|
-
return await response.json()
|
55
|
-
|
56
25
|
def upload_file(self, file, file_name):
|
57
26
|
payload = {"content": file, "filename": file_name}
|
58
27
|
return requests.post(f"{self.base_url}{SlackMethods.upload_file}", data=payload,
|
@@ -78,6 +47,10 @@ class SlackClient:
|
|
78
47
|
return requests.post(f"{self.base_url}{SlackMethods.share_files}", data=payload,
|
79
48
|
headers=self.headers, cookies=self.cookies).json()
|
80
49
|
|
50
|
+
def get_file_info(self, file_id: str):
|
51
|
+
return requests.get(url=f"{self.base_url}{SlackMethods.files_info}",
|
52
|
+
cookies=self.cookies, headers=self.headers, params={'file': file_id}).json()
|
53
|
+
|
81
54
|
def get_profile(self, user_id: str = None):
|
82
55
|
url = f'{self.base_url}{SlackMethods.profile_get}'
|
83
56
|
payload = {}
|
@@ -165,10 +138,6 @@ class SlackClient:
|
|
165
138
|
url = f'{self.base_url}{SlackMethods.conversations_replies}?{self.__ts_payload(channel, id)}'
|
166
139
|
return requests.get(url=url, cookies=self.cookies).json()
|
167
140
|
|
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
141
|
def post_message(self, channel: str, text: str):
|
173
142
|
import uuid
|
174
143
|
payload = {
|
@@ -179,21 +148,6 @@ class SlackClient:
|
|
179
148
|
url = f'{self.base_url}{SlackMethods.chat_post_message}'
|
180
149
|
return requests.post(url=url, cookies=self.cookies, headers=self.headers, data=payload).json()
|
181
150
|
|
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
151
|
def user_info(self, user: str):
|
198
152
|
url = f'{self.base_url}{SlackMethods.users_info}?{self.__user_info_payload(user)}'
|
199
153
|
return requests.get(url=url, cookies=self.cookies).json()
|
@@ -202,19 +156,6 @@ class SlackClient:
|
|
202
156
|
url = f'{self.base_url}{SlackMethods.reactions_get}?{self.__get_reactions_payload(channel, id)}'
|
203
157
|
return requests.get(url=url, cookies=self.cookies).json()
|
204
158
|
|
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
159
|
def check_email(self, email: str, user_agent: str) -> bool:
|
219
160
|
payload = {'email': email}
|
220
161
|
headers = {'User-Agent': user_agent}
|
@@ -270,23 +211,6 @@ class SlackClient:
|
|
270
211
|
return requests.post(f"{self.base_url}/{SlackMethods.auth_test}", headers=headers,
|
271
212
|
cookies=self.cookies)
|
272
213
|
|
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
214
|
def __user_info_payload(self, user):
|
291
215
|
payload = {
|
292
216
|
'token': self.token,
|
@@ -294,15 +218,6 @@ class SlackClient:
|
|
294
218
|
}
|
295
219
|
return parse.urlencode(payload)
|
296
220
|
|
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
221
|
def __update_message_payload(self, channel, id, text, file_ids):
|
307
222
|
payload = {
|
308
223
|
'parse': 'none',
|
@@ -345,13 +260,6 @@ class SlackClient:
|
|
345
260
|
}
|
346
261
|
return parse.urlencode(payload)
|
347
262
|
|
348
|
-
def __update_profile_payload(self, profile):
|
349
|
-
payload = {
|
350
|
-
'token': self.token,
|
351
|
-
'profile': profile
|
352
|
-
}
|
353
|
-
return parse.urlencode(payload)
|
354
|
-
|
355
263
|
def __channel_payload(self, channel, id=None):
|
356
264
|
payload = {
|
357
265
|
'token': self.token,
|
@@ -365,15 +273,6 @@ class SlackClient:
|
|
365
273
|
|
366
274
|
return parse.urlencode(payload)
|
367
275
|
|
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
276
|
def __ts_payload(self, channel: str, id: str):
|
378
277
|
payload = {
|
379
278
|
'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,6 @@ 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)
|
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
|