Kaynağa Gözat

add incude/exclude style filtering

Pi 1 yıl önce
ebeveyn
işleme
25531b2127
1 değiştirilmiş dosya ile 45 ekleme ve 18 silme
  1. 45 18
      app/rest/pyapi.py

+ 45 - 18
app/rest/pyapi.py

@@ -14,6 +14,12 @@ from ..activities.Plot import (
     get_data,
 )
 from ..data.QueryManager import QueryManager, display_mapper
+def get_include_exclude(value):
+    include, exclude, *_ = [
+            *map(lambda x: x.split('|') if x else [], value.split('!')), []
+    ]
+    return list(set(include)), list(set(exclude))
+
 def line(pivot, ylabel=None, xlabel=None):
     ax = sns.lineplot(data=pivot, markers=True)
     ax.set_xlabel(xlabel)
@@ -143,23 +149,32 @@ ORDER BY 1', false, false, ''::text)
 
 @route('/grocery/categories')
 def categories():
-    fields = { 'group': None }
+    fields = { 'group': ([],[]) }
     try:
         with conn.cursor() as cur:
             fields.update({
-                k: request.query[k] for k in request.query.keys() if k == 'group'
+                k: get_include_exclude(
+                    request.query[k]
+                ) for k in request.query.keys() if k == 'group'
             })
-            xml = cur.execute(SQL("""
-SELECT query_to_xml_and_xmlschema($$SELECT
+            inner = SQL("""
+SELECT
   c.name AS "Category",
   g.name AS "Group"
 FROM categories c
 JOIN groups g ON c.group_id = g.id
-WHERE g.name = COALESCE({group}, g.name)
-ORDER BY 1, 2$$, false, false, ''::text)
+WHERE
+  (g.name = ANY({group}) OR array_length({group}::text[], 1) IS NULL)
+AND
+  NOT g.name = ANY({ex_group})
+ORDER BY 1, 2
 """).format(
-  **{ k: Literal(v) for k,v in fields.items() }
-)).fetchone()[0].splitlines()
+  **{ k: Literal(i) for k, (i, _) in fields.items() },
+  **{ f'ex_{k}': Literal(e) for k, (_, e) in fields.items() }
+).as_string(cur)
+            xml = cur.execute(SQL("""
+SELECT query_to_xml_and_xmlschema({inner}, false, false, ''::text)
+""").format(inner=Literal(inner))).fetchone()[0].splitlines()
     finally:
         conn.commit()
     response.content_type = 'application/xhtml+xml; charset=utf-8'
@@ -168,16 +183,20 @@ ORDER BY 1, 2$$, false, false, ''::text)
 @route('/grocery/products')
 def products():
     fields = {
-        'group': None,
-        'category': None,
+        'group': ([],[]),
+        'category': ([],[]),
     }
     try:
         with conn.cursor() as cur:
             fields.update({
-                k: request.query[k] for k in request.query.keys() if k in ('group', 'category')
+                k: get_include_exclude(
+                    request.query[k]
+                ) for k in request.query.keys() if k in (
+                    'group', 'category'
+                )
             })
-            xml = cur.execute(SQL("""
-SELECT query_to_xml_and_xmlschema($$SELECT
+            inner = SQL("""
+SELECT
   p.name AS "Product",
   c.name AS "Category",
   g.name AS "Group"
@@ -185,13 +204,21 @@ FROM products p
 JOIN categories c ON p.category_id = c.id
 JOIN groups g ON c.group_id = g.id
 WHERE
-  g.name = COALESCE({group}, g.name)
+  (g.name = ANY({group}) OR array_length({group}::text[], 1) IS NULL)
+AND
+  NOT g.name = ANY({ex_group})
 AND
-  c.name = COALESCE({category}, c.name)
-ORDER BY 1, 2, 3$$, false, false, ''::text)
+  (c.name = ANY({category}) OR array_length({category}::text[], 1) IS NULL)
+AND
+  NOT c.name = ANY({ex_category})
+ORDER BY 1, 2, 3
 """).format(
-  **{ k: Literal(v) for k,v in fields.items() }
-)).fetchone()[0].splitlines()
+  **{ k: Literal(i) for k, (i, _) in fields.items() },
+  **{ f'ex_{k}': Literal(e) for k, (_, e) in fields.items() }
+).as_string(cur)
+            xml = cur.execute(SQL("""
+SELECT query_to_xml_and_xmlschema({inner}, false, false, ''::text)
+""").format(inner=Literal(inner))).fetchone()[0].splitlines()
     finally:
         conn.commit()
     response.content_type = 'application/xhtml+xml; charset=utf-8'