aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Peter McGoron 2021-07-23 15:14:50 -0400
committerGravatar - 2021-07-26 22:55:07 -0400
commit0fb5c9a51ecb91a0424db12ee532a4f0ec82a618 (patch)
tree3aa45bd7c68e753c358e8ea42b026e321e634023
add ability to add cards to database
-rw-r--r--example/new_note.md3
-rw-r--r--example/underwriter.dbbin0 -> 28672 bytes
-rwxr-xr-xunderwriter151
3 files changed, 154 insertions, 0 deletions
diff --git a/example/new_note.md b/example/new_note.md
new file mode 100644
index 0000000..7b16a72
--- /dev/null
+++ b/example/new_note.md
@@ -0,0 +1,3 @@
+Add new notes and tag them using the `add` command.
+
+ undertaker add new_note.md usage example command
diff --git a/example/underwriter.db b/example/underwriter.db
new file mode 100644
index 0000000..4e2118b
--- /dev/null
+++ b/example/underwriter.db
Binary files differ
diff --git a/underwriter b/underwriter
new file mode 100755
index 0000000..fa2bb4f
--- /dev/null
+++ b/underwriter
@@ -0,0 +1,151 @@
+#!/usr/bin/python3
+
+import sqlite3
+import os.path
+import sys
+from datetime import datetime, timezone
+import base64
+
+def b64(s):
+ return base64.b64encode(s.encode()).decode()
+def current_time():
+ return int(datetime.now(timezone.utc).timestamp())
+
+# TODO: triggers for tags
+
+class Cursor(sqlite3.Cursor):
+ def new_tag(self, tag):
+ self.execute(f"""
+ CREATE TABLE IF NOT EXISTS "{b64(tag)}"
+ (fn TEXT PRIMARY KEY NOT NULL)
+ """)
+ self.execute(
+ "INSERT OR IGNORE INTO tags VALUES (?, '')",
+ (tag,))
+
+ def add_card_to_tag(self, name, tag):
+ self.execute(f"""
+ INSERT OR IGNORE INTO "{b64(tag)}" VALUES (?)""", (name,))
+
+ def remove_card_from_tag(self, name, tag):
+ self.execute(f"""
+ DELETE FROM "{b64(tag)}" WHERE name = ?""", (name,))
+
+def append_tab(listing, t):
+ return t if listing is None else listing + "\t" + t
+
+class Context:
+ @staticmethod
+ def initdb(dbname):
+ con = sqlite3.connect(dbname)
+ con.executescript("""
+CREATE TABLE cards (name TEXT PRIMARY KEY NOT NULL,
+ tags TEXT NOT NULL,
+ created INTEGER NOT NULL)
+WITHOUT ROWID;
+CREATE TABLE tags (name TEXT PRIMARY KEY NOT NULL,
+ included TEXT NOT NULL)
+WITHOUT ROWID;
+""")
+ return con
+
+ def name_exists(self, name):
+ cur = self.db.execute("SELECT name FROM cards WHERE (name = ?)",
+ (name,))
+ return cur.fetchone() == (name)
+
+ def make_cursor(self):
+ return self.db.cursor(Cursor)
+
+ def get_card(self, name):
+ vals = self.db.execute(
+ "SELECT tags,created FROM cards WHERE name = ?",
+ (name,)).fetchone()
+ return (None, None) if vals is None else vals
+
+ def card_add_tags(self, name, tags):
+ tagstr,created = self.get_card(name)
+ if created is None:
+ created = current_time()
+
+ cur = self.make_cursor()
+ for t in tags:
+ cur.new_tag(t)
+ tagstr = append_tab(tagstr, t)
+ cur.add_card_to_tag(name, t)
+
+ cur.execute(
+ "INSERT OR REPLACE INTO cards VALUES (?, ?, ?)",
+ (name, tagstr, created))
+ self.db.commit()
+
+ def card_remove_tags(self, name, tags):
+ tags,created = self.get_card(name)
+ if tags is None:
+ return None
+
+ newtags = None
+ for t in tags.split("\t"):
+ if t not in tags:
+ newtags = append_tag(newtags, t)
+
+ self.db.execute(
+ "INSERT OR REPLACE INTO cards VALUES (?,?,?)",
+ (name, newtags, created))
+
+
+ def remove_card(self, name):
+ tags,_ = self.get_card(name)
+ if tags is None:
+ return None
+
+ cur = self.make_cursor()
+
+ cur.execute("DELETE FROM cards WHERE name = ?", (name,))
+ for t in tags.split("\t"):
+ cur.remove_card_from_tag(name, t)
+ self.db.commit()
+
+ def __init__(self, name):
+ if not os.path.isfile(name):
+ self.db = Context.initdb(name)
+ self.db = sqlite3.connect(name)
+
+def usage():
+ print(
+"""
+underwriter [--database | -d file] [action]
+
+tag file [tags...]: add a file to the database if it not already in
+ it, and add 0 or more tags to it
+remove files...: remove a file from the database
+untag file [tags...]: remove tags from a file
+""")
+
+
+if __name__ == "__main__":
+ args = sys.argv[1:]
+ db = "underwriter.db"
+ if len(args) == 0:
+ usage()
+ sys.exit(1)
+
+ if args[0] == "--database" or args[0] == "-d":
+ db = args[1]
+ args = args[2:]
+
+ ctx = Context(db)
+
+ if len(args) == 0:
+ usage()
+ sys.exit(0)
+ if args[0] == "tag":
+ ctx.card_add_tags(args[1], args[2:])
+ elif args[0] == "remove":
+ for i in args[1:]:
+ ctx.remove(i)
+ elif args[0] == "untag":
+ ctx.card_remove_tags(args[1], args[2:])
+ else:
+ usage()
+ sys.exit(1)