pathlib and purge

This commit is contained in:
randogoth 2023-06-07 12:26:45 +03:00
parent 534152eb9f
commit 3a5633603b
3 changed files with 71 additions and 78 deletions

View file

@ -1,20 +0,0 @@
config:
index:
- md
- wav
- txt
files:
TODO.md:
contexts: []
note: The TODO file of this project
projects:
- tagger
tags:
- frr
orvani.py:
contexts:
- private
projects:
- tagger
tags:
- python

View file

@ -1,4 +1,3 @@
+ command to remove all contexts recursively
+ plugin API
+ support for frontmatter
+ support for Comment ID3 tag

128
orvani.py
View file

@ -2,6 +2,7 @@ import os
import sys
import yaml
import shutil
from pathlib import Path
from argparse import ArgumentParser as argp, SUPPRESS, RawTextHelpFormatter as raw
from rich.console import Console
from rich.table import Table
@ -25,7 +26,8 @@ class OrvaniTag:
CTX = { # default contexts
'contexts' : '@',
'projects' : '+',
'tags' : '#'
'tags' : '#',
'note' : None
}
def __init__(self, path: str=CONTEXT_FILE, cache: str=CACHE_FILE, contexts=CTX):
@ -53,16 +55,12 @@ class OrvaniTag:
path (str): path of the new folder context
"""
self.FILE = os.path.join(path, self.FILENAME)
if os.path.isfile(self.FILE):
try:
with open(self.FILE, 'r') as data:
y = yaml.safe_load(data)
self.DB = y['files']
if 'config' in y:
self.CONFIG = y['config']
except Exception:
print('File does not exist')
self.FILE = Path(path) / self.FILENAME
if self.FILE.exists():
y = yaml.safe_load(self.FILE.read_text())
self.DB = y['files']
if 'config' in y:
self.CONFIG = y['config']
else:
self.DB = dict()
self.CONFIG = dict()
@ -72,14 +70,13 @@ class OrvaniTag:
Save current folder context to file
"""
try:
with open(self.FILE, 'w+') as data:
y = {
'files' : self.DB
}
yaml.dump(y, data)
except Exception:
print('File write error')
y = { 'files' : self.DB }
if self.CONFIG:
y['config'] = self.CONFIG
if Path(self.FILE).is_file():
with Path(self.FILE).open('w') as data:
yaml.safe_dump(y, data)
def __context(self, argv) -> dict:
"""
@ -90,17 +87,22 @@ class OrvaniTag:
"""
context = dict()
for ctx in self.CTX.keys():
context.update( { ctx : []})
if self.CTX[ctx] != None:
context.update( { ctx : []})
for arg in argv:
for ctx in self.CTX.keys():
if str(arg)[0] in self.CTX.values():
if str(arg).startswith(self.CTX[ctx]):
context[ctx].append(str(arg)[1:])
# Schema with prefix
if not self.CTX[ctx] == None:
if str(arg).startswith(self.CTX[ctx]):
context[ctx].append(str(arg)[1:])
else:
if arg != ' ':
context.update( { 'note' : str(arg)})
else:
context.update( { 'note' : None})
# Otherwise it's a note
if self.CTX[ctx] == None:
if arg != ' ':
context.update( { ctx : str(arg)})
else:
context.update( { ctx : None})
return context
def add(self, file: str, *argv: str):
@ -111,16 +113,16 @@ class OrvaniTag:
argv (list): context parameters passed to be added
"""
if os.path.isfile(file):
if os.path.dirname(file):
self.__cd(os.path.dirname(file))
file = os.path.basename(file)
target = Path(file)
if target.exists():
self.__cd(target.parent.name)
context = self.__context(argv)
if file in self.DB:
for ctx in self.CTX.keys():
self.DB[file][ctx] = list(set( self.DB[file][ctx] + context[ctx]))
if 'note' in context.keys():
self.DB[file]['note'] = context['note']
if self.CTX[ctx] != None:
self.DB[file][ctx] = list(set( self.DB[file][ctx] + context[ctx]))
else:
self.DB[file][ctx] = context[ctx]
else:
self.DB.update( { file : context } )
self.__save()
@ -133,16 +135,17 @@ class OrvaniTag:
argv (list): context parameters to be removed
"""
if os.path.isfile(file):
if os.path.dirname(file):
self.__cd(os.path.dirname(file))
file = os.path.basename(file)
target = Path(file)
if target.exists():
self.__cd(target.parent.name)
context = self.__context(argv)
if file in self.DB:
for ctx in self.CTX.keys():
for item in context[ctx]:
if item in self.DB[file][ctx]:
self.DB[file][ctx].remove(item)
# Only works for context list items
if self.CTX[ctx] != None:
for item in context[ctx]:
if item in self.DB[file][ctx]:
self.DB[file][ctx].remove(item)
self.__save()
def delete(self, file: str, fop:bool=False):
@ -153,15 +156,15 @@ class OrvaniTag:
fop (bool): if True removes the referenced file
"""
if os.path.dirname(file):
self.__cd(os.path.dirname(file))
target = Path(file)
if target.exists():
self.__cd(target.parent.name)
if fop:
os.remove(file)
file = os.path.basename(file)
target.unlink(missing_ok=True)
if file in self.DB:
del self.DB[file]
if not self.DB:
os.remove(self.FILE)
Path(self.FILE).unlink(missing_ok=True)
self.__save()
def move(self, source: str, dest: str, retain: bool=False, fop: bool=True):
@ -196,7 +199,7 @@ class OrvaniTag:
else:
shutil.move(source, dest, copy_function=shutil.copy2)
def purge(self, path: str='', recursive=True):
def purge(self, path: str='.', recursive=True):
"""
Removes context data from folder if files do not exist
@ -204,20 +207,19 @@ class OrvaniTag:
"""
if path == '':
path = './'
if not os.path.dirname(path):
path += '/'
if os.path.dirname(path):
self.__cd(os.path.dirname(path))
path = '.'
target = Path(path)
if target.exists():
self.__cd(target.parent.name)
DB = self.DB.copy()
for file in self.DB.keys():
if not os.path.isfile(file):
if not Path(file).is_file():
if file in self.DB:
del DB[file]
self.DB = DB
self.__save()
if not self.DB:
os.remove(self.FILE)
Path(self.FILE).unlink(missing_ok=True)
if recursive:
for (root,dirs,files) in os.walk(path):
if dirs:
@ -482,11 +484,23 @@ def main():
if args.file:
orvani.delete(args.file, args.no_file_operation)
elif args.command in ['clear', 'c']:
if args.file:
orvani.delete(args.file, False)
elif args.command in ['purge']:
if not args.file:
args.file = '.'
target = Path(args.file)
context_file = target / CONTEXT_FILE
cache_file = target / CACHE_FILE
context_file.unlink(missing_ok=True)
cache_file.unlink(missing_ok=True)
if args.not_recursive:
for (root,dirs,files) in os.walk(args.file):
if dirs:
for dir in dirs:
rpath = os.path.join(root, dir)
Path(CONTEXT_FILE).unlink(missing_ok=True)
Path(CACHE_FILE).unlink(missing_ok=True)
elif args.command in ['clean', 'purge']:
elif args.command in ['clean']:
if not args.file:
args.file = ''
orvani.purge(args.file, args.not_recursive)