add database handling using shelve

This commit is contained in:
Јован Ђокић-Шумарац 2024-02-04 02:44:48 +01:00
parent 62c96a30c6
commit 3552f3c049
7 changed files with 120 additions and 101 deletions

Binary file not shown.

Binary file not shown.

60
app/app.py Executable file
View file

@ -0,0 +1,60 @@
import os
import typer
from pathlib import Path
from database import Shelf
from utils import die
app = typer.Typer()
project_subcommand = typer.Typer()
app.add_typer(project_subcommand, name='project')
entries: dict = {
'dirs': [],
'projects': [],
'config': {}
}
@project_subcommand.command('add')
def project_add(path: Path, name: str = None, runner: str = None, editor: str = 'code', multi: bool = False):
global entries
if multi:
die('Cannot specify name for a dir', 2) if name else None
for dir in os.listdir(path):
entries['dirs'].append(create_entry(path/dir, name, runner, editor))
else:
entries['projects'].append(create_entry(path, name, runner, editor))
with Shelf('spyglass') as shelf:
shelf.update(entries)
def create_entry(path: Path, name: str, runner: str, editor: str):
if not name:
name = os.path.dirname(path)
if not runner:
runner = None
if not editor:
editor = None
return {name: {'path': str(path.resolve()), 'runner': str(path/runner) if runner else None, 'editor': editor}}
def main():
app()
if __name__ == '__main__':
main()

52
app/database.py Executable file
View file

@ -0,0 +1,52 @@
import os
import shelve as shelf
import platform
from pathlib import Path
from utils import die
class Shelf:
def __init__(self, filename: str):
self.file: Path = None
self.db = None
os_type: str = platform.system()
if os_type == 'Linux':
self.file = os.environ.get('HOME') + '/.local/share/' + filename
elif os_type == 'Windows':
self.file = os.environ.get('APPDATA') + filename
else:
die('OS not supported', 2)
def __enter__(self):
# Open the shelf and load data into self.db
self.db = shelf.open(self.file, writeback=True)
return self
def __exit__(self, exc_type, exc_value, traceback):
# Save any updates to the shelf
if self.db is not None:
self.db.sync()
self.db.close()
def update(self, entries: dict):
db_values = self.db.values()
if db_values:
dirs, projects, _ = db_values
new_dirs, new_projects, _ = entries.values()
for dir in new_dirs:
if dir not in dirs:
self.db['dirs'].append(dir)
for project in new_projects:
if project not in projects:
self.db['projects'].append(project)
else:
for k, v in entries.items():
self.db[k] = v

5
app/utils.py Normal file
View file

@ -0,0 +1,5 @@
def die(msg: str, code: str):
print(msg)
exit(code)

View file

@ -1,2 +1,4 @@
typer[all]
pyYAML
attrs >= 23.2.0
shelve2 >= 1.0
pyYAML >= 6.0.1

View file

@ -1,100 +0,0 @@
#!/usr/bin/python
import os
import yaml
import platform
from pathlib import Path
# from rich import print
import typer
app = typer.Typer()
project_subcommand = typer.Typer()
app.add_typer(project_subcommand, name='project')
entries: list = []
@project_subcommand.command('add')
def project_add(path: Path, name: str = None, runner: str = None, editor: str = 'code', multi: bool = False):
global entries
if multi:
if name:
print('\n[bold red]Cannot name multiple projects the same.\n')
exit(69)
for dir in os.listdir(path):
print(dir)
entries.append(assamble_entry(path/dir, name, runner, editor))
else:
entries.append(assamble_entry(path, name, runner, editor))
for project in entries:
store_project(project)
def get_database_path():
database: str = None
os_type: str = platform.system()
if os_type == 'Linux':
database = os.environ.get('HOME') + '/.local/share/spyglass-db.yaml'
elif os_type == 'Windows':
database = os.environ.get('APPDATA') + 'spyglass-db.yaml'
else:
print('OS not supported')
exit(69)
return database
def store_project(project: dict):
database: str = get_database_path()
if not os.path.exists(database):
with open(database, 'w') as f:
f.write('projects:')
data = None
with open(database, 'r') as f:
data = yaml.safe_load(f)
project_list: list = [proj for proj in data['projects'] if os.path.isdir(proj)]
print(project_list)
if project not in project_list:
project_list.append(project)
else:
print('Project already exists')
with open(database, 'w') as f:
yaml.safe_dump(data, f)
def assamble_entry(path: Path, name: str, runner: str, editor: str):
if not name:
name = os.path.dirname(path)
if not runner:
runner = 'None'
if not editor:
editor = 'code'
return {name: {'path': str(path), 'runner': str(path/runner), 'editor': editor}}
def main():
app()
if __name__ == '__main__':
main()