#!/usr/bin/env python3
import json, os, urllib.request, urllib.error
from datetime import datetime,date,time,timedelta
from zoneinfo import ZoneInfo
TOKEN=os.environ['GOOGLE_FIT_ACCESS_TOKEN']; TZ='America/Argentina/Buenos_Aires'; z=ZoneInfo(TZ)
metrics=['com.google.heart_rate.bpm','com.google.weight','com.google.body.fat.percentage','com.google.height','com.google.hydration','com.google.nutrition','com.google.sleep.segment']
def ms(d): return int(datetime.combine(d,time.min,tzinfo=z).timestamp()*1000)
def call(m,s,e):
 body={'aggregateBy':[{'dataTypeName':m}],'bucketByTime':{'period':{'type':'day','value':1,'timeZoneId':TZ}},'startTimeMillis':ms(s),'endTimeMillis':ms(e+timedelta(days=1))}
 req=urllib.request.Request('https://www.googleapis.com/fitness/v1/users/me/dataset:aggregate',data=json.dumps(body).encode(),headers={'Authorization':f'Bearer {TOKEN}','Content-Type':'application/json;encoding=utf-8'},method='POST')
 try:
  with urllib.request.urlopen(req,timeout=60) as r: return json.loads(r.read().decode()), None
 except urllib.error.HTTPError as er: return None, er.read().decode()[:200]
for m in metrics:
 pts=days=0; err=None; cur=date(2015,1,1); end=datetime.now(z).date(); chunk=timedelta(days=29)
 while cur<=end:
  ce=min(cur+chunk,end); data,err=call(m,cur,ce)
  if err: break
  for b in data.get('bucket',[]):
   has=any(ds.get('point') for ds in b.get('dataset',[]))
   if has: days+=1; pts+=sum(len(ds.get('point',[])) for ds in b.get('dataset',[]))
  cur=ce+timedelta(days=1)
 print(m, 'days', days, 'points', pts, 'err', err)
