add database handling using shelve
This commit is contained in:
parent
62c96a30c6
commit
3552f3c049
BIN
app/__pycache__/database.cpython-312.pyc
Normal file
BIN
app/__pycache__/database.cpython-312.pyc
Normal file
Binary file not shown.
BIN
app/__pycache__/utils.cpython-312.pyc
Normal file
BIN
app/__pycache__/utils.cpython-312.pyc
Normal file
Binary file not shown.
60
app/app.py
Executable file
60
app/app.py
Executable 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
52
app/database.py
Executable 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
5
app/utils.py
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
|
||||||
|
def die(msg: str, code: str):
|
||||||
|
print(msg)
|
||||||
|
exit(code)
|
||||||
|
|
|
@ -1,2 +1,4 @@
|
||||||
typer[all]
|
typer[all]
|
||||||
pyYAML
|
attrs >= 23.2.0
|
||||||
|
shelve2 >= 1.0
|
||||||
|
pyYAML >= 6.0.1
|
||||||
|
|
100
spyglass.py
100
spyglass.py
|
@ -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()
|
|
Loading…
Reference in a new issue