Files
JellyPy/plexpy/datatables.py
Tim d216c0d76a Enable video logging by default.
Move database functions to its own file.
Incorporate datatables changes into original file and remove the test file.
Remove old plexWatch processing and db files and references.
2015-07-15 12:50:33 +02:00

222 lines
8.7 KiB
Python

# This file is part of PlexPy.
#
# PlexPy is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# PlexPy is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with PlexPy. If not, see <http://www.gnu.org/licenses/>.
# TODO: Implement with sqlite3 directly instead of using db class
from plexpy import logger, helpers, database
import re
class DataTables(object):
"""
Server side processing for Datatables
"""
def __init__(self):
self.ssp_db = database.MonitorDatabase()
logger.debug(u"Database initilised!")
# TODO: Pass all parameters via kwargs
def ssp_query(self, table_name,
columns=[],
start=0,
length=0,
order_column=0,
order_dir='asc',
search_value='',
search_regex='',
custom_where='',
group_by='',
join_type=None,
join_table=None,
join_evals=None,
kwargs=None):
parameters = self.process_kwargs(kwargs)
if group_by != '':
grouping = True
else:
grouping = False
column_data = self.extract_columns(columns)
where = self.construct_where(column_data, search_value, grouping, parameters)
order = self.construct_order(column_data, order_column, order_dir, parameters, table_name, grouping)
join = ''
if join_type:
join_iter = 0
for join_type_item in join_type:
if join_type_item.upper() == 'LEFT OUTER JOIN':
join_item = 'LEFT OUTER JOIN %s ON %s = %s ' % \
(join_table[join_iter], join_evals[join_iter][0], join_evals[join_iter][1])
elif join_type_item.upper() == 'JOIN' or join_type.upper() == 'INNER JOIN':
join_item = 'INNER JOIN %s ON %s = %s ' % \
(join_table[join_iter], join_evals[join_iter][0], join_evals[join_iter][1])
else:
join_item = ''
join_iter += 1
join += join_item
logger.debug(u"join string = %s" % join)
# TODO: custom_where is ugly and causes issues with reported total results
if custom_where != '':
custom_where = 'WHERE (' + custom_where + ')'
if grouping:
if custom_where == '':
query = 'SELECT * FROM (SELECT %s FROM %s %s GROUP BY %s) %s %s' \
% (column_data['column_string'], table_name, join, group_by,
where, order)
else:
query = 'SELECT * FROM (SELECT * FROM (SELECT %s FROM %s %s GROUP BY %s) %s %s) %s' \
% (column_data['column_string'], table_name, join, group_by,
where, order, custom_where)
else:
if custom_where == '':
query = 'SELECT %s FROM %s %s %s %s' \
% (column_data['column_string'], table_name, join, where,
order)
else:
query = 'SELECT * FROM (SELECT %s FROM %s %s %s %s) %s' \
% (column_data['column_string'], table_name, join, where,
order, custom_where)
logger.debug(u"Query string: %s" % query)
filtered = self.ssp_db.select(query)
if search_value == '':
totalcount = len(filtered)
else:
totalcount = self.ssp_db.select('SELECT COUNT(*) from %s' % table_name)[0][0]
result = filtered[start:(start + length)]
output = {'result': result,
'filteredCount': len(filtered),
'totalCount': totalcount}
return output
@staticmethod
def construct_order(column_data, order_column, order_dir, parameters=None, table_name=None, grouped=False):
order = ''
if grouped:
sort_col = column_data['column_named'][order_column]
else:
sort_col = column_data['column_order'][order_column]
if parameters:
for parameter in parameters:
if parameter['data'] != '':
if int(order_column) == parameter['index']:
if parameter['data'] in column_data['column_named'] and parameter['orderable'] == 'true':
if table_name and table_name != '':
order = 'ORDER BY %s COLLATE NOCASE %s' % (sort_col, order_dir)
else:
order = 'ORDER BY %s COLLATE NOCASE %s' % (sort_col, order_dir)
else:
order = 'ORDER BY %s COLLATE NOCASE %s' % (sort_col, order_dir)
return order
@staticmethod
def construct_where(column_data, search_value='', grouping=False, parameters=None):
if search_value != '':
where = 'WHERE '
if parameters:
for column in column_data['column_named']:
search_skip = False
for parameter in parameters:
if column.rpartition('.')[-1] in parameter['data']:
if parameter['searchable'] == 'true':
where += column + ' LIKE "%' + search_value + '%" OR '
search_skip = True
else:
search_skip = True
if not search_skip:
where += column + ' LIKE "%' + search_value + '%" OR '
else:
for column in column_data['column_named']:
where += column + ' LIKE "%' + search_value + '%" OR '
# TODO: This will break the query if all parameters are excluded
where = where[:-4]
return where
else:
where = ''
return where
@staticmethod
def extract_columns(columns=[]):
columns_string = ''
columns_literal = []
columns_named = []
columns_order = []
for column in columns:
columns_string += column
columns_string += ', '
# TODO: make this case insensitive
if ' as ' in column:
columns_literal.append(column.rpartition(' as ')[0])
columns_named.append(column.rpartition(' as ')[-1].rpartition('.')[-1])
columns_order.append(column.rpartition(' as ')[-1])
else:
columns_literal.append(column)
columns_named.append(column.rpartition('.')[-1])
columns_order.append(column)
columns_string = columns_string[:-2]
column_data = {'column_string': columns_string,
'column_literal': columns_literal,
'column_named': columns_named,
'column_order': columns_order
}
return column_data
# TODO: Fix this method. Should not break if kwarg list is not sorted.
def process_kwargs(self, kwargs):
column_parameters = []
for kwarg in sorted(kwargs):
if re.search(r"\[(\w+)\]", kwarg) and kwarg[:7] == 'columns':
parameters = re.findall(r"\[(\w+)\]", kwarg)
array_index = ''
for parameter in parameters:
pass_complete = False
if parameter.isdigit():
array_index = parameter
if parameter == 'data':
data = kwargs.get('columns[' + array_index + '][data]', "")
if parameter == 'orderable':
orderable = kwargs.get('columns[' + array_index + '][orderable]', "")
if parameter == 'searchable':
searchable = kwargs.get('columns[' + array_index + '][searchable]', "")
pass_complete = True
if pass_complete:
row = {'index': int(array_index),
'data': data,
'searchable': searchable,
'orderable': orderable}
column_parameters.append(row)
return sorted(column_parameters, key=lambda i: i['index'])