diff --git a/db/other.db b/db/other.db
index 9d54596..7e235f4 100644
Binary files a/db/other.db and b/db/other.db differ
diff --git a/db/test.db b/db/test.db
index a05030f..bfbe8c4 100644
Binary files a/db/test.db and b/db/test.db differ
diff --git a/modules/__pycache__/index.cpython-37.pyc b/modules/__pycache__/index.cpython-37.pyc
index a7134b4..eeff6c6 100644
Binary files a/modules/__pycache__/index.cpython-37.pyc and b/modules/__pycache__/index.cpython-37.pyc differ
diff --git a/modules/htmlize.py b/modules/htmlize.py
new file mode 100644
index 0000000..1ab8329
--- /dev/null
+++ b/modules/htmlize.py
@@ -0,0 +1,88 @@
+import config
+
+def tabelize(table_list):
+ ''' Construct a table out of
+
+ 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 += ''
+ if not isinstance(row, (list,tuple)):
+ table += f"| {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"| {row} | "
+ else:
+ for item in row:
+ table += f" {item} | "
+ table += '
'
+ table += '
'
+ 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"| {item} | "
- table += '
'
- table += '
'
- 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}