This repository has been archived by the owner on Jul 23, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
extract_scale_measurements.py
executable file
·180 lines (155 loc) · 6.5 KB
/
extract_scale_measurements.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
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
#!/usr/bin/python3
"""Example of using hangups.build_user_conversation_list to data."""
import os
import argparse
import asyncio
import gspread
import logging
from dateutil.parser import parse
from oauth2client.service_account import ServiceAccountCredentials
from collections import namedtuple
from pytz import timezone
from time import strftime
import hangups
import appdirs
os.set_blocking(0, True)
est = timezone(
strftime("%Z").replace('CST', 'CST6CDT').replace('EDT', 'EST5EDT'))
ScaleEntry = namedtuple(
'ScaleEntry', ['timestamp', 'weight', 'fat', 'water', 'muscle', 'bone'])
HOME = os.environ['HOME']
def insert_entries_into_spreadsheet(new_entries):
credentials = ServiceAccountCredentials.from_json_keyfile_name(
f'{HOME}/setup_files/build/gapi_scripts/gspread.json',
['https://spreadsheets.google.com/feeds'])
gc = gspread.authorize(credentials)
spreadsheet = gc.open_by_key(
'1MG8so2pFKoOIpt0Vo9pUAtoNk-Y1SnHq9DiEFi-m5Uw')
wsheet = spreadsheet.sheet1
current_entries = {}
for irow, vals in enumerate(wsheet.get_all_values()):
if irow == 0:
continue
tstamp = parse(vals[0]).replace(tzinfo=est)
weight, fat, water, muscle, bone = [float(x) for x in vals[1:]]
entry = ScaleEntry(tstamp.isoformat(), weight, fat, water, muscle,
bone)
current_entries[tstamp.date().isoformat()] = entry
last_row = irow
current_days = set(current_entries.keys())
new_days = set(new_entries.keys()) - current_days
current_row = last_row + 2
for day in sorted(new_days):
new_entry = new_entries[day]
print(new_entries[day])
wsheet.insert_row([getattr(new_entry, x) for x in new_entry._fields],
index=current_row)
current_row += 1
current_entries[day] = new_entry
return current_entries
@asyncio.coroutine
def extract_scale_inputs(client, _):
_, conversation_list = (yield from
hangups.build_user_conversation_list(client))
all_conversations = conversation_list.get_all(include_archived=True)
print('{} known conversations'.format(len(all_conversations)))
entries = set()
for conversation in all_conversations:
if all(x.full_name == 'Daniel Boline' for x in conversation.users):
oldest_event = None
oldest_time = None
for event in conversation.events:
if oldest_time is None or event.timestamp < oldest_time:
oldest_event = event.id_
oldest_time = event.timestamp
for _ in range(10):
conversation.get_events(event_id=oldest_event)
for event in conversation.events:
if event.timestamp < oldest_time:
oldest_event = event.id_
oldest_time = event.timestamp
if event.text[0].isnumeric() and event.text[-1].isnumeric(
):
entries.add(
(event.text.strip(), event.timestamp.isoformat()))
new_entries = {}
for txt, tstmp in entries:
tstmp = parse(tstmp).astimezone(est)
try:
if ':' in txt:
weight, fat, water, muscle, bone = [
int(x) / 10. for x in txt.split(':')
]
elif '=' in txt:
weight, fat, water, muscle, bone = [
int(x) / 10. for x in txt.split('=')
]
if muscle > 300.0:
muscle = muscle / 10.
except ValueError:
continue
new_entry = ScaleEntry(tstmp.isoformat(), weight, fat, water, muscle,
bone)
new_entries[tstmp.date().isoformat()] = new_entry
insert_entries_into_spreadsheet(new_entries)
def run_example(example_coroutine, *extra_args):
"""Run a hangups example coroutine.
Args:
example_coroutine (coroutine): Coroutine to run with a connected
hangups client and arguments namespace as arguments.
extra_args (str): Any extra command line arguments required by the
example.
"""
args = _get_parser(extra_args).parse_args()
logging.basicConfig(level=logging.DEBUG if args.debug else logging.WARNING)
# Obtain hangups authentication cookies, prompting for credentials from
# standard input if necessary.
cookies = hangups.auth.get_auth_stdin(args.token_path)
client = hangups.Client(cookies)
task = asyncio.async(_async_main(example_coroutine, client, args))
loop = asyncio.get_event_loop()
try:
loop.run_until_complete(task)
except KeyboardInterrupt:
task.cancel()
loop.run_forever()
except hangups.exceptions.NetworkError:
print('Network problem. Try again later?')
#finally:
#loop.close()
def _get_parser(extra_args):
"""Return ArgumentParser with any extra arguments."""
parser = argparse.ArgumentParser(
formatter_class=argparse.ArgumentDefaultsHelpFormatter, )
dirs = appdirs.AppDirs('hangups', 'hangups')
default_token_path = os.path.join(dirs.user_cache_dir, 'refresh_token.txt')
parser.add_argument('--token-path',
default=default_token_path,
help='path used to store OAuth refresh token')
parser.add_argument('-d',
'--debug',
action='store_true',
help='log detailed debugging messages')
for extra_arg in extra_args:
parser.add_argument(extra_arg, required=True)
return parser
@asyncio.coroutine
def _async_main(example_coroutine, client, args):
"""Run the example coroutine."""
# Spawn a task for hangups to run in parallel with the example coroutine.
task = asyncio.async(client.connect())
# Wait for hangups to either finish connecting or raise an exception.
on_connect = asyncio.Future()
client.on_connect.add_observer(lambda: on_connect.set_result(None))
done, _ = yield from asyncio.wait((on_connect, task),
return_when=asyncio.FIRST_COMPLETED)
yield from asyncio.gather(*done)
# Run the example coroutine. Afterwards, disconnect hangups gracefully and
# yield the hangups task to handle any exceptions.
try:
yield from example_coroutine(client, args)
finally:
yield from client.disconnect()
yield from task
if __name__ == '__main__':
run_example(extract_scale_inputs)