Select final, but dirty

This commit is contained in:
2019-07-04 17:13:16 +02:00
parent d28ba44acc
commit 8b8545e5b9
9 changed files with 248 additions and 66 deletions

Binary file not shown.

Binary file not shown.

88
modules/htmlize.py Normal file
View File

@@ -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 = '<table>'
for row in table_list:
table += '<tr>'
if not isinstance(row, (list,tuple)):
table += f"<td> {row} </td>"
else:
for item in row:
table += f"<td> {item} </td>"
table += '</tr>'
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 = '<table>'
for row in table_list:
table += '<tr>'
if not isinstance(row, (list, tuple)):
table += f"<td> <a href=\"./{row}/\">{row}</a> </td>"
else:
for item in row:
table += f"<td> <a href=\"./{item}/\">{item}</a> </td>"
table += '</tr>'
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 """<div>ERROR: {}!</div><br>{}""".format(e, read_path)

View File

@@ -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 = '<table>'
for row in table_list:
table += '<tr>'
for item in row:
table += f"<td> {item} </td>"
table += '</tr>'
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):

6
templates/dbs.html Normal file
View File

@@ -0,0 +1,6 @@
<h2>DB Schema for {_db}</h2>
{_schema}
<h3>Tables:</h3>
{_tables}
<hr>
<div>Result: {_status}</div>

2
templates/error.html Normal file
View File

@@ -0,0 +1,2 @@
<h1>ERROR</h1>
<p>{_error}</p>

6
templates/schema.html Normal file
View File

@@ -0,0 +1,6 @@
<h2>DB Schema for {_db}</h2>
{_schema}
<h3>Tables:</h3>
{_tables}
<hr>
<div>Result: {_status}</div>

6
templates/table.html Normal file
View File

@@ -0,0 +1,6 @@
<h2>DB '{_db}' / Table '{_table}'</h2>
<div>
{_rows}
</div>
<hr>
<div>Result: {_status}</div>