From b5e8d6575210795bc9b80cc9466f4c701b262054 Mon Sep 17 00:00:00 2001 From: Luke Gessler Date: Tue, 30 Oct 2018 17:16:35 -0400 Subject: [PATCH 01/19] put validation rules tables into tabs --- css/gitdox.css | 35 +++++++++++++++++++++++++++-- js/validation_rules.js | 12 ++++++++++ templates/validation_rules.mustache | 27 +++++++++++----------- 3 files changed, 59 insertions(+), 15 deletions(-) diff --git a/css/gitdox.css b/css/gitdox.css index 8205a60..e56913b 100644 --- a/css/gitdox.css +++ b/css/gitdox.css @@ -164,8 +164,39 @@ padding: 10px; height: 12.8px; } -#ValidationTableContainer{ -width: 100%} +/* for validation_rules */ +ul.tabs{ + margin: 0px; + padding: 0px; + list-style: none; +} + +ul.tabs li{ + background: none; + display: inline-block; + padding: 10px 15px; + cursor: pointer; + min-width: 100px; + font-size: 18px; + font-weight: 600; + color: #222; + text-align: center; +} + +ul.tabs li.current{ + background: #ededed; + color: #222; +} + +.tab-content{ + display: none; + background: #ededed; + padding: 15px; +} + +.tab-content.current{ + display: inherit; +} .jtable td{ word-break: break-all; diff --git a/js/validation_rules.js b/js/validation_rules.js index 48315b6..2d7c89a 100644 --- a/js/validation_rules.js +++ b/js/validation_rules.js @@ -221,3 +221,15 @@ $(document).ready(function () { }); $('#export-table-container').jtable('load'); }); + +$(document).ready(function(){ + $('ul.tabs li').click(function(){ + var tab_id = $(this).attr('data-tab'); + + $('ul.tabs li').removeClass('current'); + $('.tab-content').removeClass('current'); + + $(this).addClass('current'); + $("#"+tab_id).addClass('current'); + }); +}); diff --git a/templates/validation_rules.mustache b/templates/validation_rules.mustache index 74032da..48e2553 100644 --- a/templates/validation_rules.mustache +++ b/templates/validation_rules.mustache @@ -32,11 +32,12 @@ {{> header}}
-

GitDox - Validation

-

- validation rule management | back to document list +

GitDox - Validation Rules

+

+ return to index

