leadguru-jobs 0.403.0__py3-none-any.whl → 0.405.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.403.0.dist-info → leadguru_jobs-0.405.0.dist-info}/METADATA +5 -10
- leadguru_jobs-0.405.0.dist-info/RECORD +26 -0
- lgt_jobs/__init__.py +4 -4
- lgt_jobs/jobs/analytics.py +1 -1
- lgt_jobs/jobs/archive_leads.py +2 -2
- lgt_jobs/jobs/bot_stats_update.py +11 -10
- lgt_jobs/jobs/chat_history.py +6 -6
- lgt_jobs/jobs/inbox_leads.py +6 -5
- lgt_jobs/jobs/mass_message.py +2 -2
- lgt_jobs/jobs/send_code.py +1 -1
- lgt_jobs/jobs/send_slack_message.py +5 -5
- lgt_jobs/jobs/update_slack_profile.py +14 -12
- lgt_jobs/jobs/user_balance_update.py +5 -5
- lgt_jobs/jobs/workspace_connect.py +5 -7
- lgt_jobs/main.py +11 -9
- lgt_jobs/runner.py +9 -6
- lgt_jobs/smtp.py +1 -1
- leadguru_jobs-0.403.0.dist-info/RECORD +0 -49
- lgt_jobs/lgt_common/__init__.py +0 -0
- lgt_jobs/lgt_common/discord_client/__init__.py +0 -0
- lgt_jobs/lgt_common/discord_client/discord_client.py +0 -58
- lgt_jobs/lgt_common/discord_client/methods.py +0 -15
- lgt_jobs/lgt_common/enums/__init__.py +0 -0
- lgt_jobs/lgt_common/enums/slack_errors.py +0 -6
- lgt_jobs/lgt_common/helpers.py +0 -18
- lgt_jobs/lgt_common/lgt_logging.py +0 -15
- lgt_jobs/lgt_common/pubsub/__init__.py +0 -0
- lgt_jobs/lgt_common/pubsub/command.py +0 -14
- lgt_jobs/lgt_common/pubsub/messages.py +0 -37
- lgt_jobs/lgt_common/pubsub/pubsubfactory.py +0 -51
- lgt_jobs/lgt_common/slack_client/__init__.py +0 -0
- lgt_jobs/lgt_common/slack_client/methods.py +0 -46
- lgt_jobs/lgt_common/slack_client/slack_client.py +0 -392
- lgt_jobs/lgt_common/slack_client/web_client.py +0 -164
- lgt_jobs/lgt_data/__init__.py +0 -0
- lgt_jobs/lgt_data/analytics.py +0 -723
- lgt_jobs/lgt_data/engine.py +0 -223
- lgt_jobs/lgt_data/enums.py +0 -68
- lgt_jobs/lgt_data/helpers.py +0 -2
- lgt_jobs/lgt_data/model.py +0 -960
- lgt_jobs/lgt_data/mongo_repository.py +0 -980
- {leadguru_jobs-0.403.0.dist-info → leadguru_jobs-0.405.0.dist-info}/WHEEL +0 -0
- {leadguru_jobs-0.403.0.dist-info → leadguru_jobs-0.405.0.dist-info}/top_level.txt +0 -0
@@ -1,980 +0,0 @@
|
|
1
|
-
import os
|
2
|
-
import re
|
3
|
-
from typing import List, Optional
|
4
|
-
import pymongo
|
5
|
-
from dateutil import tz
|
6
|
-
from pymongo import MongoClient
|
7
|
-
from bson.objectid import ObjectId
|
8
|
-
from .enums import SourceType
|
9
|
-
from .model import (LeadModel, BaseModel, UserModel, UserResetPasswordModel, BoardModel, BoardedStatus,
|
10
|
-
DedicatedBotModel, SlackMemberInformation, UserTemplateModel, LinkedinContact,
|
11
|
-
ExtendedUserLeadModel, UserLeadModel, ExtendedLeadModel, UserContact)
|
12
|
-
from datetime import datetime, UTC
|
13
|
-
from collections import OrderedDict
|
14
|
-
|
15
|
-
client = MongoClient(os.environ.get('MONGO_CONNECTION_STRING', 'mongodb://127.0.0.1:27017/'))
|
16
|
-
|
17
|
-
|
18
|
-
def to_object_id(oid):
|
19
|
-
if isinstance(oid, ObjectId):
|
20
|
-
return oid
|
21
|
-
return ObjectId(oid)
|
22
|
-
|
23
|
-
|
24
|
-
class BaseMongoRepository:
|
25
|
-
collection_name = ''
|
26
|
-
database_name = 'lgt_admin'
|
27
|
-
model: BaseModel = BaseModel()
|
28
|
-
|
29
|
-
def collection(self):
|
30
|
-
return client[self.database_name][self.collection_name]
|
31
|
-
|
32
|
-
def _collection(self, collection_name):
|
33
|
-
return client[self.database_name][collection_name]
|
34
|
-
|
35
|
-
def insert_many(self, items):
|
36
|
-
insert_items = map(lambda x: x.to_dic(), items)
|
37
|
-
self.collection().insert_many(insert_items)
|
38
|
-
|
39
|
-
def insert(self, item: BaseModel):
|
40
|
-
return self.collection().insert_one(item.to_dic())
|
41
|
-
|
42
|
-
def add(self, item: BaseModel):
|
43
|
-
return self.insert(item)
|
44
|
-
|
45
|
-
def delete(self, id):
|
46
|
-
res = self.collection().delete_one({'_id': to_object_id(id)})
|
47
|
-
return res
|
48
|
-
|
49
|
-
|
50
|
-
class UserMongoRepository(BaseMongoRepository):
|
51
|
-
collection_name = 'users'
|
52
|
-
model = UserModel
|
53
|
-
|
54
|
-
def get(self, _id):
|
55
|
-
return UserModel.from_dic(self.collection().find_one({'_id': to_object_id(_id)}))
|
56
|
-
|
57
|
-
def get_by_email(self, email: str):
|
58
|
-
pipeline = {'email': email}
|
59
|
-
doc = self.collection().find_one(pipeline)
|
60
|
-
return UserModel.from_dic(doc)
|
61
|
-
|
62
|
-
def set(self, _id, **kwargs):
|
63
|
-
update_dict = {k: v for k, v in kwargs.items() if v is not None}
|
64
|
-
self.collection().update_one({'_id': to_object_id(_id)}, {'$set': update_dict})
|
65
|
-
|
66
|
-
def get_users(self, users_ids=None, include_inactive=False):
|
67
|
-
pipeline = {}
|
68
|
-
|
69
|
-
if users_ids is not None:
|
70
|
-
pipeline['_id'] = {'$in': [to_object_id(_id) for _id in users_ids]}
|
71
|
-
|
72
|
-
if not include_inactive:
|
73
|
-
pipeline['inactive'] = False
|
74
|
-
|
75
|
-
return [UserModel.from_dic(doc) for doc in self.collection().find(pipeline)]
|
76
|
-
|
77
|
-
|
78
|
-
class UserLeadMongoRepository(BaseMongoRepository):
|
79
|
-
collection_name = 'user_leads'
|
80
|
-
model = ExtendedUserLeadModel
|
81
|
-
|
82
|
-
def get_count(self, user_id, **kwargs):
|
83
|
-
pipeline = self.__create_leads_filter(user_id, **kwargs)
|
84
|
-
return self.collection().count_documents(pipeline)
|
85
|
-
|
86
|
-
def get_many(self, ids: list, user_id):
|
87
|
-
docs = self.collection().find({"id": {'$in': ids}, 'user_id': to_object_id(user_id)})
|
88
|
-
leads = [ExtendedUserLeadModel.from_dic(lead) for lead in docs]
|
89
|
-
senders = [lead.message.sender_id for lead in leads]
|
90
|
-
contacts = SlackContactUserRepository().find(user_id, users=senders)
|
91
|
-
for lead in leads:
|
92
|
-
lead.contact = next(filter(lambda x: x.sender_id == lead.message.sender_id, contacts), None)
|
93
|
-
|
94
|
-
return leads
|
95
|
-
|
96
|
-
def get_leads(self, user_id, skip: int, limit: int, **kwargs) -> List[ExtendedUserLeadModel]:
|
97
|
-
pipeline = self.__create_leads_filter(user_id, **kwargs)
|
98
|
-
sort_field = kwargs.get('sort_field', 'last_action_at')
|
99
|
-
sort_direction = kwargs.get('sort_direction', 'ASCENDING')
|
100
|
-
sort_direction = pymongo.ASCENDING if sort_direction == 'ASCENDING' else pymongo.DESCENDING
|
101
|
-
docs = list(self.collection().find(pipeline).sort([(sort_field, sort_direction)]).skip(skip).limit(limit))
|
102
|
-
leads = [ExtendedUserLeadModel.from_dic(x) for x in docs]
|
103
|
-
senders = [lead.message.sender_id for lead in leads]
|
104
|
-
contacts = SlackContactUserRepository().find(users=senders)
|
105
|
-
for lead in leads:
|
106
|
-
lead.contact = next(filter(lambda x: x.sender_id == lead.message.sender_id, contacts), None)
|
107
|
-
return leads
|
108
|
-
|
109
|
-
@staticmethod
|
110
|
-
def __create_leads_filter(user_id, **kwargs):
|
111
|
-
pipeline: dict = {'user_id': to_object_id(user_id)}
|
112
|
-
|
113
|
-
if kwargs.get('status') is not None:
|
114
|
-
pipeline['status'] = kwargs.get('status', '')
|
115
|
-
|
116
|
-
if kwargs.get('board_id'):
|
117
|
-
pipeline['board_id'] = to_object_id(kwargs.get('board_id'))
|
118
|
-
elif kwargs.get('board_id') is not None:
|
119
|
-
pipeline['$or'] = [{'board_id': ''}, {'board_id': None}]
|
120
|
-
|
121
|
-
archived = kwargs.get('archived')
|
122
|
-
from_date = kwargs.get('from_date')
|
123
|
-
to_date = kwargs.get('to_date')
|
124
|
-
has_followup = kwargs.get('has_followup', None)
|
125
|
-
followup_to = kwargs.get('followup_to_date', None)
|
126
|
-
followup_from = kwargs.get('followup_from_date', None)
|
127
|
-
created_to = kwargs.get('created_to_date', None)
|
128
|
-
created_from = kwargs.get('created_from_date', None)
|
129
|
-
sender_ids = kwargs.get('sender_ids', None)
|
130
|
-
text = kwargs.get('text', None)
|
131
|
-
stop_words = kwargs.get('stop_words', None)
|
132
|
-
tags = kwargs.get('tags', None)
|
133
|
-
configs = kwargs.get('config', None)
|
134
|
-
bots_names = kwargs.get('bots_names', None)
|
135
|
-
locations = kwargs.get('locations', None)
|
136
|
-
dedicated_bots_ids = kwargs.get('dedicated_bots_ids', None)
|
137
|
-
with_chat = kwargs.get('with_chat', None)
|
138
|
-
leads_ids = kwargs.get('leads_ids', None)
|
139
|
-
exclude_leads = kwargs.get('exclude_leads', None)
|
140
|
-
exclude_senders = kwargs.get('exclude_senders', None)
|
141
|
-
|
142
|
-
pipeline['message.profile.display_name'] = {
|
143
|
-
"$ne": "Slackbot"
|
144
|
-
}
|
145
|
-
|
146
|
-
if leads_ids is not None:
|
147
|
-
pipeline["id"] = {'$in': leads_ids}
|
148
|
-
|
149
|
-
if exclude_leads:
|
150
|
-
pipeline['id'] = {'$nin': exclude_leads}
|
151
|
-
|
152
|
-
if exclude_senders:
|
153
|
-
pipeline['message.sender_id'] = {'$nin': exclude_senders}
|
154
|
-
|
155
|
-
if archived is not None:
|
156
|
-
pipeline['archived'] = archived
|
157
|
-
|
158
|
-
if with_chat is not None:
|
159
|
-
pipeline['chat_history'] = {'$exists': True, '$ne': []}
|
160
|
-
|
161
|
-
if has_followup is not None:
|
162
|
-
pipeline['followup_date'] = {'$ne': None} if has_followup else {'$eq': None}
|
163
|
-
|
164
|
-
if from_date or to_date:
|
165
|
-
pipeline['last_action_at'] = {}
|
166
|
-
|
167
|
-
if from_date:
|
168
|
-
start = datetime(from_date.year, from_date.month, from_date.day, tzinfo=tz.tzutc())
|
169
|
-
pipeline['last_action_at']['$gte'] = start
|
170
|
-
|
171
|
-
if to_date:
|
172
|
-
end = datetime(to_date.year, to_date.month, to_date.day, 23, 59, 59, tzinfo=tz.tzutc())
|
173
|
-
pipeline['last_action_at']['$lte'] = end
|
174
|
-
|
175
|
-
if locations and len(locations) > 0:
|
176
|
-
pipeline['message.locations'] = {"$in": locations}
|
177
|
-
|
178
|
-
if sender_ids:
|
179
|
-
pipeline['message.sender_id'] = {'$in': sender_ids}
|
180
|
-
|
181
|
-
if followup_from or followup_to:
|
182
|
-
pipeline['followup_date'] = {}
|
183
|
-
|
184
|
-
if followup_from:
|
185
|
-
followup_from = datetime(followup_from.year, followup_from.month, followup_from.day, tzinfo=tz.tzutc())
|
186
|
-
pipeline['followup_date']['$gte'] = followup_from
|
187
|
-
|
188
|
-
if followup_to:
|
189
|
-
followup_to = datetime(followup_to.year, followup_to.month, followup_to.day, 23, 59, 59, tzinfo=tz.tzutc())
|
190
|
-
pipeline['followup_date']['$lte'] = followup_to
|
191
|
-
|
192
|
-
if created_to or created_from:
|
193
|
-
pipeline['created_at'] = {}
|
194
|
-
|
195
|
-
if created_to:
|
196
|
-
created_to = datetime(created_to.year, created_to.month, created_to.day, 23, 59, 59, tzinfo=tz.tzutc())
|
197
|
-
pipeline['created_at']['$lte'] = created_to
|
198
|
-
|
199
|
-
if created_from:
|
200
|
-
created_from = datetime(created_from.year, created_from.month, created_from.day, tzinfo=tz.tzutc())
|
201
|
-
pipeline['created_at']['$gte'] = created_from
|
202
|
-
|
203
|
-
if stop_words:
|
204
|
-
pipeline['full_message_text'] = {'$regex': f'^(?!.*({stop_words})).*$', '$options': 'i'}
|
205
|
-
elif text:
|
206
|
-
pipeline['$text'] = {'$search': text}
|
207
|
-
|
208
|
-
if tags:
|
209
|
-
pipeline["tags"] = {"$elemMatch": {"$in": tags}}
|
210
|
-
|
211
|
-
if configs:
|
212
|
-
pipeline["message.configs.id"] = {"$in": configs}
|
213
|
-
|
214
|
-
if bots_names is not None:
|
215
|
-
pipeline['message.name'] = {'$in': bots_names}
|
216
|
-
|
217
|
-
if dedicated_bots_ids is not None:
|
218
|
-
pipeline["message.dedicated_slack_options.bot_id"] = {"$in": dedicated_bots_ids}
|
219
|
-
return pipeline
|
220
|
-
|
221
|
-
def get_unanswered_leads_ids(self, user_id: str, from_date=None):
|
222
|
-
pipeline = [
|
223
|
-
{
|
224
|
-
'$match':
|
225
|
-
{
|
226
|
-
'user_id': to_object_id(user_id)
|
227
|
-
}
|
228
|
-
},
|
229
|
-
{
|
230
|
-
'$match':
|
231
|
-
{
|
232
|
-
'chat_history': {'$exists': True, '$not': {'$size': 0}}
|
233
|
-
}
|
234
|
-
},
|
235
|
-
{
|
236
|
-
'$project':
|
237
|
-
{
|
238
|
-
'id': 1,
|
239
|
-
'sender_id': "$message.sender_id",
|
240
|
-
'last_message': {'$arrayElemAt': ['$chat_history', 0]}
|
241
|
-
}
|
242
|
-
},
|
243
|
-
{
|
244
|
-
'$addFields':
|
245
|
-
{
|
246
|
-
'is_user_message': {'$ne': ['$sender_id', '$last_message.user']}
|
247
|
-
}
|
248
|
-
},
|
249
|
-
{
|
250
|
-
'$match':
|
251
|
-
{
|
252
|
-
'$and':
|
253
|
-
[
|
254
|
-
{'last_message.text': {'$regex': '\\?'}},
|
255
|
-
{'is_user_message': False}
|
256
|
-
]
|
257
|
-
}
|
258
|
-
}
|
259
|
-
]
|
260
|
-
|
261
|
-
if from_date:
|
262
|
-
beginning_of_the_day = datetime(from_date.year, from_date.month, from_date.day, 0, 0, 0, 0)
|
263
|
-
pipeline.insert(0, {"$match": {"created_at": {"$gte": beginning_of_the_day}}})
|
264
|
-
|
265
|
-
data = list(self.collection().aggregate(pipeline))
|
266
|
-
leads_ids = [item['id'] for item in data]
|
267
|
-
return leads_ids
|
268
|
-
|
269
|
-
def get_daily_analytics_by_workspace(self, user_configs: list,
|
270
|
-
dedicated_only: bool | None,
|
271
|
-
from_date: datetime,
|
272
|
-
to_date: datetime,
|
273
|
-
user_id: str):
|
274
|
-
pipeline = [
|
275
|
-
{
|
276
|
-
'$addFields': {
|
277
|
-
'dedicated': {
|
278
|
-
'$anyElementTrue': {
|
279
|
-
'$map': {
|
280
|
-
'input': "$message.configs.id",
|
281
|
-
'as': "config",
|
282
|
-
'in': {'$in': ["$$config", user_configs]}
|
283
|
-
}
|
284
|
-
}
|
285
|
-
}
|
286
|
-
}
|
287
|
-
},
|
288
|
-
{
|
289
|
-
'$project': {
|
290
|
-
'created_at': {
|
291
|
-
'$dateToString': {
|
292
|
-
'format': '%Y-%m-%d',
|
293
|
-
'date': '$created_at'
|
294
|
-
}
|
295
|
-
},
|
296
|
-
'id': '$id'
|
297
|
-
}
|
298
|
-
},
|
299
|
-
{
|
300
|
-
'$group': {
|
301
|
-
'_id': '$created_at',
|
302
|
-
'data': {'$push': '$id'}
|
303
|
-
}
|
304
|
-
},
|
305
|
-
{
|
306
|
-
'$sort': {'_id': 1}
|
307
|
-
}
|
308
|
-
]
|
309
|
-
|
310
|
-
if dedicated_only:
|
311
|
-
pipeline.insert(1, {"$match": {'dedicated': True}})
|
312
|
-
elif dedicated_only is False:
|
313
|
-
pipeline.insert(1, {"$match": {'dedicated': False}})
|
314
|
-
|
315
|
-
if from_date:
|
316
|
-
beginning_of_the_day = datetime(from_date.year, from_date.month, from_date.day, 0, 0, 0, 0)
|
317
|
-
pipeline.insert(0, {"$match": {"created_at": {"$gte": beginning_of_the_day}}})
|
318
|
-
|
319
|
-
if to_date:
|
320
|
-
end_of_the_day = datetime(to_date.year, to_date.month, to_date.day, 23, 59, 59, 999)
|
321
|
-
pipeline.insert(0, {"$match": {"created_at": {"$lte": end_of_the_day}}})
|
322
|
-
|
323
|
-
if user_id:
|
324
|
-
pipeline.insert(0, {"$match": {'user_id': to_object_id(user_id)}})
|
325
|
-
|
326
|
-
saved_messages = list(self.collection().aggregate(pipeline))
|
327
|
-
saved_messages_dic = OrderedDict()
|
328
|
-
|
329
|
-
for item in saved_messages:
|
330
|
-
saved_messages_dic[item["_id"]] = item["data"]
|
331
|
-
|
332
|
-
return saved_messages_dic
|
333
|
-
|
334
|
-
def get_leads_after(self, action_after: datetime) -> [ExtendedUserLeadModel]:
|
335
|
-
leads = self.collection().find({'last_action_at': {'$gte': action_after}})
|
336
|
-
return [ExtendedUserLeadModel.from_dic(lead) for lead in leads]
|
337
|
-
|
338
|
-
def add_lead(self, user_id, lead: UserLeadModel) -> None:
|
339
|
-
if not lead.created_at:
|
340
|
-
lead.created_at = datetime.now(UTC)
|
341
|
-
|
342
|
-
if hasattr(lead, "_id"):
|
343
|
-
lead._id = ObjectId()
|
344
|
-
|
345
|
-
lead.user_id = user_id
|
346
|
-
self.insert(lead)
|
347
|
-
|
348
|
-
def update_lead(self, user_id, lead_id: str, **kwargs):
|
349
|
-
pipeline = {'user_id': to_object_id(user_id), 'id': lead_id}
|
350
|
-
update_dict = {k: v for k, v in kwargs.items() if v is not None}
|
351
|
-
if 'board_id' in update_dict:
|
352
|
-
update_dict['board_id'] = to_object_id(update_dict['board_id']) if len(update_dict['board_id']) == 24 \
|
353
|
-
else update_dict['board_id']
|
354
|
-
self.collection().update_one(pipeline, {'$set': update_dict})
|
355
|
-
|
356
|
-
return ExtendedUserLeadModel.from_dic(self.collection().find_one(pipeline))
|
357
|
-
|
358
|
-
def update_same_leads(self, user_id, sender_id: str, **kwargs):
|
359
|
-
pipeline = {'user_id': to_object_id(user_id), 'message.sender_id': sender_id}
|
360
|
-
update_dict = {k: v for k, v in kwargs.items() if v is not None}
|
361
|
-
self.collection().update_many(pipeline, {'$set': update_dict})
|
362
|
-
|
363
|
-
def update_leads_order(self, user_id, lead_ids: [str]):
|
364
|
-
pipeline = {'user_id': to_object_id(user_id), 'id': {'$in': lead_ids}}
|
365
|
-
docs = list(self.collection().find(pipeline))
|
366
|
-
|
367
|
-
order = 0
|
368
|
-
for lead_id in lead_ids:
|
369
|
-
for doc in docs:
|
370
|
-
if doc['id'] == lead_id:
|
371
|
-
self.collection().update_one({'id': lead_id}, {'$set': {'order': order}}, upsert=False)
|
372
|
-
order = order + 1
|
373
|
-
|
374
|
-
def delete_lead(self, user_id, lead_id: str):
|
375
|
-
"""
|
376
|
-
|
377
|
-
:param user_id:
|
378
|
-
:param lead_id:
|
379
|
-
:return: UserLeadModel
|
380
|
-
"""
|
381
|
-
|
382
|
-
pipeline = {'user_id': to_object_id(user_id), 'id': lead_id}
|
383
|
-
self.collection().delete_one(pipeline)
|
384
|
-
|
385
|
-
def get_lead(self, user_id, message_id: str = None, lead_id: str = None, **kwargs):
|
386
|
-
"""
|
387
|
-
|
388
|
-
:param user_id:
|
389
|
-
:param message_id:
|
390
|
-
:param lead_id:
|
391
|
-
:return: UserLeadModel
|
392
|
-
"""
|
393
|
-
|
394
|
-
pipeline = {'user_id': to_object_id(user_id)}
|
395
|
-
sender_id = kwargs.get('sender_id')
|
396
|
-
|
397
|
-
if message_id:
|
398
|
-
pipeline['message.message_id'] = message_id
|
399
|
-
|
400
|
-
if lead_id:
|
401
|
-
pipeline['id'] = lead_id
|
402
|
-
|
403
|
-
if sender_id:
|
404
|
-
pipeline['message.sender_id'] = sender_id
|
405
|
-
|
406
|
-
return ExtendedUserLeadModel.from_dic(self.collection().find_one(pipeline))
|
407
|
-
|
408
|
-
|
409
|
-
class UserResetPasswordMongoRepository(BaseMongoRepository):
|
410
|
-
pass
|
411
|
-
|
412
|
-
collection_name = 'user_reset_passwords'
|
413
|
-
model = UserResetPasswordModel
|
414
|
-
|
415
|
-
def get(self, _id):
|
416
|
-
return UserResetPasswordModel.from_dic(self.collection().find_one({'_id': to_object_id(_id)}))
|
417
|
-
|
418
|
-
def delete(self, email):
|
419
|
-
self.collection().delete_many({'email': email})
|
420
|
-
|
421
|
-
def add(self, email) -> str:
|
422
|
-
model = UserResetPasswordModel()
|
423
|
-
model.email = email
|
424
|
-
return self.collection().insert_one({'email': email}).inserted_id
|
425
|
-
|
426
|
-
|
427
|
-
class LeadMongoRepository(BaseMongoRepository):
|
428
|
-
pass
|
429
|
-
|
430
|
-
database_name = 'lgt_admin'
|
431
|
-
collection_name = 'general_leads'
|
432
|
-
model = LeadModel
|
433
|
-
|
434
|
-
def delete(self, _id):
|
435
|
-
res = self.collection().delete_one({'id': _id})
|
436
|
-
return res
|
437
|
-
|
438
|
-
def get(self, _id=None, **kwargs):
|
439
|
-
pipeline = {}
|
440
|
-
timestamp = kwargs.get("timestamp")
|
441
|
-
message_id = kwargs.get("message_id")
|
442
|
-
channel_id = kwargs.get("channel_id")
|
443
|
-
if _id:
|
444
|
-
pipeline['id'] = _id
|
445
|
-
if message_id:
|
446
|
-
pipeline['message.message_id'] = message_id
|
447
|
-
if channel_id:
|
448
|
-
pipeline['message.channel_id'] = channel_id
|
449
|
-
if timestamp:
|
450
|
-
pipeline['message.timestamp'] = timestamp
|
451
|
-
result: dict = self.collection().find_one(pipeline)
|
452
|
-
if not result:
|
453
|
-
return None
|
454
|
-
|
455
|
-
return LeadModel.from_dic(result)
|
456
|
-
|
457
|
-
def get_many(self, ids: list):
|
458
|
-
docs = self.collection().find({"id": {'$in': ids}})
|
459
|
-
leads = [ExtendedLeadModel.from_dic(lead) for lead in docs]
|
460
|
-
senders = [lead.message.sender_id for lead in leads]
|
461
|
-
contacts = SlackContactUserRepository().find(users=senders)
|
462
|
-
for lead in leads:
|
463
|
-
lead.contact = next(filter(lambda x: x.sender_id == lead.message.sender_id, contacts), None)
|
464
|
-
|
465
|
-
return leads
|
466
|
-
|
467
|
-
def get_by_sender_id(self, sender_id, exclude_leads: [str], skip: int, limit: int):
|
468
|
-
pipeline = {'message.sender_id': sender_id, 'id': {'$nin': exclude_leads}}
|
469
|
-
leads = self.collection().find(pipeline).sort([('created_at', pymongo.DESCENDING)]).skip(skip).limit(limit)
|
470
|
-
return [LeadModel.from_dic(lead) for lead in leads]
|
471
|
-
|
472
|
-
def get_by_message_id(self, message_id):
|
473
|
-
"""
|
474
|
-
|
475
|
-
:rtype: LeadModel
|
476
|
-
:param message_id:
|
477
|
-
"""
|
478
|
-
doc: dict = self.collection().find_one({'message.message_id': message_id})
|
479
|
-
if not doc:
|
480
|
-
return None
|
481
|
-
|
482
|
-
return LeadModel.from_dic(doc)
|
483
|
-
|
484
|
-
def update(self, _id: str, **kwargs):
|
485
|
-
update_dict = {k: v for k, v in kwargs.items() if v is not None}
|
486
|
-
self.collection().update_one({'id': _id}, {'$set': update_dict}, upsert=False)
|
487
|
-
|
488
|
-
def get_count(self, **kwargs):
|
489
|
-
pipeline = self.__create_leads_filter(**kwargs)
|
490
|
-
return self.collection().count_documents(pipeline)
|
491
|
-
|
492
|
-
def get_list(self, skip, limit, **kwargs):
|
493
|
-
pipeline = self.__create_leads_filter(**kwargs)
|
494
|
-
|
495
|
-
sort_field = kwargs.get('sort_field', 'created_at')
|
496
|
-
sort_direction = kwargs.get('sort_direction', 'ASCENDING')
|
497
|
-
sort_direction = pymongo.ASCENDING if sort_direction == 'ASCENDING' else pymongo.DESCENDING
|
498
|
-
|
499
|
-
leads = self.collection().find(pipeline).sort([(sort_field, sort_direction)]).skip(skip).limit(limit)
|
500
|
-
return [LeadModel.from_dic(lead) for lead in leads]
|
501
|
-
|
502
|
-
def __create_leads_filter(self, **kwargs):
|
503
|
-
pipeline: dict = {"hidden": False}
|
504
|
-
|
505
|
-
from_date: datetime = kwargs.get('from_date')
|
506
|
-
to_date: datetime = kwargs.get('to_date')
|
507
|
-
|
508
|
-
country = kwargs.get('country', None)
|
509
|
-
user_id = kwargs.get('user_id', None)
|
510
|
-
tags = kwargs.get('tags', None)
|
511
|
-
text = kwargs.get('text', None)
|
512
|
-
stop_words = kwargs.get('stop_words', None)
|
513
|
-
exclude_leads = kwargs.get('exclude_leads', None)
|
514
|
-
exclude_senders = kwargs.get('exclude_senders', None)
|
515
|
-
excluded_channels = kwargs.get('excluded_channels', None)
|
516
|
-
sender_ids = kwargs.get('sender_ids', None)
|
517
|
-
configs = kwargs.get('config', None)
|
518
|
-
bots_names = kwargs.get('bots_names', None)
|
519
|
-
locations = kwargs.get('locations', None)
|
520
|
-
publication_text = kwargs.get('publication_text')
|
521
|
-
|
522
|
-
pipeline['message.profile.display_name'] = {
|
523
|
-
"$ne": "Slackbot"
|
524
|
-
}
|
525
|
-
|
526
|
-
if from_date or to_date:
|
527
|
-
pipeline['created_at'] = {}
|
528
|
-
|
529
|
-
if from_date:
|
530
|
-
start = from_date.astimezone(tz.tzutc())
|
531
|
-
pipeline['created_at']['$gte'] = start
|
532
|
-
|
533
|
-
if to_date:
|
534
|
-
end = to_date.astimezone(tz.tzutc())
|
535
|
-
pipeline['created_at']['$lte'] = end
|
536
|
-
|
537
|
-
if locations and len(locations) > 0:
|
538
|
-
pipeline['message.locations'] = {"$in": locations}
|
539
|
-
|
540
|
-
if country:
|
541
|
-
pipeline["message.slack_options.country"] = re.compile(country, re.IGNORECASE)
|
542
|
-
|
543
|
-
if user_id:
|
544
|
-
pipeline["$or"] = [
|
545
|
-
{"message.dedicated_slack_options": {"$exists": False}},
|
546
|
-
{"message.dedicated_slack_options": None},
|
547
|
-
{"message.dedicated_slack_options.user_id": f"{user_id}"},
|
548
|
-
]
|
549
|
-
else:
|
550
|
-
pipeline["user_id"] = {'$exists': False}
|
551
|
-
|
552
|
-
if stop_words:
|
553
|
-
pipeline['full_message_text'] = {'$regex': f'^(?!.*({stop_words})).*$', '$options': 'i'}
|
554
|
-
elif text:
|
555
|
-
pipeline['$text'] = {'$search': text}
|
556
|
-
|
557
|
-
if publication_text:
|
558
|
-
pipeline['message.message'] = {'$regex': publication_text, '$options': 'i'}
|
559
|
-
|
560
|
-
if tags:
|
561
|
-
pipeline["tags"] = {"$elemMatch": {"$in": tags}}
|
562
|
-
|
563
|
-
if exclude_leads:
|
564
|
-
pipeline['id'] = {'$nin': exclude_leads}
|
565
|
-
|
566
|
-
if exclude_senders:
|
567
|
-
pipeline['message.sender_id'] = {'$nin': exclude_senders}
|
568
|
-
|
569
|
-
if excluded_channels:
|
570
|
-
pipeline['$and'] = []
|
571
|
-
for ws, channels in excluded_channels.items():
|
572
|
-
if channels is not None:
|
573
|
-
pipeline['$and'].append(
|
574
|
-
{'$or': [{'message.name': {'$ne': ws}}, {'message.channel_id': {'$nin': channels}}]})
|
575
|
-
|
576
|
-
if sender_ids:
|
577
|
-
pipeline['message.sender_id'] = {'$in': sender_ids}
|
578
|
-
|
579
|
-
if configs:
|
580
|
-
pipeline["message.configs.id"] = {"$not": {"$elemMatch": {"$nin": configs}}}
|
581
|
-
|
582
|
-
if bots_names is not None:
|
583
|
-
pipeline['message.name'] = {'$in': bots_names}
|
584
|
-
|
585
|
-
pipeline['message.profile.real_name'] = {'$ne': 'Slackbot'}
|
586
|
-
|
587
|
-
return pipeline
|
588
|
-
|
589
|
-
def get_per_day(self, date: datetime):
|
590
|
-
start_day = datetime(date.year, date.month, date.day, 0, 0, 0, tzinfo=tz.tzutc())
|
591
|
-
end_day = datetime(date.year, date.month, date.day, 23, 59, 59, tzinfo=tz.tzutc())
|
592
|
-
docs = self.collection().find({'created_at': {'$gte': start_day, '$lte': end_day}}).sort('created_at', 1)
|
593
|
-
return [LeadModel.from_dic(x) for x in docs]
|
594
|
-
|
595
|
-
|
596
|
-
class SpamLeadsMongoRepository(LeadMongoRepository):
|
597
|
-
pass
|
598
|
-
|
599
|
-
def __init__(self):
|
600
|
-
self.collection_name = 'spam_leads'
|
601
|
-
|
602
|
-
def get_list(self, skip, limit, sort_field: str = 'created_at', sort_direction: str = 'ASCENDING', **kwargs):
|
603
|
-
pipeline = self.__create_leads_filter(**kwargs)
|
604
|
-
sort_direction = pymongo.ASCENDING if sort_direction == 'ASCENDING' else pymongo.DESCENDING
|
605
|
-
docs = self.collection().find(pipeline).sort([(sort_field, sort_direction)]).skip(skip).limit(limit)
|
606
|
-
leads = [ExtendedLeadModel.from_dic(doc) for doc in docs]
|
607
|
-
senders = [lead.message.sender_id for lead in leads]
|
608
|
-
contacts = SlackContactUserRepository().find(users=senders)
|
609
|
-
for lead in leads:
|
610
|
-
lead.contact = next(filter(lambda x: x.sender_id == lead.message.sender_id, contacts), None)
|
611
|
-
return leads
|
612
|
-
|
613
|
-
def get_count(self, **kwargs):
|
614
|
-
pipeline = self.__create_leads_filter(**kwargs)
|
615
|
-
return self.collection().count_documents(pipeline)
|
616
|
-
|
617
|
-
def __create_leads_filter(self, **kwargs):
|
618
|
-
pipeline = {"user_id": {'$exists': False}}
|
619
|
-
text = kwargs.get('text', None)
|
620
|
-
stop_words = kwargs.get('stop_words', None)
|
621
|
-
if stop_words:
|
622
|
-
pipeline['full_message_text'] = {'$regex': f'^(?!.*({stop_words})).*$', '$options': 'i'}
|
623
|
-
elif text:
|
624
|
-
pipeline['$text'] = {'$search': text}
|
625
|
-
|
626
|
-
return pipeline
|
627
|
-
|
628
|
-
|
629
|
-
class GarbageLeadsMongoRepository(SpamLeadsMongoRepository):
|
630
|
-
pass
|
631
|
-
|
632
|
-
def __init__(self):
|
633
|
-
super().__init__()
|
634
|
-
self.collection_name = 'garbage_leads'
|
635
|
-
|
636
|
-
|
637
|
-
class GarbageUserLeadsMongoRepository(UserLeadMongoRepository):
|
638
|
-
pass
|
639
|
-
|
640
|
-
def __init__(self):
|
641
|
-
self.database_name = 'lgt_admin'
|
642
|
-
self.collection_name = 'garbage_leads'
|
643
|
-
|
644
|
-
|
645
|
-
class SpamUserLeadsMongoRepository(UserLeadMongoRepository):
|
646
|
-
pass
|
647
|
-
|
648
|
-
def __init__(self):
|
649
|
-
self.database_name = 'lgt_admin'
|
650
|
-
self.collection_name = 'spam_leads'
|
651
|
-
|
652
|
-
|
653
|
-
class BoardsMongoRepository(BaseMongoRepository):
|
654
|
-
pass
|
655
|
-
|
656
|
-
collection_name = 'boards'
|
657
|
-
model = BoardModel
|
658
|
-
|
659
|
-
def create_board(self, user_id: str, name: str, **kwargs):
|
660
|
-
is_primary = kwargs.get('is_primary', False)
|
661
|
-
|
662
|
-
if is_primary:
|
663
|
-
primary_board: dict = self.collection().find_one({'user_id': to_object_id(user_id),
|
664
|
-
'is_primary': is_primary})
|
665
|
-
if primary_board:
|
666
|
-
return BoardModel.from_dic(primary_board)
|
667
|
-
|
668
|
-
board = BoardModel()
|
669
|
-
board.name = name
|
670
|
-
board.created_at = datetime.now(UTC)
|
671
|
-
board.user_id = to_object_id(user_id)
|
672
|
-
board.is_primary = is_primary
|
673
|
-
self.collection().insert_one(BoardModel.to_dic(board))
|
674
|
-
|
675
|
-
return BoardModel.from_dic(self.collection().find_one({'user_id': to_object_id(user_id), 'name': name}))
|
676
|
-
|
677
|
-
def add_default_statuses(self, user_id: str, board_id: str):
|
678
|
-
pipeline = {'user_id': to_object_id(user_id), '_id': to_object_id(board_id)}
|
679
|
-
board = BoardModel.from_dic(self.collection().find_one(pipeline))
|
680
|
-
|
681
|
-
if not board:
|
682
|
-
return None
|
683
|
-
|
684
|
-
board.statuses.append(BoardedStatus().from_dic({'name': 'Lead', 'order': 0}))
|
685
|
-
board.statuses.append(BoardedStatus().from_dic({'name': 'Prospect', 'order': 1}))
|
686
|
-
board.statuses.append(BoardedStatus().from_dic({'name': 'Opportunity', 'order': 2}))
|
687
|
-
board.statuses.append(BoardedStatus().from_dic({'name': 'Call', 'order': 3}))
|
688
|
-
board.statuses.append(BoardedStatus().from_dic({'name': 'Contract', 'order': 4}))
|
689
|
-
board.statuses.append(BoardedStatus().from_dic({'name': 'Refused', 'order': 5}))
|
690
|
-
|
691
|
-
return self.update_board(user_id, board_id, statuses=board.statuses)
|
692
|
-
|
693
|
-
def get(self, user_id: str, **kwargs):
|
694
|
-
pipeline = {'user_id': to_object_id(user_id)}
|
695
|
-
is_primary = kwargs.get('is_primary')
|
696
|
-
default = kwargs.get('default')
|
697
|
-
name = kwargs.get('name')
|
698
|
-
|
699
|
-
if is_primary is not None:
|
700
|
-
pipeline['is_primary'] = is_primary
|
701
|
-
|
702
|
-
if default is not None:
|
703
|
-
pipeline['default'] = default
|
704
|
-
|
705
|
-
if name:
|
706
|
-
pipeline['name'] = name
|
707
|
-
|
708
|
-
docs = self.collection().find(pipeline).sort('created_at', 1)
|
709
|
-
return [BoardModel.from_dic(doc) for doc in docs]
|
710
|
-
|
711
|
-
def get_primary(self, user_id: str):
|
712
|
-
return BoardModel.from_dic(self.collection().find_one({'user_id': to_object_id(user_id), 'is_primary': True}))
|
713
|
-
|
714
|
-
def get_by_id(self, id: str):
|
715
|
-
return BoardModel.from_dic(self.collection().find_one({'_id': to_object_id(id)}))
|
716
|
-
|
717
|
-
def delete_by_id(self, id: str):
|
718
|
-
return self.collection().delete_many({'_id': to_object_id(id)})
|
719
|
-
|
720
|
-
def update_board(self, user_id, board_id: str, **kwargs):
|
721
|
-
pipeline = {'user_id': to_object_id(user_id), '_id': to_object_id(board_id)}
|
722
|
-
|
723
|
-
if kwargs.get('statuses'):
|
724
|
-
kwargs['statuses'] = [status.to_dic() for status in kwargs.get('statuses')
|
725
|
-
if isinstance(status, BoardedStatus)]
|
726
|
-
|
727
|
-
doc = BoardModel.from_dic(self.collection().find_one(pipeline))
|
728
|
-
if not doc:
|
729
|
-
return None
|
730
|
-
|
731
|
-
update_dict = {k: v for k, v in kwargs.items() if v is not None}
|
732
|
-
self.collection().update_one(pipeline, {'$set': update_dict})
|
733
|
-
|
734
|
-
self._collection('user_leads').update_many({'user_id': to_object_id(user_id), 'board_id': to_object_id(doc.id)},
|
735
|
-
{'$set': {'board_id': to_object_id(board_id)}})
|
736
|
-
|
737
|
-
return BoardModel.from_dic(self.collection().find_one(pipeline))
|
738
|
-
|
739
|
-
|
740
|
-
class DedicatedBotRepository(BaseMongoRepository):
|
741
|
-
pass
|
742
|
-
|
743
|
-
collection_name = 'dedicated_bots'
|
744
|
-
|
745
|
-
def get_by_user_and_source_id(self, user_id: str, source_id: str) -> Optional[DedicatedBotModel]:
|
746
|
-
doc = self.collection().find_one({"user_id": ObjectId(f"{user_id}"), "source.source_id": source_id})
|
747
|
-
return DedicatedBotModel.from_dic(doc)
|
748
|
-
|
749
|
-
def get_by_user_and_active_server_id(self, user_id: str, active_server_id: str) -> Optional[DedicatedBotModel]:
|
750
|
-
doc = self.collection().find_one({"user_id": ObjectId(f"{user_id}"), "active_servers.id": active_server_id})
|
751
|
-
return DedicatedBotModel.from_dic(doc)
|
752
|
-
|
753
|
-
def add_or_update(self, bot: DedicatedBotModel):
|
754
|
-
bot_dict = bot.to_dic()
|
755
|
-
if '_id' in bot_dict:
|
756
|
-
bot_dict.pop('_id')
|
757
|
-
update_response = self.collection().update_one({"source.source_id": bot.source.source_id,
|
758
|
-
"user_name": bot.user_name,
|
759
|
-
"user_id": to_object_id(bot.user_id)},
|
760
|
-
{'$set': bot_dict}, upsert=True)
|
761
|
-
bot.id = update_response.upserted_id if update_response.upserted_id else bot.id
|
762
|
-
return bot
|
763
|
-
|
764
|
-
def get_all(self, only_valid: bool = False, **kwargs) -> List[DedicatedBotModel]:
|
765
|
-
kwargs["only_valid"] = only_valid
|
766
|
-
pipeline = self.__create_bots_filter(**kwargs)
|
767
|
-
docs = self.collection().find(pipeline)
|
768
|
-
return [DedicatedBotModel.from_dic(doc) for doc in docs]
|
769
|
-
|
770
|
-
def get_one(self, **kwargs):
|
771
|
-
pipeline = self.__create_bots_filter(**kwargs)
|
772
|
-
return DedicatedBotModel.from_dic(self.collection().find_one(pipeline))
|
773
|
-
|
774
|
-
def get_user_bots(self, user_id: str, only_valid: bool = False,
|
775
|
-
include_deleted: bool = False, include_paused: bool = False, **kwargs) -> List[DedicatedBotModel]:
|
776
|
-
pipeline = {'user_id': to_object_id(user_id)}
|
777
|
-
user_name = kwargs.get('user_name')
|
778
|
-
|
779
|
-
if user_name:
|
780
|
-
pipeline['user_name'] = user_name
|
781
|
-
|
782
|
-
if not include_deleted:
|
783
|
-
pipeline['deleted'] = False
|
784
|
-
|
785
|
-
if not include_paused:
|
786
|
-
pipeline['paused'] = False
|
787
|
-
|
788
|
-
if only_valid:
|
789
|
-
pipeline['invalid_creds'] = False
|
790
|
-
|
791
|
-
return [DedicatedBotModel.from_dic(doc) for doc in self.collection().find(pipeline)]
|
792
|
-
|
793
|
-
def delete(self, _id: str):
|
794
|
-
self.collection().update_one({'_id': to_object_id(f"{_id}")}, {"$set": {"deleted": True}})
|
795
|
-
|
796
|
-
@staticmethod
|
797
|
-
def __create_bots_filter(**kwargs):
|
798
|
-
pipeline = {}
|
799
|
-
name = kwargs.get('name')
|
800
|
-
source_type = kwargs.get('source_type', None)
|
801
|
-
user_name = kwargs.get('user_name')
|
802
|
-
only_valid = kwargs.get('only_valid')
|
803
|
-
include_paused = kwargs.get('include_paused', False)
|
804
|
-
include_deleted = kwargs.get('include_deleted', False)
|
805
|
-
bot_id = kwargs.get('id')
|
806
|
-
user_id = kwargs.get('user_id')
|
807
|
-
source_id = kwargs.get('source_id')
|
808
|
-
server_id = kwargs.get('server_id')
|
809
|
-
|
810
|
-
if bot_id:
|
811
|
-
pipeline["_id"] = to_object_id(bot_id)
|
812
|
-
|
813
|
-
if user_id:
|
814
|
-
pipeline["user_id"] = to_object_id(user_id)
|
815
|
-
|
816
|
-
if name:
|
817
|
-
pipeline["name"] = name
|
818
|
-
|
819
|
-
if source_type:
|
820
|
-
pipeline["source.source_type"] = source_type
|
821
|
-
|
822
|
-
if user_name:
|
823
|
-
pipeline["user_name"] = user_name
|
824
|
-
|
825
|
-
if source_id:
|
826
|
-
pipeline["source.source_id"] = source_id
|
827
|
-
|
828
|
-
if server_id:
|
829
|
-
pipeline["servers"] = {'$elemMatch': {'id': server_id, 'active': True}}
|
830
|
-
|
831
|
-
if only_valid:
|
832
|
-
pipeline['invalid_creds'] = False
|
833
|
-
|
834
|
-
if not include_deleted:
|
835
|
-
pipeline['deleted'] = False
|
836
|
-
|
837
|
-
if not include_paused and source_type == SourceType.DISCORD:
|
838
|
-
pipeline['paused'] = False
|
839
|
-
|
840
|
-
return pipeline
|
841
|
-
|
842
|
-
|
843
|
-
class SlackContactUserRepository(BaseMongoRepository):
|
844
|
-
collection_name = "slack_contact"
|
845
|
-
model = SlackMemberInformation
|
846
|
-
|
847
|
-
def find(self, text: Optional[str] = None, skip: int = 0, limit: int = 1000, **kwargs):
|
848
|
-
pipeline = {}
|
849
|
-
|
850
|
-
users = kwargs.pop("users")
|
851
|
-
presence_updated_at = kwargs.pop("online_updated_at", None)
|
852
|
-
if text:
|
853
|
-
pipeline['$text'] = {'$search': text}
|
854
|
-
|
855
|
-
if users:
|
856
|
-
pipeline['sender_id'] = {'$in': users}
|
857
|
-
|
858
|
-
if presence_updated_at:
|
859
|
-
pipeline['online_updated_at'] = {'$gte': presence_updated_at}
|
860
|
-
|
861
|
-
pipeline = {**pipeline, **kwargs}
|
862
|
-
|
863
|
-
docs = self.collection().find(pipeline).sort([("real_name", pymongo.ASCENDING)]) \
|
864
|
-
.skip(skip) \
|
865
|
-
.limit(limit)
|
866
|
-
return [SlackMemberInformation.from_dic(doc) for doc in docs]
|
867
|
-
|
868
|
-
def find_one(self, user_id: str):
|
869
|
-
pipeline = {"sender_id": user_id}
|
870
|
-
return SlackMemberInformation.from_dic(self.collection().find_one(pipeline))
|
871
|
-
|
872
|
-
def get_count_in_workspaces(self):
|
873
|
-
pipeline = [
|
874
|
-
{
|
875
|
-
'$match': {
|
876
|
-
'user': {
|
877
|
-
'$ne': 'USLACKBOT'
|
878
|
-
}
|
879
|
-
}
|
880
|
-
}, {
|
881
|
-
'$group': {
|
882
|
-
'_id': '$workspace',
|
883
|
-
'count': {
|
884
|
-
'$sum': 1
|
885
|
-
}
|
886
|
-
}
|
887
|
-
}
|
888
|
-
]
|
889
|
-
docs = list(self.collection().aggregate(pipeline))
|
890
|
-
return {doc['_id']: doc['count'] for doc in docs}
|
891
|
-
|
892
|
-
|
893
|
-
class UserTemplatesRepository(BaseMongoRepository):
|
894
|
-
collection_name = "user_templates"
|
895
|
-
model = UserTemplateModel
|
896
|
-
|
897
|
-
def get_all(self, user_id: str):
|
898
|
-
return [UserTemplateModel.from_dic(doc) for doc in self.collection().find({'user_id': to_object_id(user_id)})]
|
899
|
-
|
900
|
-
def get(self, id: str):
|
901
|
-
return UserTemplateModel.from_dic(self.collection().find_one({'_id': to_object_id(id)}))
|
902
|
-
|
903
|
-
def create_or_update(self, template: UserTemplateModel):
|
904
|
-
result = self.collection().update_one(
|
905
|
-
{"_id": to_object_id(template.id)},
|
906
|
-
{'$set': template.to_dic()},
|
907
|
-
upsert=True)
|
908
|
-
|
909
|
-
if result.upserted_id:
|
910
|
-
template.id = result.upserted_id
|
911
|
-
|
912
|
-
return template
|
913
|
-
|
914
|
-
def delete_by_id(self, id: str):
|
915
|
-
return self.collection().find_one_and_delete({'_id': to_object_id(id)})
|
916
|
-
|
917
|
-
|
918
|
-
class LinkedinContactRepository(BaseMongoRepository):
|
919
|
-
collection_name = "linkedin_contact"
|
920
|
-
model = LinkedinContact
|
921
|
-
|
922
|
-
def find(self, **kwargs):
|
923
|
-
docs = self.collection().find({**kwargs})
|
924
|
-
return [LinkedinContact.from_dic(doc) for doc in docs]
|
925
|
-
|
926
|
-
|
927
|
-
class UserContactsRepository(BaseMongoRepository):
|
928
|
-
collection_name = 'user_contacts'
|
929
|
-
|
930
|
-
def find(self, user_id: str, **kwargs):
|
931
|
-
pipeline = {'user_id': to_object_id(user_id)}
|
932
|
-
|
933
|
-
users = kwargs.get('users')
|
934
|
-
spam = kwargs.get('spam')
|
935
|
-
with_chat_only = kwargs.get('with_chat_only', False)
|
936
|
-
|
937
|
-
if users:
|
938
|
-
pipeline['sender_id'] = {'$in': users}
|
939
|
-
|
940
|
-
if spam is not None:
|
941
|
-
pipeline['spam'] = spam
|
942
|
-
|
943
|
-
if with_chat_only:
|
944
|
-
pipeline['chat_id'] = {'$ne': None}
|
945
|
-
|
946
|
-
docs = self.collection().find(pipeline)
|
947
|
-
return [UserContact.from_dic(doc) for doc in docs]
|
948
|
-
|
949
|
-
def find_one(self, user_id: str, **kwargs):
|
950
|
-
pipeline = {'user_id': to_object_id(user_id)}
|
951
|
-
|
952
|
-
sender_id = kwargs.get('sender_id')
|
953
|
-
if sender_id:
|
954
|
-
pipeline['sender_id'] = sender_id
|
955
|
-
|
956
|
-
if contact_instance := self.collection().find_one(pipeline):
|
957
|
-
return UserContact.from_dic(contact_instance)
|
958
|
-
|
959
|
-
def update(self, user_id: str, sender_id: str, **kwargs):
|
960
|
-
pipeline = {'user_id': to_object_id(user_id), 'sender_id': sender_id}
|
961
|
-
update_dict = {k: v for k, v in kwargs.items() if v is not None}
|
962
|
-
self.collection().update_one(pipeline, {'$set': update_dict}, upsert=False)
|
963
|
-
|
964
|
-
|
965
|
-
class TeamRepository(BaseMongoRepository):
|
966
|
-
collection_name = 'teams'
|
967
|
-
|
968
|
-
def get_teammate(self, user_id: str, teammate_id: str):
|
969
|
-
pipeline = [
|
970
|
-
{
|
971
|
-
"$match": {
|
972
|
-
"$or": [
|
973
|
-
{"author_id": to_object_id(user_id), "recipient_id": to_object_id(teammate_id)},
|
974
|
-
{"author_id": to_object_id(teammate_id), "recipient_id": to_object_id(user_id)}
|
975
|
-
],
|
976
|
-
"status": "approved"
|
977
|
-
}
|
978
|
-
}
|
979
|
-
]
|
980
|
-
return list(self.collection().aggregate(pipeline))
|