HPI/my/orgmode.py
Dima Gerasimov 2a2478bfa9 core: update cachew annotations
orgmode: expose method to construct cacheable note
2020-10-21 01:29:29 +02:00

85 lines
2.2 KiB
Python

'''
Programmatic access and queries to org-mode files on the filesystem
'''
from datetime import datetime, date
from pathlib import Path
from typing import List, Sequence, Iterable, NamedTuple, Optional
from .core import PathIsh
from .core.common import mcachew
from .core.cachew import cache_dir
from my.config import orgmode as user_config
from porg import Org
# temporary? hack to cache org-mode notes
class OrgNote(NamedTuple):
created: Optional[datetime]
heading: str
tags: List[str]
# todo move to common?
import re
def _sanitize(p: Path) -> str:
return re.sub(r'\W', '_', str(p))
def to_note(x: Org) -> OrgNote:
# ugh. hack to merely make it cacheable
created: Optional[datetime]
try:
# TODO(porg) not sure if created should ever throw... maybe warning/log?
c = x.created
if c is not None and isinstance(c, date):
# meh. not sure if should return date...
created = None
else:
created = c
except Exception as e:
created = None
return OrgNote(
created=created,
heading=x.heading, # todo include the rest?
tags=list(x.tags),
)
# todo move to porg?
class Query:
def __init__(self, files: Sequence[Path]) -> None:
self.files = files
# TODO yield errors?
@mcachew(
cache_path=lambda _, f: cache_dir() / 'orgmode' / _sanitize(f), force_file=True,
depends_on=lambda _, f: (f, f.stat().st_mtime),
)
def _iterate(self, f: Path) -> Iterable[OrgNote]:
o = Org.from_file(f)
for x in o.iterate():
yield to_note(x)
def all(self) -> Iterable[OrgNote]:
for f in self.files:
yield from self._iterate(f)
# TODO very confusing names...
# TODO careful... maybe use orgparse iterate instead?? ugh.
def get_all(self):
return self._xpath_all('//org')
def query_all(self, query):
for of in self.files:
org = Org.from_file(str(of))
yield from query(org)
def _xpath_all(self, query: str):
return self.query_all(lambda x: x.xpath_all(query))
def query() -> Query:
return Query(files=list(user_config.files))