HPI/my/core/orgmode.py
Dima Gerasimov dd928964e6 general: fix mypy errors after mypy and pytz stubs updates
see 968fd6d01d/stubs/pytz/pytz/tzinfo.pyi (L6)
it says all concrete instances should not be None
2021-12-19 18:53:29 +00:00

53 lines
1.6 KiB
Python

"""
Various helpers for reading org-mode data
"""
from datetime import datetime
def parse_org_datetime(s: str) -> datetime:
s = s.strip('[]')
for fmt, cl in [
("%Y-%m-%d %a %H:%M", datetime),
("%Y-%m-%d %H:%M" , datetime),
# todo not sure about these... fallback on 00:00?
# ("%Y-%m-%d %a" , date),
# ("%Y-%m-%d" , date),
]:
try:
return datetime.strptime(s, fmt)
except ValueError:
continue
else:
raise RuntimeError(f"Bad datetime string {s}")
# TODO I guess want to borrow inspiration from bs4? element type <-> tag; and similar logic for find_one, find_all
from orgparse import OrgNode
from typing import Iterable, TypeVar, Callable
V = TypeVar('V')
def collect(n: OrgNode, cfun: Callable[[OrgNode], Iterable[V]]) -> Iterable[V]:
yield from cfun(n)
for c in n.children:
yield from collect(c, cfun)
from more_itertools import one
from orgparse.extra import Table
def one_table(o: OrgNode) -> Table:
return one(collect(o, lambda n: (x for x in n.body_rich if isinstance(x, Table))))
class TypedTable(Table):
def __new__(cls, orig: Table) -> 'TypedTable':
tt = super().__new__(TypedTable)
tt.__dict__ = orig.__dict__
blocks = list(orig.blocks)
header = blocks[0] # fist block is schema
if len(header) == 2:
# TODO later interpret first line as types
header = header[1:]
setattr(tt, '_blocks', [header, *blocks[1:]])
return tt
@property
def blocks(self):
return getattr(self, '_blocks')