11# -*- coding: utf-8 -*-
2+ import collections
23import logging
34import time
45
@@ -27,7 +28,7 @@ def get_slack_users_simple(self, slack, exclude_api_user=True):
2728 emails .append ((member ['id' ], member ['name' ], member ['profile' ]['email' ]))
2829 return emails
2930
30- def sync_members (self , autodeactivate = False ):
31+ def sync_members (self , autodeactivate = False , resend = True ):
3132 """Sync members, NOTE: https://github.com/ErikKalkoken/slackApiDoc/blob/master/users.admin.setInactive.md says
3233 deactivation via API works only on paid tiers"""
3334 if not api_configured ():
@@ -36,15 +37,25 @@ def sync_members(self, autodeactivate=False):
3637 slack = get_client (session = session )
3738 slack_users = self .get_slack_users_simple (slack )
3839 slack_emails = set ([x [2 ] for x in slack_users ])
39- add_members = Member .objects .exclude (email__in = slack_emails )
40- for member in add_members :
40+ add_members = collections .deque (Member .objects .exclude (email__in = slack_emails ))
41+
42+ while add_members :
43+ member = add_members .popleft ()
4144 try :
42- resp = slack .users .admin .invite (member .email )
45+ resp = slack .users .admin .invite (member .email , resend = resend )
4346 if 'ok' not in resp .body or not resp .body ['ok' ]:
4447 self .logger .error ("Could not invite {}, response: {}" .format (member .email , resp .body ))
45- time .sleep (0.1 ) # rate-limit
48+ time .sleep (0.25 ) # rate-limit
4649 except Exception as e :
47- logger .exception ("Got exception when trying to invite {}" .format (member .email ))
50+ if 'Retry-After' in e .response .headers :
51+ wait_s = int (e .response .headers ['Retry-After' ])
52+ logger .warning ("Asked to wait {}s" .format (wait_s ))
53+ time .sleep (wait_s )
54+ add_members .appendleft (member )
55+ continue
56+ else :
57+ logger .exception ("Got exception when trying to invite {}" .format (member .email ))
58+ raise e
4859
4960 member_emails = set (Member .objects .values_list ('email' , flat = True ))
5061 remove_slack_emails = slack_emails - member_emails
@@ -59,14 +70,23 @@ def sync_members(self, autodeactivate=False):
5970 return remove_usernames
6071
6172 userids_by_email = {x [2 ]: x [0 ] for x in slack_users }
62- for email in remove_slack_emails :
73+ remove_iter = collections .deque (remove_slack_emails )
74+ while remove_iter :
75+ email = remove_iter .popleft ()
6376 try :
6477 resp = slack .users .admin .setInactive (userids_by_email [email ])
6578 if 'ok' not in resp .body or not resp .body ['ok' ]:
66- self .logger .error (
67- "Could not deactivate {}, response: {}" .format (email , resp .body ))
68- time .sleep (0.1 ) # rate-limit
79+ self .logger .error ("Could not deactivate {}, response: {}" .format (email , resp .body ))
80+ time .sleep (0.25 ) # rate-limit
6981 except Exception as e :
70- logger .exception ("Got exception when trying to deactivate {}" .format (email ))
82+ if 'Retry-After' in e .response .headers :
83+ wait_s = int (e .response .headers ['Retry-After' ])
84+ logger .warning ("Asked to wait {}s" .format (wait_s ))
85+ time .sleep (wait_s )
86+ remove_iter .appendleft (email )
87+ continue
88+ else :
89+ logger .exception ("Got exception when trying to deactivate {}" .format (email ))
90+ raise e
7191
7292 return remove_usernames
0 commit comments