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