+ +
-
-
-
-
-
-
-
-
-
-
+
+
+
+
From 241d2eee92bebf229d05ddd50da533a16bf10844 Mon Sep 17 00:00:00 2001 From: Luke Gessler Date: Tue, 30 Oct 2018 20:30:22 -0400 Subject: [PATCH 02/19] make metadata editing async in editor.py --- css/gitdox.css | 16 +++++ js/editor.js | 51 +++++++++++++++ modules/editor_metadata.py | 96 +++++++++++++++++++++++++++++ templates/editor.mustache | 29 +++------ templates/validation_rules.mustache | 17 ----- 5 files changed, 172 insertions(+), 37 deletions(-) create mode 100755 modules/editor_metadata.py diff --git a/css/gitdox.css b/css/gitdox.css index e56913b..876727b 100644 --- a/css/gitdox.css +++ b/css/gitdox.css @@ -198,6 +198,22 @@ ul.tabs li.current{ display: inherit; } +/* override jtable styles for consistency with rest of gitdox */ +.jtable-title { + font-size: 16px !important; + border: none !important; + border-radius: 0 !important; + background: #eeeeee !important; +} +table.jtable { + border: none !important; +} + +.ui-widget-overlay { + opacity: 0.5 !important; +} + + .jtable td{ word-break: break-all; } diff --git a/js/editor.js b/js/editor.js index c6f6ab7..5ecea1d 100755 --- a/js/editor.js +++ b/js/editor.js @@ -44,3 +44,54 @@ function export_ether(){ window.open('export.py?docs=' + doc_id + '&stylesheet=' + stylesheet, '_new'); } + +$(document).ready(function () { + // get id from hidden form element. Watch out, might break in the future + var docid = $("#id").val(); + $('#metadata-table-container').jtable({ + title: 'Metadata', + sorting: true, + actions: { + listAction: function (postData, jtParams) { + jtParams.domain = 'meta'; + return $.Deferred(function ($dfd) { + $.ajax({ + url: 'modules/editor_metadata.py?action=list&docid=' + docid, + type: 'POST', + dataType: 'json', + data: jtParams, + success: function (data) { + $dfd.resolve(data); + }, + error: function() { + $dfd.reject(); + } + }); + }); + }, + createAction: 'modules/editor_metadata.py?action=create', + deleteAction: 'modules/editor_metadata.py?action=delete&docid=' + docid + }, + fields: { + id: { + title: 'ID', + key: true, + visibility:'hidden' + }, + docid: { + title: 'Document ID', + defaultValue: docid, + type: 'hidden' + }, + key: { + title: 'Key', + options: 'modules/editor_metadata.py?action=keys' + }, + value: { + title: 'Value' + } + } + }); + $('#metadata-table-container').jtable('load'); +}); + diff --git a/modules/editor_metadata.py b/modules/editor_metadata.py new file mode 100755 index 0000000..fc2c0c4 --- /dev/null +++ b/modules/editor_metadata.py @@ -0,0 +1,96 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +from gitdox_sql import * +import json +import cgi +import os +import platform + +parameter = cgi.FieldStorage() +action = parameter.getvalue("action") +id = parameter.getvalue("id") +docid = parameter.getvalue("docid") +key = parameter.getvalue("key") +value = parameter.getvalue("value") + +if platform.system() == "Windows": + prefix = "transc\\" +else: + prefix = "" + +def read_options(**kwargs): + if "file" in kwargs: + kwargs["file"] = prefix + kwargs["file"] + names = open(kwargs["file"],'r').read().replace("\r","").split("\n") + names = list(name[:name.find("\t")] for name in names) + elif "names" in kwargs: + names = kwargs[names] + selected = kwargs["selected"] if "selected" in kwargs else None + return names + +def row_to_dict(row): + return {'id': row[1], + 'docid': row[0], + 'key': row[2], + 'value': row[3]} + +def get_metadata(): + resp = {} + try: + resp['Result'] = 'OK' + resp['Records'] = [row_to_dict(r) for r in get_doc_meta(docid)] + print json.dumps(resp) + except: + resp['Result'] = 'Error' + resp['Message'] = 'Could not fetch metadata' + print json.dumps(resp) + +def get_default_key_options(): + resp = {} + try: + resp['Result'] = 'OK' + resp['Options'] = read_options(file='..' + os.sep + 'metadata_fields.tab') + print json.dumps(resp) + except: + resp['Result'] = 'Error' + resp['Message'] = 'Could not fetch metadata key options' + print json.dumps(resp) + +def create_metadata(): + resp = {} + try: + save_meta(int(docid), key.decode("utf8"), value.decode("utf8")) + resp['Result'] = 'OK' + resp['Record'] = {'docid': docid, + 'key': key, + 'value': value} + print json.dumps(resp) + except: + resp['Result'] = 'Error' + resp['Message'] = 'Could not create metadata' + print json.dumps(resp) + +def delete_metadata(): + resp = {} + try: + delete_meta(int(id), int(docid)) + resp['Result'] = 'OK' + print json.dumps(resp) + except: + resp['Result'] = 'Error' + resp['Message'] = 'Could not delete metadata' + print json.dumps(resp) + +print "Content-type:application/json\r\n\r\n" +if action == "list": + get_metadata() +elif action == "create": + create_metadata() +elif action == "delete": + delete_metadata() +elif action == "keys": + get_default_key_options() +else: + print json.dumps({'Result': 'Error', + 'Message': 'Unknown action: "' + str(action) + '"'}) diff --git a/templates/editor.mustache b/templates/editor.mustache index f331cc9..cc72b94 100644 --- a/templates/editor.mustache +++ b/templates/editor.mustache @@ -14,28 +14,18 @@ + + + + + + - - - - + + - {{{navbar_html}}} @@ -153,8 +143,7 @@ {{> codemirror}} {{/ether_mode}} -

Metadata

- {{{metadata_html}}} +
diff --git a/templates/validation_rules.mustache b/templates/validation_rules.mustache index 48e2553..f954c83 100644 --- a/templates/validation_rules.mustache +++ b/templates/validation_rules.mustache @@ -37,23 +37,6 @@ return to index

- - -
- - - -

- {{{corpus_metadata_html}}} - - - -

- -
Add Corpus Metadata
-
diff --git a/templates/popup_meta.mustache b/templates/popup_meta.mustache deleted file mode 100644 index de0c744..0000000 --- a/templates/popup_meta.mustache +++ /dev/null @@ -1,29 +0,0 @@ - - - - - -
- field name (e.g., author):
- - - {{#options}} - -
- field value (e.g., Besa):
-
- -
- - From f5cead90966a7f7ad37501fd624f8aa64411a38e Mon Sep 17 00:00:00 2001 From: Luke Gessler Date: Wed, 31 Oct 2018 13:29:57 -0400 Subject: [PATCH 08/19] add doesntexist operator for ethercalc validation --- js/validation_rules.js | 2 +- modules/validation/ether_validator.py | 16 +++++++++++++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/js/validation_rules.js b/js/validation_rules.js index 2d7c89a..b69caf8 100644 --- a/js/validation_rules.js +++ b/js/validation_rules.js @@ -156,7 +156,7 @@ $(document).ready(function () { }, operator: { title: 'Operator', - options: ['~', '|', '=', '==', '>', 'exists'] + options: ['~', '|', '=', '==', '>', 'exists', 'doesntexist'] }, argument: { title: 'Argument' diff --git a/modules/validation/ether_validator.py b/modules/validation/ether_validator.py index fab8156..2801d0b 100644 --- a/modules/validation/ether_validator.py +++ b/modules/validation/ether_validator.py @@ -21,7 +21,19 @@ def _apply_exists(self, parsed_ether): col_letters = colmap[self.name] # list of letters with col name if len(col_letters) == 0: - report += "Column named " + self.name + " not found
" + report += "Column named '" + self.name + "' not found
" + return report, tooltip, cells + + def _apply_doesntexist(self, parsed_ether): + report = '' + tooltip = '' + cells = [] + colmap = parsed_ether['__colmap__'] # name -> list of col letters + col_letters = colmap[self.name] # list of letters with col name + + if len(col_letters) > 0: + report += "Columns named '" + self.name + "' are not allowed
" + cells += [letter + "1" for letter in col_letters] return report, tooltip, cells def _apply_span_equals_number(self, parsed_ether): @@ -283,6 +295,8 @@ def _apply_rule(self, parsed_ether): if self.operator == "exists": return self._apply_exists(parsed_ether) + if self.operator == "doesntexist": + return self._apply_doesntexist(parsed_ether) elif self.operator == "|": return self._apply_span_equals_number(parsed_ether) elif self.operator == "~": From d544d33a4457c10ff49c74e44d9c9ed97e36237c Mon Sep 17 00:00:00 2001 From: Luke Gessler Date: Wed, 31 Oct 2018 17:53:42 -0400 Subject: [PATCH 09/19] require login for using editor's metadata service --- ..._metadata.py => editor_metadata_service.py | 58 ++++++++++++------- js/editor.js | 17 +++--- modules/gitdox_sql.py | 22 ++++--- 3 files changed, 58 insertions(+), 39 deletions(-) rename modules/editor_metadata.py => editor_metadata_service.py (62%) diff --git a/modules/editor_metadata.py b/editor_metadata_service.py similarity index 62% rename from modules/editor_metadata.py rename to editor_metadata_service.py index 9f77a2a..cb3cc88 100755 --- a/modules/editor_metadata.py +++ b/editor_metadata_service.py @@ -1,11 +1,12 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -from gitdox_sql import * import json import cgi import os import platform +from modules.gitdox_sql import * +from modules.logintools import login parameter = cgi.FieldStorage() action = parameter.getvalue("action") @@ -21,14 +22,14 @@ prefix = "" def read_options(**kwargs): - if "file" in kwargs: - kwargs["file"] = prefix + kwargs["file"] - names = open(kwargs["file"],'r').read().replace("\r","").split("\n") - names = list(name[:name.find("\t")] for name in names) - elif "names" in kwargs: - names = kwargs[names] - selected = kwargs["selected"] if "selected" in kwargs else None - return names + if "file" in kwargs: + kwargs["file"] = prefix + kwargs["file"] + names = open(kwargs["file"],'r').read().replace("\r","").split("\n") + names = list(name[:name.find("\t")] for name in names) + elif "names" in kwargs: + names = kwargs[names] + selected = kwargs["selected"] if "selected" in kwargs else None + return names def row_to_dict(row): return {'id': row[1], @@ -87,15 +88,30 @@ def delete_metadata(): resp['Message'] = 'Could not delete metadata' print json.dumps(resp) -print "Content-type:application/json\r\n\r\n" -if action == "list": - get_metadata() -elif action == "create": - create_metadata() -elif action == "delete": - delete_metadata() -elif action == "keys": - get_default_key_options() -else: - print json.dumps({'Result': 'Error', - 'Message': 'Unknown action: "' + str(action) + '"'}) + + +def open_main_server(): + thisscript = os.environ.get('SCRIPT_NAME', '') + loginaction = None + theform = cgi.FieldStorage() + scriptpath = os.path.dirname(os.path.realpath(__file__)) + os.sep + userdir = scriptpath + "users" + os.sep + loginaction, userconfig = login(theform, userdir, thisscript, loginaction) + user = userconfig["username"] + admin = userconfig["admin"] + + print "Content-type:application/json\r\n\r\n" + if action == "list": + get_metadata() + elif action == "create": + create_metadata() + elif action == "delete": + delete_metadata() + elif action == "keys": + get_default_key_options() + else: + print json.dumps({'Result': 'Error', + 'Message': 'Unknown action: "' + str(action) + '"'}) + +if __name__ == '__main__': + open_main_server() diff --git a/js/editor.js b/js/editor.js index fa1eb2d..dfbb688 100755 --- a/js/editor.js +++ b/js/editor.js @@ -56,7 +56,7 @@ $(document).ready(function () { jtParams.domain = 'meta'; return $.Deferred(function ($dfd) { $.ajax({ - url: 'modules/editor_metadata.py?action=list&docid=' + docid, + url: 'editor_metadata_service.py?action=list&docid=' + docid, type: 'POST', dataType: 'json', data: jtParams, @@ -69,8 +69,8 @@ $(document).ready(function () { }); }); }, - createAction: 'modules/editor_metadata.py?action=create', - deleteAction: 'modules/editor_metadata.py?action=delete&docid=' + docid + createAction: 'editor_metadata_service.py?action=create', + deleteAction: 'editor_metadata_service.py?action=delete&docid=' + docid }, fields: { id: { @@ -95,7 +95,7 @@ $(document).ready(function () { // for autocomplete support https://github.com/volosoft/jtable/issues/115 formCreated: function(event, formData) { $.ajax({ - url: 'modules/editor_metadata.py?action=keys', + url: 'editor_metadata_service.py?action=keys', type: 'POST', dataType: 'json', data: {}, @@ -122,7 +122,7 @@ $(document).ready(function () { jtParams.domain = 'meta'; return $.Deferred(function ($dfd) { $.ajax({ - url: 'modules/editor_metadata.py?corpus=true&action=list&docid=' + docid, + url: 'editor_metadata_service.py?corpus=true&action=list&docid=' + docid, type: 'POST', dataType: 'json', data: jtParams, @@ -135,8 +135,8 @@ $(document).ready(function () { }); }); }, - createAction: 'modules/editor_metadata.py?corpus=true&action=create', - deleteAction: 'modules/editor_metadata.py?corpus=true&action=delete&docid=' + docid + createAction: 'editor_metadata_service.py?corpus=true&action=create', + deleteAction: 'editor_metadata_service.py?corpus=true&action=delete&docid=' + docid }, fields: { id: { @@ -145,7 +145,6 @@ $(document).ready(function () { visibility:'hidden' }, docid: { - title: 'Document ID', defaultValue: docid, type: 'hidden' }, @@ -161,7 +160,7 @@ $(document).ready(function () { // for autocomplete support https://github.com/volosoft/jtable/issues/115 formCreated: function(event, formData) { $.ajax({ - url: 'modules/editor_metadata.py?corpus=true&action=keys', + url: 'editor_metadata_service.py?corpus=true&action=keys', type: 'POST', dataType: 'json', data: {}, diff --git a/modules/gitdox_sql.py b/modules/gitdox_sql.py index a9237bb..5977d3c 100755 --- a/modules/gitdox_sql.py +++ b/modules/gitdox_sql.py @@ -188,23 +188,27 @@ def get_doc_meta(doc_id, corpus=False): def get_corpora(): return generic_query("SELECT DISTINCT corpus FROM docs ORDER BY corpus COLLATE NOCASE", None) -def get_validate_rules(): - return generic_query("SELECT corpus, doc, domain, name, operator, argument, id FROM validate", None) +def get_validate_rules(sort=None, domain=None): + query = "SELECT corpus, doc, domain, name, operator, argument, id FROM validate" + args = [] + if domain: + query += " WHERE domain=? " + args.append(domain) + if sort: + query += " ORDER BY " + sort + return generic_query(query, args) def get_xml_rules(): - return generic_query("SELECT corpus, doc, domain, name, operator, argument, id FROM validate WHERE domain = 'xml'", None) + return get_validate_rules(domain='xml') def get_meta_rules(): - return generic_query("SELECT corpus, doc, domain, name, operator, argument, id FROM validate WHERE domain = 'meta'", None) + return get_validate_rules(domain='meta') def get_ether_rules(): - return generic_query("SELECT corpus, doc, domain, name, operator, argument, id FROM validate WHERE domain = 'ether'", None) + return get_validate_rules(domain='ether') def get_export_rules(): - return generic_query("SELECT corpus, doc, domain, name, operator, argument, id FROM validate WHERE domain = 'export'", None) - -def get_sorted_rules(sort): - return generic_query("SELECT corpus, doc, domain, name, operator, argument, id FROM validate ORDER BY " + sort, None) # parameterization doesn't work for order by + return get_validate_rules(domain='export') def create_validate_rule(doc, corpus, domain, name, operator, argument): new_id = generic_query("INSERT INTO validate(doc,corpus,domain,name,operator,argument) VALUES(?,?,?,?,?,?)", (doc, corpus, domain, name, operator, argument), return_new_id = True) From e4bcaec991b6e18f86babc231c00e583fb079101 Mon Sep 17 00:00:00 2001 From: Luke Gessler Date: Wed, 31 Oct 2018 17:54:52 -0400 Subject: [PATCH 10/19] consolidate modules/jtable* in validation_rules_service.py --- js/validation_rules.js | 58 +++++++-------- modules/jtable_create_rule.py | 41 ----------- modules/jtable_delete_rule.py | 26 ------- modules/jtable_rule_list.py | 44 ----------- modules/jtable_schema_list.py | 32 -------- modules/jtable_update_rule.py | 32 -------- validation_rules_service.py | 134 ++++++++++++++++++++++++++++++++++ 7 files changed, 161 insertions(+), 206 deletions(-) delete mode 100755 modules/jtable_create_rule.py delete mode 100755 modules/jtable_delete_rule.py delete mode 100755 modules/jtable_rule_list.py delete mode 100755 modules/jtable_schema_list.py delete mode 100755 modules/jtable_update_rule.py create mode 100755 validation_rules_service.py diff --git a/js/validation_rules.js b/js/validation_rules.js index b69caf8..ee31ba5 100644 --- a/js/validation_rules.js +++ b/js/validation_rules.js @@ -7,7 +7,7 @@ $(document).ready(function () { jtParams.domain = 'xml'; return $.Deferred(function ($dfd) { $.ajax({ - url: 'modules/jtable_rule_list.py', + url: 'validation_rules_service.py?action=list', type: 'POST', dataType: 'json', data: jtParams, @@ -20,9 +20,9 @@ $(document).ready(function () { }); }); }, - createAction: 'modules/jtable_create_rule.py', - updateAction: 'modules/jtable_update_rule.py', - deleteAction: 'modules/jtable_delete_rule.py' + createAction: 'validation_rules_service.py?action=create', + updateAction: 'validation_rules_service.py?action=update', + deleteAction: 'validation_rules_service.py?action=delete' }, fields: { id: { @@ -31,9 +31,8 @@ $(document).ready(function () { visibility:'hidden' }, domain: { - title: 'Domain', - options: ['xml'], - visibility: 'hidden' + defaultValue: 'xml', + type: 'hidden' }, doc: { title: 'Document' @@ -43,7 +42,7 @@ $(document).ready(function () { }, name: { title: 'XSD Schema', - options: 'modules/jtable_schema_list.py?extension=xsd' + options: 'validation_rules_service.py?action=listschemas&extension=xsd' } } }); @@ -59,7 +58,7 @@ $(document).ready(function () { jtParams.domain = 'meta'; return $.Deferred(function ($dfd) { $.ajax({ - url: 'modules/jtable_rule_list.py', + url: 'validation_rules_service.py?action=list', type: 'POST', dataType: 'json', data: jtParams, @@ -72,9 +71,9 @@ $(document).ready(function () { }); }); }, - createAction: 'modules/jtable_create_rule.py', - updateAction: 'modules/jtable_update_rule.py', - deleteAction: 'modules/jtable_delete_rule.py' + createAction: 'validation_rules_service.py?action=create', + updateAction: 'validation_rules_service.py?action=update', + deleteAction: 'validation_rules_service.py?action=delete' }, fields: { id: { @@ -83,9 +82,8 @@ $(document).ready(function () { visibility:'hidden' }, domain: { - title: 'Domain', - options: ['meta'], - visibility: 'hidden' + defaultValue: 'meta', + type: 'hidden' }, doc: { title: 'Document' @@ -117,7 +115,7 @@ $(document).ready(function () { jtParams.domain = 'ether'; return $.Deferred(function ($dfd) { $.ajax({ - url: 'modules/jtable_rule_list.py', + url: 'validation_rules_service.py?action=list', type: 'POST', dataType: 'json', data: jtParams, @@ -130,9 +128,9 @@ $(document).ready(function () { }); }); }, - createAction: 'modules/jtable_create_rule.py', - updateAction: 'modules/jtable_update_rule.py', - deleteAction: 'modules/jtable_delete_rule.py' + createAction: 'validation_rules_service.py?action=create', + updateAction: 'validation_rules_service.py?action=update', + deleteAction: 'validation_rules_service.py?action=delete' }, fields: { id: { @@ -141,9 +139,8 @@ $(document).ready(function () { visibility:'hidden' }, domain: { - title: 'Domain', - options: ['ether'], - visibility: 'hidden' + defaultValue: 'ether', + type: 'hidden' }, doc: { title: 'Document' @@ -175,7 +172,7 @@ $(document).ready(function () { jtParams.domain = 'export'; return $.Deferred(function ($dfd) { $.ajax({ - url: 'modules/jtable_rule_list.py', + url: 'validation_rules_service.py?action=list', type: 'POST', dataType: 'json', data: jtParams, @@ -188,9 +185,9 @@ $(document).ready(function () { }); }); }, - createAction: 'modules/jtable_create_rule.py', - updateAction: 'modules/jtable_update_rule.py', - deleteAction: 'modules/jtable_delete_rule.py' + createAction: 'validation_rules_service.py?action=create', + updateAction: 'validation_rules_service.py?action=update', + deleteAction: 'validation_rules_service.py?action=delete' }, fields: { id: { @@ -199,9 +196,8 @@ $(document).ready(function () { visibility:'hidden' }, domain: { - title: 'Domain', - options: ['export'], - visibility: 'hidden' + defaultValue: 'export', + type: 'hidden' }, doc: { title: 'Document' @@ -211,11 +207,11 @@ $(document).ready(function () { }, name: { title: 'Export Spec', - options: 'modules/jtable_schema_list.py?extension=ini' + options: 'validation_rules_service.py?action=listschemas&extension=ini' }, argument: { title: 'XSD Schema', - options: 'modules/jtable_schema_list.py?extension=xsd' + options: 'validation_rules_service.py?action=listschemas&extension=xsd' } } }); diff --git a/modules/jtable_create_rule.py b/modules/jtable_create_rule.py deleted file mode 100755 index f795eb7..0000000 --- a/modules/jtable_create_rule.py +++ /dev/null @@ -1,41 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -from gitdox_sql import * -import json -import cgi - - -def create_rule(): - jtable_result = {} - try: - parameter = cgi.FieldStorage() - doc = parameter.getvalue("doc") - corpus = parameter.getvalue("corpus") - domain = parameter.getvalue("domain") - name = parameter.getvalue("name") - operator = parameter.getvalue("operator") - argument = parameter.getvalue("argument") - - id = create_validate_rule(doc,corpus,domain,name,operator,argument) - - new_json_rule = {} - new_json_rule['id'] = id - new_json_rule['doc'] = doc - new_json_rule['corpus'] = corpus - new_json_rule['domain'] = domain - new_json_rule['name'] = name - new_json_rule['operator'] = operator - new_json_rule['argument'] = argument - - jtable_result['Result'] = 'OK' - jtable_result['Record'] = new_json_rule - return json.dumps(jtable_result) - except: - jtable_result['Result'] = 'Error' - jtable_result['Message'] = 'Something went wrong in jtable_create_rule.py' - return json.dumps(jtable_result) - - -print "Content-type:application/json\r\n\r\n" -print create_rule() diff --git a/modules/jtable_delete_rule.py b/modules/jtable_delete_rule.py deleted file mode 100755 index 0131d74..0000000 --- a/modules/jtable_delete_rule.py +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/env python -# -*- coding: UTF-8 -*- - -from gitdox_sql import * -import json -import cgi - - -def delete_rule(): - jtable_result = {} - try: - parameter = cgi.FieldStorage() - id = parameter.getvalue("id") - - delete_validate_rule(id) - - jtable_result['Result'] = 'OK' - return json.dumps(jtable_result) - except: - jtable_result['Result'] = 'Error' - jtable_result['Message'] = 'Something went wrong in jtable_delete_rule.py' - return json.dumps(jtable_result) - - -print "Content-type:application/json\r\n\r\n" -print delete_rule() \ No newline at end of file diff --git a/modules/jtable_rule_list.py b/modules/jtable_rule_list.py deleted file mode 100755 index bfee072..0000000 --- a/modules/jtable_rule_list.py +++ /dev/null @@ -1,44 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -from gitdox_sql import * -import json -import cgi - - -def list_rules(): - jtable_result = {} - try: - parameter = cgi.FieldStorage() - sort = parameter.getvalue("jtSorting") - domain_filter = parameter.getvalue("domain") - if sort is not None: - rules = get_sorted_rules(sort) - else: - rules = get_validate_rules() - - json_rules = [] - for rule in rules: - if domain_filter and rule[2] != domain_filter: - continue - - new_json_rule = {} - new_json_rule['corpus'] = rule[0] - new_json_rule['doc'] = rule[1] - new_json_rule['domain'] = rule[2] - new_json_rule['name'] = rule[3] - new_json_rule['operator'] = rule[4] - new_json_rule['argument'] = rule[5] - new_json_rule['id'] = rule[6] - json_rules.append(new_json_rule) - jtable_result['Result'] = 'OK' - jtable_result['Records'] = json_rules - return json.dumps(jtable_result) - except: - jtable_result['Result'] = 'Error' - jtable_result['Message'] = 'Something went wrong in jtable_rule_list.py' - return json.dumps(jtable_result) - - -print "Content-type:application/json\r\n\r\n" -print list_rules() diff --git a/modules/jtable_schema_list.py b/modules/jtable_schema_list.py deleted file mode 100755 index 30d0be9..0000000 --- a/modules/jtable_schema_list.py +++ /dev/null @@ -1,32 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -from gitdox_sql import * -import json -import cgi -import os - -schema_dir = (os.path.dirname(os.path.dirname(os.path.realpath(__file__))) - + os.sep - + 'schemas') - -def list_files(): - jtable_result = {} - ext = cgi.FieldStorage().getvalue("extension") - - try: - options = [{"DisplayText": x, - "Value": x} - for x in os.listdir(schema_dir) - if x.endswith(ext)] - jtable_result['Result'] = 'OK' - jtable_result['Options'] = options - return json.dumps(jtable_result) - except: - jtable_result['Result'] = 'Error' - jtable_result['Message'] = 'Something went wrong in jtable_xsd_list.py' - return json.dumps(jtable_result) - - -print "Content-type:application/json\r\n\r\n" -print list_files() diff --git a/modules/jtable_update_rule.py b/modules/jtable_update_rule.py deleted file mode 100755 index 6cf91f1..0000000 --- a/modules/jtable_update_rule.py +++ /dev/null @@ -1,32 +0,0 @@ -#!/usr/bin/env python -# -*- coding: UTF-8 -*- - -from gitdox_sql import * -import json -import cgi - - -def update_rules(): - jtable_result = {} - try: - parameter = cgi.FieldStorage() - doc = parameter.getvalue("doc") - corpus = parameter.getvalue("corpus") - domain = parameter.getvalue("domain") - name = parameter.getvalue("name") - operator = parameter.getvalue("operator") - argument = parameter.getvalue("argument") - id = parameter.getvalue("id") - - update_validate_rule(doc,corpus,domain,name,operator,argument,id) - - jtable_result['Result'] = 'OK' - return json.dumps(jtable_result) - except: - jtable_result['Result'] = 'Error' - jtable_result['Message'] = 'Something went wrong in jtable_update_rule.py' - return json.dumps(jtable_result) - - -print "Content-type:application/json\r\n\r\n" -print update_rules() \ No newline at end of file diff --git a/validation_rules_service.py b/validation_rules_service.py new file mode 100755 index 0000000..d435b91 --- /dev/null +++ b/validation_rules_service.py @@ -0,0 +1,134 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +import json +import cgi +import os +import platform +from modules.gitdox_sql import * +from modules.logintools import login + +parameter = cgi.FieldStorage() +action = parameter.getvalue("action") + +# for rules +doc = parameter.getvalue("doc") +corpus = parameter.getvalue("corpus") +domain = parameter.getvalue("domain") +name = parameter.getvalue("name") +operator = parameter.getvalue("operator") +argument = parameter.getvalue("argument") +id = parameter.getvalue("id") + +# for schemas +schema_dir = os.path.dirname(os.path.realpath(__file__)) + os.sep + 'schemas' +extension = parameter.getvalue("extension") + +# for sorting +sort = parameter.getvalue("jtSorting") + +def row_to_dict(row): + return {'corpus': row[0], + 'doc': row[1], + 'domain': row[2], + 'name': row[3], + 'operator': row[4], + 'argument': row[5], + 'id': row[6]} + +def list_rules(): + resp = {} + try: + parameter = cgi.FieldStorage() + rules = get_validate_rules(sort=sort, domain=domain) + + json_rules = [row_to_dict(row) for row in rules] + resp['Result'] = 'OK' + resp['Records'] = json_rules + print json.dumps(resp) + except: + resp['Result'] = 'Error' + resp['Message'] = 'Something went wrong while attempting to retrieve the list of rules.' + print json.dumps(resp) + +def create_rule(): + resp = {} + try: + id = create_validate_rule(doc, corpus, domain, name, operator, argument) + resp['Result'] = 'OK' + resp['Record'] = {'doc': doc, + 'corpus': corpus, + 'domain': domain, + 'name': name, + 'operator': operator, + 'argument': argument, + 'id': id} + print json.dumps(resp) + except: + resp['Result'] = 'Error' + resp['Message'] = 'Something went wrong while attempting to create a new rule.' + print json.dumps(resp) + +def update_rule(): + resp = {} + try: + update_validate_rule(doc, corpus, domain, name, operator, argument, id) + resp['Result'] = 'OK' + print json.dumps(resp) + except: + resp['Result'] = 'Error' + resp['Message'] = 'Something went wrong while attempting to update a rule.' + print json.dumps(resp) + +def delete_rule(): + resp = {} + try: + delete_validate_rule(id) + resp['Result'] = 'OK' + print json.dumps(resp) + except: + resp['Result'] = 'Error' + resp['Message'] = 'Something went wrong while trying to delete a rule.' + print json.dumps(resp) + + +def list_schemas(): + resp = {} + try: + resp['Result'] = 'OK' + resp['Options'] = [{"DisplayText": x, "Value": x} + for x in os.listdir(schema_dir) + if x.endswith(extension)] + print json.dumps(resp) + except: + resp['Result'] = 'Error' + resp['Message'] = 'Something went wrong while trying to list schemas.' + print json.dumps(resp) + +def open_main_server(): + thisscript = os.environ.get('SCRIPT_NAME', '') + loginaction = None + theform = cgi.FieldStorage() + scriptpath = os.path.dirname(os.path.realpath(__file__)) + os.sep + userdir = scriptpath + "users" + os.sep + loginaction, userconfig = login(theform, userdir, thisscript, loginaction) + user = userconfig["username"] + admin = userconfig["admin"] + + print "Content-type:application/json\r\n\r\n" + if action == "list": + list_rules() + elif action == "create": + create_rule() + elif action == "update": + update_rule() + elif action == "delete": + delete_rule() + elif action == "listschemas": + list_schemas() + else: + print json.dumps({'Result': 'Error', + 'Message': 'Unknown action: "' + str(action) + '"'}) + +if __name__ == '__main__': + open_main_server() From 15207c3fd72d33d2c8521b922302b97e289b6981 Mon Sep 17 00:00:00 2001 From: Luke Gessler Date: Wed, 31 Oct 2018 17:57:59 -0400 Subject: [PATCH 11/19] forbid demo user from making changes using jtables --- editor_metadata_service.py | 6 ++++-- validation_rules_service.py | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/editor_metadata_service.py b/editor_metadata_service.py index cb3cc88..f01a720 100755 --- a/editor_metadata_service.py +++ b/editor_metadata_service.py @@ -103,12 +103,14 @@ def open_main_server(): print "Content-type:application/json\r\n\r\n" if action == "list": get_metadata() + elif action == "keys": + get_default_key_options() + elif user == "demo": + print json.dumps({'Result': 'Error', 'Message': 'Demo user may not make changes.'}) elif action == "create": create_metadata() elif action == "delete": delete_metadata() - elif action == "keys": - get_default_key_options() else: print json.dumps({'Result': 'Error', 'Message': 'Unknown action: "' + str(action) + '"'}) diff --git a/validation_rules_service.py b/validation_rules_service.py index d435b91..07d058f 100755 --- a/validation_rules_service.py +++ b/validation_rules_service.py @@ -118,14 +118,16 @@ def open_main_server(): print "Content-type:application/json\r\n\r\n" if action == "list": list_rules() + elif action == "listschemas": + list_schemas() + elif user == "demo": + print json.dumps({'Result': 'Error', 'Message': 'Demo user may not make changes.'}) elif action == "create": create_rule() elif action == "update": update_rule() elif action == "delete": delete_rule() - elif action == "listschemas": - list_schemas() else: print json.dumps({'Result': 'Error', 'Message': 'Unknown action: "' + str(action) + '"'}) From 903492cb3d83283e1d2e50aa4add2644575bcb82 Mon Sep 17 00:00:00 2001 From: Luke Gessler Date: Wed, 31 Oct 2018 18:25:03 -0400 Subject: [PATCH 12/19] remember last opened tab --- js/editor.js | 21 ++++++++++++++++----- js/validation_rules.js | 21 ++++++++++++++++----- templates/editor.mustache | 4 ++-- templates/validation_rules.mustache | 8 ++++---- 4 files changed, 38 insertions(+), 16 deletions(-) diff --git a/js/editor.js b/js/editor.js index dfbb688..cb2a241 100755 --- a/js/editor.js +++ b/js/editor.js @@ -178,13 +178,24 @@ $(document).ready(function () { $(document).ready(function(){ - $('ul.tabs li').click(function(){ - var tab_id = $(this).attr('data-tab'); - + function activateTab(liId, divId) { $('ul.tabs li').removeClass('current'); $('.tab-content').removeClass('current'); + $("#"+liId).addClass('current'); + $("#"+divId).addClass('current'); + } + + var liId = localStorage.getItem(location.pathname + "activeLiId"); + var divId = localStorage.getItem(location.pathname + "activeDivId"); + if (liId && divId) { + activateTab(liId, divId); + } - $(this).addClass('current'); - $("#"+tab_id).addClass('current'); + $('ul.tabs li').click(function() { + var liId = $(this).attr('id'); + var divId = $(this).attr('data-tab'); + activateTab(liId, divId); + localStorage.setItem(location.pathname + "activeLiId", liId); + localStorage.setItem(location.pathname + "activeDivId", divId); }); }); diff --git a/js/validation_rules.js b/js/validation_rules.js index ee31ba5..fb13e11 100644 --- a/js/validation_rules.js +++ b/js/validation_rules.js @@ -219,13 +219,24 @@ $(document).ready(function () { }); $(document).ready(function(){ - $('ul.tabs li').click(function(){ - var tab_id = $(this).attr('data-tab'); - + function activateTab(liId, divId) { $('ul.tabs li').removeClass('current'); $('.tab-content').removeClass('current'); + $("#"+liId).addClass('current'); + $("#"+divId).addClass('current'); + } + + var liId = localStorage.getItem(location.pathname + "activeLiId"); + var divId = localStorage.getItem(location.pathname + "activeDivId"); + if (liId && divId) { + activateTab(liId, divId); + } - $(this).addClass('current'); - $("#"+tab_id).addClass('current'); + $('ul.tabs li').click(function() { + var liId = $(this).attr('id'); + var divId = $(this).attr('data-tab'); + activateTab(liId, divId); + localStorage.setItem(location.pathname + "activeLiId", liId); + localStorage.setItem(location.pathname + "activeDivId", divId); }); }); diff --git a/templates/editor.mustache b/templates/editor.mustache index d6c99c7..312bb6f 100644 --- a/templates/editor.mustache +++ b/templates/editor.mustache @@ -144,8 +144,8 @@ {{/ether_mode}}
    - - + +
diff --git a/templates/validation_rules.mustache b/templates/validation_rules.mustache index f954c83..9df0223 100644 --- a/templates/validation_rules.mustache +++ b/templates/validation_rules.mustache @@ -38,10 +38,10 @@

    - - - - + + + +
From 52f74e14374243b809a8ab02da7d05bc6cd3fc3f Mon Sep 17 00:00:00 2001 From: Luke Gessler Date: Wed, 31 Oct 2018 18:45:40 -0400 Subject: [PATCH 13/19] move div id=header into header template --- templates/admin.mustache | 4 +--- templates/editor.mustache | 4 +--- templates/header.mustache | 30 +++++++++++++++-------------- templates/index.mustache | 4 +--- templates/user_admin.mustache | 4 +--- templates/validation_rules.mustache | 4 +--- 6 files changed, 21 insertions(+), 29 deletions(-) diff --git a/templates/admin.mustache b/templates/admin.mustache index 24879b5..ba7fb60 100644 --- a/templates/admin.mustache +++ b/templates/admin.mustache @@ -27,9 +27,7 @@ {{{ navbar_html }}}
- + {{> header }}

GitDox - Administration

diff --git a/templates/editor.mustache b/templates/editor.mustache index 312bb6f..e224502 100644 --- a/templates/editor.mustache +++ b/templates/editor.mustache @@ -30,9 +30,7 @@ {{{navbar_html}}}

- + {{> header}}

GitDox: Edit

{{{ editor_help_link_html }}} diff --git a/templates/header.mustache b/templates/header.mustache index 2c359aa..1ab9b72 100644 --- a/templates/header.mustache +++ b/templates/header.mustache @@ -1,16 +1,18 @@ -