108 lines
3.2 KiB
Python
108 lines
3.2 KiB
Python
#!/usr/bin/env python
|
|
|
|
import json
|
|
import re
|
|
from click import secho, echo
|
|
from habitmove.nomiedata import Tracker, Event, Activity, NomieImport
|
|
|
|
|
|
def load_file(filename):
|
|
with open(filename) as f:
|
|
nomie_data = json.load(f)
|
|
return nomie_data
|
|
|
|
|
|
# generate a yes/no cli question with a default answer
|
|
def confirmation_question(question, default_no=True):
|
|
choices = " [y/N]: " if default_no else " [Y/n]: "
|
|
default_answer = "n" if default_no else "y"
|
|
reply = str(input(question + choices)).lower().strip() or default_answer
|
|
if reply[0] == "y":
|
|
return True
|
|
if reply[0] == "n":
|
|
return False
|
|
else:
|
|
return False if default_no else True
|
|
|
|
|
|
# display stats and ask user to confirm if they seem okay
|
|
def verify_continue(data: NomieImport):
|
|
trackers = ""
|
|
for t in data.trackers:
|
|
trackers += t.label + ", "
|
|
trackers = trackers[:-2]
|
|
|
|
activity_count = 0
|
|
for e in data.events:
|
|
activity_count += len(e.activities) if e.activities else 0
|
|
|
|
secho(f"Exporting from nomie {data.version}:", fg="green")
|
|
echo(f"Found trackers: {trackers}")
|
|
echo(
|
|
f"Found events: {len(data.events)} entries, containing {activity_count} individual activities."
|
|
)
|
|
if not confirmation_question("Do you want to continue?", default_no=False):
|
|
echo("Aborted.")
|
|
exit(0)
|
|
|
|
|
|
def get_trackers(raw_trackers):
|
|
tracker_list = list[Tracker]()
|
|
for tracker_tuple in raw_trackers.items():
|
|
tracker_list.append(Tracker(**tracker_tuple[1]))
|
|
return tracker_list
|
|
|
|
|
|
def get_events(raw_events, tracker_list):
|
|
events = list[Event]()
|
|
for event in raw_events:
|
|
event["id"] = event["_id"]
|
|
event.pop("_id")
|
|
event["text"] = event["note"]
|
|
event.pop("note")
|
|
|
|
activities = get_activities_for_event(event["text"], tracker_list)
|
|
|
|
events.append(Event(**event, activities=activities))
|
|
|
|
return events
|
|
|
|
|
|
def extract_tags_from_text(text, tagmarker="#"):
|
|
"""Return lists of tuples of all event tags found in text.
|
|
Parameters:
|
|
text (str): The text to search through.
|
|
tagmarker (str): Optional character marking beginning of tag, defaults to '#'.
|
|
Returns:
|
|
tags (list): List of tuples in the form [('tag', '3'), ('anothertag', '')].
|
|
"""
|
|
string_tags = re.findall(rf"{tagmarker}(\w+)(?:\((\d+)\))?", text)
|
|
tags_with_int_counters = []
|
|
for tag in string_tags:
|
|
tags_with_int_counters.append((tag[0], None if tag[1] == "" else int(tag[1])))
|
|
return tags_with_int_counters
|
|
|
|
|
|
def get_activities_for_event(event_text, tracker_list):
|
|
activities = []
|
|
tag_list = extract_tags_from_text(event_text)
|
|
for tracker in tracker_list:
|
|
for tag in tag_list:
|
|
if tracker.tag in tag[0]:
|
|
activities.append(Activity(tracker=tracker, value=tag[1]))
|
|
return activities
|
|
|
|
|
|
# return the data belonging to nomie
|
|
def get_data(file, interactive=True):
|
|
raw_data = load_file(file)
|
|
nomie_version = raw_data["nomie"]["number"]
|
|
|
|
tracker_list = get_trackers(raw_data["trackers"])
|
|
event_list = get_events(raw_data["events"], tracker_list)
|
|
|
|
data = NomieImport(nomie_version, tracker_list, event_list)
|
|
if interactive:
|
|
verify_continue(data)
|
|
|
|
return data
|