From 8b8545e5b9a03c8d16bc89d787ef60c2e9a5bb9a Mon Sep 17 00:00:00 2001 From: Milan Toman Date: Thu, 4 Jul 2019 17:13:16 +0200 Subject: [PATCH] Select final, but dirty --- db/other.db | Bin 8192 -> 8192 bytes db/test.db | Bin 8192 -> 12288 bytes modules/__pycache__/index.cpython-37.pyc | Bin 1515 -> 765 bytes modules/htmlize.py | 88 ++++++++++ modules/sqlite.py | 206 +++++++++++++++-------- templates/dbs.html | 6 + templates/error.html | 2 + templates/schema.html | 6 + templates/table.html | 6 + 9 files changed, 248 insertions(+), 66 deletions(-) create mode 100644 modules/htmlize.py create mode 100644 templates/dbs.html create mode 100644 templates/error.html create mode 100644 templates/schema.html create mode 100644 templates/table.html diff --git a/db/other.db b/db/other.db index 9d54596c0378c90f380a93bbba481d675ac3aeaf..7e235f48c207c3e538c34f457c4b6d3fdb41ba34 100644 GIT binary patch delta 90 zcmZp0XmFSy&B!uQ#+i|2W5N=CE@u7{4E&$@ukxSREGV#x--4T&nN!v)QK2j+vA9x( niJ8foNe9R+&QwSQ;#18JWcj#Tl6;;*89uoN%53P&BbT JwKzXF6#(9*J#PR2 delta 73 zcmZojXmFSyEy&Ekz`z8=Fu*ub$C#g)LC-{i7bwKYe}IAiz-C2(ApXe*_+2=d_-`@r UzvsWTSy15w|HJ^c$+zUy0J`K4tN;K2 diff --git a/modules/__pycache__/index.cpython-37.pyc b/modules/__pycache__/index.cpython-37.pyc index a7134b440f741c00fabb5bb605a582e634ec529c..eeff6c69037ed00ea60074ffb2ce19775771957d 100644 GIT binary patch delta 347 zcmaFO{g;)`iIy-BqOzme=-Yed_6lzlmk@}SUE^#5fhLANfv{69E>cCe5_zGO|~LlpvWz@ z>j6Mn?bu literal 1515 zcmbtUOHbQC5VjpVaYI2p^jgWvsi^>ylt3Q{@i|`WJerIz+;w&v>Je8ZoamV$#}G%`=I5wP1pT~zZ!(={`jFH-m^yDa27(@8nvzR0*95U^8x=ydx zTk3S5ua(JS*f$iuT;!~ zO69|0#NZ!Fu->#!1dtDavKLR+z_vCxu1wI2DD(ctAwkC`>`wps2%NnKSua z%WP<)->+T#NbV_3WW?N~NYcO!hcwGZ>Btu+3=VwokU<)`F()~LJ0Zf>T~0@ZrB)BH zC-KJ7o|yW0VcO@*N?Gb)>}J)$2#p {row} " + else: + for item in row: + table += f" {item} " + table += '' + table += '' + return table + +def tabelize_links(table_list): + ''' Making a table with links + + Constructs a clickable link in HTML, so that the link points to ./link + + Args: + *table_list:* tuple() / list(), rows and items as tuples / lists + + Sets: + *N/A* + + Returns: + *table:* str(), html table code made from tuples / lists + + Raises: + *N/A* + + ''' + table = '' + for row in table_list: + table += '' + if not isinstance(row, (list, tuple)): + table += f"" + else: + for item in row: + table += f"" + table += '' + table += '
{row} {item}
' + return table + +def read_html(filename, _STATIC_DIR): + '''Read a html file + + Reads a file from a selected static directory - needs to be set as static + in the cherrypy (chttpd.py). + + Args: + ``filename`` *str()*, plain filename, without any path specification, + without extension + ``_STATIC_DIR`` *str()*, path relative to the project root, + where chttpd.py resides + + Returns: + *str()*, parsed html code from the read file, or a HTML + formatted error if file cannot be read for any reason + + Exceptions: + On file read fail, string with Exception text is returned + + ''' + read_path = config._ROOT+ _STATIC_DIR + filename + '.html' + try: + with open(read_path, 'r') as handle: + return handle.read() + except Exception as e: + return """
ERROR: {}!

{}""".format(e, read_path) diff --git a/modules/sqlite.py b/modules/sqlite.py index adeac4b..ebaa308 100644 --- a/modules/sqlite.py +++ b/modules/sqlite.py @@ -3,8 +3,57 @@ import cherrypy import config import sqlite3 import os +import json +from modules import htmlize +class Checker(object): + def __init__(self): + ''' Sanity check + Describes tables in DB, or lists the contents + + Args: + *None* + + Sets: + *N/A:* Nothing yet + + Returns: + *N/A:* boolean(), valid, or not? + + Raises: + *N/A* Nothing yet + + ''' + __name__ = "SQLite SQL validator" + + def is_table(db, table): + ''' Checks if table exists in a DB + + Escaping, sanitizing and checking what are we sending to the DB + + Args: + *query* Query to be sent to the DB + + Sets: + *N/A* + + Returns: + *result:* bool(), is the code to be executed OK, or not + + Raises: + *N/A* + + ''' + db_file = f"{config._ROOT}/{config._DB_PATH}/{db}" + try: + open(db_file) + except Exception as e: + result = [ False, e ] + + return result + + class select(object): def __init__(self): ''' SELECT method for API @@ -28,26 +77,6 @@ class select(object): self.html = '' self.json = '' - def CheckSelect(self): - ''' Checks and sanitizes a query - - Escaping, sanitizing and checking what are we sending to the DB - - Args: - *query* Query to be sent to the DB - - Sets: - *N/A* - - Returns: - *result:* bool(), is the code to be executed OK, or not - - Raises: - *N/A* - - ''' - return True - def _cp_dispatch(self, vpath): ''' Modify the request path, REST way @@ -69,11 +98,17 @@ class select(object): *N/A* ''' + dbs = os.listdir(f"{config._ROOT}/{config._DB_PATH}") if len(vpath) == 1: - cherrypy.request.params['schema'] = vpath.pop() - return self + schema = vpath.pop() + if schema in dbs: + cherrypy.request.params['schema'] = schema + return self + else: + del schema + return self - if len(vpath) == 2: + elif len(vpath) == 2: cherrypy.request.params['table'] = vpath.pop() cherrypy.request.params['db'] = vpath.pop() cherrypy.request.params['values'] = '*' @@ -100,11 +135,21 @@ class select(object): *N/A* ''' - db_file = f"{config._ROOT}/{db}" - try: - open(db_file) - except Exception as e: - raise RuntimeError(f"ERROR: Unable to read DB file: {e}") + db_file = f"{config._ROOT}/{config._DB_PATH}/{db}" + if os.path.exists(db_file): + error = False + if os.path.isfile(db_file): + error = False + else: + error = f"{db_file} is not a standard file" + html_result = htmlize.read_html('error', '/templates/') + result = html_result.format(_error=error) + return result + else: + error = f"{db_file} does not exist" + html_result = htmlize.read_html('error', '/templates/') + result = html_result.format(_error=error) + return result conn = sqlite3.connect(db_file) c = conn.cursor() if len(kwargs) == 0: @@ -117,32 +162,6 @@ class select(object): conn.close() return result - def tabelize(self, table_list): - ''' Calling the actual data from DB - - Connect to DB, execute a query and return data - - Args: - *table_list:* tuple() / list(), rows and items as tuples / lists - - Sets: - *N/A* - - Returns: - *table:* str(), html table code made from tuples / lists - - Raises: - *N/A* - - ''' - table = '' - for row in table_list: - table += '' - for item in row: - table += f"" - table += '' - table += '
{item}
' - return table @cherrypy.expose def index(self, **kwargs): @@ -166,19 +185,74 @@ class select(object): *N/A* ''' - if 'schema' in kwargs.keys(): - result = self.sqlite_wrapper( - kwargs["schema"] - ) - else: - result = self.sqlite_wrapper( - kwargs['db'], - table=kwargs['table'], - values=kwargs['values'] - ) self.html = '' - self.html += self.tabelize(result) - return self.html + self.json = {} + url = cherrypy.url() + if 'schema' in kwargs.keys(): + # No table is defined, we want the 'schema' of the DB + try: + db = kwargs["schema"] + result = self.sqlite_wrapper(db) + status = 'OK' + except Exception as e: + result = '' + status = f"ERROR: {e}" + self.html = htmlize.read_html('schema','/templates/') + # schema has weird structure, returns (val,) hence schema[0] + # [2] - third element '[0]CREATE [1]TABLE [2]'xyz' ... + tables = [schema[0].split(' ')[2].strip('\'') for schema in result] + self.html = self.html.format( + _db=db, + _schema=htmlize.tabelize(result), + _tables=htmlize.tabelize_links(tables), + _status=status + ) + self.json.update({ + "result": {"tables": tables}, + "status": status + }) + elif 'table' in kwargs.keys(): + # In case a table is defined, what are the values? + db = kwargs['db'] + table = kwargs['table'] + try: + result = self.sqlite_wrapper( + db, + table=table, + values=kwargs['values'] + ) + status = 'OK' + except Exception as e: + result = '' + status = f"ERROR: {e}" + self.html = htmlize.read_html('table','/templates/') + self.html = self.html.format( + _db=db, + _table=table, + _rows=htmlize.tabelize(result), + _status=status + ) + self.json.update({ + "result": {"rows": result}, + "status": status + }) + elif url.split('/')[-2] == 'select': + #No DB, nor table is defined, list DBs in config._DB_PATH + dbs = os.listdir(f"{config._ROOT}/{config._DB_PATH}") + result = [db for db in dbs] + self.html += htmlize.tabelize_links(result) + self.json.update({ + "result":{"databases": result}, + "status": "OK" + }) + else: + result = htmlize.read_html('error', '/templates/') + e = f'DB is non existent, or wrong parameter specified. Check URL' + return result.format(_error=e) + if 'json' in kwargs.keys(): + return json.dumps(self.json) + else: + return self.html class insert(object): diff --git a/templates/dbs.html b/templates/dbs.html new file mode 100644 index 0000000..34e438f --- /dev/null +++ b/templates/dbs.html @@ -0,0 +1,6 @@ +

DB Schema for {_db}

+{_schema} +

Tables:

+{_tables} +
+
Result: {_status}
diff --git a/templates/error.html b/templates/error.html new file mode 100644 index 0000000..9d488b3 --- /dev/null +++ b/templates/error.html @@ -0,0 +1,2 @@ +

ERROR

+

{_error}

diff --git a/templates/schema.html b/templates/schema.html new file mode 100644 index 0000000..34e438f --- /dev/null +++ b/templates/schema.html @@ -0,0 +1,6 @@ +

DB Schema for {_db}

+{_schema} +

Tables:

+{_tables} +
+
Result: {_status}
diff --git a/templates/table.html b/templates/table.html new file mode 100644 index 0000000..8d26c11 --- /dev/null +++ b/templates/table.html @@ -0,0 +1,6 @@ +

DB '{_db}' / Table '{_table}'

+
+ {_rows} +
+
+
Result: {_status}