From be2b765141c03f3251764863a3f12eb7cf98652f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Ignacio=20S=C3=A1nchez?= Date: Wed, 23 Dec 2020 22:20:37 -0300 Subject: [PATCH 1/6] add translator between a predefined grammar and django's filter lookups --- Pipfile | 1 + Pipfile.lock | 115 ++++++++++++++++++++++++++++--------------- grammar/__init__.py | 0 grammar/grammar.lark | 26 ++++++++++ grammar/parser.py | 55 +++++++++++++++++++++ grammar/tests.py | 38 ++++++++++++++ testsettings.py | 1 + 7 files changed, 196 insertions(+), 40 deletions(-) create mode 100644 grammar/__init__.py create mode 100644 grammar/grammar.lark create mode 100644 grammar/parser.py create mode 100644 grammar/tests.py diff --git a/Pipfile b/Pipfile index d1b16cb..d27fa6c 100644 --- a/Pipfile +++ b/Pipfile @@ -48,6 +48,7 @@ sphinx-rtd-theme = "*" [packages] Django = "==3.0.7" apscheduler = "*" +lark-parser = "*" [requires] python_version = "3.8" diff --git a/Pipfile.lock b/Pipfile.lock index e07e4c3..c6e3138 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "f20848f1c65336760f49dc339b1d90c8026e8a17ceca4092c922d3b4b24ca842" + "sha256": "d72f9f46a769b0fa0ae53f2244b7bfb3a33617d7aeab2255cb6dd4ab2502cfb9" }, "pipfile-spec": 6, "requires": { @@ -26,10 +26,11 @@ }, "asgiref": { "hashes": [ - "sha256:a5098bc870b80e7b872bff60bb363c7f2c2c89078759f6c47b53ff8c525a152e", - "sha256:cd88907ecaec59d78e4ac00ea665b03e571cb37e3a0e37b3702af1a9e86c365a" + "sha256:5ee950735509d04eb673bd7f7120f8fa1c9e2df495394992c73234d526907e17", + "sha256:7162a3cb30ab0609f1a4c95938fd73e8604f63bdba516a7f7d64b83ff09478f0" ], - "version": "==3.3.0" + "markers": "python_version >= '3.5'", + "version": "==3.3.1" }, "django": { "hashes": [ @@ -39,18 +40,27 @@ "index": "pypi", "version": "==3.0.7" }, + "lark-parser": { + "hashes": [ + "sha256:20bdefdf1b6e9bcb38165ea5cc4f27921a99c6f4c35264a3a953fd60335f1f8c", + "sha256:8b747e1f544dcc2789e3feaddd2a50c6a73bed69d62e9c69760c1e1f7d23495f" + ], + "index": "pypi", + "version": "==0.11.1" + }, "pytz": { "hashes": [ - "sha256:a494d53b6d39c3c6e44c3bec237336e14305e4f29bbf800b599253057fbb79ed", - "sha256:c35965d010ce31b23eeb663ed3cc8c906275d6be1a34393a1d73a41febf4a048" + "sha256:3e6b7dd2d1e0a59084bcee14a17af60c5c562cdc16d828e8eba2e683d3a7e268", + "sha256:5c55e189b682d420be27c6995ba6edce0c0a77dd67bfbe2ae6607134d5851ffd" ], - "version": "==2020.1" + "version": "==2020.4" }, "six": { "hashes": [ "sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259", "sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced" ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==1.15.0" }, "sqlparse": { @@ -58,6 +68,7 @@ "sha256:017cde379adbd6a1f15a61873f43e8274179378e95ef3fede90b5aa64d304ed0", "sha256:0f91fd2e829c44362cbcfab3e9ae12e22badaa8a29ad5ff599f9ec109f0454e8" ], + "markers": "python_version >= '3.5'", "version": "==0.4.1" }, "tzlocal": { @@ -86,10 +97,11 @@ }, "asgiref": { "hashes": [ - "sha256:a5098bc870b80e7b872bff60bb363c7f2c2c89078759f6c47b53ff8c525a152e", - "sha256:cd88907ecaec59d78e4ac00ea665b03e571cb37e3a0e37b3702af1a9e86c365a" + "sha256:5ee950735509d04eb673bd7f7120f8fa1c9e2df495394992c73234d526907e17", + "sha256:7162a3cb30ab0609f1a4c95938fd73e8604f63bdba516a7f7d64b83ff09478f0" ], - "version": "==3.3.0" + "markers": "python_version >= '3.5'", + "version": "==3.3.1" }, "astroid": { "hashes": [ @@ -108,10 +120,11 @@ }, "babel": { "hashes": [ - "sha256:1aac2ae2d0d8ea368fa90906567f5c08463d98ade155c0c4bfedd6a0f7160e38", - "sha256:d670ea0b10f8b723672d3a6abeb87b565b244da220d76b4dba1b66269ec152d4" + "sha256:9d35c22fcc79893c3ecc85ac4a56cde1ecf3f19c540bba0922308a6c06ca6fa5", + "sha256:da031ab54472314f210b0adcff1588ee5d1d1d0ba4dbd07b94dba82bde791e05" ], - "version": "==2.8.0" + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==2.9.0" }, "backcall": { "hashes": [ @@ -126,27 +139,30 @@ "sha256:52b5919b81842b1854196eaae5ca29679a2f2e378905c346d3ca8227c2c66080", "sha256:9f8ccbeb6183c6e6cddea37592dfb0167485c1e3b13b3363bc325aa8bda3adbd" ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", "version": "==3.2.1" }, "certifi": { "hashes": [ - "sha256:5930595817496dd21bb8dc35dad090f1c2cd0adfaf21204bf6732ca5d8ee34d3", - "sha256:8fc0819f1f30ba15bdb34cceffb9ef04d99f420f68eb75d901e9560b8749fc41" + "sha256:1a4995114262bffbc2413b159f2a1a480c969de6e6eb13ee966d470af86af59c", + "sha256:719a74fb9e33b9bd44cc7f3a8d94bc35e4049deebe19ba7d8e108280cfd59830" ], - "version": "==2020.6.20" + "version": "==2020.12.5" }, "chardet": { "hashes": [ - "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae", - "sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691" + "sha256:0d6f53a15db4120f2b08c94f11e7d93d2c911ee118b6b30a04ec3ee8310179fa", + "sha256:f864054d66fd9118f2e67044ac8981a54775ec5b67aed0441892edb553d21da5" ], - "version": "==3.0.4" + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", + "version": "==4.0.0" }, "colorama": { "hashes": [ "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b", "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2" ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", "version": "==0.4.4" }, "decorator": { @@ -178,6 +194,7 @@ "sha256:b307872f855b18632ce0c21c5e45be78c0ea7ae4c15c828c20788b26921eb3f6", "sha256:b97d804b1e9b523befed77c48dacec60e6dcb0b5391d57af6a65a312a90648c0" ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==2.10" }, "imagesize": { @@ -185,6 +202,7 @@ "sha256:6965f19a6a2039c7d48bca7dba2473069ff854c36ae6f19d2cde309d998228a1", "sha256:b1f6b5a4eab1f73479a50fb79fcf729514a900c341d8503d62a62dbc4127a2b1" ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==1.2.0" }, "importlib-metadata": { @@ -244,10 +262,11 @@ }, "keyring": { "hashes": [ - "sha256:4e34ea2fdec90c1c43d6610b5a5fafa1b9097db1802948e90caf5763974b8f8d", - "sha256:9aeadd006a852b78f4b4ef7c7556c2774d2432bbef8ee538a3e9089ac8b11466" + "sha256:4c41ce4f6d1ee91d589a346699ef5a94ba3429603ac8f700cc0097644cdd6748", + "sha256:a144f7e1044c897c3976202af868cb0ac860f4d433d5d0f8e750fa1a2f0f0b50" ], - "version": "==21.4.0" + "markers": "python_version >= '3.6'", + "version": "==21.7.0" }, "lazy-object-proxy": { "hashes": [ @@ -325,10 +344,11 @@ }, "packaging": { "hashes": [ - "sha256:4357f74f47b9c12db93624a82154e9b120fa8293699949152b22065d556079f8", - "sha256:998416ba6962ae7fbd6596850b80e17859a5753ba17c32284f67bfff33784181" + "sha256:24e0da08660a87484d1602c30bb4902d74816b6985b93de36926f5bc95741858", + "sha256:78598185a7008a470d64526a8059de9aaa449238f280fc9eb6b13ba6c4109093" ], - "version": "==20.4" + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==20.8" }, "parso": { "hashes": [ @@ -414,14 +434,15 @@ "sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1", "sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b" ], + "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==2.4.7" }, "pytz": { "hashes": [ - "sha256:a494d53b6d39c3c6e44c3bec237336e14305e4f29bbf800b599253057fbb79ed", - "sha256:c35965d010ce31b23eeb663ed3cc8c906275d6be1a34393a1d73a41febf4a048" + "sha256:3e6b7dd2d1e0a59084bcee14a17af60c5c562cdc16d828e8eba2e683d3a7e268", + "sha256:5c55e189b682d420be27c6995ba6edce0c0a77dd67bfbe2ae6607134d5851ffd" ], - "version": "==2020.1" + "version": "==2020.4" }, "readme-renderer": { "hashes": [ @@ -432,10 +453,11 @@ }, "requests": { "hashes": [ - "sha256:b3559a131db72c33ee969480840fff4bb6dd111de7dd27c8ee1f820f4f00231b", - "sha256:fe75cc94a9443b9246fc7049224f75604b113c36acb93f87b80ed42c44cbb898" + "sha256:27973dd4a904a4f13b263a19c866c13b92a39ed1c964655f025f3f8d3d75b804", + "sha256:c210084e36a42ae6b9219e00e48287def368a26d03a048ddad7bfee44f75871e" ], - "version": "==2.24.0" + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", + "version": "==2.25.1" }, "requests-toolbelt": { "hashes": [ @@ -456,6 +478,7 @@ "sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259", "sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced" ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==1.15.0" }, "snowballstemmer": { @@ -467,11 +490,11 @@ }, "sphinx": { "hashes": [ - "sha256:321d6d9b16fa381a5306e5a0b76cd48ffbc588e6340059a729c6fdd66087e0e8", - "sha256:ce6fd7ff5b215af39e2fcd44d4a321f6694b4530b6f2b2109b64d120773faea0" + "sha256:4dcde313801f23ea4789ac31e5405e240cb758b5d375804807f2f3cc3c396bfa", + "sha256:77c801947eb86457822e01eadd5c2e2de020db0201f1f9fc98b0927980b6d212" ], "index": "pypi", - "version": "==3.2.1" + "version": "==3.4.0" }, "sphinx-rtd-theme": { "hashes": [ @@ -486,6 +509,7 @@ "sha256:806111e5e962be97c29ec4c1e7fe277bfd19e9652fb1a4392105b43e01af885a", "sha256:a072735ec80e7675e3f432fcae8610ecf509c5f1869d17e2eecff44389cdbc58" ], + "markers": "python_version >= '3.5'", "version": "==1.0.2" }, "sphinxcontrib-devhelp": { @@ -493,6 +517,7 @@ "sha256:8165223f9a335cc1af7ffe1ed31d2871f325254c0423bc0c4c7cd1c1e4734a2e", "sha256:ff7f1afa7b9642e7060379360a67e9c41e8f3121f2ce9164266f61b9f4b338e4" ], + "markers": "python_version >= '3.5'", "version": "==1.0.2" }, "sphinxcontrib-django": { @@ -508,6 +533,7 @@ "sha256:3c0bc24a2c41e340ac37c85ced6dafc879ab485c095b1d65d2461ac2f7cca86f", "sha256:e8f5bb7e31b2dbb25b9cc435c8ab7a79787ebf7f906155729338f3156d93659b" ], + "markers": "python_version >= '3.5'", "version": "==1.0.3" }, "sphinxcontrib-jsmath": { @@ -515,6 +541,7 @@ "sha256:2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178", "sha256:a9925e4a4587247ed2191a22df5f6970656cb8ca2bd6284309578f2153e0c4b8" ], + "markers": "python_version >= '3.5'", "version": "==1.0.1" }, "sphinxcontrib-qthelp": { @@ -522,6 +549,7 @@ "sha256:4c33767ee058b70dba89a6fc5c1892c0d57a54be67ddd3e7875a18d14cba5a72", "sha256:bd9fc24bcb748a8d51fd4ecaade681350aa63009a347a8c14e637895444dfab6" ], + "markers": "python_version >= '3.5'", "version": "==1.0.3" }, "sphinxcontrib-serializinghtml": { @@ -529,6 +557,7 @@ "sha256:eaa0eccc86e982a9b939b2b82d12cc5d013385ba5eadcc7e4fed23f4405f77bc", "sha256:f242a81d423f59617a8e5cf16f5d4d74e28ee9a66f9e5b637a18082991db5a9a" ], + "markers": "python_version >= '3.5'", "version": "==1.1.4" }, "sqlparse": { @@ -536,6 +565,7 @@ "sha256:017cde379adbd6a1f15a61873f43e8274179378e95ef3fede90b5aa64d304ed0", "sha256:0f91fd2e829c44362cbcfab3e9ae12e22badaa8a29ad5ff599f9ec109f0454e8" ], + "markers": "python_version >= '3.5'", "version": "==0.4.1" }, "toml": { @@ -548,10 +578,11 @@ }, "tqdm": { "hashes": [ - "sha256:9ad44aaf0fc3697c06f6e05c7cf025dd66bc7bcb7613c66d85f4464c47ac8fad", - "sha256:ef54779f1c09f346b2b5a8e5c61f96fbcb639929e640e59f8cf810794f406432" + "sha256:38b658a3e4ecf9b4f6f8ff75ca16221ae3378b2e175d846b6b33ea3a20852cf5", + "sha256:d4f413aecb61c9779888c64ddf0c62910ad56dcbe857d8922bb505d4dbff0df1" ], - "version": "==4.51.0" + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==4.54.1" }, "traitlets": { "hashes": [ @@ -584,6 +615,7 @@ "sha256:6daac9731f172c2a22ade6ed0c00197ee7cc1221aa84cfdf9c31defeb059a907", "sha256:715ff2f2df46121071622063fc7543d9b1fd19ebfc4f5c8895af64a77a8c852c", "sha256:73d785a950fc82dd2a25897d525d003f6378d1cb23ab305578394694202a58c3", + "sha256:7e4c9d7658aaa1fc80018593abdf8598bf91325af6af5cce4ce7c73bc45ea53d", "sha256:8c8aaad94455178e3187ab22c8b01a3837f8ee50e09cf31f1ba129eb293ec30b", "sha256:8ce678dbaf790dbdb3eba24056d5364fb45944f33553dd5869b7580cdbb83614", "sha256:92c325624e304ebf0e025d1224b77dd4e6393f18aab8d829b5b7e04afe9b7a2c", @@ -595,8 +627,10 @@ "sha256:d43943ef777f9a1c42bf4e552ba23ac77a6351de620aa9acf64ad54933ad4d34", "sha256:d5d33e9e7af3b34a40dc05f498939f0ebf187f07c385fd58d591c533ad8562fe", "sha256:d648b8e3bf2fe648745c8ffcee3db3ff903d0817a01a12dd6a6ea7a8f4889072", + "sha256:f208eb7aff048f6bea9586e61af041ddf7f9ade7caed625742af423f6bae3298", "sha256:fac11badff8313e23717f3dada86a15389d0708275bddf766cca67a84ead3e91", "sha256:fc0fea399acb12edbf8a628ba8d2312f583bdbdb3335635db062fa98cf71fca4", + "sha256:fcf135e17cc74dbfbc05894ebca928ffeb23d9790b3167a674921db19082401f", "sha256:fe460b922ec15dd205595c9b5b99e2f056fd98ae8f9f56b888e7a17dc2b757e7" ], "index": "pypi", @@ -604,10 +638,11 @@ }, "urllib3": { "hashes": [ - "sha256:8d7eaa5a82a1cac232164990f04874c594c9453ec55eef02eab885aa02fc17a2", - "sha256:f5321fbe4bf3fefa0efd0bfe7fb14e90909eb62a48ccda331726b4319897dd5e" + "sha256:19188f96923873c92ccb987120ec4acaa12f0461fa9ce5d3d0772bc965a39e08", + "sha256:d8ff90d979214d7b4f8ce956e80f4028fc6860e4431f731ea4a8c08f23f99473" ], - "version": "==1.25.11" + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' and python_version < '4'", + "version": "==1.26.2" }, "wcwidth": { "hashes": [ diff --git a/grammar/__init__.py b/grammar/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/grammar/grammar.lark b/grammar/grammar.lark new file mode 100644 index 0000000..346b042 --- /dev/null +++ b/grammar/grammar.lark @@ -0,0 +1,26 @@ +start : query + | expression + +query : "("* expression ")"* + | query CONNECTOR query + +expression : computed OPERATOR atom + +computed : FIELD + | computed "." computed + +atom : "True" -> true + | "False" -> false + | NUMBER + | WORD + | ESCAPED_STRING -> string + +CONNECTOR : "and" | "or" +FIELD : (WORD | "_")+ +OPERATOR : "<" | "<=" | "==" | ">=" | ">" | "null" | "is" + + +%import common.WORD +%import common.NUMBER +%import common.ESCAPED_STRING +%ignore " " \ No newline at end of file diff --git a/grammar/parser.py b/grammar/parser.py new file mode 100644 index 0000000..e48034b --- /dev/null +++ b/grammar/parser.py @@ -0,0 +1,55 @@ +from lark import Lark, Transformer + + +class DjangoQueriesTransformer(Transformer): + """ + Applies multiple transformations over the parsed tree + """ + def start(self, tree): + return tree[0] + + def OPERATOR(self, tree): + operator_map = { + ">": "__gt", + "<": "__lt", + "==": "__eq", + "is": "", + "null": "__isnull", + } + return operator_map[tree.value] + + def atom(self, a): + (a,) = a + return a.value + + def query(self, tree): + if len(tree) == 3: + return {**tree[0], **tree[2]} + else: + return tree[0] + + def expression(self, tree): + return {"".join(tree[:2]): tree[2]} + + def computed(self, tree): + return "__".join(tree) + + def string(self, s): + (s,) = s + return s.strip('"') + + def true(self, _): + return True + + def false(self, _): + return False + + +def translate_query(expression, grammar): + lexer = Lark(grammar) + + parse_tree = lexer.parse(expression, start="start") + query_dict = DjangoQueriesTransformer( + visit_tokens=True + ).transform(parse_tree) + return query_dict diff --git a/grammar/tests.py b/grammar/tests.py new file mode 100644 index 0000000..b9c8934 --- /dev/null +++ b/grammar/tests.py @@ -0,0 +1,38 @@ +from pathlib import Path + +from django.test import TestCase +from drip.models import Drip + +from .parser import translate_query + + +class GrammarTest(TestCase): + def test_grammar(self): + grammar = Path(Path(__file__).parent, "grammar.lark").open() + grammar = "".join(grammar.readlines()) + + drip1 = Drip(name="Nacho's Drip").save() + drip2 = Drip(name="Nice Drip").save() + drip3 = Drip(name="Not so nice").save() + + input_expression = "(enabled is False)" \ + "and (sent_drips null True)" \ + "and (name is \"Nacho's Drip\")" + filter = translate_query(input_expression, grammar) + assert Drip.objects.filter(**filter).count() == 1 + + input_expression = "enabled is False" + filter = translate_query(input_expression, grammar) + assert Drip.objects.filter(**filter).count() == 3 + + input_expression = "(enabled is False) and (name is \"Not so nice\")" + filter = translate_query(input_expression, grammar) + assert Drip.objects.filter(**filter).count() == 1 + + input_expression = "(enabled is False) and (sent_drips null True)" + filter = translate_query(input_expression, grammar) + assert Drip.objects.filter(**filter).count() == 3 + + input_expression = "(enabled is False) and (sent_drips null False)" + filter = translate_query(input_expression, grammar) + assert Drip.objects.filter(**filter).count() == 0 diff --git a/testsettings.py b/testsettings.py index 0998dee..d829186 100755 --- a/testsettings.py +++ b/testsettings.py @@ -20,6 +20,7 @@ 'django.contrib.messages', 'drip', + 'grammar', # testing only 'credits', From ac849e2e6fea1afc5433f26e829dcfbb7328a2d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Ignacio=20S=C3=A1nchez?= Date: Wed, 23 Dec 2020 22:29:32 -0300 Subject: [PATCH 2/6] remove unused variables --- grammar/tests.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/grammar/tests.py b/grammar/tests.py index b9c8934..5c50ec0 100644 --- a/grammar/tests.py +++ b/grammar/tests.py @@ -11,9 +11,9 @@ def test_grammar(self): grammar = Path(Path(__file__).parent, "grammar.lark").open() grammar = "".join(grammar.readlines()) - drip1 = Drip(name="Nacho's Drip").save() - drip2 = Drip(name="Nice Drip").save() - drip3 = Drip(name="Not so nice").save() + Drip(name="Nacho's Drip").save() + Drip(name="Nice Drip").save() + Drip(name="Not so nice").save() input_expression = "(enabled is False)" \ "and (sent_drips null True)" \ From 3b903f0a7e587c8bd2237097a1701fe138a7e6a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Ignacio=20S=C3=A1nchez?= Date: Fri, 8 Jan 2021 09:50:37 -0300 Subject: [PATCH 3/6] add lark-parser to install_requires in setup.py --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 0fb1878..444f080 100755 --- a/setup.py +++ b/setup.py @@ -20,7 +20,7 @@ author = 'Kalil de Lima' author_email = 'kalil@rootstrap.com' license = 'MIT' -install_requires = ['Django>=2.2', 'apscheduler'] +install_requires = ['Django>=2.2', 'apscheduler', 'lark-parser'] keywords = 'django drip email user query' From 8cfa140d3f9948c7793f8de2520824a9a776d493 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Ignacio=20S=C3=A1nchez?= Date: Fri, 8 Jan 2021 10:48:24 -0300 Subject: [PATCH 4/6] add setup.py to .travis.yml --- .travis.yml | 8 +++----- tests/test_travis_config.py | 6 ++++++ 2 files changed, 9 insertions(+), 5 deletions(-) create mode 100644 tests/test_travis_config.py diff --git a/.travis.yml b/.travis.yml index 8e4761b..f6bde78 100755 --- a/.travis.yml +++ b/.travis.yml @@ -10,14 +10,11 @@ python: - "pypy3" -env: - global: - - CC_TEST_REPORTER_ID - - env: - DJANGO_VERSION="2.2" - DJANGO_VERSION="3.0.7" + global: + - CC_TEST_REPORTER_ID install: @@ -25,6 +22,7 @@ install: - pip3 install Sphinx - pip3 install flake8 - pip install coverage + - python setup.py -q install script: diff --git a/tests/test_travis_config.py b/tests/test_travis_config.py new file mode 100644 index 0000000..27ca50d --- /dev/null +++ b/tests/test_travis_config.py @@ -0,0 +1,6 @@ +from django.test import TestCase + + +class TravisTestCase(TestCase): + pass + From 5008f288adb53269a34305105dbee1b69cb7c9f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Ignacio=20S=C3=A1nchez?= Date: Mon, 8 Feb 2021 11:56:19 -0300 Subject: [PATCH 5/6] fix travis config & install lark-parser --- .travis.yml | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index f6bde78..c78eb0a 100755 --- a/.travis.yml +++ b/.travis.yml @@ -11,25 +11,28 @@ python: env: - - DJANGO_VERSION="2.2" - - DJANGO_VERSION="3.0.7" global: - CC_TEST_REPORTER_ID +env: + - DJANGO_VERSION="2.2" + - DJANGO_VERSION="3.0.7" + + install: - pip3 install "Django==${DJANGO_VERSION}" - pip3 install Sphinx - pip3 install flake8 - - pip install coverage - - python setup.py -q install - + - pip3 install coverage + - pip3 install lark-parser script: # makemigrations of each app is needed - python manage.py makemigrations drip - python manage.py makemigrations credits - python manage.py makemigrations auth + - python manage.py makemigrations grammar - python manage.py migrate - flake8 . - coverage run manage.py test From e1b96a53a5c56405b65abde480219c4973107469 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Ignacio=20S=C3=A1nchez?= Date: Mon, 8 Feb 2021 11:59:39 -0300 Subject: [PATCH 6/6] remove unused test case --- tests/test_travis_config.py | 6 ------ 1 file changed, 6 deletions(-) delete mode 100644 tests/test_travis_config.py diff --git a/tests/test_travis_config.py b/tests/test_travis_config.py deleted file mode 100644 index 27ca50d..0000000 --- a/tests/test_travis_config.py +++ /dev/null @@ -1,6 +0,0 @@ -from django.test import TestCase - - -class TravisTestCase(TestCase): - pass -