1
1
# -*- coding: utf-8 -*-
2
+ import collections
2
3
import logging
3
4
import time
4
5
@@ -27,7 +28,7 @@ def get_slack_users_simple(self, slack, exclude_api_user=True):
27
28
emails .append ((member ['id' ], member ['name' ], member ['profile' ]['email' ]))
28
29
return emails
29
30
30
- def sync_members (self , autodeactivate = False ):
31
+ def sync_members (self , autodeactivate = False , resend = True ):
31
32
"""Sync members, NOTE: https://github.com/ErikKalkoken/slackApiDoc/blob/master/users.admin.setInactive.md says
32
33
deactivation via API works only on paid tiers"""
33
34
if not api_configured ():
@@ -36,15 +37,25 @@ def sync_members(self, autodeactivate=False):
36
37
slack = get_client (session = session )
37
38
slack_users = self .get_slack_users_simple (slack )
38
39
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 .count ():
43
+ member = add_members .popleft ()
41
44
try :
42
- resp = slack .users .admin .invite (member .email )
45
+ resp = slack .users .admin .invite (member .email , resend = resend )
43
46
if 'ok' not in resp .body or not resp .body ['ok' ]:
44
47
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
46
49
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
48
59
49
60
member_emails = set (Member .objects .values_list ('email' , flat = True ))
50
61
remove_slack_emails = slack_emails - member_emails
@@ -59,14 +70,23 @@ def sync_members(self, autodeactivate=False):
59
70
return remove_usernames
60
71
61
72
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 .count ():
75
+ email = remove_iter .popleft ()
63
76
try :
64
77
resp = slack .users .admin .setInactive (userids_by_email [email ])
65
78
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
69
81
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
71
91
72
92
return remove_usernames
0 commit comments