diff --git a/app/Gulag.py b/app/Gulag.py index 0934229..d87a0ca 100644 --- a/app/Gulag.py +++ b/app/Gulag.py @@ -59,7 +59,8 @@ class Gulag: for arg in args: if(arg == 'query_offset' or arg == 'query_limit' or arg == 'sort_index' or arg == 'sort_order' - or arg == 'rfc822_message' or arg == 'filters'): + or arg == 'rfc822_message' or arg == 'filters' + or arg in self.db.vcols): continue if arg not in self.fields[fields_target]: raise GulagException( diff --git a/app/GulagDB.py b/app/GulagDB.py index 71c5820..84f40ab 100644 --- a/app/GulagDB.py +++ b/app/GulagDB.py @@ -15,7 +15,7 @@ class GulagDBException(Exception): class GulagDB: conn = None uri_prefixes = None - vcols = None + vcols = {} def __init__(self, args, uri_prefixes): try: @@ -35,12 +35,12 @@ class GulagDB: database=args['name'], autocommit=True ) - self.uri_prefixes = uri_prefixes - # virtual columns cannot not be stated in where-clause - self.vcols['attach_count'] = {} - self.vcols['uri_count'] = {} except mariadb.Error as e: raise GulagDBException(whoami(self) + str(e)) from e + self.uri_prefixes = uri_prefixes + # virtual columns cannot not be stated in where-clause + self.vcols['attach_count'] = {} + self.vcols['uri_count'] = {} def close(self): self.conn.close() @@ -108,34 +108,36 @@ class GulagDB: cnt += 1 return where_clause -def get_where_clause_from_filters(self,filters_json): - # {"groupOp":"AND","rules":[{"field":"available","op":"eq","data":"true"}]} - filters = None - where_clause = "" - try: - filters = json.loads(filters_json) - except json.JSONDecodeError as e: - raise GulagDBException(whoami(self) + "JSON parse error: " + e.msg) from e - for rule in filters['rules']: - field_op_data = None - if(rule['op'] == 'eq'): - field_op_data = rule['field'] + "='" + rule['data'] + "'" - elif(rule['op'] == 'bw'): - field_op_data = rule['field'] + " like '" + rule['data'] + "%'" - elif(rule['op'] == 'ew'): - field_op_data = rule['field'] + " like '%" + rule['data'] + "'" - elif(rule['op'] == 'cn'): - field_op_data = rule['field'] + " like '%" + rule['data'] + "%'" - if(field_op_data == None): - raise GulagDBException(whoami(self) + "invalid rule-op: " + rule['op']) - if(len(filters['rules']) == 1 or len(where_clause) == 0): - if rule['field'] in self.vcols: - where_clause = "having " + field_op_data + def get_where_clause_from_filters(self,filters_json): + # {"groupOp":"AND","rules":[{"field":"uri_count","op":"eq","data":"3"}]} + filters = None + where_clause = "" + try: + filters = json.loads(filters_json) + except json.JSONDecodeError as e: + raise GulagDBException(whoami(self) + "JSON parse error: " + e.msg) from e + for rule in filters['rules']: + field_op_data = None + if(rule['op'] == 'eq'): + field_op_data = rule['field'] + "='" + rule['data'] + "'" + elif(rule['op'] == 'bw'): + field_op_data = rule['field'] + " like '" + rule['data'] + "%'" + elif(rule['op'] == 'ew'): + field_op_data = rule['field'] + " like '%" + rule['data'] + "'" + elif(rule['op'] == 'cn'): + field_op_data = rule['field'] + " like '%" + rule['data'] + "%'" + elif(rule['op'] == 'ne'): + field_op_data = rule['field'] + " <>'" + rule['data'] + "'" + if(field_op_data == None): + raise GulagDBException(whoami(self) + "invalid rule-op: " + rule['op']) + if(len(filters['rules']) == 1 or len(where_clause) == 0): + if rule['field'] in self.vcols: + where_clause = "having " + field_op_data + else: + where_clause = "where " + field_op_data else: - where_clause = "where " + field_op_data - else: - where_clause += " " + filters['groupOp'] + " " + field_op_data - return where_clause + where_clause += " " + filters['groupOp'] + " " + field_op_data + return where_clause def get_mailboxes(self): try: diff --git a/app/Resources.py b/app/Resources.py index 6c07c82..affe269 100644 --- a/app/Resources.py +++ b/app/Resources.py @@ -89,7 +89,7 @@ class ResQuarMailAttachment(GulagResource): abort(400, message=e.message) class ResQuarMailURIs(GulagResource): - def get(self,quarmail_id): + def get(self,quarmail_id): args = { "quarmail_id": quarmail_id } @@ -125,4 +125,3 @@ class ResRSPAMDImporter(GulagResource): return {"resource: ": "HTTP2IMAP for RSPAMD"} except GulagException as e: abort(400, message=e.message) - diff --git a/gulag-openapi-2.0.yaml b/gulag-openapi-2.0.yaml index 68680ac..ad06330 100644 --- a/gulag-openapi-2.0.yaml +++ b/gulag-openapi-2.0.yaml @@ -118,6 +118,11 @@ paths: type: string required: false description: get full RFC822 email message for each QuarMail object + - in: query + name: filters + type: string + required: false + description: jqgrid-style search filter responses: 200: description: search results matching criteria