From 51106465d39f7d3f950fe4224b13e7e643ff8883 Mon Sep 17 00:00:00 2001 From: Dima Gerasimov Date: Sun, 6 Jan 2019 23:57:15 +0000 Subject: [PATCH] get rid of kython for server counterpart --- TODO.org | 25 ++++++++------- publish | 2 +- server/ci.sh | 7 +++++ server/org_tools.py | 75 +++++++++++++++++++++++++++++++++++++++++++++ server/server.py | 5 ++- 5 files changed, 97 insertions(+), 17 deletions(-) create mode 100755 server/ci.sh create mode 100644 server/org_tools.py diff --git a/TODO.org b/TODO.org index 2a3d44a..c915d3c 100644 --- a/TODO.org +++ b/TODO.org @@ -1,26 +1,18 @@ -* TODO [#A] adjust permissions... I guess gonna have to make it include /capture endpoint? - - - - * START [#B] release somewhere? not sure if necessary -* TODO [#B] get rid of kython, run ci for python too? +* START [#B] get rid of kython, run ci for python too? * TODO [#B] doesn't look like hotkey working unless you manually rebind.. wtf? * TODO [#C] how to test it? try on different pages? -* TODO [#C] some sort of append logic? e.g. don't dump immediately and add as subitems? +* TODO [#C] some sort of delayed append logic? e.g. don't dump immediately and add as subitems? * TODO [#C] make notification configurable or only in case of errors -* TODO [#D] do not minfy for dev -* TODO not sure, maybe extension press should be default? control it via option? * TODO [#C] or, add menu to extension? -* TODO unsafe-eval in content security policy?? - -* TODO make manifest templated so we don't have to hardcode actions +* TODO [#D] do not minfy for dev +* TODO [#D] make manifest templated so we don't have to hardcode actions -* TODO +* TODO [#D] ## Packing After the development of your extension run the command @@ -30,6 +22,10 @@ $ NODE_ENV=production npm run build Now, the content of `build` folder will be the extension ready to be submitted to the Chrome Web Store. Just take a look at the [official guide](https://developer.chrome.com/webstore/publish) to more infos about publishing. +* TODO not sure, maybe extension press should be default? control it via option? +* DONE [#A] adjust permissions... I guess gonna have to make it include /capture endpoint? + CLOSED: [2019-01-06 Sun 23:57] + * DONE [#A] move server to a separate folder, systemd install script CLOSED: [2019-01-05 Sat 14:38] @@ -48,3 +44,6 @@ Now, the content of `build` folder will be the extension ready to be submitted t * DONE [#D] nicer manifest? CLOSED: [2019-01-06 Sun 13:43] +* DONE unsafe-eval in content security policy?? + CLOSED: [2019-01-06 Sun 23:36] + diff --git a/publish b/publish index 6cc6c62..3452cdd 100755 --- a/publish +++ b/publish @@ -1,5 +1,5 @@ #!/bin/bash -set -eu +set -eux VERSION="$(git tag --points-at)" diff --git a/server/ci.sh b/server/ci.sh new file mode 100755 index 0000000..f22b3fb --- /dev/null +++ b/server/ci.sh @@ -0,0 +1,7 @@ +#!/bin/bash +set -eux +# TODO add to proper ci pipeline +pylint -E server.py setup + +# TODO ugh mypy complains at hug's annotations +mypy --check-untyped-defs server.py setup diff --git a/server/org_tools.py b/server/org_tools.py new file mode 100644 index 0000000..2024bf1 --- /dev/null +++ b/server/org_tools.py @@ -0,0 +1,75 @@ +from datetime import datetime +import logging +from pathlib import Path +import re +from typing import List, Optional + +def date2org(t: datetime) -> str: + return t.strftime("%Y-%m-%d %a") + +def datetime2orgtime(t: datetime) -> str: + return t.strftime("%H:%M") + +def datetime2org(t: datetime) -> str: + return date2org(t) + " " + datetime2orgtime(t) + +# TODO priority maybe?? +# TODO need to sanitize! +def as_org_entry( + heading: Optional[str] = None, + tags: List[str] = [], + body: Optional[str] = None, + created: Optional[datetime]=None, + todo=True, +): + if heading is None: + if body is None: + raise RuntimeError('Both heading and body are empty!!') + heading = body.splitlines()[0] # TODO ?? + + if body is None: + body = '' + + # TODO FIXME escape everything properly! + heading = re.sub(r'\s', ' ', heading) + # TODO remove newlines from body + + NOW = datetime.now() # TODO tz?? + # appended only added if it's different from created + app = [f':APPENDED: [{datetime2org(NOW)}]'] if created is not None else [] + if created is None: + created = NOW + + + todo_s = ' TODO' if todo else '' + tag_s = ':'.join(tags) + + sch = [f' SCHEDULED: <{date2org(NOW)}>'] if todo else [] + + if len(tag_s) != 0: + tag_s = f':{tag_s}:' + lines = [ + f"""*{todo_s} {heading} {tag_s}""", + *sch, + ':PROPERTIES:', + *app, + f':CREATED: [{datetime2org(created)}]', + ':END:', + body, + "", + "", + ] + return '\n'.join(lines) + +# TODO should we check if it exists first? +def append_org_entry( + path: Path, + *args, + **kwargs, +): + res = as_org_entry(*args, **kwargs) + # https://stackoverflow.com/a/13232181 + if len(res.encode('utf8')) > 4096: + logging.warning("writing out %s might be non-atomic", res) + with path.open('a') as fo: + fo.write(res) diff --git a/server/server.py b/server/server.py index 29113e0..94dbf57 100644 --- a/server/server.py +++ b/server/server.py @@ -5,9 +5,8 @@ import re import hug # type: ignore import hug.types as T # type: ignore -from kython.org import append_org_entry - -from config import CAPTURE_PATH +from config import CAPTURE_PATH # TODO mm, maybe configure it during server setup? +from org_tools import append_org_entry def empty(s) -> bool: return s is None or len(s.strip()) == 0