1
0

Obsidian import: More intelligent time behaviour
Some checks failed
Test Python / Test (push) Failing after 32s

This commit is contained in:
Jon Michael Aanes 2024-10-16 23:58:22 +02:00
parent a64cbc6186
commit c8c142bd1b
Signed by: Jmaa
SSH Key Fingerprint: SHA256:Ab0GfHGCblESJx7JRE4fj4bFy/KRpeLhi41y4pF3sNA
4 changed files with 55 additions and 8 deletions

View File

@ -119,8 +119,9 @@ def import_watched_series_csv(vault: ObsidianVault, rows: Rows) -> int:
sample.single_label_with_category('episode.index'),
sample.single_label_with_category('episode.name'),
)
return Event(sample.start_at.time(),
sample.end_at.time(),
expected_tz = datetime.timezone(datetime.timedelta(hours=2)) # TODO: Determine this in a more intelligent manner
return Event(sample.start_at.astimezone(expected_tz).replace(second=0,microsecond=0).time(),
sample.end_at.astimezone(expected_tz).replace(second=0,microsecond=0).time(),
verb,
sample.single_label_with_category('series.name'),
comment,
@ -162,6 +163,5 @@ def import_data(obsidian_path: Path, dry_run=True):
data_path = Path('output/show_episodes_watched.csv')
rows = load_csv_file(data_path)
logger.info('Loaded CSV with %d lines', len(rows))
rows = rows[:7]
num_updated = import_watched_series_csv(vault, rows)
logger.info('Updated %d files', num_updated)

View File

@ -210,25 +210,43 @@ def format_event_string(event: Event) -> str:
):
return event.comment
return f'{event.start_time:%H:%M} | {event.verb} [[{event.subject}]]. {event.comment}'.strip()
buf = []
buf.append(f'{event.start_time:%H:%M}')
if event.end_time and event.end_time != event.start_time:
buf.append(f'-{event.end_time:%H:%M}')
buf.append(' | ')
buf.append(event.verb)
buf.append(' [[')
buf.append(event.subject)
buf.append(']]. ')
buf.append(event.comment.strip())
return ''.join(buf)
RE_TIME = r'(\d\d:\d\d(?::\d\d(?:\.\d+?))?)'
RE_VERB = r'(\w+(?:ed|te))'
RE_LINK_MD = r'\[([^\]]*)\]\(?:[^)]*\)'
RE_LINK_WIKI = r'\[\[([^\]]*)\]\]'
RE_TIME_FORMAT = RE_TIME + r'(?:\s*\-\s*' + RE_TIME + r')?'
def parse_event_string(event_str: str) -> Event:
if m := re.match(
r'^\s*' + RE_TIME + r'[ :\|-]*(\w+ed)\s+\[([^\]]*)\]\([^)]*\)\.?\s*(.*)$',
r'^\s*' + RE_TIME_FORMAT + r'[ :\|-]*'+RE_VERB+r'\s+'+RE_LINK_MD+r'\.?\s*(.*)$',
event_str,
):
start = datetime.time.fromisoformat(m.group(1))
return Event(start, start, m.group(2), m.group(3), m.group(4))
end = datetime.time.fromisoformat(m.group(2)) if m.group(2) else start
return Event(start, end, m.group(3), m.group(4), m.group(5))
if m := re.match(
r'^\s*' + RE_TIME + '[ :\|-]*(\w+ed)\s+\[\[([^\]]*)\]\]\.?\s*(.*)$',
r'^\s*' + RE_TIME_FORMAT + r'[ :\|-]*'+RE_VERB+r'\s+'+RE_LINK_WIKI+r'\.?\s*(.*)$',
event_str,
):
start = datetime.time.fromisoformat(m.group(1))
return Event(start, start, m.group(2), m.group(3), m.group(4))
end = datetime.time.fromisoformat(m.group(2)) if m.group(2) else start
return Event(start, end, m.group(3), m.group(4), m.group(5))
logger.info('Could not parse format: %s', event_str)
return Event(None, None, None, None, event_str)

View File

@ -23,6 +23,10 @@ class ActivitySample:
start_at: datetime.datetime | None
end_at: datetime.datetime | None
def __post_init__(self):
if self.start_at and self.end_at:
assert self.start_at <= self.end_at
def single_label_with_category(self, category: str) -> str:
for label in self.labels:
if label.category == category:
@ -35,6 +39,11 @@ class RealizedActivitySample(ActivitySample):
start_at: datetime.datetime
end_at: datetime.datetime
def __post_init__(self):
assert self.start_at is not None
assert self.end_at is not None
assert self.start_at <= self.end_at
def heuristically_realize_samples(
samples: list[ActivitySample],
@ -45,6 +54,8 @@ def heuristically_realize_samples(
* No samples overlap.
"""
samples.sort(key = lambda x: x.end_at)
previous_sample_end = None
for sample in samples:
end_at = sample.end_at

View File

@ -0,0 +1,18 @@
import datetime
import pytest
from obsidian_import import obsidian
EXAMPLES = [
obsidian.Event(datetime.time(12, 0, 0), datetime.time(12, 0, 0), "Ate",
"Lunch", "instantly"),
obsidian.Event(datetime.time(20, 0, 0), datetime.time(22, 0, 0),
"Watched", "Tom and Jerry", "on the *Television*"),
obsidian.Event(None, None, None, None, "Took a walk"),
]
@pytest.mark.parametrize("event", EXAMPLES)
def test_format_preserves_information(event: obsidian.Event):
formatted = obsidian.format_event_string(event)
assert obsidian.parse_event_string(formatted) == event