100 lines
3.5 KiB
Python
100 lines
3.5 KiB
Python
|
#!/usr/bin/env python3
|
||
|
|
||
|
import argparse
|
||
|
import json
|
||
|
import sqlite3
|
||
|
|
||
|
from vinetrimmer.utils.AtomicSQL import AtomicSQL
|
||
|
|
||
|
|
||
|
class LocalVault:
|
||
|
def __init__(self, vault_path):
|
||
|
"""
|
||
|
Update local key vault to newer system.
|
||
|
This should ONLY be run if you have the old structure with keys in a table named `keys`.
|
||
|
It will move and update the structure of the items in `keys` to their respective new locations and structure.
|
||
|
:param vault_path: sqlite db path
|
||
|
"""
|
||
|
self.adb = AtomicSQL()
|
||
|
self.ticket = self.adb.load(sqlite3.connect(vault_path))
|
||
|
if not self.table_exists("keys"):
|
||
|
return
|
||
|
rows = self.adb.safe_execute(
|
||
|
self.ticket,
|
||
|
lambda db, cursor: cursor.execute("SELECT `service`, `title`, `content_keys` FROM `keys`")
|
||
|
).fetchall()
|
||
|
for service, title, content_keys in rows:
|
||
|
service = service.lower()
|
||
|
content_keys = json.loads(content_keys)
|
||
|
if not self.table_exists(service):
|
||
|
self.create_table(service)
|
||
|
for kid, key in [x.split(":") for x in content_keys]:
|
||
|
print(f"Inserting: {kid} {key} {title}")
|
||
|
existing_row, existing_title = self.row_exists(service, kid, key)
|
||
|
if existing_row:
|
||
|
if title and not existing_title:
|
||
|
print(" -- exists, but the title doesn't, so ill merge")
|
||
|
self.adb.safe_execute(
|
||
|
self.ticket,
|
||
|
lambda db, cursor: cursor.execute(
|
||
|
f"UPDATE `{service}` SET `title`=? WHERE `kid`=? AND `key_`=?",
|
||
|
(title, kid, key)
|
||
|
)
|
||
|
)
|
||
|
continue
|
||
|
print(" -- skipping (exists already)")
|
||
|
continue
|
||
|
self.adb.safe_execute(
|
||
|
self.ticket,
|
||
|
lambda db, cursor: cursor.execute(
|
||
|
f"INSERT INTO `{service}` (kid, key_, title) VALUES (?, ?, ?)",
|
||
|
(kid, key, title)
|
||
|
)
|
||
|
)
|
||
|
self.adb.commit(self.ticket)
|
||
|
|
||
|
def row_exists(self, table, kid, key):
|
||
|
return self.adb.safe_execute(
|
||
|
self.ticket,
|
||
|
lambda db, cursor: cursor.execute(
|
||
|
f"SELECT count(id), title FROM `{table}` WHERE kid=? AND key_=?",
|
||
|
[kid, key]
|
||
|
)
|
||
|
).fetchone()
|
||
|
|
||
|
def table_exists(self, name):
|
||
|
return self.adb.safe_execute(
|
||
|
self.ticket,
|
||
|
lambda db, cursor: cursor.execute(
|
||
|
"SELECT count(name) FROM sqlite_master WHERE type='table' AND name=?",
|
||
|
[name.lower()]
|
||
|
)
|
||
|
).fetchone()[0] == 1
|
||
|
|
||
|
def create_table(self, name):
|
||
|
self.adb.safe_execute(
|
||
|
self.ticket,
|
||
|
lambda db, cursor: cursor.execute(
|
||
|
"""
|
||
|
CREATE TABLE {} (
|
||
|
"id" INTEGER NOT NULL UNIQUE,
|
||
|
"kid" TEXT NOT NULL COLLATE NOCASE,
|
||
|
"key_" TEXT NOT NULL COLLATE NOCASE,
|
||
|
"title" TEXT NULL,
|
||
|
PRIMARY KEY("id" AUTOINCREMENT),
|
||
|
UNIQUE("kid", "key_")
|
||
|
);
|
||
|
""".format(name.lower())
|
||
|
)
|
||
|
)
|
||
|
|
||
|
|
||
|
parser = argparse.ArgumentParser()
|
||
|
parser.add_argument(
|
||
|
"-i", "--input",
|
||
|
help="vault",
|
||
|
required=True)
|
||
|
args = parser.parse_args()
|
||
|
|
||
|
LocalVault(args.input)
|