diff --git a/private/Backup.py b/private/Backup.py index ef5e13f..95df494 100755 --- a/private/Backup.py +++ b/private/Backup.py @@ -96,7 +96,10 @@ class Backup: returner = io.StringIO() write_csv = csv.DictWriter(returner, fieldnames=self.field_names, quoting=self.quoting, dialect=self.dialect) write_csv.writeheader() - write_csv.writerows(fetched) + for row in fetched: + write_csv.writerow(dict(row)) + # sqlite3.Row doesn't "easily" convert to a dict itself sadly, so just a quick help from us here + # it actually even delivers a list(sqlite3.Row) also, which doesnt make the life a whole lot easier if self.filename == "stdout": print(returner.getvalue()) @@ -116,8 +119,13 @@ if __name__ == "__main__": L = ListUsers.ListUsers(config['DEFAULT']['applications_db'], unapproved=args.unapproved, approved=args.approved) fetch = L.get_fetch() - B = Backup(args.file) - B.backup_to_file(fetch) + if fetch: + B = Backup(args.file) + B.setFieldnames(fetch[0].keys()) # sqlite3.row delivers its keys for us! SO NICE! + B.backup_to_file(fetch) + else: + print("nothing to backup!") + exit(1) exit(0) except KeyboardInterrupt as e: pass diff --git a/private/ListUsers.py b/private/ListUsers.py index d19864f..df7283a 100755 --- a/private/ListUsers.py +++ b/private/ListUsers.py @@ -1,9 +1,12 @@ #!/usr/bin/env python3 from lib.sqlitedb import SQLiteDB -import configparser import lib.uis.default as default_cmd # Follows -u, -a, -f flags +from typing import List # Typing support! +import sqlite3 # sqlite3.Row-Object +import configparser + class ListUsers: db = None @@ -25,13 +28,12 @@ class ListUsers: query = "SELECT * FROM `applications` WHERE `status` = '0'" elif approved: # Approved users query = "SELECT * FROM `applications` WHERE `status` = '1'" - elif single_user is not None: - query = "SELECT * FROM `applications` WHERE `username` = ?" - self.usersFetch = self.db.safequery(query, tuple([single_user])) - return else: # All users query = "SELECT * FROM `applications`" self.usersFetch = self.db.query(query) + if single_user is not None: + query = "SELECT * FROM `applications` WHERE `username` = ?" + self.usersFetch = self.db.safequery(query, tuple([single_user])) def output_as_list(self) -> str: """Generates a string with one (approved) user per line and one newline at the end @@ -50,11 +52,11 @@ class ListUsers: def prettyPrint(self) -> None: pass # see below why not implemented yet, texttable... - def get_fetch(self) -> list: + def get_fetch(self) -> List[sqlite3.Row]: """ Returns a complete fetch done by the lib.sqlitedb-class - :return: Complete fetchall() in a dict - :rtype: list + :return: Complete fetchall(). A List[sqlite3.Row] with dict-emulation objects. + :rtype: List[sqlite3.Row] """ return self.usersFetch diff --git a/private/lib/sqlitedb.py b/private/lib/sqlitedb.py index 1dc1aa0..d131e00 100644 --- a/private/lib/sqlitedb.py +++ b/private/lib/sqlitedb.py @@ -1,11 +1,12 @@ #!/usr/bin/env python3 import sqlite3 from sys import stderr as stderr +from typing import List # Typing support! # create dictionary out of sqlite results def dict_factory(cursor, row): - d = {} + d: dict = {} for idx, col in enumerate(cursor.description): d[col[0]] = row[idx] return d @@ -34,7 +35,7 @@ class SQLiteDB: except sqlite3.Error as e: print("Connection error: %s" % e, file=stderr) - self.cursor.row_factory = dict_factory # every result will be a dict now + self.cursor.row_factory = sqlite3.Row # every result will be a dict now def __del__(self): try: @@ -43,7 +44,7 @@ class SQLiteDB: except sqlite3.Error as e: print("Couldn't gracefully close db: %s" % e, file=stderr) - def query(self, qq: str) -> list: + def query(self, qq: str) -> List[sqlite3.Row]: """Do a query and automagically get the fetched results in a list :param qq: Query to execute :type qq: str @@ -71,14 +72,14 @@ class SQLiteDB: # we could try to utilise that ourselfs in a function. Be c a r e f u l, these values in the tuple MUST HAVE # THE RIGHT TYPE - def safequery(self, qq: str, deliver: tuple) -> list: + def safequery(self, qq: str, deliver: tuple) -> List[sqlite3.Row]: """ Shall handle any query that has user input in it as an alternative to self.query :param qq: Query to execute :type qq: str :param deliver: User inputs marked with the placeholder(`?`) in the str :type deliver: tuple :returns: A tuple(/list) consisting with any fetched results - :rtype: list + :rtype: List[sqlite3.Row] """ try: @@ -88,7 +89,7 @@ class SQLiteDB: except TypeError as e: print("Types in given tuple doesnt match to execute query \"%s\": %s" % (qq, e), file=stderr) self.last_result = [] - except sqlite3.OperationalError as e: + except sqlite3.OperationalError: self._createTable() return self.safequery(qq, deliver) except sqlite3.Error as e: @@ -138,7 +139,7 @@ class SQLiteDB: return False return True - def _createTable(self): + def _createTable(self) -> None: try: self.cursor.execute( "CREATE TABLE IF NOT EXISTS applications("