Skip to content

Instantly share code, notes, and snippets.

@gnmerritt
Created September 27, 2023 22:32
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gnmerritt/8a735b0bd1fc4a05d42c735b3c6d926f to your computer and use it in GitHub Desktop.
Save gnmerritt/8a735b0bd1fc4a05d42c735b3c6d926f to your computer and use it in GitHub Desktop.
Loop Habit Tracker to Streaks data converter
#
# This script converts from Loop Habit Tracker (https://play.google.com/store/apps/details?id=org.isoron.uhabits)
# to Streaks (https://apps.apple.com/us/app/streaks/id963034692)
#
# Export your Loop Habits data as a CSV and unzip it into the same folder as
# this script. You should have a bunch of directories with names corresponding
# to your habits and each one should contain a Checkmarks.csv file we're going
# to read and convert for Streaks
#
import argparse
import csv
import datetime
import os
HABITS = [
# Add the habits you want to transfer over here
'001 Floss', # should be the name of a folder
'002 your habits here',
]
LOOP_TO_STREAKS = {
0: 'missed_manually',
2: 'completed_manually',
# skipped_manually
}
def parse_args():
parser = argparse.ArgumentParser(prog="LoopToStreaks")
parser.add_argument('output_csv', help="CSV in Streaks format")
return parser.parse_args()
def main(args):
lines = []
for habit in HABITS:
lines += read_habit(habit)
if not lines:
return
with open(args.output_csv, 'w') as f:
writer = csv.DictWriter(f, fieldnames=lines[0].keys())
writer.writeheader()
for r in lines:
writer.writerow(r)
def read_habit(habit):
checkmarks_csv = os.path.join(habit, 'Checkmarks.csv')
if not os.path.exists(checkmarks_csv):
raise Exception(f"Could not open '{checkmarks_csv}'")
print(f"reading {checkmarks_csv}")
lines = []
with open(checkmarks_csv, 'r') as f:
reader = csv.reader(f)
for line in reader:
date_s, status_s = line
status = int(status_s)
date = datetime.datetime.strptime(date_s, '%Y-%m-%d') # 2022-04-30
entry = LOOP_TO_STREAKS.get(status)
if not entry:
continue
lines.append({
'entry_date': date.strftime('%Y%m%d'),
'entry_timestamp': date.isoformat() + '.000Z',
'title': habit,
'entry_type': entry,
'quantity': 0.0,
})
return lines
if __name__ == "__main__":
args = parse_args()
main(args)
entry_date entry_timestamp title entry_type quantity
20230916 2023-09-16T00:00:00.000Z 001 Floss completed_manually 0.0
20230909 2023-09-09T00:00:00.000Z 001 Floss completed_manually 0.0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment