1
1
# -*- coding: utf-8 -*-
2
+ import logging
3
+ import time
4
+
2
5
from django .conf import settings
3
- from members .objects import Member
6
+ from members .models import Member
4
7
from requests .sessions import Session
5
8
6
9
from .utils import api_configured , get_client
7
10
8
- logger = logger .getLogger ()
11
+ logger = logging .getLogger ()
9
12
10
13
11
14
class SlackMemberSync (object ):
15
+ """Sync members and slack members"""
16
+
12
17
def get_slack_users_simple (self , slack , exclude_api_user = True ):
18
+ """Get just the properties we need from the slack members list"""
13
19
response = slack .users .list ()
14
20
emails = []
15
21
for member in response .body ['members' ]:
@@ -24,16 +30,43 @@ def get_slack_users_simple(self, slack, exclude_api_user=True):
24
30
def sync_members (self , autodeactivate = False ):
25
31
"""Sync members, NOTE: https://github.com/ErikKalkoken/slackApiDoc/blob/master/users.admin.setInactive.md says
26
32
deactivation via API works only on paid tiers"""
33
+ if not api_configured ():
34
+ raise RuntimeError ("Slack API not configured" )
27
35
with Session () as session :
28
36
slack = get_client (session = session )
29
37
slack_users = self .get_slack_users_simple (slack )
30
- slac_emails = [x [2 ] for x in slack_users ]
38
+ slack_emails = set ( [x [2 ] for x in slack_users ])
31
39
add_members = Member .objects .exclude (email__in = slack_emails )
32
40
for member in add_members :
33
41
try :
34
42
resp = slack .users .admin .invite (member .email )
35
43
if 'ok' not in resp .body or not resp .body ['ok' ]:
36
44
self .logger .error ("Could not invite {}, response: {}" .format (member .email , response .body ))
45
+ time .sleep (0.1 ) # rate-limit
37
46
except Exception as e :
38
47
logger .exception ("Got exception when trying to invite {}" .format (member .email ))
39
- # TODO: check which members should be removed
48
+
49
+ member_emails = set (Member .objects .values_list ('email' , flat = True ))
50
+ remove_slack_emails = slack_emails - member_emails
51
+ remove_usernames = []
52
+ if not remove_slack_emails :
53
+ return remove_usernames
54
+
55
+ usernames_by_email = {x [2 ]: x [1 ] for x in slack_users }
56
+ remove_usernames = [(usernames_by_email [x ], x ) for x in remove_slack_emails ]
57
+
58
+ if not autodeactivate :
59
+ return remove_usernames
60
+
61
+ userids_by_email = {x [2 ]: x [0 ] for x in slack_users }
62
+ for email in remove_slack_emails :
63
+ try :
64
+ resp = slack .users .admin .setInactive (userids_by_email [email ])
65
+ if 'ok' not in resp .body or not resp .body ['ok' ]:
66
+ self .logger .error (
67
+ "Could not deactivate {}, response: {}" .format (email , response .body ))
68
+ time .sleep (0.1 ) # rate-limit
69
+ except Exception as e :
70
+ logger .exception ("Got exception when trying to deactivate {}" .format (email ))
71
+
72
+ return remove_usernames
0 commit comments