Browse Source

cli improvements

boyska 3 years ago
parent
commit
cb5eb9a98d
2 changed files with 60 additions and 18 deletions
  1. 42 17
      marxbook/cli.py
  2. 18 1
      marxbook/store.py

+ 42 - 17
marxbook/cli.py

@@ -26,9 +26,17 @@ def get_parser():
     add_p.add_argument("--tag", help="Comma-separated list of tags", default="")
     add_p.add_argument("--title", help="If omitted, auto-fetch")
     add_p.add_argument("--description", help="If omitted, auto-fetch")
+    add_p.add_argument("--edit", dest='edit', action='store_true', default=None)
+    add_p.add_argument("--no-edit", dest='edit', action='store_false', default=None)
     add_p.add_argument("url", nargs="?")
     add_p.set_defaults(func=main_add)
 
+    rm_p = subcommands.add_parser("rm")
+    rm_p.add_argument("--folder", default="")
+    rm_p.add_argument("path")
+    rm_p.set_defaults(func=main_rm)
+
+
     return p
 
 
@@ -52,27 +60,33 @@ def main_list(store, args):
         print(args.fmt.replace(r'\t', '\t').format(**markdata))
 
 
-def edit_before_add(data: dict, args) -> dict:
-    ser = marxbook.Serializer()
-    fd, fpath = tempfile.mkstemp()
-    buf = os.fdopen(fd, "w")
-    buf.write(ser.encode(data))
-    buf.close()
-    proc = subprocess.Popen([args.editor, fpath])
-    proc.communicate()
+class Edit:
+    def __init__(self, args):
+        self.args = args
+
+    def edit_before_add(self, data: dict) -> dict:
+        ser = marxbook.Serializer()
+        fd, fpath = tempfile.mkstemp()
+        buf = os.fdopen(fd, "w")
+        buf.write(ser.encode(data))
+        buf.close()
+        proc = subprocess.Popen([self.args.editor, fpath])
+        proc.communicate()
+
+        with open(fpath) as buf:
+            read_data = ser.decode(buf.read())
+        os.unlink(fpath)
+        data = {}
+        for key in read_data:
+            data[key.lower()] = read_data[key]
+        return data
 
-    with open(fpath) as buf:
-        read_data = ser.decode(buf.read())
-    os.unlink(fpath)
-    data = {}
-    for key in read_data:
-        data[key.lower()] = read_data[key]
-    return data
 
 
 def main_add(store, args):
     store = store.folder(args.folder)
     batch = args.batch
+    editor = Edit(args)
     if args.url is not None:
         urls = [args.url]
     else:
@@ -90,12 +104,23 @@ def main_add(store, args):
                 data["title"] = _title
             if not args.description:
                 data["description"] = _description
-        if not batch:
-            data = edit_before_add(data, args)
+        # shall we edit?
+        edit_needed = not batch
+        if args.edit is not None:
+            edit_needed = args.edit
+        if edit_needed:
+            data = editor.edit_before_add(data)
         store.add(**data)
     print(urls)
 
 
+def main_rm(store, args):
+    store = store.folder(args.folder)
+    dirpath, name = os.path.split(args.path)
+    store = store.folder(dirpath)
+    store.find(name).unlink()
+
+
 if __name__ == "__main__":
     ret = main()
     if type(ret) is int:

+ 18 - 1
marxbook/store.py

@@ -1,4 +1,5 @@
 import hashlib
+import os
 import re
 from pathlib import Path
 import logging
@@ -34,6 +35,22 @@ class Store:
         with fpath.open() as buf:
             return self.serializer.decode(buf.read())
 
+    def find(self, prefix_path: str) -> Path:
+        '''
+        prefix_path is a special form of contraction. Let's say prefix_path=utils/time/5e
+        If there is a single file starting with 5e inside utils/time, then that's found!
+        '''
+        if os.path.exists(prefix_path):
+            return prefix_path
+    
+        candidates = list(self.basedir.glob(prefix_path + '*'))
+        if not candidates:
+            raise FileNotFoundError("%s not found" % prefix_path)
+        if len(candidates) > 1:
+            raise ValueError("Ambiguous prefix %s" % prefix_path)
+        return candidates[0]
+        
+
     def __iter__(self):
         for urlfile in self.basedir.glob('**/*'):
             if not urlfile.is_file():
@@ -56,7 +73,7 @@ class Serializer:
 
     def encode(self, data: dict) -> str:
         m = ''
-        tags = data.pop('tags', [])  # those are special!
+        tags = data.pop('tag', [])  # those are special!
         for key in data:
             m += '%s: %s\n' % (key.title(), str(data[key]).replace('\n', ' '))
         for tag in tags: