-
Notifications
You must be signed in to change notification settings - Fork 0
/
update_users.py
159 lines (124 loc) · 4.98 KB
/
update_users.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
# update_users.py
#
# This program updates the user JSON using a google spreadsheet.
import drive_utils
import datetime as dt
import util
import defs
import json
import os
import random
BUFFER_TIME = 2 # extra seconds before last tick to check for new users
# map between strings indicating refresh time and seconds
update_period = {
"1 minute" : 60,
"5 minutes" : 300,
"10 minutes": 600,
"20 minutes": 1200,
"1 hour" : 3600,
}
def total_users():
'''return the total number of active users'''
user_files = os.listdir(os.path.join(os.getcwd(), "data/user"))
user_files = filter(lambda x: "_users.json" in x, user_files)
total = 0
# open each state user json file and count number of users
for state_path in user_files:
with open(os.path.join("data/user", state_path), "r") as f:
state_dict = json.load(f)
total += len(state_dict)
return total
def all_states():
'''create list of all states that there are users'''
user_files = os.listdir(os.path.join(os.getcwd(), "data/user"))
user_files = filter(lambda x: "_users.json" in x, user_files)
states = []
for state in user_files:
states.append(state[0:2])
return states
def new_entries(drive_service, sheet_name, last_tick=None):
'''read from the google spreadsheet and find new users'''
# get last update time
if last_tick is None:
last_tick = dt.datetime.now() - dt.timedelta(seconds=(defs.TICK_TIME + BUFFER_TIME))
print("Checking {} for new entries since {}".format(
sheet_name, last_tick.strftime("%m/%d/%Y %H:%M:%S")
))
# open json file with document IDs
with open("data/credentials/doc_ids.json", "r") as f:
doc_ids = json.load(f)
# look up sheet id and sheet range
sheet_id = doc_ids[sheet_name]["sheet_id"]
sheet_range = doc_ids[sheet_name]["sheet_range"]
# access sheet
sheets = drive_service.spreadsheets()
result = sheets.values().get(
spreadsheetId=sheet_id,
range=sheet_range
).execute()
values = result.get('values', [])
# filter out only the newest entries since the last tick
values.reverse() # reverse to parse latest first
last_new = None
for i, row in enumerate(values):
if row[0] == "Timestamp":
last_new = i
break
response_time = dt.datetime.strptime(row[0], "%m/%d/%Y %H:%M:%S")
# break on the column headers or previously seen rows
if response_time < last_tick:
last_new = i
break
# reverse back so users are updated chronologically
return list(reversed(values[0:last_new]))
def add_users(user_list):
'''add new users to the appropriate JSON'''
# TODO - sort by state and only open when the state changes
for row in user_list:
state = row[3] # access state abbreviation
state_json_path = "data/user/{}_users.json".format(state)
# load state data if it exists; otherwise use empty list
state_dict = None
if os.path.exists(state_json_path):
with open(state_json_path, "r") as f:
state_dict = json.load(f)
else:
state_dict = {}
# create a new user dictionary
new_user = {}
email_address = util.clean_email_address(row[1])
print("Adding/updating user: {}, {}".format(email_address, state))
# reject zip codes and search radii that are not integers
try:
new_user["zip"] = int(row[2])
new_user["search_radius"] = int(row[4])
except BaseException as e:
new_user["zip"] = 0
new_user["search_radius"] = 0
new_user["last_avail"] = [] # last available locations
new_user["thread_id"] = None # threadID for threading emails
new_user["msg_id"] = None # message ID for threading
new_user["rand_offset"] = random.randint(0, 9999)
new_user["refresh_interval"] = update_period[row[5]] # sec. between updates
state_dict[email_address] = new_user
# dump the updated json back
state_data = json.dumps(state_dict, indent = 4)
with open(state_json_path, "w") as f:
f.write(state_data)
def remove_users(user_list):
'''remove a list of users from the user json'''
for user in user_list:
email_address = util.clean_email_address(user[1])
state = user[2]
state_json_path = "data/user/{}_users.json".format(state)
print("Removing user: {}, {}".format(email_address, state))
# open the json file of users
with open(state_json_path, "r") as f:
state_dict = json.load(f)
# delete the user from the dictionary
state_dict.pop(email_address, None)
# dump the updated json back
state_data = json.dumps(state_dict, indent = 4)
with open(state_json_path, "w") as f:
f.write(state_data)
return