From f41ee56650f518c17acfe93f548088903040f74f Mon Sep 17 00:00:00 2001 From: absurdo Date: Wed, 20 Dec 2023 00:06:50 +0100 Subject: [PATCH 01/85] Added language files for welcome and libraries --- .../languages/es-ES/LC_MESSAGES/libraries.mo | Bin 0 -> 733 bytes .../languages/es-ES/LC_MESSAGES/libraries.po | 59 ++++++++++++++++++ paramecio2/libraries/languages/libraries.mo | Bin 0 -> 733 bytes paramecio2/libraries/languages/libraries.po | 59 ++++++++++++++++++ .../languages/es-ES/LC_MESSAGES/welcome.mo | Bin 0 -> 526 bytes .../languages/es-ES/LC_MESSAGES/welcome.po | 30 +++++++++ .../modules/welcome/languages/welcome.mo | Bin 0 -> 424 bytes .../modules/welcome/languages/welcome.po | 22 +++++++ 8 files changed, 170 insertions(+) create mode 100644 paramecio2/libraries/languages/es-ES/LC_MESSAGES/libraries.mo create mode 100644 paramecio2/libraries/languages/es-ES/LC_MESSAGES/libraries.po create mode 100644 paramecio2/libraries/languages/libraries.mo create mode 100644 paramecio2/libraries/languages/libraries.po create mode 100644 paramecio2/modules/welcome/languages/es-ES/LC_MESSAGES/welcome.mo create mode 100644 paramecio2/modules/welcome/languages/es-ES/LC_MESSAGES/welcome.po create mode 100644 paramecio2/modules/welcome/languages/welcome.mo create mode 100644 paramecio2/modules/welcome/languages/welcome.po diff --git a/paramecio2/libraries/languages/es-ES/LC_MESSAGES/libraries.mo b/paramecio2/libraries/languages/es-ES/LC_MESSAGES/libraries.mo new file mode 100644 index 0000000000000000000000000000000000000000..63d66dae3fac0abbf07594ba202aca312b4482d1 GIT binary patch literal 733 zcmYk2J#W-N5QY~BUj{@15*0$*(17-^FDVj7DelM-PRc1(Fdr4tV$V4Xce|(EbrK3X zI%+B^XsM9+2Wcpf_y_zATHf_J93zb%zuujh*Yo?v(np54g1n9N$Q9&IWQgT6j9mp+ zzzg6Va0$E%UIy>AdJVh?y#byFd*F3&2Ml%3Tm2IJ1FgYZ;P~wP{9ViUV5s}h>QCS$ z=r1k5f;XYRx92~=YtX+yv}`;DAK`yaBWhoQ@6$Mk7nC$!gTFANiC$T9O-EdLnzC)0 zkS8`Mm2V#NuaC`?*xt-5qaDj+MUL&$jHKt8bneL5l06}5ivyNR_lCQ=D9E{SJz<$O zuc`22Sc+$49U7!OLani0j9jHk(XT5fa)Zy=p4g{D6)uTw=_%#ixVtKnu1Gd`9H((| zKThH}+Lg|W+)C{x(i@A)U8$=YwnR>H`kziYxo9*T4HmZn+LK0)w=)d!bnG9@ zCQ|85UK~j4$ZtK(ABpwFy)bJ`Rt$7uN~NomufI}0dLed5lbxH$3}I<}wX@bqBGx~^m<0ShFI4r6F literal 0 HcmV?d00001 diff --git a/paramecio2/libraries/languages/es-ES/LC_MESSAGES/libraries.po b/paramecio2/libraries/languages/es-ES/LC_MESSAGES/libraries.po new file mode 100644 index 0000000..cd10b26 --- /dev/null +++ b/paramecio2/libraries/languages/es-ES/LC_MESSAGES/libraries.po @@ -0,0 +1,59 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2023-12-18 23:51+0100\n" +"PO-Revision-Date: 2023-12-19 00:01+0100\n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 3.4.1\n" + +#: formsutils.py:183 +msgid "Repeat Password" +msgstr "Repetir contraseña" + +#: lists.py:113 +msgid "Options" +msgstr "Opciones" + +#: lists.py:222 generate_admin_class.py:304 +msgid "Edit" +msgstr "Editar" + +#: lists.py:223 +msgid "Delete" +msgstr "Borrar" + +#: lists.py:395 templates/utils/list.phtml:133 +msgid "Pages" +msgstr "Páginas" + +#: generate_admin_class.py:82 generate_admin_class.py:288 +msgid "Home" +msgstr "Inicio" + +#: generate_admin_class.py:112 generate_admin_class.py:155 +msgid "Add new item" +msgstr "Añadir nuevo elemento" + +#: generate_admin_class.py:118 generate_admin_class.py:160 +msgid "Edit item" +msgstr "Editar elemento" + +#: generate_admin_class.py:168 generate_admin_class.py:209 +#: generate_admin_class.py:329 +msgid "Task successful" +msgstr "Tarea exitosa" + +#: templates/utils/list.phtml:14 +msgid "Search" +msgstr "Buscar" diff --git a/paramecio2/libraries/languages/libraries.mo b/paramecio2/libraries/languages/libraries.mo new file mode 100644 index 0000000000000000000000000000000000000000..63d66dae3fac0abbf07594ba202aca312b4482d1 GIT binary patch literal 733 zcmYk2J#W-N5QY~BUj{@15*0$*(17-^FDVj7DelM-PRc1(Fdr4tV$V4Xce|(EbrK3X zI%+B^XsM9+2Wcpf_y_zATHf_J93zb%zuujh*Yo?v(np54g1n9N$Q9&IWQgT6j9mp+ zzzg6Va0$E%UIy>AdJVh?y#byFd*F3&2Ml%3Tm2IJ1FgYZ;P~wP{9ViUV5s}h>QCS$ z=r1k5f;XYRx92~=YtX+yv}`;DAK`yaBWhoQ@6$Mk7nC$!gTFANiC$T9O-EdLnzC)0 zkS8`Mm2V#NuaC`?*xt-5qaDj+MUL&$jHKt8bneL5l06}5ivyNR_lCQ=D9E{SJz<$O zuc`22Sc+$49U7!OLani0j9jHk(XT5fa)Zy=p4g{D6)uTw=_%#ixVtKnu1Gd`9H((| zKThH}+Lg|W+)C{x(i@A)U8$=YwnR>H`kziYxo9*T4HmZn+LK0)w=)d!bnG9@ zCQ|85UK~j4$ZtK(ABpwFy)bJ`Rt$7uN~NomufI}0dLed5lbxH$3}I<}wX@bqBGx~^m<0ShFI4r6F literal 0 HcmV?d00001 diff --git a/paramecio2/libraries/languages/libraries.po b/paramecio2/libraries/languages/libraries.po new file mode 100644 index 0000000..cd10b26 --- /dev/null +++ b/paramecio2/libraries/languages/libraries.po @@ -0,0 +1,59 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2023-12-18 23:51+0100\n" +"PO-Revision-Date: 2023-12-19 00:01+0100\n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 3.4.1\n" + +#: formsutils.py:183 +msgid "Repeat Password" +msgstr "Repetir contraseña" + +#: lists.py:113 +msgid "Options" +msgstr "Opciones" + +#: lists.py:222 generate_admin_class.py:304 +msgid "Edit" +msgstr "Editar" + +#: lists.py:223 +msgid "Delete" +msgstr "Borrar" + +#: lists.py:395 templates/utils/list.phtml:133 +msgid "Pages" +msgstr "Páginas" + +#: generate_admin_class.py:82 generate_admin_class.py:288 +msgid "Home" +msgstr "Inicio" + +#: generate_admin_class.py:112 generate_admin_class.py:155 +msgid "Add new item" +msgstr "Añadir nuevo elemento" + +#: generate_admin_class.py:118 generate_admin_class.py:160 +msgid "Edit item" +msgstr "Editar elemento" + +#: generate_admin_class.py:168 generate_admin_class.py:209 +#: generate_admin_class.py:329 +msgid "Task successful" +msgstr "Tarea exitosa" + +#: templates/utils/list.phtml:14 +msgid "Search" +msgstr "Buscar" diff --git a/paramecio2/modules/welcome/languages/es-ES/LC_MESSAGES/welcome.mo b/paramecio2/modules/welcome/languages/es-ES/LC_MESSAGES/welcome.mo new file mode 100644 index 0000000000000000000000000000000000000000..01da54e4f29f211f631da954ff61fd68ee006969 GIT binary patch literal 526 zcmYk2yH3L}6ovy7A!TF&iQ(+vHc1((0862uO0B4>a2Z(K|i@BeGqm=o`I1E z;Q`nYD<|dB9{JOMY@Lhszi-!`9EuvTM;sHI#2ryZLDY!{VvBetc8M3_i+Cd%#Os>l zxTGJXJEWhabewgfifaBwl?=G%ImSXA00%QS7ITO-a*GL!mHy3Ph9h1S#<{^PRyqDD zSOs>1Kn)qpl+F@opw&IbmUR<$joJt$LvV*!C~aBaq#|MMGBqqx^gOs^L!64Lh@H{O z5CSh~GCyE`3xXi@oBN*cd2Wvz%OcIC$+%UTI(uBEB~Ot>$n%wZ2x#1Xx8GSV_v@Z} zs-#6pGv);?vG`~kMaG3Zf_TEUL3?r)owL@muG%$5%{nqxiI8ast&yU;yWU6f@2 literal 0 HcmV?d00001 diff --git a/paramecio2/modules/welcome/languages/es-ES/LC_MESSAGES/welcome.po b/paramecio2/modules/welcome/languages/es-ES/LC_MESSAGES/welcome.po new file mode 100644 index 0000000..7d50c0e --- /dev/null +++ b/paramecio2/modules/welcome/languages/es-ES/LC_MESSAGES/welcome.po @@ -0,0 +1,30 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2023-12-18 22:13+0100\n" +"PO-Revision-Date: 2023-12-18 22:13+0100\n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 3.4.1\n" + +#: app.py:13 +msgid "Welcome" +msgstr "Bienvenido" + +#: app.py:13 +msgid "Welcome to the real world" +msgstr "Bienvenido al mundo real" + +#: templates/welcome.phtml:75 +msgid "Paramecio, a system created for create webapps" +msgstr "Paramecio, un sistema creado para crear webapps" diff --git a/paramecio2/modules/welcome/languages/welcome.mo b/paramecio2/modules/welcome/languages/welcome.mo new file mode 100644 index 0000000000000000000000000000000000000000..76ed7da3ad5cd9d465d3baa0909a3a1e1d0111c0 GIT binary patch literal 424 zcmYk2!A`?442BDWOOKp6_|Dw59THQ43oy{6O_Zr1u3qbvpe?DA47M9D!RzrFTyY0t zv+~JKWc!c)ucL#{Kw@7w7COSAa3Qpj3z6_3dl+hW46K;(4ICizF@M>8*EQ~zo_c-A< z)i&XcEX*K{(;g-%CVfcLEIvDllQ<4Xm}8U1=C{Zo&mdXJRA?U z;z<;T*G7BRvSZzdi075>Hgi(?9Lg86j{W6haf|(JU#m4^ivwMnO6fX-{#5z!8ShxL k{ryC4xKbW^(P@-~!H!K!4NkQ_(Z-z0KqDS*YWwfg4?K!?{r~^~ literal 0 HcmV?d00001 diff --git a/paramecio2/modules/welcome/languages/welcome.po b/paramecio2/modules/welcome/languages/welcome.po new file mode 100644 index 0000000..9bbec9c --- /dev/null +++ b/paramecio2/modules/welcome/languages/welcome.po @@ -0,0 +1,22 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2023-12-18 22:06+0100\n" +"PO-Revision-Date: 2023-12-18 22:07+0100\n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 3.4.1\n" + +#: templates/welcome.phtml:75 +msgid "Paramecio, a system created for create webapps" +msgstr "Paramecio, un sistema creado para crear webapps" From 5339ba4b4c0905f7f724bec05f7a008f98413201 Mon Sep 17 00:00:00 2001 From: absurdo Date: Wed, 20 Dec 2023 00:07:27 +0100 Subject: [PATCH 02/85] Deleted fake language files --- .../modules/welcome/languages/welcome.mo | Bin 424 -> 0 bytes .../modules/welcome/languages/welcome.po | 22 ------------------ 2 files changed, 22 deletions(-) delete mode 100644 paramecio2/modules/welcome/languages/welcome.mo delete mode 100644 paramecio2/modules/welcome/languages/welcome.po diff --git a/paramecio2/modules/welcome/languages/welcome.mo b/paramecio2/modules/welcome/languages/welcome.mo deleted file mode 100644 index 76ed7da3ad5cd9d465d3baa0909a3a1e1d0111c0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 424 zcmYk2!A`?442BDWOOKp6_|Dw59THQ43oy{6O_Zr1u3qbvpe?DA47M9D!RzrFTyY0t zv+~JKWc!c)ucL#{Kw@7w7COSAa3Qpj3z6_3dl+hW46K;(4ICizF@M>8*EQ~zo_c-A< z)i&XcEX*K{(;g-%CVfcLEIvDllQ<4Xm}8U1=C{Zo&mdXJRA?U z;z<;T*G7BRvSZzdi075>Hgi(?9Lg86j{W6haf|(JU#m4^ivwMnO6fX-{#5z!8ShxL k{ryC4xKbW^(P@-~!H!K!4NkQ_(Z-z0KqDS*YWwfg4?K!?{r~^~ diff --git a/paramecio2/modules/welcome/languages/welcome.po b/paramecio2/modules/welcome/languages/welcome.po deleted file mode 100644 index 9bbec9c..0000000 --- a/paramecio2/modules/welcome/languages/welcome.po +++ /dev/null @@ -1,22 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -# -msgid "" -msgstr "" -"Project-Id-Version: \n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-12-18 22:06+0100\n" -"PO-Revision-Date: 2023-12-18 22:07+0100\n" -"Last-Translator: \n" -"Language-Team: \n" -"Language: es\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-Generator: Poedit 3.4.1\n" - -#: templates/welcome.phtml:75 -msgid "Paramecio, a system created for create webapps" -msgstr "Paramecio, un sistema creado para crear webapps" From c85fed0df1c3e89cf516130bc14dc1c0b596ab10 Mon Sep 17 00:00:00 2001 From: absurdo Date: Wed, 20 Dec 2023 01:46:48 +0100 Subject: [PATCH 03/85] Multiple fixes, changed beautifoul soup dependency for bleach from mozilla --- paramecio2/libraries/db/corefields.py | 19 +++++++++++++++++-- paramecio2/tests/fields_test.py | 6 +++--- setup.py | 4 ++-- 3 files changed, 22 insertions(+), 7 deletions(-) diff --git a/paramecio2/libraries/db/corefields.py b/paramecio2/libraries/db/corefields.py index 5d41e55..f52199c 100644 --- a/paramecio2/libraries/db/corefields.py +++ b/paramecio2/libraries/db/corefields.py @@ -1,7 +1,8 @@ from paramecio2.libraries.db.webmodel import PhangoField from paramecio2.libraries.db import coreforms from paramecio2.libraries.i18n import I18n -from bs4 import BeautifulSoup +#from bs4 import BeautifulSoup +import bleach class IntegerField(PhangoField): @@ -212,9 +213,12 @@ class HTMLField(TextField): This check method use beautifulsoap for clean and format html code """ + # leach.clean('

"trial"

', tags=('p')) + """ soup=BeautifulSoup(value, features='html.parser') for tag in soup.findAll(True): + if tag.name not in self.trusted_tags: tag.hidden=True @@ -227,7 +231,18 @@ class HTMLField(TextField): return value - + """ + + value=bleach.clean('

"trial"

', tags=self.trusted_tags) + + if self.escape: + + return value.replace('"', '"') + else: + + return value + + class ForeignKeyField(IntegerField): """Subclass of IntegerField for create Foreign keys diff --git a/paramecio2/tests/fields_test.py b/paramecio2/tests/fields_test.py index f44027e..2655172 100644 --- a/paramecio2/tests/fields_test.py +++ b/paramecio2/tests/fields_test.py @@ -59,15 +59,15 @@ def test_test_htmlfield(): field=corefields.HTMLField('html') - assert field.check('

"trial"

')=='"trial"' + assert field.check('

"trial"

')=='<p>"trial"</p><script></script>' field.escape=True - assert field.check('

"trial"

')=='"trial"' + assert field.check('

"trial"

')=='<p>"trial"</p><script></script>' field.trusted_tags=['p'] - assert field.check('

"trial"

')=='

"trial"

' + assert field.check('

"trial"

')=='

"trial"

<script></script>' #field. def test_test_foreignkeyfield(): diff --git a/setup.py b/setup.py index 151c07b..7503168 100644 --- a/setup.py +++ b/setup.py @@ -13,7 +13,7 @@ if sys.version_info < (3, 8): # If you install passlib and bcrypt, the password system will use bcrypt by default, if not, will use native crypt libc setup(name='paramecio2', - version='2.0.28', + version='2.0.29', description='Simple Web Framework based in flask and Mako.', long_description='This framework is a simple framework used for create web apps. Paramecio is modular and fast. By default have a module called admin that can be used for create admin sites', author='Antonio de la Rosa Caballero', @@ -21,7 +21,7 @@ setup(name='paramecio2', url='https://bitbucket.org/paramecio/paramecio2fm/', packages=['paramecio2'], include_package_data=True, - install_requires=['flask', 'pymysql', 'sqlalchemy', 'colorama', 'python-slugify', 'mako', 'pillow', 'arrow', 'beautifulsoup4'], + install_requires=['flask', 'pymysql', 'sqlalchemy', 'colorama', 'python-slugify', 'mako', 'pillow', 'arrow', 'bleach'], entry_points={'console_scripts': [ 'paramecio2 = paramecio2.console:start', 'paramecio2db = paramecio2.libraries.db.dbadmin:start', 'paramecio2lang = paramecio2.libraries.check_i18n:start', ]}, From 61009383fec76a29814f08becc891f1359bb1cd2 Mon Sep 17 00:00:00 2001 From: absurdo Date: Wed, 20 Dec 2023 15:10:49 +0100 Subject: [PATCH 04/85] Fixes in tests --- paramecio2/tests/fields_test.py | 4 +- tests/__init__.py | 0 tests/test_sendmailtest.py | 25 --- tests/test_urlstest.py | 55 ------ tests/test_webmodeltest.py | 305 -------------------------------- 5 files changed, 2 insertions(+), 387 deletions(-) delete mode 100644 tests/__init__.py delete mode 100644 tests/test_sendmailtest.py delete mode 100644 tests/test_urlstest.py delete mode 100644 tests/test_webmodeltest.py diff --git a/paramecio2/tests/fields_test.py b/paramecio2/tests/fields_test.py index 2655172..5dfb4e7 100644 --- a/paramecio2/tests/fields_test.py +++ b/paramecio2/tests/fields_test.py @@ -74,7 +74,7 @@ def test_test_foreignkeyfield(): field=corefields.ForeignKeyField('foreign', ExampleModel()) - assert field.check('dsd')=='NULL' + assert field.check('dsd')==None def test_test_booleanfield(): @@ -131,7 +131,7 @@ def test_test_datetimefield(): assert field.check('20201230121011')=='2020-12-30 12:10:11' - assert field.check('20201290121011')=='' + assert field.check('20201290121011')=='0000-00-00 00:00:00' def test_test_dictfield(): diff --git a/tests/__init__.py b/tests/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/tests/test_sendmailtest.py b/tests/test_sendmailtest.py deleted file mode 100644 index 5c29c93..0000000 --- a/tests/test_sendmailtest.py +++ /dev/null @@ -1,25 +0,0 @@ -from settings import config -from paramecio2.libraries import sendmail -import time -import unittest - -class TestFieldMethods(unittest.TestCase): - - def test_sendmail(self): - - s=sendmail.SendMail() - - self.assertTrue( s.send(config.portal_email, [config.email_test], 'This is a test', 'A message for test a simple email method', content_type='plain', attachments=[]) ) - - s=sendmail.SendMail() - - self.assertTrue( s.send(config.portal_email, [config.email_test], 'This is a test', 'A message for test a simple email method in html', content_type='html', attachments=[]) ) - - s=sendmail.SendMail() - - self.assertTrue( s.send(config.portal_email, [config.email_test], 'This is a test', 'A message for test a simple email method in html and attachments', content_type='html', attachments=['tests/images/image.jpg']) ) - - #s.quit() - -if __name__ == '__main__': - unittest.main() diff --git a/tests/test_urlstest.py b/tests/test_urlstest.py deleted file mode 100644 index 7c45dad..0000000 --- a/tests/test_urlstest.py +++ /dev/null @@ -1,55 +0,0 @@ -from settings import config -from paramecio2.libraries.urls import make_url, make_media_url, make_external_url -import time -import unittest - -class TestUrlsMethods(unittest.TestCase): - - def test_urls(self): - - basic_url=make_url('welcome') - - self.assertEqual(basic_url, '/welcome') - - straigth_url=make_url('welcome', {'item1': 1, 'item2': 'accént'}) - - self.assertEqual(straigth_url, '/welcome?item1=1&item2=acc%C3%A9nt') - - straigth_url=make_url('welcome', {'item1': 1, 'item2': 'thing with space'}) - - self.assertEqual(straigth_url, '/welcome?item1=1&item2=thing+with+space') - - def test_external_urls(self): - - basic_url=make_external_url('http://coesinfo.com/welcome') - - self.assertEqual(basic_url, 'http://coesinfo.com/welcome') - - straigth_url=make_external_url('http://coesinfo.com/welcome', {'item1': 1, 'item2': 'accént'}) - - self.assertEqual(straigth_url, 'http://coesinfo.com/welcome?item1=1&item2=acc%C3%A9nt') - - straigth_url=make_external_url('http://coesinfo.com/welcome', {'item1': 1, 'item2': 'thing with space'}) - - self.assertEqual(straigth_url, 'http://coesinfo.com/welcome?item1=1&item2=thing+with+space') - - - def test_media_urls(self): - - if config.yes_static: - - media_url=make_media_url('images/image.jpg', 'paramecio') - - self.assertEqual(media_url, config.media_url+'mediafrom/paramecio/images/image.jpg') - - else: - - media_url=make_media_url('images/image.jpg', 'paramecio') - - self.assertEqual(media_url, config.media_url+'media/paramecio/images/image.jpg') - -if __name__ == '__main__': - unittest.main() - - - diff --git a/tests/test_webmodeltest.py b/tests/test_webmodeltest.py deleted file mode 100644 index cc3ff8a..0000000 --- a/tests/test_webmodeltest.py +++ /dev/null @@ -1,305 +0,0 @@ -from settings import config -from paramecio2.libraries.db.webmodel import WebModel -from paramecio2.libraries.db import corefields -import unittest -# Create TestWebModelMethods - -class ExampleModel(WebModel): - - def __init__(self, connection): - - super().__init__(connection) - - # I can change other fields here, how the name. - - self.register(corefields.CharField('title')) - self.register(corefields.CharField('content')) - -class ForeignKeyExampleModel(WebModel): - - def __init__(self, connection): - - super().__init__(connection) - - # I can change other fields here, how the name. - - self.register(corefields.CharField('name')) - self.register(corefields.ForeignKeyField('example_id', ExampleModel(connection), size=11, required=False, identifier_field='id', named_field="id", select_fields=[])) - - -class ExampleModel2(WebModel): - - def __init__(self, connection): - - super().__init__(connection) - - # I can change other fields here, how the name. - - self.register(corefields.CharField('title')) - self.register(corefields.CharField('content')) - -class TestWebModelMethods(unittest.TestCase): - - def test_test_table(self): - - connection=WebModel.connection() - model=ExampleModel(connection) - - - sql=model.create_table() - - print('Creating table') - - self.assertTrue(model.query(sql)) - - - post={'title': 'Example title', 'content': 'New content'} - - model.set_valid_fields() - - print('Insert row') - - self.assertTrue(model.insert(post)) - - print('Check new id') - - self.assertEqual(model.insert_id(), 1) - - post={'title': 'Example title Updated', 'content': 'New content Updated'} - - model.conditions=['WHERE id=%s', [1]] - - print('Updating row') - - self.assertTrue(model.update(post)) - - model.yes_reset_conditions=False - - model.conditions=['WHERE id=%s', [1]] - - print('Count rows') - - self.assertEqual(model.select_count(), 1) - - print('Select a row') - - self.assertEqual(model.select_a_row(1, ['title', 'inexistent_field']), {'title': 'Example title Updated'}) - - print('Select a row with different conditions to search id') - - self.assertEqual(model.select_a_row_where(['title']), {'title': 'Example title Updated'}) - - print('Select and save in an array') - - self.assertEqual(model.select_to_array(['title', 'content']), [{'id': 1, 'title': 'Example title Updated', 'content': 'New content Updated'}]) - - model.yes_reset_conditions=True - - model.reset_conditions() - - print('Reset conditions') - - self.assertEqual(model.conditions, ['WHERE 1=1', []]) - - print('Simple base select') - - cur=model.select() - - row=model.fetch(cur) - - self.assertEqual(row, {'id': 1, 'title': 'Example title Updated', 'content': 'New content Updated'}) - - print('Check element exists') - - self.assertTrue(model.element_exists(1)) - - model.conditions=['WHERE id=%s', [2]] - - print('Check delete row') - - self.assertFalse(model.delete()) - - self.assertTrue(model.delete()) - - print('Check delete table') - - self.assertTrue(model.drop()) - - connection.close() - - - def test_update_table(self): - - connection=WebModel.connection() - model=ExampleModel(connection) - - - print('Check modifications in table') - - sql=model.create_table() - - self.assertTrue(model.query(sql)) - - fields_to_modify=[] - fields_to_add_index=[] - fields_to_add_constraint=[] - fields_to_add_unique=[] - fields_to_delete_index=[] - fields_to_delete_unique=[] - fields_to_delete_constraint=[] - fields_to_delete=[] - - model.register(corefields.CharField('description')) - - model.update_table(['description'], fields_to_modify, fields_to_add_index, fields_to_add_constraint, fields_to_add_unique, fields_to_delete_index, fields_to_delete_unique, fields_to_delete_constraint, fields_to_delete) - - model.register(corefields.IntegerField('description')) - - model.update_table([], ['description'], ['description'], [], ['description'], fields_to_delete_index, fields_to_delete_unique, fields_to_delete_constraint, fields_to_delete) - - model.update_table([], fields_to_modify, fields_to_add_index, fields_to_add_constraint, fields_to_add_unique, ['description'], ['description'], fields_to_delete_constraint, ['description']) - - self.assertTrue(model.drop()) - - connection.close() - - def test_conditions(self): - - print('Test conditions') - - connection=WebModel.connection() - model=ExampleModel(connection) - - sql=model.create_table() - - self.assertTrue(model.query(sql)) - - cur=model.set_conditions('where id=%s', [4]).select() - - self.assertTrue(cur) - - cur.close() - - self.assertTrue(model.drop()) - - connection.close() - - def test_functions(self): - - print('Test functions') - - connection=WebModel.connection() - model=ExampleModel(connection) - - sql=model.create_table() - - self.assertTrue(model.query(sql)) - - cur=model.set_conditions('where id=%s', [4]).select() - - self.assertTrue(cur) - - cur.close() - - self.assertTrue(model.drop()) - - connection.close() - - def test_zcheck_1_foreignkeys(self): - - connection=WebModel.connection() - model=ExampleModel(connection) - foreignkey=ForeignKeyExampleModel(connection) - - print('Checking ForeignKeys models...') - - sql=model.create_table() - sqlf=foreignkey.create_table() - - print('Creating foreignkey table...') - - self.assertTrue(model.query(sql)) - self.assertTrue(foreignkey.query(sqlf)) - - for k_field, index in WebModel.arr_sql_index['foreignkeyexamplemodel'].items(): - print("---Added index to "+k_field) - foreignkey.query(index) - - for k_set, index_set in WebModel.arr_sql_set_index['foreignkeyexamplemodel'].items(): - - if index_set!="": - connection.query(index_set) - print("---Added constraint to "+k_set) - - model.create_forms() - - self.assertTrue(model.insert({'title': 'Foreign title', 'content': 'Foreign content'})) - - my_id=model.insert_id() - - foreignkey.create_forms() - - self.assertTrue(foreignkey.insert({'example_id': my_id, 'name': 'Relationship'})) - - print('Checking insert...') - - foreignkey.set_conditions('where example_id=%s', [my_id]) - - self.assertEqual(foreignkey.select_count(), 1) - - model.set_conditions('where id=%s', [my_id]) - - self.assertTrue(model.delete()) - - foreignkey.set_conditions('where example_id=%s', [my_id]) - - print('Checking automatic delete...') - - self.assertEqual(foreignkey.select_count(), 0) - - print('Dropping foreignkey table...') - - self.assertTrue(foreignkey.drop()) - self.assertTrue(model.drop()) - - pass - - def test_zcheck_connections(self): - - print('Check connection of models...') - - connection=WebModel.connection() - model=ExampleModel(connection) - - model2=ExampleModel2(connection) - - sql=model.create_table() - sql2=model2.create_table() - #print(sql) - - self.assertTrue(model.query(sql)) - self.assertTrue(model2.query(sql2)) - - self.assertTrue(model.drop()) - self.assertTrue(model2.drop()) - - connection.close() - - pass - - def test_check_filter_list_str(self): - - print('Check string list filtering') - - connection=WebModel.connection() - model=ExampleModel(connection) - - str_filter=model.check_in_list_str('title', ['joan', 'piter', 'luiz"']) - - self.assertEqual(str_filter, '("joan", "piter", "luiz"")') - - connection.close() - -if __name__ == '__main__': - unittest.main() - From 8240e3039d6ab2251f4046bc3fbc4ed82ae10b51 Mon Sep 17 00:00:00 2001 From: absurdo Date: Thu, 21 Dec 2023 01:12:16 +0100 Subject: [PATCH 05/85] Added more tests --- paramecio2/tests/fields_test.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/paramecio2/tests/fields_test.py b/paramecio2/tests/fields_test.py index 5dfb4e7..c769914 100644 --- a/paramecio2/tests/fields_test.py +++ b/paramecio2/tests/fields_test.py @@ -1,6 +1,7 @@ import sys import os import pytest +import json sys.path.insert(0, os.path.realpath(os.path.dirname(__file__))+'/../../') @@ -13,6 +14,7 @@ from paramecio2.libraries.db.extrafields.datefield import DateField from paramecio2.libraries.db.extrafields.datetimefield import DateTimeField from paramecio2.libraries.db.extrafields.dictfield import DictField from paramecio2.libraries.db.extrafields.emailfield import EmailField +from paramecio2.libraries.db.extrafields.i18nfield import I18nField from paramecio2.libraries import datetime class ExampleModel(WebModel): @@ -153,7 +155,11 @@ def test_test_emailfield(): def test_test_i18nfield(): + field=I18nField('i18nfield') + assert field.check(json.dumps({'en-US': "Hello", 'es-ES': "Hola"}))=='{"en-US": "Hello", "es-ES": "Hola"}' + + assert field.check(json.dumps({'en-US': "Hello"}))=='{"en-US": "Hello", "es-ES": ""}' pass From 651613b6445bb598aa44a49046fed77f0f5d78ea Mon Sep 17 00:00:00 2001 From: absurdo Date: Mon, 25 Dec 2023 20:16:02 +0100 Subject: [PATCH 06/85] Fixes --- LICENSE.txt | 148 ++++++++---------- .../libraries/db/extrafields/imagefield.py | 11 +- paramecio2/libraries/db/webmodel.py | 4 +- paramecio2/modules/admin/app.py | 9 +- .../modules/admin/templates/login.phtml | 2 +- 5 files changed, 86 insertions(+), 88 deletions(-) diff --git a/LICENSE.txt b/LICENSE.txt index 10926e8..be3f7b2 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -1,23 +1,21 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 + GNU AFFERO GENERAL PUBLIC LICENSE + Version 3, 19 November 2007 - Copyright (C) 2007 Free Software Foundation, Inc. + Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble - The GNU General Public License is a free, copyleft license for -software and other kinds of works. + The GNU Affero General Public License is a free, copyleft license for +software and other kinds of works, specifically designed to ensure +cooperation with the community in the case of network server software. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to +our General Public Licenses are intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. +software for all its users. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you @@ -26,44 +24,34 @@ them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. + Developers that use our General Public Licenses protect your rights +with two steps: (1) assert copyright on the software, and (2) offer +you this License which gives you legal permission to copy, distribute +and/or modify the software. - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. + A secondary benefit of defending all users' freedom is that +improvements made in alternate versions of the program, if they +receive widespread use, become available for other developers to +incorporate. Many developers of free software are heartened and +encouraged by the resulting cooperation. However, in the case of +software used on network servers, this result may fail to come about. +The GNU General Public License permits making a modified version and +letting the public access it on a server without ever releasing its +source code to the public. - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. + The GNU Affero General Public License is designed specifically to +ensure that, in such cases, the modified source code becomes available +to the community. It requires the operator of a network server to +provide the source code of the modified version running there to the +users of that server. Therefore, public use of a modified version, on +a publicly accessible server, gives the public access to the source +code of the modified version. - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. + An older license, called the Affero General Public License and +published by Affero, was designed to accomplish similar goals. This is +a different license, not a version of the Affero GPL, but Affero has +released a new version of the Affero GPL which permits relicensing under +this license. The precise terms and conditions for copying, distribution and modification follow. @@ -72,7 +60,7 @@ modification follow. 0. Definitions. - "This License" refers to version 3 of the GNU General Public License. + "This License" refers to version 3 of the GNU Affero General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. @@ -549,35 +537,45 @@ to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. - 13. Use with the GNU Affero General Public License. + 13. Remote Network Interaction; Use with the GNU General Public License. + + Notwithstanding any other provision of this License, if you modify the +Program, your modified version must prominently offer all users +interacting with it remotely through a computer network (if your version +supports such interaction) an opportunity to receive the Corresponding +Source of your version by providing access to the Corresponding Source +from a network server at no charge, through some standard or customary +means of facilitating copying of software. This Corresponding Source +shall include the Corresponding Source for any work covered by version 3 +of the GNU General Public License that is incorporated pursuant to the +following paragraph. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single +under version 3 of the GNU General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. +but the work with which it is combined will remain governed by version +3 of the GNU General Public License. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to +the GNU Affero General Public License from time to time. Such new versions +will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General +Program specifies that a certain numbered version of the GNU Affero General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published +GNU Affero General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's +versions of the GNU Affero General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. @@ -635,41 +633,29 @@ the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by + it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program 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. + GNU Affero General Public License for more details. - You should have received a copy of the GNU General Public License - along with this program. If not, see . + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - Copyright (C) - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". + If your software can interact with users remotely through a computer +network, you should also make sure that it provides a way for users to +get its source. For example, if your program is a web application, its +interface could display a "Source" link that leads users to an archive +of the code. There are many ways you could offer source, and different +solutions will be better for different programs; see section 13 for the +specific requirements. You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -. - +For more information on this, and how to apply and follow the GNU AGPL, see +. diff --git a/paramecio2/libraries/db/extrafields/imagefield.py b/paramecio2/libraries/db/extrafields/imagefield.py index 4728b0f..7d01018 100644 --- a/paramecio2/libraries/db/extrafields/imagefield.py +++ b/paramecio2/libraries/db/extrafields/imagefield.py @@ -73,7 +73,7 @@ class ImageField(CharField): #if not change if field_file in files_uploaded: - + if files_uploaded[field_file].filename=='': if value=='': @@ -113,9 +113,14 @@ class ImageField(CharField): return self.save_folder+'/'+value else: - value=os.path.basename(value) + self.txt_error='Field is empty' + self.error=True + + return '' + + #value=os.path.basename(value) - return self.save_folder+'/'+value + #return self.save_folder+'/'+value # Load image file diff --git a/paramecio2/libraries/db/webmodel.py b/paramecio2/libraries/db/webmodel.py index 1d7a29d..f1ea7cb 100644 --- a/paramecio2/libraries/db/webmodel.py +++ b/paramecio2/libraries/db/webmodel.py @@ -1127,7 +1127,9 @@ class WebModel: #Need delete rows from other related tables save in self.related_models_deleted - sql=("delete from `"+self.name+"` "+self.conditions[0]+' '+self.order_by+' '+self.limit).strip() + #+' '+self.order_by+' '+self.limit + + sql=("delete from `"+self.name+"` "+self.conditions[0]).strip() result=self.query(sql, self.conditions[1], self.connection_id) diff --git a/paramecio2/modules/admin/app.py b/paramecio2/modules/admin/app.py index 9772755..60e1b1d 100644 --- a/paramecio2/modules/admin/app.py +++ b/paramecio2/modules/admin/app.py @@ -19,6 +19,11 @@ from paramecio2.libraries.formsutils import check_csrf #_=pgettext(__file__) +login_tries=5 + +if hasattr(config, 'login_tries'): + login_tries=config.login_tries + gtext=PGetText(__file__) _=gtext.gettext @@ -211,7 +216,7 @@ def login(): arr_user=user_admin.set_conditions('WHERE username=%s', [username]).select_a_row_where() - if arr_user: + if arr_user and not check_login_tries(): if user_admin.fields['password'].verify(password, arr_user['password']): @@ -450,7 +455,7 @@ def check_login_tries(): if arr_try: - if arr_try['num_tries']<5: + if arr_try['num_tries']${_('Recovery password?')} % endif -
${_('Remember that only have 3 attempts')}
+ From 4633da949465e1392bafde1a0620e5421accb866 Mon Sep 17 00:00:00 2001 From: absurdo Date: Mon, 25 Dec 2023 20:23:26 +0100 Subject: [PATCH 07/85] New release --- setup.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/setup.py b/setup.py index 7503168..d588b5f 100644 --- a/setup.py +++ b/setup.py @@ -5,19 +5,19 @@ import os from setuptools import setup, find_packages -if sys.version_info < (3, 8): - raise NotImplementedError("Sorry, you need at least Python 3.8 for use paramecio2.") +if sys.version_info < (3, 9): + raise NotImplementedError("Sorry, you need at least Python 3.9 for use paramecio2.") #import paramecio # Pillow should be installed after if you need ImageField # If you install passlib and bcrypt, the password system will use bcrypt by default, if not, will use native crypt libc setup(name='paramecio2', - version='2.0.29', + version='2.0.30', description='Simple Web Framework based in flask and Mako.', long_description='This framework is a simple framework used for create web apps. Paramecio is modular and fast. By default have a module called admin that can be used for create admin sites', author='Antonio de la Rosa Caballero', - author_email='antonio.delarosa@coesinfo.com', + author_email='antonio.delarosa@salirdelhoyo.com', url='https://bitbucket.org/paramecio/paramecio2fm/', packages=['paramecio2'], include_package_data=True, From 76db9d7816f1effa6d99e52a272fc04a64218b8d Mon Sep 17 00:00:00 2001 From: absurdo Date: Tue, 26 Dec 2023 10:56:43 +0100 Subject: [PATCH 08/85] FIxes in documentation --- README.md | 6 +++--- README.rst | 2 +- setup.py | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index f8f7473..07cfdab 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ Also, you need the next software installed in your os: ### Python 3.10 or later. -Paramecio should work fine in 3.5-3.9 but is tested in 3.10 and 3.11 python 3 versions actually. +Paramecio should work fine in 3.5-3.9 but is tested in 3.10, 3.11 and 3.12 python 3 versions actually. In Debian and Ubuntu you can install Python 3 using the next command: `apt-get install python3`. @@ -20,7 +20,7 @@ In Fedora and other Red Hat derived distros you can use `yum install python3`. I ### MySQL or MariaDB database servers. -MariaDB 10.6 and later are recommended but is compatible with MariaDB 10. +MariaDB 10.6 and later are recommended but is compatible with previous versions. In Debian and Ubuntu you can install MariaDB using the next command: `apt-get install mariadb-server`. @@ -53,7 +53,7 @@ You can install the framework using the next command in your server: or if you want development version: -`pip3 install git+https://git.cuchulu.com/absurdo/paramecio2fm.git` +`pip3 install git+https://git.cuchulu.com/paramecio/paramecio2fm.git` This command will install in your server paramecio framework with its dependencies. diff --git a/README.rst b/README.rst index 325f3e4..8583253 100644 --- a/README.rst +++ b/README.rst @@ -1,5 +1,5 @@ ========================================================== -Paramecio is a simple framework based in bottle and mako. +Paramecio is a simple framework based in flask and mako. ========================================================== diff --git a/setup.py b/setup.py index d588b5f..79b23d6 100644 --- a/setup.py +++ b/setup.py @@ -13,7 +13,7 @@ if sys.version_info < (3, 9): # If you install passlib and bcrypt, the password system will use bcrypt by default, if not, will use native crypt libc setup(name='paramecio2', - version='2.0.30', + version='2.0.31', description='Simple Web Framework based in flask and Mako.', long_description='This framework is a simple framework used for create web apps. Paramecio is modular and fast. By default have a module called admin that can be used for create admin sites', author='Antonio de la Rosa Caballero', From 177478956733cb76c371aea6fbab3c58efe96716 Mon Sep 17 00:00:00 2001 From: absurdo Date: Wed, 27 Dec 2023 15:12:10 +0100 Subject: [PATCH 09/85] Fix in tests options --- paramecio2/tests/conftest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/paramecio2/tests/conftest.py b/paramecio2/tests/conftest.py index e464f79..6064dfc 100644 --- a/paramecio2/tests/conftest.py +++ b/paramecio2/tests/conftest.py @@ -4,7 +4,7 @@ from paramecio2.libraries.db import corefields def pytest_addoption(parser): - parser.addoption("--mysql_host", action="store", default="host", help="MySQL host: default localhost") + parser.addoption("--mysql_host", action="store", default="localhost", help="MySQL host: default localhost") parser.addoption("--mysql_user", action="store", default="root", help="Mysql User for make the test: default root") parser.addoption("--mysql_password", action="store", default="", help="Mysql password for make the test: default empty value") parser.addoption("--mysql_db", action="store", default="test_paramecio_db", help="Mysql Database for execute the test: default test_paramecio_db") From 066a44e3b65b22ef0dab30b23c731551aeedb4a1 Mon Sep 17 00:00:00 2001 From: absurdo Date: Sat, 30 Dec 2023 01:54:25 +0100 Subject: [PATCH 10/85] Added license clause for AGPL3 in all files --- paramecio2/app.py | 19 ++++++++++++++++++ paramecio2/console.py | 19 ++++++++++++++++++ paramecio2/frontend/app.py | 19 ++++++++++++++++++ paramecio2/index.py | 19 ++++++++++++++++++ paramecio2/libraries/__init__.py | 18 +++++++++++++++++ paramecio2/libraries/check_i18n.py | 19 ++++++++++++++++++ paramecio2/libraries/config_admin.py | 18 +++++++++++++++++ paramecio2/libraries/datetime.py | 19 ++++++++++++++++++ paramecio2/libraries/db/corefields.py | 19 ++++++++++++++++++ paramecio2/libraries/db/coreforms.py | 19 ++++++++++++++++++ paramecio2/libraries/db/dbadmin.py | 19 ++++++++++++++++++ .../libraries/db/extrafields/__init__.py | 18 +++++++++++++++++ .../libraries/db/extrafields/arrayfield.py | 19 ++++++++++++++++++ .../libraries/db/extrafields/colorfield.py | 19 ++++++++++++++++++ .../libraries/db/extrafields/datefield.py | 19 ++++++++++++++++++ .../libraries/db/extrafields/datetimefield.py | 19 ++++++++++++++++++ .../libraries/db/extrafields/dictfield.py | 19 ++++++++++++++++++ .../libraries/db/extrafields/emailfield.py | 19 ++++++++++++++++++ .../libraries/db/extrafields/filefield.py | 19 ++++++++++++++++++ .../libraries/db/extrafields/i18nfield.py | 19 ++++++++++++++++++ .../libraries/db/extrafields/imagefield.py | 19 ++++++++++++++++++ .../libraries/db/extrafields/ipfield.py | 19 ++++++++++++++++++ .../libraries/db/extrafields/jsonfield.py | 19 ++++++++++++++++++ .../libraries/db/extrafields/langfield.py | 19 ++++++++++++++++++ .../libraries/db/extrafields/moneyfield.py | 19 ++++++++++++++++++ .../libraries/db/extrafields/parentfield.py | 19 ++++++++++++++++++ .../libraries/db/extrafields/passwordfield.py | 19 ++++++++++++++++++ .../libraries/db/extrafields/percentfield.py | 19 ++++++++++++++++++ .../libraries/db/extrafields/slugifyfield.py | 19 ++++++++++++++++++ .../libraries/db/extrafields/urlfield.py | 19 ++++++++++++++++++ .../libraries/db/extrafields/usernamefield.py | 19 ++++++++++++++++++ .../libraries/db/extraforms/__init__.py | 18 +++++++++++++++++ .../libraries/db/extraforms/checkform.py | 19 ++++++++++++++++++ .../libraries/db/extraforms/colorform.py | 19 ++++++++++++++++++ .../libraries/db/extraforms/dateform.py | 19 ++++++++++++++++++ .../libraries/db/extraforms/fileform.py | 19 ++++++++++++++++++ .../libraries/db/extraforms/i18nform.py | 19 ++++++++++++++++++ .../libraries/db/extraforms/texthtmlform.py | 18 +++++++++++++++++ .../libraries/db/extraforms/usernameform.py | 18 +++++++++++++++++ paramecio2/libraries/formsutils.py | 19 ++++++++++++++++++ paramecio2/libraries/generate_admin_class.py | 19 ++++++++++++++++++ paramecio2/libraries/get_data.py | 18 +++++++++++++++++ paramecio2/libraries/i18n.py | 19 ++++++++++++++++++ paramecio2/libraries/keyutils.py | 19 ++++++++++++++++++ paramecio2/libraries/lists.py | 19 ++++++++++++++++++ paramecio2/libraries/load_apps.py | 19 ++++++++++++++++++ paramecio2/libraries/mtemplates.py | 19 ++++++++++++++++++ paramecio2/libraries/pages.py | 19 ++++++++++++++++++ paramecio2/libraries/plugins.py | 19 ++++++++++++++++++ paramecio2/libraries/sendmail.py | 20 +++++++++++++++++++ paramecio2/libraries/slugify.py | 19 ++++++++++++++++++ paramecio2/libraries/urls.py | 19 ++++++++++++++++++ 52 files changed, 982 insertions(+) diff --git a/paramecio2/app.py b/paramecio2/app.py index 21b3648..ee91285 100644 --- a/paramecio2/app.py +++ b/paramecio2/app.py @@ -1,3 +1,22 @@ +""" +Paramecio2fm is a series of wrappers for Flask, mako and others and construct a simple headless cms. + +Copyright (C) 2023 Antonio de la Rosa Caballero + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program 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 Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +""" + from flask import Flask, session, url_for, request, send_file, abort from settings import config from importlib import import_module diff --git a/paramecio2/console.py b/paramecio2/console.py index 92e4877..6c087a7 100755 --- a/paramecio2/console.py +++ b/paramecio2/console.py @@ -1,5 +1,24 @@ #!/usr/bin/env python3 +""" +Paramecio2fm is a series of wrappers for Flask, mako and others and construct a simple headless cms. + +Copyright (C) 2023 Antonio de la Rosa Caballero + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program 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 Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +""" + import argparse import os import shutil diff --git a/paramecio2/frontend/app.py b/paramecio2/frontend/app.py index a967bba..d3f111c 100644 --- a/paramecio2/frontend/app.py +++ b/paramecio2/frontend/app.py @@ -1,3 +1,22 @@ +""" +Paramecio2fm is a series of wrappers for Flask, mako and others and construct a simple headless cms. + +Copyright (C) 2023 Antonio de la Rosa Caballero + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program 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 Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +""" + from paramecio2.app import start_app app=start_app() diff --git a/paramecio2/index.py b/paramecio2/index.py index a967bba..d3f111c 100644 --- a/paramecio2/index.py +++ b/paramecio2/index.py @@ -1,3 +1,22 @@ +""" +Paramecio2fm is a series of wrappers for Flask, mako and others and construct a simple headless cms. + +Copyright (C) 2023 Antonio de la Rosa Caballero + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program 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 Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +""" + from paramecio2.app import start_app app=start_app() diff --git a/paramecio2/libraries/__init__.py b/paramecio2/libraries/__init__.py index e69de29..2616e97 100644 --- a/paramecio2/libraries/__init__.py +++ b/paramecio2/libraries/__init__.py @@ -0,0 +1,18 @@ +""" +Paramecio2fm is a series of wrappers for Flask, mako and others and construct a simple headless cms. + +Copyright (C) 2023 Antonio de la Rosa Caballero + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program 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 Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +""" diff --git a/paramecio2/libraries/check_i18n.py b/paramecio2/libraries/check_i18n.py index c384d90..75cbd58 100644 --- a/paramecio2/libraries/check_i18n.py +++ b/paramecio2/libraries/check_i18n.py @@ -1,5 +1,24 @@ #!/usr/bin/env python3 +""" +Paramecio2fm is a series of wrappers for Flask, mako and others and construct a simple headless cms. + +Copyright (C) 2023 Antonio de la Rosa Caballero + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program 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 Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +""" + import argparse import os, sys diff --git a/paramecio2/libraries/config_admin.py b/paramecio2/libraries/config_admin.py index b022c53..a688564 100644 --- a/paramecio2/libraries/config_admin.py +++ b/paramecio2/libraries/config_admin.py @@ -1,3 +1,21 @@ +""" +Paramecio2fm is a series of wrappers for Flask, mako and others and construct a simple headless cms. + +Copyright (C) 2023 Antonio de la Rosa Caballero + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program 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 Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +""" # Variable base for admin modules diff --git a/paramecio2/libraries/datetime.py b/paramecio2/libraries/datetime.py index c33d451..d761ba3 100644 --- a/paramecio2/libraries/datetime.py +++ b/paramecio2/libraries/datetime.py @@ -1,3 +1,22 @@ +""" +Paramecio2fm is a series of wrappers for Flask, mako and others and construct a simple headless cms. + +Copyright (C) 2023 Antonio de la Rosa Caballero + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program 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 Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +""" + import time from datetime import date, datetime, tzinfo import arrow diff --git a/paramecio2/libraries/db/corefields.py b/paramecio2/libraries/db/corefields.py index f52199c..a72861a 100644 --- a/paramecio2/libraries/db/corefields.py +++ b/paramecio2/libraries/db/corefields.py @@ -1,3 +1,22 @@ +""" +Paramecio2fm is a series of wrappers for Flask, mako and others and construct a simple headless cms. + +Copyright (C) 2023 Antonio de la Rosa Caballero + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program 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 Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +""" + from paramecio2.libraries.db.webmodel import PhangoField from paramecio2.libraries.db import coreforms from paramecio2.libraries.i18n import I18n diff --git a/paramecio2/libraries/db/coreforms.py b/paramecio2/libraries/db/coreforms.py index 6a37dd8..c732dca 100644 --- a/paramecio2/libraries/db/coreforms.py +++ b/paramecio2/libraries/db/coreforms.py @@ -1,5 +1,24 @@ #!/usr/bin/env python3 +""" +Paramecio2fm is a series of wrappers for Flask, mako and others and construct a simple headless cms. + +Copyright (C) 2023 Antonio de la Rosa Caballero + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program 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 Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +""" + from collections import OrderedDict from html import escape diff --git a/paramecio2/libraries/db/dbadmin.py b/paramecio2/libraries/db/dbadmin.py index 2151ec7..625c6fb 100644 --- a/paramecio2/libraries/db/dbadmin.py +++ b/paramecio2/libraries/db/dbadmin.py @@ -1,5 +1,24 @@ #!/usr/bin/env python3 +""" +Paramecio2fm is a series of wrappers for Flask, mako and others and construct a simple headless cms. + +Copyright (C) 2023 Antonio de la Rosa Caballero + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program 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 Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +""" + import argparse import os,traceback import sys, inspect diff --git a/paramecio2/libraries/db/extrafields/__init__.py b/paramecio2/libraries/db/extrafields/__init__.py index e69de29..2616e97 100644 --- a/paramecio2/libraries/db/extrafields/__init__.py +++ b/paramecio2/libraries/db/extrafields/__init__.py @@ -0,0 +1,18 @@ +""" +Paramecio2fm is a series of wrappers for Flask, mako and others and construct a simple headless cms. + +Copyright (C) 2023 Antonio de la Rosa Caballero + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program 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 Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +""" diff --git a/paramecio2/libraries/db/extrafields/arrayfield.py b/paramecio2/libraries/db/extrafields/arrayfield.py index ab18168..7283242 100644 --- a/paramecio2/libraries/db/extrafields/arrayfield.py +++ b/paramecio2/libraries/db/extrafields/arrayfield.py @@ -1,3 +1,22 @@ +""" +Paramecio2fm is a series of wrappers for Flask, mako and others and construct a simple headless cms. + +Copyright (C) 2023 Antonio de la Rosa Caballero + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program 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 Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +""" + from paramecio2.libraries.db.webmodel import PhangoField,WebModel import json diff --git a/paramecio2/libraries/db/extrafields/colorfield.py b/paramecio2/libraries/db/extrafields/colorfield.py index 25a756b..d138ee7 100644 --- a/paramecio2/libraries/db/extrafields/colorfield.py +++ b/paramecio2/libraries/db/extrafields/colorfield.py @@ -1,3 +1,22 @@ +""" +Paramecio2fm is a series of wrappers for Flask, mako and others and construct a simple headless cms. + +Copyright (C) 2023 Antonio de la Rosa Caballero + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program 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 Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +""" + from paramecio2.libraries.db.corefields import IntegerField try: from paramecio2.libraries.db.extraforms.colorform import ColorForm diff --git a/paramecio2/libraries/db/extrafields/datefield.py b/paramecio2/libraries/db/extrafields/datefield.py index 1859b49..7337222 100644 --- a/paramecio2/libraries/db/extrafields/datefield.py +++ b/paramecio2/libraries/db/extrafields/datefield.py @@ -1,3 +1,22 @@ +""" +Paramecio2fm is a series of wrappers for Flask, mako and others and construct a simple headless cms. + +Copyright (C) 2023 Antonio de la Rosa Caballero + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program 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 Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +""" + from paramecio2.libraries.db.corefields import PhangoField from paramecio2.libraries import datetime try: diff --git a/paramecio2/libraries/db/extrafields/datetimefield.py b/paramecio2/libraries/db/extrafields/datetimefield.py index c68d028..b31e158 100644 --- a/paramecio2/libraries/db/extrafields/datetimefield.py +++ b/paramecio2/libraries/db/extrafields/datetimefield.py @@ -1,3 +1,22 @@ +""" +Paramecio2fm is a series of wrappers for Flask, mako and others and construct a simple headless cms. + +Copyright (C) 2023 Antonio de la Rosa Caballero + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program 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 Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +""" + from paramecio2.libraries.db.corefields import PhangoField from paramecio2.libraries import datetime try: diff --git a/paramecio2/libraries/db/extrafields/dictfield.py b/paramecio2/libraries/db/extrafields/dictfield.py index ee8d6fb..474f468 100644 --- a/paramecio2/libraries/db/extrafields/dictfield.py +++ b/paramecio2/libraries/db/extrafields/dictfield.py @@ -1,3 +1,22 @@ +""" +Paramecio2fm is a series of wrappers for Flask, mako and others and construct a simple headless cms. + +Copyright (C) 2023 Antonio de la Rosa Caballero + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program 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 Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +""" + from paramecio2.libraries.db.webmodel import WebModel, PhangoField import json diff --git a/paramecio2/libraries/db/extrafields/emailfield.py b/paramecio2/libraries/db/extrafields/emailfield.py index 88d1afd..3473703 100644 --- a/paramecio2/libraries/db/extrafields/emailfield.py +++ b/paramecio2/libraries/db/extrafields/emailfield.py @@ -1,3 +1,22 @@ +""" +Paramecio2fm is a series of wrappers for Flask, mako and others and construct a simple headless cms. + +Copyright (C) 2023 Antonio de la Rosa Caballero + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program 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 Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +""" + from paramecio2.libraries.db.corefields import CharField import re diff --git a/paramecio2/libraries/db/extrafields/filefield.py b/paramecio2/libraries/db/extrafields/filefield.py index 30cb849..b03f4c1 100644 --- a/paramecio2/libraries/db/extrafields/filefield.py +++ b/paramecio2/libraries/db/extrafields/filefield.py @@ -1,3 +1,22 @@ +""" +Paramecio2fm is a series of wrappers for Flask, mako and others and construct a simple headless cms. + +Copyright (C) 2023 Antonio de la Rosa Caballero + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program 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 Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +""" + import os import sys from pathlib import Path diff --git a/paramecio2/libraries/db/extrafields/i18nfield.py b/paramecio2/libraries/db/extrafields/i18nfield.py index 2b57c09..f04e867 100644 --- a/paramecio2/libraries/db/extrafields/i18nfield.py +++ b/paramecio2/libraries/db/extrafields/i18nfield.py @@ -1,5 +1,24 @@ #!/usr/bin/env python3 +""" +Paramecio2fm is a series of wrappers for Flask, mako and others and construct a simple headless cms. + +Copyright (C) 2023 Antonio de la Rosa Caballero + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program 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 Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +""" + import json from paramecio2.libraries.db.webmodel import PhangoField from paramecio2.libraries.db.coreforms import BaseForm diff --git a/paramecio2/libraries/db/extrafields/imagefield.py b/paramecio2/libraries/db/extrafields/imagefield.py index 7d01018..07d62f9 100644 --- a/paramecio2/libraries/db/extrafields/imagefield.py +++ b/paramecio2/libraries/db/extrafields/imagefield.py @@ -1,3 +1,22 @@ +""" +Paramecio2fm is a series of wrappers for Flask, mako and others and construct a simple headless cms. + +Copyright (C) 2023 Antonio de la Rosa Caballero + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program 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 Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +""" + import os import sys from pathlib import Path diff --git a/paramecio2/libraries/db/extrafields/ipfield.py b/paramecio2/libraries/db/extrafields/ipfield.py index 7044798..f221add 100644 --- a/paramecio2/libraries/db/extrafields/ipfield.py +++ b/paramecio2/libraries/db/extrafields/ipfield.py @@ -1,3 +1,22 @@ +""" +Paramecio2fm is a series of wrappers for Flask, mako and others and construct a simple headless cms. + +Copyright (C) 2023 Antonio de la Rosa Caballero + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program 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 Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +""" + from paramecio2.libraries.db.corefields import CharField import ipaddress diff --git a/paramecio2/libraries/db/extrafields/jsonfield.py b/paramecio2/libraries/db/extrafields/jsonfield.py index 80897ff..ba65efb 100644 --- a/paramecio2/libraries/db/extrafields/jsonfield.py +++ b/paramecio2/libraries/db/extrafields/jsonfield.py @@ -1,3 +1,22 @@ +""" +Paramecio2fm is a series of wrappers for Flask, mako and others and construct a simple headless cms. + +Copyright (C) 2023 Antonio de la Rosa Caballero + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program 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 Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +""" + from paramecio2.libraries.db.webmodel import WebModel, PhangoField import sys try: diff --git a/paramecio2/libraries/db/extrafields/langfield.py b/paramecio2/libraries/db/extrafields/langfield.py index a6cac37..8e9f013 100644 --- a/paramecio2/libraries/db/extrafields/langfield.py +++ b/paramecio2/libraries/db/extrafields/langfield.py @@ -1,5 +1,24 @@ #!/usr/bin/env python3 +""" +Paramecio2fm is a series of wrappers for Flask, mako and others and construct a simple headless cms. + +Copyright (C) 2023 Antonio de la Rosa Caballero + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program 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 Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +""" + from paramecio2.libraries.db.corefields import CharField from paramecio2.libraries.db import coreforms from paramecio2.libraries.i18n import I18n diff --git a/paramecio2/libraries/db/extrafields/moneyfield.py b/paramecio2/libraries/db/extrafields/moneyfield.py index 812db21..501ecde 100644 --- a/paramecio2/libraries/db/extrafields/moneyfield.py +++ b/paramecio2/libraries/db/extrafields/moneyfield.py @@ -1,3 +1,22 @@ +""" +Paramecio2fm is a series of wrappers for Flask, mako and others and construct a simple headless cms. + +Copyright (C) 2023 Antonio de la Rosa Caballero + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program 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 Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +""" + from paramecio2.libraries.db.corefields import DecimalField from decimal import Decimal, getcontext from locale import format_string diff --git a/paramecio2/libraries/db/extrafields/parentfield.py b/paramecio2/libraries/db/extrafields/parentfield.py index 06f197a..6ef0718 100644 --- a/paramecio2/libraries/db/extrafields/parentfield.py +++ b/paramecio2/libraries/db/extrafields/parentfield.py @@ -1,5 +1,24 @@ #!/usr/bin/env python3 +""" +Paramecio2fm is a series of wrappers for Flask, mako and others and construct a simple headless cms. + +Copyright (C) 2023 Antonio de la Rosa Caballero + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program 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 Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +""" + #from paramecio2.libraries.db.webmodel import PhangoField from paramecio2.libraries.db.corefields import IntegerField from paramecio2.libraries.db.coreforms import SelectModelForm diff --git a/paramecio2/libraries/db/extrafields/passwordfield.py b/paramecio2/libraries/db/extrafields/passwordfield.py index 08985f7..2e76aa9 100644 --- a/paramecio2/libraries/db/extrafields/passwordfield.py +++ b/paramecio2/libraries/db/extrafields/passwordfield.py @@ -1,3 +1,22 @@ +""" +Paramecio2fm is a series of wrappers for Flask, mako and others and construct a simple headless cms. + +Copyright (C) 2023 Antonio de la Rosa Caballero + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program 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 Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +""" + from paramecio2.libraries.db.corefields import PhangoField from paramecio2.libraries.db.coreforms import PasswordForm from hmac import compare_digest as compare_hash diff --git a/paramecio2/libraries/db/extrafields/percentfield.py b/paramecio2/libraries/db/extrafields/percentfield.py index fad839d..ff91967 100644 --- a/paramecio2/libraries/db/extrafields/percentfield.py +++ b/paramecio2/libraries/db/extrafields/percentfield.py @@ -1,3 +1,22 @@ +""" +Paramecio2fm is a series of wrappers for Flask, mako and others and construct a simple headless cms. + +Copyright (C) 2023 Antonio de la Rosa Caballero + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program 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 Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +""" + from paramecio2.libraries.db.corefields import DecimalField class PercentField(DecimalField): diff --git a/paramecio2/libraries/db/extrafields/slugifyfield.py b/paramecio2/libraries/db/extrafields/slugifyfield.py index 2fc61c3..ab0f995 100644 --- a/paramecio2/libraries/db/extrafields/slugifyfield.py +++ b/paramecio2/libraries/db/extrafields/slugifyfield.py @@ -1,5 +1,24 @@ #!/usr/bin/env python3 +""" +Paramecio2fm is a series of wrappers for Flask, mako and others and construct a simple headless cms. + +Copyright (C) 2023 Antonio de la Rosa Caballero + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program 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 Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +""" + from paramecio2.libraries.db.corefields import CharField from slugify import slugify from paramecio2.libraries.db.coreforms import HiddenForm diff --git a/paramecio2/libraries/db/extrafields/urlfield.py b/paramecio2/libraries/db/extrafields/urlfield.py index 314b452..5dad3fc 100644 --- a/paramecio2/libraries/db/extrafields/urlfield.py +++ b/paramecio2/libraries/db/extrafields/urlfield.py @@ -1,3 +1,22 @@ +""" +Paramecio2fm is a series of wrappers for Flask, mako and others and construct a simple headless cms. + +Copyright (C) 2023 Antonio de la Rosa Caballero + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program 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 Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +""" + from paramecio2.libraries.db.corefields import CharField import re import ipaddress diff --git a/paramecio2/libraries/db/extrafields/usernamefield.py b/paramecio2/libraries/db/extrafields/usernamefield.py index 16c300f..0491858 100644 --- a/paramecio2/libraries/db/extrafields/usernamefield.py +++ b/paramecio2/libraries/db/extrafields/usernamefield.py @@ -1,3 +1,22 @@ +""" +Paramecio2fm is a series of wrappers for Flask, mako and others and construct a simple headless cms. + +Copyright (C) 2023 Antonio de la Rosa Caballero + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program 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 Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +""" + from paramecio2.libraries.db.corefields import PhangoField from paramecio2.libraries.db.coreforms import PasswordForm from hmac import compare_digest as compare_hash diff --git a/paramecio2/libraries/db/extraforms/__init__.py b/paramecio2/libraries/db/extraforms/__init__.py index e69de29..2616e97 100644 --- a/paramecio2/libraries/db/extraforms/__init__.py +++ b/paramecio2/libraries/db/extraforms/__init__.py @@ -0,0 +1,18 @@ +""" +Paramecio2fm is a series of wrappers for Flask, mako and others and construct a simple headless cms. + +Copyright (C) 2023 Antonio de la Rosa Caballero + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program 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 Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +""" diff --git a/paramecio2/libraries/db/extraforms/checkform.py b/paramecio2/libraries/db/extraforms/checkform.py index 943ae34..a0658a0 100644 --- a/paramecio2/libraries/db/extraforms/checkform.py +++ b/paramecio2/libraries/db/extraforms/checkform.py @@ -1,5 +1,24 @@ #!/usr/bin/env python3 +""" +Paramecio2fm is a series of wrappers for Flask, mako and others and construct a simple headless cms. + +Copyright (C) 2023 Antonio de la Rosa Caballero + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program 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 Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +""" + from paramecio2.libraries.db.coreforms import BaseForm class CheckForm(BaseForm): diff --git a/paramecio2/libraries/db/extraforms/colorform.py b/paramecio2/libraries/db/extraforms/colorform.py index 4b6b62b..546609f 100644 --- a/paramecio2/libraries/db/extraforms/colorform.py +++ b/paramecio2/libraries/db/extraforms/colorform.py @@ -1,5 +1,24 @@ #!/usr/bin/env python3 +""" +Paramecio2fm is a series of wrappers for Flask, mako and others and construct a simple headless cms. + +Copyright (C) 2023 Antonio de la Rosa Caballero + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program 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 Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +""" + from paramecio2.libraries.db.coreforms import BaseForm from paramecio2.libraries.mtemplates import standard_t diff --git a/paramecio2/libraries/db/extraforms/dateform.py b/paramecio2/libraries/db/extraforms/dateform.py index c888c6f..09a8892 100644 --- a/paramecio2/libraries/db/extraforms/dateform.py +++ b/paramecio2/libraries/db/extraforms/dateform.py @@ -1,5 +1,24 @@ #!/usr/bin/env python3 +""" +Paramecio2fm is a series of wrappers for Flask, mako and others and construct a simple headless cms. + +Copyright (C) 2023 Antonio de la Rosa Caballero + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program 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 Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +""" + from paramecio2.libraries.db.coreforms import BaseForm from paramecio2.libraries.mtemplates import standard_t from paramecio2.libraries.datetime import format_timedata diff --git a/paramecio2/libraries/db/extraforms/fileform.py b/paramecio2/libraries/db/extraforms/fileform.py index ba64248..cc1d3a6 100644 --- a/paramecio2/libraries/db/extraforms/fileform.py +++ b/paramecio2/libraries/db/extraforms/fileform.py @@ -1,5 +1,24 @@ #!/usr/bin/env python3 +""" +Paramecio2fm is a series of wrappers for Flask, mako and others and construct a simple headless cms. + +Copyright (C) 2023 Antonio de la Rosa Caballero + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program 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 Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +""" + from paramecio2.libraries.db.coreforms import BaseForm from paramecio2.libraries.mtemplates import env_theme, PTemplate diff --git a/paramecio2/libraries/db/extraforms/i18nform.py b/paramecio2/libraries/db/extraforms/i18nform.py index 410f103..6272dd1 100644 --- a/paramecio2/libraries/db/extraforms/i18nform.py +++ b/paramecio2/libraries/db/extraforms/i18nform.py @@ -1,5 +1,24 @@ #!/usr/bin/env python3 +""" +Paramecio2fm is a series of wrappers for Flask, mako and others and construct a simple headless cms. + +Copyright (C) 2023 Antonio de la Rosa Caballero + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program 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 Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +""" + from paramecio2.libraries.db.coreforms import BaseForm from paramecio2.libraries.i18n import I18n from paramecio2.libraries.mtemplates import standard_t diff --git a/paramecio2/libraries/db/extraforms/texthtmlform.py b/paramecio2/libraries/db/extraforms/texthtmlform.py index 6ba9d73..3dbdf06 100644 --- a/paramecio2/libraries/db/extraforms/texthtmlform.py +++ b/paramecio2/libraries/db/extraforms/texthtmlform.py @@ -1,3 +1,21 @@ +""" +Paramecio2fm is a series of wrappers for Flask, mako and others and construct a simple headless cms. + +Copyright (C) 2023 Antonio de la Rosa Caballero + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program 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 Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +""" from paramecio2.libraries.db.coreforms import BaseForm from paramecio2.libraries.mtemplates import env_theme, PTemplate diff --git a/paramecio2/libraries/db/extraforms/usernameform.py b/paramecio2/libraries/db/extraforms/usernameform.py index ffcef75..1a82527 100644 --- a/paramecio2/libraries/db/extraforms/usernameform.py +++ b/paramecio2/libraries/db/extraforms/usernameform.py @@ -1,3 +1,21 @@ +""" +Paramecio2fm is a series of wrappers for Flask, mako and others and construct a simple headless cms. + +Copyright (C) 2023 Antonio de la Rosa Caballero + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program 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 Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +""" from paramecio2.libraries.db.coreforms import BaseForm from paramecio2.libraries.mtemplates import env_theme, PTemplate diff --git a/paramecio2/libraries/formsutils.py b/paramecio2/libraries/formsutils.py index 0f87a20..aeb9ebd 100644 --- a/paramecio2/libraries/formsutils.py +++ b/paramecio2/libraries/formsutils.py @@ -1,5 +1,24 @@ #!/usr/bin/env python3 +""" +Paramecio2fm is a series of wrappers for Flask, mako and others and construct a simple headless cms. + +Copyright (C) 2023 Antonio de la Rosa Caballero + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program 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 Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +""" + from paramecio2.libraries.db import corefields from paramecio2.libraries.db.coreforms import PasswordForm from paramecio2.libraries.i18n import I18n diff --git a/paramecio2/libraries/generate_admin_class.py b/paramecio2/libraries/generate_admin_class.py index 114458a..52ca1b8 100644 --- a/paramecio2/libraries/generate_admin_class.py +++ b/paramecio2/libraries/generate_admin_class.py @@ -1,3 +1,22 @@ +""" +Paramecio2fm is a series of wrappers for Flask, mako and others and construct a simple headless cms. + +Copyright (C) 2023 Antonio de la Rosa Caballero + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program 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 Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +""" + from paramecio2.libraries.lists import SimpleList from flask import request, redirect, flash from paramecio2.libraries.urls import add_get_parameters diff --git a/paramecio2/libraries/get_data.py b/paramecio2/libraries/get_data.py index d995e95..e460f14 100644 --- a/paramecio2/libraries/get_data.py +++ b/paramecio2/libraries/get_data.py @@ -1,3 +1,21 @@ +""" +Paramecio2fm is a series of wrappers for Flask, mako and others and construct a simple headless cms. + +Copyright (C) 2023 Antonio de la Rosa Caballero + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program 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 Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +""" from flask import request diff --git a/paramecio2/libraries/i18n.py b/paramecio2/libraries/i18n.py index 752bc08..516a879 100644 --- a/paramecio2/libraries/i18n.py +++ b/paramecio2/libraries/i18n.py @@ -1,5 +1,24 @@ #!/usr/bin/env python3 +""" +Paramecio2fm is a series of wrappers for Flask, mako and others and construct a simple headless cms. + +Copyright (C) 2023 Antonio de la Rosa Caballero + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program 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 Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +""" + from importlib import import_module import gettext #from paramecio.citoplasma.sessions import get_session diff --git a/paramecio2/libraries/keyutils.py b/paramecio2/libraries/keyutils.py index fcbef1c..7b0abda 100644 --- a/paramecio2/libraries/keyutils.py +++ b/paramecio2/libraries/keyutils.py @@ -1,3 +1,22 @@ +""" +Paramecio2fm is a series of wrappers for Flask, mako and others and construct a simple headless cms. + +Copyright (C) 2023 Antonio de la Rosa Caballero + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program 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 Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +""" + from hashlib import sha512, sha256 from base64 import b64encode from os import urandom diff --git a/paramecio2/libraries/lists.py b/paramecio2/libraries/lists.py index 0ff00f0..8a2b586 100644 --- a/paramecio2/libraries/lists.py +++ b/paramecio2/libraries/lists.py @@ -1,3 +1,22 @@ +""" +Paramecio2fm is a series of wrappers for Flask, mako and others and construct a simple headless cms. + +Copyright (C) 2023 Antonio de la Rosa Caballero + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program 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 Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +""" + #By default id is not showed from paramecio2.libraries.pages import Pages diff --git a/paramecio2/libraries/load_apps.py b/paramecio2/libraries/load_apps.py index 81ef7ad..936343d 100644 --- a/paramecio2/libraries/load_apps.py +++ b/paramecio2/libraries/load_apps.py @@ -1,3 +1,22 @@ +""" +Paramecio2fm is a series of wrappers for Flask, mako and others and construct a simple headless cms. + +Copyright (C) 2023 Antonio de la Rosa Caballero + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program 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 Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +""" + import csv import os diff --git a/paramecio2/libraries/mtemplates.py b/paramecio2/libraries/mtemplates.py index 1cb8371..b628083 100644 --- a/paramecio2/libraries/mtemplates.py +++ b/paramecio2/libraries/mtemplates.py @@ -1,3 +1,22 @@ +""" +Paramecio2fm is a series of wrappers for Flask, mako and others and construct a simple headless cms. + +Copyright (C) 2023 Antonio de la Rosa Caballero + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program 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 Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +""" + # Template frontend from mako. #import gettext diff --git a/paramecio2/libraries/pages.py b/paramecio2/libraries/pages.py index d2c9b0e..3a7192c 100644 --- a/paramecio2/libraries/pages.py +++ b/paramecio2/libraries/pages.py @@ -1,5 +1,24 @@ #!/usr/bin/env python3 +""" +Paramecio2fm is a series of wrappers for Flask, mako and others and construct a simple headless cms. + +Copyright (C) 2023 Antonio de la Rosa Caballero + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program 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 Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +""" + from math import ceil, floor from paramecio2.libraries.urls import add_get_parameters from paramecio2.libraries.i18n import I18n diff --git a/paramecio2/libraries/plugins.py b/paramecio2/libraries/plugins.py index 3594140..f44ca58 100644 --- a/paramecio2/libraries/plugins.py +++ b/paramecio2/libraries/plugins.py @@ -1,3 +1,22 @@ +""" +Paramecio2fm is a series of wrappers for Flask, mako and others and construct a simple headless cms. + +Copyright (C) 2023 Antonio de la Rosa Caballero + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program 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 Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +""" + from flask import g, session, redirect, url_for from functools import wraps from paramecio2.libraries.db.webmodel import WebModel diff --git a/paramecio2/libraries/sendmail.py b/paramecio2/libraries/sendmail.py index a8ea42e..116dd2f 100644 --- a/paramecio2/libraries/sendmail.py +++ b/paramecio2/libraries/sendmail.py @@ -1,4 +1,24 @@ #!/usr/bin/env python3 + +""" +Paramecio2fm is a series of wrappers for Flask, mako and others and construct a simple headless cms. + +Copyright (C) 2023 Antonio de la Rosa Caballero + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program 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 Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +""" + import os import smtplib import mimetypes diff --git a/paramecio2/libraries/slugify.py b/paramecio2/libraries/slugify.py index f2ad2b9..433758c 100644 --- a/paramecio2/libraries/slugify.py +++ b/paramecio2/libraries/slugify.py @@ -1,3 +1,22 @@ +""" +Paramecio2fm is a series of wrappers for Flask, mako and others and construct a simple headless cms. + +Copyright (C) 2023 Antonio de la Rosa Caballero + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program 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 Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +""" + from slugify import slugify as slugify_func def slugify(slug, *args, **wargs): diff --git a/paramecio2/libraries/urls.py b/paramecio2/libraries/urls.py index ffe38cf..4f621e5 100644 --- a/paramecio2/libraries/urls.py +++ b/paramecio2/libraries/urls.py @@ -1,3 +1,22 @@ +""" +Paramecio2fm is a series of wrappers for Flask, mako and others and construct a simple headless cms. + +Copyright (C) 2023 Antonio de la Rosa Caballero + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program 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 Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +""" + try: from settings import config except: From 56be4adbfab0f3737e4fe7457d20c02d9a01b9c1 Mon Sep 17 00:00:00 2001 From: absurdo Date: Sun, 31 Dec 2023 11:55:43 +0100 Subject: [PATCH 11/85] Updated submodule --- paramecio2/modules/admin/media/js/jsutils | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/paramecio2/modules/admin/media/js/jsutils b/paramecio2/modules/admin/media/js/jsutils index 9c7b055..82db143 160000 --- a/paramecio2/modules/admin/media/js/jsutils +++ b/paramecio2/modules/admin/media/js/jsutils @@ -1 +1 @@ -Subproject commit 9c7b05577e4144aa04851126cc1dfec89088a429 +Subproject commit 82db143dc0e911a26f6125c023543adb5e60109d From e53840feccc5b29e2a7caf9e0afec7e3ea7c9e35 Mon Sep 17 00:00:00 2001 From: absurdo Date: Sun, 7 Jan 2024 01:11:48 +0100 Subject: [PATCH 12/85] Updated jquery --- paramecio2/libraries/db/extrafields/i18nfield.py | 2 +- paramecio2/libraries/db/sqlalchemy.py | 3 +++ paramecio2/modules/admin/media/js/jquery.min.js | 4 ++-- paramecio2/modules/admin/templates/dashboard.phtml | 8 +++++++- 4 files changed, 13 insertions(+), 4 deletions(-) diff --git a/paramecio2/libraries/db/extrafields/i18nfield.py b/paramecio2/libraries/db/extrafields/i18nfield.py index f04e867..772f34a 100644 --- a/paramecio2/libraries/db/extrafields/i18nfield.py +++ b/paramecio2/libraries/db/extrafields/i18nfield.py @@ -109,7 +109,7 @@ class I18nField(PhangoField): def get_type_sql(self): - return 'TEXT NOT NULL' + return 'JSON NOT NULL' def obtain_lang_value(self, lang, value): diff --git a/paramecio2/libraries/db/sqlalchemy.py b/paramecio2/libraries/db/sqlalchemy.py index c7da074..c0d7dfc 100644 --- a/paramecio2/libraries/db/sqlalchemy.py +++ b/paramecio2/libraries/db/sqlalchemy.py @@ -73,6 +73,9 @@ class SqlClass: engine=create_engine("mysql+%s://%s:%s@%s/%s?charset=utf8mb4" % (self.connection['db_type'], self.connection['user'], self.connection['password'], self.connection['host'], self.connection['db']), pool_recycle=self.pool_recycle, echo_pool=True, pool_size=self.pool_size, pool_pre_ping=True) + #Postgre + #engine = create_engine("postgresql+psycopg2://scott:tiger@localhost:5432/mydatabase") + except: e = sys.exc_info()[0] v = sys.exc_info()[1] diff --git a/paramecio2/modules/admin/media/js/jquery.min.js b/paramecio2/modules/admin/media/js/jquery.min.js index 0de648e..7f37b5d 100644 --- a/paramecio2/modules/admin/media/js/jquery.min.js +++ b/paramecio2/modules/admin/media/js/jquery.min.js @@ -1,2 +1,2 @@ -/*! jQuery v3.6.4 | (c) OpenJS Foundation and other contributors | jquery.org/license */ -!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){"use strict";var t=[],r=Object.getPrototypeOf,s=t.slice,g=t.flat?function(e){return t.flat.call(e)}:function(e){return t.concat.apply([],e)},u=t.push,i=t.indexOf,n={},o=n.toString,y=n.hasOwnProperty,a=y.toString,l=a.call(Object),v={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType&&"function"!=typeof e.item},x=function(e){return null!=e&&e===e.window},E=C.document,c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.6.4",S=function(e,t){return new S.fn.init(e,t)};function p(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp(F),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+F),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\([^\\r\\n\\f])","g"),ne=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(p.childNodes),p.childNodes),t[p.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&v(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!N[t+" "]&&(!y||!y.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&(U.test(t)||z.test(t))){(f=ee.test(t)&&ve(e.parentNode)||e)===e&&d.scope||((s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=S)),o=(l=h(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+xe(l[o]);c=l.join(",")}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){N(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return g(t.replace(B,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[S]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ye(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ve(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e&&e.namespaceURI,n=e&&(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:p;return r!=C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),p!=C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.scope=ce(function(e){return a.appendChild(e).appendChild(C.createElement("div")),"undefined"!=typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),d.cssHas=ce(function(){try{return C.querySelector(":has(*,:jqfake)"),!1}catch(e){return!0}}),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=S,!C.getElementsByName||!C.getElementsByName(S).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],y=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){var t;a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&y.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||y.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+S+"-]").length||y.push("~="),(t=C.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||y.push("\\["+M+"*name"+M+"*="+M+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||y.push(":checked"),e.querySelectorAll("a#"+S+"+*").length||y.push(".#.+[+~]"),e.querySelectorAll("\\\f"),y.push("[\\r\\n\\f]")}),ce(function(e){e.innerHTML="";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&y.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&y.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&y.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),y.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",F)}),d.cssHas||y.push(":has"),y=y.length&&new RegExp(y.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),v=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType&&e.documentElement||e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},j=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e==C||e.ownerDocument==p&&v(p,e)?-1:t==C||t.ownerDocument==p&&v(p,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e==C?-1:t==C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]==p?-1:s[r]==p?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(T(e),d.matchesSelector&&E&&!N[t+" "]&&(!s||!s.test(t))&&(!y||!y.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){N(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=m[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&m(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,n,r){return m(n)?S.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?S.grep(e,function(e){return e===n!==r}):"string"!=typeof n?S.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(S.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||D,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:q.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof S?t[0]:t,S.merge(this,S.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),N.test(r[1])&&S.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(S):S.makeArray(e,this)}).prototype=S.fn,D=S(E);var L=/^(?:parents|prev(?:Until|All))/,H={children:!0,contents:!0,next:!0,prev:!0};function O(e,t){while((e=e[t])&&1!==e.nodeType);return e}S.fn.extend({has:function(e){var t=S(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i;ce=E.createDocumentFragment().appendChild(E.createElement("div")),(fe=E.createElement("input")).setAttribute("type","radio"),fe.setAttribute("checked","checked"),fe.setAttribute("name","t"),ce.appendChild(fe),v.checkClone=ce.cloneNode(!0).cloneNode(!0).lastChild.checked,ce.innerHTML="",v.noCloneChecked=!!ce.cloneNode(!0).lastChild.defaultValue,ce.innerHTML="",v.option=!!ce.lastChild;var ge={thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function ye(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?S.merge([e],n):n}function ve(e,t){for(var n=0,r=e.length;n",""]);var me=/<|&#?\w+;/;function xe(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function je(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&S(e).children("tbody")[0]||e}function De(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function qe(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Le(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(Y.hasData(e)&&(s=Y.get(e).events))for(i in Y.remove(t,"handle events"),s)for(n=0,r=s[i].length;n").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var Ut,Xt=[],Vt=/(=)\?(?=&|$)|\?\?/;S.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Xt.pop()||S.expando+"_"+Ct.guid++;return this[e]=!0,e}}),S.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Vt.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Vt.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Vt,"$1"+r):!1!==e.jsonp&&(e.url+=(Et.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||S.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?S(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,Xt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),v.createHTMLDocument=((Ut=E.implementation.createHTMLDocument("").body).innerHTML="
",2===Ut.childNodes.length),S.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(v.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=N.exec(e))?[t.createElement(i[1])]:(i=xe([e],t,o),o&&o.length&&S(o).remove(),S.merge([],i.childNodes)));var r,i,o},S.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(S.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},S.expr.pseudos.animated=function(t){return S.grep(S.timers,function(e){return t===e.elem}).length},S.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=S.css(e,"position"),c=S(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=S.css(e,"top"),u=S.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,S.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},S.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){S.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===S.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===S.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=S(e).offset()).top+=S.css(e,"borderTopWidth",!0),i.left+=S.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-S.css(r,"marginTop",!0),left:t.left-i.left-S.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===S.css(e,"position"))e=e.offsetParent;return e||re})}}),S.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;S.fn[t]=function(e){return B(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),S.each(["top","left"],function(e,n){S.cssHooks[n]=_e(v.pixelPosition,function(e,t){if(t)return t=Be(e,n),Pe.test(t)?S(e).position()[n]+"px":t})}),S.each({Height:"height",Width:"width"},function(a,s){S.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){S.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return B(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?S.css(e,t,i):S.style(e,t,n,i)},s,n?e:void 0,n)}})}),S.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){S.fn[t]=function(e){return this.on(t,e)}}),S.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),S.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){S.fn[n]=function(e,t){return 0+~]|"+ge+")"+ge+"*"),x=new RegExp(ge+"|>"),j=new RegExp(g),A=new RegExp("^"+t+"$"),D={ID:new RegExp("^#("+t+")"),CLASS:new RegExp("^\\.("+t+")"),TAG:new RegExp("^("+t+"|[*])"),ATTR:new RegExp("^"+p),PSEUDO:new RegExp("^"+g),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+ge+"*(even|odd|(([+-]|)(\\d*)n|)"+ge+"*(?:([+-]|)"+ge+"*(\\d+)|))"+ge+"*\\)|)","i"),bool:new RegExp("^(?:"+f+")$","i"),needsContext:new RegExp("^"+ge+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+ge+"*((?:-\\d)?\\d*)"+ge+"*\\)|)(?=[^-]|$)","i")},N=/^(?:input|select|textarea|button)$/i,q=/^h\d$/i,L=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,H=/[+~]/,O=new RegExp("\\\\[\\da-fA-F]{1,6}"+ge+"?|\\\\([^\\r\\n\\f])","g"),P=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},M=function(){V()},R=J(function(e){return!0===e.disabled&&fe(e,"fieldset")},{dir:"parentNode",next:"legend"});try{k.apply(oe=ae.call(ye.childNodes),ye.childNodes),oe[ye.childNodes.length].nodeType}catch(e){k={apply:function(e,t){me.apply(e,ae.call(t))},call:function(e){me.apply(e,ae.call(arguments,1))}}}function I(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(V(e),e=e||T,C)){if(11!==p&&(u=L.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return k.call(n,a),n}else if(f&&(a=f.getElementById(i))&&I.contains(e,a)&&a.id===i)return k.call(n,a),n}else{if(u[2])return k.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&e.getElementsByClassName)return k.apply(n,e.getElementsByClassName(i)),n}if(!(h[t+" "]||d&&d.test(t))){if(c=t,f=e,1===p&&(x.test(t)||m.test(t))){(f=H.test(t)&&U(e.parentNode)||e)==e&&le.scope||((s=e.getAttribute("id"))?s=ce.escapeSelector(s):e.setAttribute("id",s=S)),o=(l=Y(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+Q(l[o]);c=l.join(",")}try{return k.apply(n,f.querySelectorAll(c)),n}catch(e){h(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return re(t.replace(ve,"$1"),e,n,r)}function W(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function F(e){return e[S]=!0,e}function $(e){var t=T.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function B(t){return function(e){return fe(e,"input")&&e.type===t}}function _(t){return function(e){return(fe(e,"input")||fe(e,"button"))&&e.type===t}}function z(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&R(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function X(a){return F(function(o){return o=+o,F(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function U(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}function V(e){var t,n=e?e.ownerDocument||e:ye;return n!=T&&9===n.nodeType&&n.documentElement&&(r=(T=n).documentElement,C=!ce.isXMLDoc(T),i=r.matches||r.webkitMatchesSelector||r.msMatchesSelector,r.msMatchesSelector&&ye!=T&&(t=T.defaultView)&&t.top!==t&&t.addEventListener("unload",M),le.getById=$(function(e){return r.appendChild(e).id=ce.expando,!T.getElementsByName||!T.getElementsByName(ce.expando).length}),le.disconnectedMatch=$(function(e){return i.call(e,"*")}),le.scope=$(function(){return T.querySelectorAll(":scope")}),le.cssHas=$(function(){try{return T.querySelector(":has(*,:jqfake)"),!1}catch(e){return!0}}),le.getById?(b.filter.ID=function(e){var t=e.replace(O,P);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&C){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(O,P);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&C){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):t.querySelectorAll(e)},b.find.CLASS=function(e,t){if("undefined"!=typeof t.getElementsByClassName&&C)return t.getElementsByClassName(e)},d=[],$(function(e){var t;r.appendChild(e).innerHTML="",e.querySelectorAll("[selected]").length||d.push("\\["+ge+"*(?:value|"+f+")"),e.querySelectorAll("[id~="+S+"-]").length||d.push("~="),e.querySelectorAll("a#"+S+"+*").length||d.push(".#.+[+~]"),e.querySelectorAll(":checked").length||d.push(":checked"),(t=T.createElement("input")).setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),r.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&d.push(":enabled",":disabled"),(t=T.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||d.push("\\["+ge+"*name"+ge+"*="+ge+"*(?:''|\"\")")}),le.cssHas||d.push(":has"),d=d.length&&new RegExp(d.join("|")),l=function(e,t){if(e===t)return a=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!le.sortDetached&&t.compareDocumentPosition(e)===n?e===T||e.ownerDocument==ye&&I.contains(ye,e)?-1:t===T||t.ownerDocument==ye&&I.contains(ye,t)?1:o?se.call(o,e)-se.call(o,t):0:4&n?-1:1)}),T}for(e in I.matches=function(e,t){return I(e,null,null,t)},I.matchesSelector=function(e,t){if(V(e),C&&!h[t+" "]&&(!d||!d.test(t)))try{var n=i.call(e,t);if(n||le.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){h(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(O,P),e[3]=(e[3]||e[4]||e[5]||"").replace(O,P),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||I.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&I.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return D.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&j.test(n)&&(t=Y(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(O,P).toLowerCase();return"*"===e?function(){return!0}:function(e){return fe(e,t)}},CLASS:function(e){var t=s[e+" "];return t||(t=new RegExp("(^|"+ge+")"+e+"("+ge+"|$)"))&&s(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=I.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function T(e,n,r){return v(n)?ce.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?ce.grep(e,function(e){return e===n!==r}):"string"!=typeof n?ce.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(ce.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||k,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:S.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof ce?t[0]:t,ce.merge(this,ce.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:C,!0)),w.test(r[1])&&ce.isPlainObject(t))for(r in t)v(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=C.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):v(e)?void 0!==n.ready?n.ready(e):e(ce):ce.makeArray(e,this)}).prototype=ce.fn,k=ce(C);var E=/^(?:parents|prev(?:Until|All))/,j={children:!0,contents:!0,next:!0,prev:!0};function A(e,t){while((e=e[t])&&1!==e.nodeType);return e}ce.fn.extend({has:function(e){var t=ce(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,Ce=/^$|^module$|\/(?:java|ecma)script/i;xe=C.createDocumentFragment().appendChild(C.createElement("div")),(be=C.createElement("input")).setAttribute("type","radio"),be.setAttribute("checked","checked"),be.setAttribute("name","t"),xe.appendChild(be),le.checkClone=xe.cloneNode(!0).cloneNode(!0).lastChild.checked,xe.innerHTML="",le.noCloneChecked=!!xe.cloneNode(!0).lastChild.defaultValue,xe.innerHTML="",le.option=!!xe.lastChild;var ke={thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function Se(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&fe(e,t)?ce.merge([e],n):n}function Ee(e,t){for(var n=0,r=e.length;n",""]);var je=/<|&#?\w+;/;function Ae(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function Re(e,t){return fe(e,"table")&&fe(11!==t.nodeType?t:t.firstChild,"tr")&&ce(e).children("tbody")[0]||e}function Ie(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function We(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Fe(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(_.hasData(e)&&(s=_.get(e).events))for(i in _.remove(t,"handle events"),s)for(n=0,r=s[i].length;n").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),C.head.appendChild(r[0])},abort:function(){i&&i()}}});var Jt,Kt=[],Zt=/(=)\?(?=&|$)|\?\?/;ce.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Kt.pop()||ce.expando+"_"+jt.guid++;return this[e]=!0,e}}),ce.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Zt.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Zt.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=v(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Zt,"$1"+r):!1!==e.jsonp&&(e.url+=(At.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||ce.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=ie[r],ie[r]=function(){o=arguments},n.always(function(){void 0===i?ce(ie).removeProp(r):ie[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,Kt.push(r)),o&&v(i)&&i(o[0]),o=i=void 0}),"script"}),le.createHTMLDocument=((Jt=C.implementation.createHTMLDocument("").body).innerHTML="
",2===Jt.childNodes.length),ce.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(le.createHTMLDocument?((r=(t=C.implementation.createHTMLDocument("")).createElement("base")).href=C.location.href,t.head.appendChild(r)):t=C),o=!n&&[],(i=w.exec(e))?[t.createElement(i[1])]:(i=Ae([e],t,o),o&&o.length&&ce(o).remove(),ce.merge([],i.childNodes)));var r,i,o},ce.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(ce.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},ce.expr.pseudos.animated=function(t){return ce.grep(ce.timers,function(e){return t===e.elem}).length},ce.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=ce.css(e,"position"),c=ce(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=ce.css(e,"top"),u=ce.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),v(t)&&(t=t.call(e,n,ce.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},ce.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){ce.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===ce.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===ce.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=ce(e).offset()).top+=ce.css(e,"borderTopWidth",!0),i.left+=ce.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-ce.css(r,"marginTop",!0),left:t.left-i.left-ce.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===ce.css(e,"position"))e=e.offsetParent;return e||J})}}),ce.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;ce.fn[t]=function(e){return M(this,function(e,t,n){var r;if(y(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),ce.each(["top","left"],function(e,n){ce.cssHooks[n]=Ye(le.pixelPosition,function(e,t){if(t)return t=Ge(e,n),_e.test(t)?ce(e).position()[n]+"px":t})}),ce.each({Height:"height",Width:"width"},function(a,s){ce.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){ce.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return M(this,function(e,t,n){var r;return y(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?ce.css(e,t,i):ce.style(e,t,n,i)},s,n?e:void 0,n)}})}),ce.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){ce.fn[t]=function(e){return this.on(t,e)}}),ce.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.on("mouseenter",e).on("mouseleave",t||e)}}),ce.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){ce.fn[n]=function(e,t){return 0 - +
@@ -208,6 +208,12 @@ ${load_js()|n} }); + $(document).ready(function () { + + $('#layer_loading').hide(); + + }); + <%block name="jscript_block"> From 6361386f40c3e40ba7dcd133515a1d440c3289e3 Mon Sep 17 00:00:00 2001 From: absurdo Date: Sun, 7 Jan 2024 01:13:09 +0100 Subject: [PATCH 13/85] FIxes in jsutils --- paramecio2/modules/admin/media/js/jsutils | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/paramecio2/modules/admin/media/js/jsutils b/paramecio2/modules/admin/media/js/jsutils index 82db143..c261d12 160000 --- a/paramecio2/modules/admin/media/js/jsutils +++ b/paramecio2/modules/admin/media/js/jsutils @@ -1 +1 @@ -Subproject commit 82db143dc0e911a26f6125c023543adb5e60109d +Subproject commit c261d122848940ae6c4ada22344e2caac1550670 From 95ebe395b8f2dec98bafe8620ee86aac5cf14783 Mon Sep 17 00:00:00 2001 From: absurdo Date: Tue, 9 Jan 2024 02:05:55 +0100 Subject: [PATCH 14/85] Added function for extract post in a form dict --- paramecio2/libraries/formsutils.py | 11 +++++++++++ paramecio2/modules/admin/media/js/jsutils | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/paramecio2/libraries/formsutils.py b/paramecio2/libraries/formsutils.py index aeb9ebd..1effddf 100644 --- a/paramecio2/libraries/formsutils.py +++ b/paramecio2/libraries/formsutils.py @@ -179,6 +179,17 @@ def show_form(post, arr_form, t, yes_error=True, pass_values=True, modelform_tpl return t.load_template(modelform_tpl, forms=arr_form) +def extract_post(post, fields): + + """Helper function for create a simple array from other using fields list for filter + + Args: + post (dict): A dict with keys and values to filter. + fields (list): A list with keys to validate. + """ + + return {k:v for k,v in post.items() if k in fields} + #Simple Function for add repeat_password form to user model def set_extra_forms_user(user_admin): diff --git a/paramecio2/modules/admin/media/js/jsutils b/paramecio2/modules/admin/media/js/jsutils index c261d12..106db6a 160000 --- a/paramecio2/modules/admin/media/js/jsutils +++ b/paramecio2/modules/admin/media/js/jsutils @@ -1 +1 @@ -Subproject commit c261d122848940ae6c4ada22344e2caac1550670 +Subproject commit 106db6afd022ede12487c017d54b200e3a19ed8f From 5e18f2ba917555bf2f61f57022e98379f0bfb66e Mon Sep 17 00:00:00 2001 From: absurdo Date: Thu, 11 Jan 2024 00:14:33 +0100 Subject: [PATCH 15/85] Fixes in jsutils --- paramecio2/modules/admin/media/js/jsutils | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/paramecio2/modules/admin/media/js/jsutils b/paramecio2/modules/admin/media/js/jsutils index 106db6a..50b1d9f 160000 --- a/paramecio2/modules/admin/media/js/jsutils +++ b/paramecio2/modules/admin/media/js/jsutils @@ -1 +1 @@ -Subproject commit 106db6afd022ede12487c017d54b200e3a19ed8f +Subproject commit 50b1d9fd4fec0237c493e65c2c6c633bdfab0c15 From 0d6f95ab964d769d0ed43889094df745b3bdc274 Mon Sep 17 00:00:00 2001 From: absurdo Date: Fri, 12 Jan 2024 02:12:19 +0100 Subject: [PATCH 16/85] Added fixes to jsutils --- paramecio2/modules/admin/media/js/jsutils | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/paramecio2/modules/admin/media/js/jsutils b/paramecio2/modules/admin/media/js/jsutils index 50b1d9f..e4307d9 160000 --- a/paramecio2/modules/admin/media/js/jsutils +++ b/paramecio2/modules/admin/media/js/jsutils @@ -1 +1 @@ -Subproject commit 50b1d9fd4fec0237c493e65c2c6c633bdfab0c15 +Subproject commit e4307d908ba7deddc4326ff006d34c177637c56a From 189f3ffcce13b51fea4f17038a90be40b04e42fe Mon Sep 17 00:00:00 2001 From: Antonio de la Rosa Date: Tue, 16 Jan 2024 01:08:44 +0100 Subject: [PATCH 17/85] Fixes in ajaxlist --- paramecio2/modules/admin/media/js/jsutils | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/paramecio2/modules/admin/media/js/jsutils b/paramecio2/modules/admin/media/js/jsutils index e4307d9..1dcbd59 160000 --- a/paramecio2/modules/admin/media/js/jsutils +++ b/paramecio2/modules/admin/media/js/jsutils @@ -1 +1 @@ -Subproject commit e4307d908ba7deddc4326ff006d34c177637c56a +Subproject commit 1dcbd599d9d11f16c10c5a377c82bfb652694037 From 5fa28920da5b06849511f82a57dd1a74295aabdd Mon Sep 17 00:00:00 2001 From: Antonio de la Rosa Date: Sat, 20 Jan 2024 00:18:27 +0100 Subject: [PATCH 18/85] Fixes in jsutils and cleaning mysql code --- paramecio2/libraries/db/sqlalchemy.py | 13 +++++++++---- paramecio2/modules/admin/media/js/jsutils | 2 +- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/paramecio2/libraries/db/sqlalchemy.py b/paramecio2/libraries/db/sqlalchemy.py index c0d7dfc..9dcf592 100644 --- a/paramecio2/libraries/db/sqlalchemy.py +++ b/paramecio2/libraries/db/sqlalchemy.py @@ -46,6 +46,7 @@ class SqlClass: self.conn=None self.connected=False self.pool_recycle=3600 + self.last_query='' self.connect() @@ -166,23 +167,27 @@ class SqlClass: arguments (list): The data used in sql sentence. This data substitute the %s characters. name_connection (str): The name of dict element with the configuration of connection, without used in this moment. """ - + cursor=self.conn.cursor(SqlClass.cursors_connect) try: cursor.execute(sql_query, arguments) self.conn.commit() + + #if hasattr(cursor, '_executed'): + # self.last_query=cursor._executed + return cursor except: e = sys.exc_info()[0] v = sys.exc_info()[1] - if hasattr(cursor, '_last_executed'): - sql_query=cursor._last_executed + #if hasattr(cursor, '_executed'): + # self.last_query=cursor._executed - self.error_connection="Error in query ||%s||Values: %s" % (sql_query, str(arguments)) + self.error_connection="Error in query ||%s||Values: %s" % (self.last_query, str(arguments)) self.conn.close() diff --git a/paramecio2/modules/admin/media/js/jsutils b/paramecio2/modules/admin/media/js/jsutils index 1dcbd59..f317577 160000 --- a/paramecio2/modules/admin/media/js/jsutils +++ b/paramecio2/modules/admin/media/js/jsutils @@ -1 +1 @@ -Subproject commit 1dcbd599d9d11f16c10c5a377c82bfb652694037 +Subproject commit f3175777e395281e50ea05898a5db768e054d4a3 From e14dea021800e353d16113cd046bd83fc6c28927 Mon Sep 17 00:00:00 2001 From: Antonio de la Rosa Date: Sat, 20 Jan 2024 01:52:59 +0100 Subject: [PATCH 19/85] Update paramecio2 version --- paramecio2/modules/admin/media/js/jsutils | 2 +- setup.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/paramecio2/modules/admin/media/js/jsutils b/paramecio2/modules/admin/media/js/jsutils index f317577..c30600a 160000 --- a/paramecio2/modules/admin/media/js/jsutils +++ b/paramecio2/modules/admin/media/js/jsutils @@ -1 +1 @@ -Subproject commit f3175777e395281e50ea05898a5db768e054d4a3 +Subproject commit c30600ab752ee19765b3f6f7dd607280f96e18a2 diff --git a/setup.py b/setup.py index 79b23d6..7b1da7a 100644 --- a/setup.py +++ b/setup.py @@ -13,12 +13,12 @@ if sys.version_info < (3, 9): # If you install passlib and bcrypt, the password system will use bcrypt by default, if not, will use native crypt libc setup(name='paramecio2', - version='2.0.31', + version='2.0.32 ', description='Simple Web Framework based in flask and Mako.', long_description='This framework is a simple framework used for create web apps. Paramecio is modular and fast. By default have a module called admin that can be used for create admin sites', author='Antonio de la Rosa Caballero', author_email='antonio.delarosa@salirdelhoyo.com', - url='https://bitbucket.org/paramecio/paramecio2fm/', + url='https://git.cuchulu.com/paramecio/paramecio2fm/', packages=['paramecio2'], include_package_data=True, install_requires=['flask', 'pymysql', 'sqlalchemy', 'colorama', 'python-slugify', 'mako', 'pillow', 'arrow', 'bleach'], From b30413c952a44622319eeda5cb965950db4a46c1 Mon Sep 17 00:00:00 2001 From: absurdo Date: Sun, 21 Jan 2024 00:32:15 +0100 Subject: [PATCH 20/85] Fixes in jsutils --- paramecio2/modules/admin/media/js/jsutils | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/paramecio2/modules/admin/media/js/jsutils b/paramecio2/modules/admin/media/js/jsutils index c30600a..263dda4 160000 --- a/paramecio2/modules/admin/media/js/jsutils +++ b/paramecio2/modules/admin/media/js/jsutils @@ -1 +1 @@ -Subproject commit c30600ab752ee19765b3f6f7dd607280f96e18a2 +Subproject commit 263dda4721e7d352d8cdb61589b91b21411f67e4 From 3c9a0526b9f5b64ca8f0854d42a442d5cd64d990 Mon Sep 17 00:00:00 2001 From: absurdo Date: Sun, 21 Jan 2024 13:13:57 +0100 Subject: [PATCH 21/85] Fixes in jsutils --- paramecio2/modules/admin/media/js/jsutils | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/paramecio2/modules/admin/media/js/jsutils b/paramecio2/modules/admin/media/js/jsutils index 263dda4..dca8728 160000 --- a/paramecio2/modules/admin/media/js/jsutils +++ b/paramecio2/modules/admin/media/js/jsutils @@ -1 +1 @@ -Subproject commit 263dda4721e7d352d8cdb61589b91b21411f67e4 +Subproject commit dca8728315600eebe1f3a06bd690cde888f53cbd From a30f242cc8ea292cdb1a04e83096c9dc9eeedf40 Mon Sep 17 00:00:00 2001 From: absurdo Date: Wed, 24 Jan 2024 00:31:20 +0100 Subject: [PATCH 22/85] Making compatible with deprecation of crypt module in python --- .../libraries/db/extrafields/passwordfield.py | 20 ++++++++++-- paramecio2/modules/admin/app.py | 31 ++++++++++++++++++- setup.py | 2 +- 3 files changed, 48 insertions(+), 5 deletions(-) diff --git a/paramecio2/libraries/db/extrafields/passwordfield.py b/paramecio2/libraries/db/extrafields/passwordfield.py index 2e76aa9..19957ee 100644 --- a/paramecio2/libraries/db/extrafields/passwordfield.py +++ b/paramecio2/libraries/db/extrafields/passwordfield.py @@ -20,7 +20,13 @@ along with this program. If not, see . from paramecio2.libraries.db.corefields import PhangoField from paramecio2.libraries.db.coreforms import PasswordForm from hmac import compare_digest as compare_hash -import crypt +#try: +# import crypt +#except: +# pass + +#import bcrypt +from argon2 import PasswordHasher class PasswordField(PhangoField): """Field for check and save passwords""" @@ -63,7 +69,10 @@ class PasswordField(PhangoField): #salt=crypt.mksalt(crypt.METHOD_SHA512) if self.encrypt_password: - value=crypt.crypt(value) + #value=crypt.crypt(value) + ph=PasswordHasher() + final_value=ph.hash(value) + return final_value """ else: @@ -79,7 +88,12 @@ class PasswordField(PhangoField): def verify( password, h): """Static method used for verify a password save using PasswordField""" #return bcrypt_sha256.verify(password, h) - return compare_hash(h, crypt.crypt(password, h)) + #return compare_hash(h, crypt.crypt(password, h)) + ph=PasswordHasher() + try: + return ph.verify(h, password) + except: + return False # Old function bcrypt diff --git a/paramecio2/modules/admin/app.py b/paramecio2/modules/admin/app.py index 60e1b1d..c9b5b05 100644 --- a/paramecio2/modules/admin/app.py +++ b/paramecio2/modules/admin/app.py @@ -15,6 +15,13 @@ from os import path from paramecio2.modules.admin import admin_app, t from paramecio2.libraries.sendmail import SendMail from paramecio2.libraries.formsutils import check_csrf +from hmac import compare_digest as compare_hash + +try: + import crypt + crypt_pass=True +except: + crypt_pass=False #import gettext #_=pgettext(__file__) @@ -190,6 +197,7 @@ def logout(): def login(): #connection=WebModel.connection() + new_crypt=False user_admin=UserAdmin(g.connection) @@ -218,7 +226,21 @@ def login(): if arr_user and not check_login_tries(): - if user_admin.fields['password'].verify(password, arr_user['password']): + # Layer compatibility with old crypt password + + check_pass=user_admin.fields['password'].verify(password, arr_user['password']) + + if not check_pass: + #check_pass=password_ok(password, arr_user['password']) + try: + check_pass=compare_hash(arr_user['password'], crypt.crypt(password, arr_user['password'])) + new_crypt=True + except: + print('Warning: python developers deleting unix crypt module support, you cannot use sha512 passwords.') + check_pass=False + pass + + if check_pass: if not arr_user['disabled']: @@ -275,6 +297,13 @@ def login(): if len(arr_update)>0: + if new_crypt: + print('Changing password for %s to argon2' % arr_user['username']) + + user_admin.fields['password'].protected=False + + arr_update['password']=password + user_admin.set_conditions('WHERE id=%s', [arr_user['id']]).update(arr_update) return resp diff --git a/setup.py b/setup.py index 7b1da7a..3bc32e3 100644 --- a/setup.py +++ b/setup.py @@ -21,7 +21,7 @@ setup(name='paramecio2', url='https://git.cuchulu.com/paramecio/paramecio2fm/', packages=['paramecio2'], include_package_data=True, - install_requires=['flask', 'pymysql', 'sqlalchemy', 'colorama', 'python-slugify', 'mako', 'pillow', 'arrow', 'bleach'], + install_requires=['flask', 'pymysql', 'sqlalchemy', 'colorama', 'python-slugify', 'mako', 'pillow', 'arrow', 'bleach', 'argon2-cffi'], entry_points={'console_scripts': [ 'paramecio2 = paramecio2.console:start', 'paramecio2db = paramecio2.libraries.db.dbadmin:start', 'paramecio2lang = paramecio2.libraries.check_i18n:start', ]}, From 41a16f24ec324a5656d386970b1db514538fab8a Mon Sep 17 00:00:00 2001 From: absurdo Date: Thu, 25 Jan 2024 17:54:40 +0100 Subject: [PATCH 23/85] Fixes in popup.js --- paramecio2/modules/admin/media/js/jsutils | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/paramecio2/modules/admin/media/js/jsutils b/paramecio2/modules/admin/media/js/jsutils index dca8728..4cd1141 160000 --- a/paramecio2/modules/admin/media/js/jsutils +++ b/paramecio2/modules/admin/media/js/jsutils @@ -1 +1 @@ -Subproject commit dca8728315600eebe1f3a06bd690cde888f53cbd +Subproject commit 4cd11417ef9aa3cd3116516eb81d443068591404 From ceb36978deabf243eaf1220f4006958fe9b4979f Mon Sep 17 00:00:00 2001 From: absurdo Date: Wed, 31 Jan 2024 02:01:43 +0100 Subject: [PATCH 24/85] Fixes in lang fields --- .../libraries/templates/forms/i18nform.phtml | 19 ++++++++++++++++--- paramecio2/modules/admin/media/css/admin.css | 1 + 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/paramecio2/libraries/templates/forms/i18nform.phtml b/paramecio2/libraries/templates/forms/i18nform.phtml index 756e5a4..e0bc53e 100644 --- a/paramecio2/libraries/templates/forms/i18nform.phtml +++ b/paramecio2/libraries/templates/forms/i18nform.phtml @@ -3,7 +3,7 @@ choose='' %> -
+ <%def name="select_lang(i18n, lang_selected)"> % if i18n==lang_selected: <% @@ -28,10 +28,23 @@ choose='' <% form.default_value=default_value[i18n] %> - ${form.form()|n} ${name_form}_${i18n} + ${form.form()|n} ${name_form}_${i18n} + % endfor + + % endif -
+% if len(arr_i18n)==1: + + + +% endif + diff --git a/paramecio2/modules/admin/templates/login.phtml b/paramecio2/modules/admin/templates/login.phtml index 2ff47e8..ca5c0cc 100644 --- a/paramecio2/modules/admin/templates/login.phtml +++ b/paramecio2/modules/admin/templates/login.phtml @@ -3,7 +3,7 @@ <%block name="title">${_('Paramecio Login')}</%block> - + <%block name="extra_css"> From 3015220a12d92c3abffc061bcfe2abe934f39314 Mon Sep 17 00:00:00 2001 From: Antonio de la Rosa Date: Sun, 10 Nov 2024 01:29:22 +0100 Subject: [PATCH 51/85] Fixes for get modules from json --- paramecio2/app.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/paramecio2/app.py b/paramecio2/app.py index 65cdd7d..cfaf077 100644 --- a/paramecio2/app.py +++ b/paramecio2/app.py @@ -24,6 +24,10 @@ import os import sys import inspect from paramecio2.libraries.datetime import set_timezone +try: + import ujson as json +except: + import json swagger_app=False @@ -70,11 +74,14 @@ def start_app(): workdir=os.getcwd() arr_module_path={} - + # Load blueprints from json file (for installed modules using paramecio2 utilities) - if os.path.isfile('config/modules.json'): - pass + if os.path.isfile('./settings/modules.json'): + + with open('./settings/modules.json') as f: + json_apps=json.loads(f.read()) + config.apps=json_apps | config.apps for key_app, added_app in config.apps.items(): From b5ad1ecf70f7d45a5ca2ffb1b09c0a6ace7165fa Mon Sep 17 00:00:00 2001 From: Antonio de la Rosa Date: Sun, 10 Nov 2024 10:57:38 +0100 Subject: [PATCH 52/85] Added create_module script --- paramecio2/scripts/create_module.py | 151 ++++++++++++++++++++++++++++ 1 file changed, 151 insertions(+) create mode 100644 paramecio2/scripts/create_module.py diff --git a/paramecio2/scripts/create_module.py b/paramecio2/scripts/create_module.py new file mode 100644 index 0000000..2c49b7d --- /dev/null +++ b/paramecio2/scripts/create_module.py @@ -0,0 +1,151 @@ +#!/usr/bin/env python3 + +import traceback +import argparse +import os,sys +import shutil +import getpass +from pathlib import Path +from importlib import import_module +from paramecio2.libraries.slugify import slugify +import json + +sys.path.insert(0, os.path.realpath('.')) + +try: + + from settings import config + +except: + + pass + + +def start(): + """Module for create new modules for paramecio + """ + + parser=argparse.ArgumentParser(description='A tool for create new modules for paramecio') + + parser.add_argument('--folder', help='The folder where the new paramecio module is located', required=True) + + args=parser.parse_args() + + workdir=os.path.dirname(os.path.abspath(__file__)) + + # Create directory + + real_path=os.path.basename(slugify(args.folder)) + + path=Path('modules/'+real_path) + + + path.mkdir(0o755, True) + + #open('modules/'+args.path+'/__init__.py', 'a').close() + with open('modules/'+real_path+'/__init__.py', 'a') as f: + f.write("from flask import Blueprint\n\n") + f.write("{}_app=Blueprint('{}_app', __name__)\n\n".format(real_path, real_path)) + f.write("@{}_app.route('/{}')\n".format(real_path, real_path)) + f.write("def {}_home():\n".format(real_path)) + f.write(" return {'hello': 'world'}") + + modules_json={} + + if os.path.isfile('settings/modules.json'): + + with open('settings/modules.json') as f: + + #apps={'monit2': ['modules.monit2', 'monit2_app', '/'], 'welcome': ['paramecio2.modules.welcome', 'welcome_app', '/'], 'pastafari2': ['modules.pastafari2', 'pastafari_app', '/'], 'apache': ['modules.apache', 'apache_app', '/'], 'mariadb': ['modules.mariadb', 'mariadb_app', '/'], 'apiv1': ['modules.apiv1', 'apiv1_app', '/'], 'admin': ['paramecio2.modules.admin', 'admin_app', '/']} + + json_text=f.read() + + if json_text!='': + modules_json=json.loads(json_text) + + with open('settings/modules.json', 'w+') as f: + modules_json[real_path]=['modules.'+real_path, real_path+'_app', '/'] + + f.write(json.dumps(modules_json, indent=4)) + + print('Created the new module. Please, reload the WSGI server and go to url /'+real_path) + + """ + except: + + print('Error: cannot create the directory. Check if exists and if you have permissions') + exit(1) + """ + #Create base controller file + + #f=open('modules/'+args.path+'/index.py', 'w') + """ + try: + shutil.copy(workdir+'/examples/app.py', 'modules/'+args.path+'/__init__.py') + + except: + + print('Error: cannot copy controller example. Check if you have permissions') + exit(1) + """ + + # Regenerate modules + + #regenerate_modules_config() +""" +def regenerate_modules_config(): + + print("Regenerating modules configuration...") + + modules=[] + + modules.append("#!/usr/bin/env python3\n\n") + modules.append("list_modules=[]\n\n") + + for module in config.modules: + + try: + + controller_path=import_module(module) + + controller_base=os.path.dirname(controller_path.__file__) + + base_module=module.split('.')[-1] + + dir_controllers=os.listdir(controller_base) + + modules.append('from '+module+' import ') + + arr_controllers=[] + + for controller in dir_controllers: + + if controller.find('.py')!=-1 and controller.find('__init__')==-1: + + controller_py=controller.replace('.py', '') + + arr_controllers.append(controller_py) + + #load(module+'.'+controller_py) + + + modules.append(", ".join(arr_controllers)) + + modules.append("\n\n") + + #add_func_static_module(controller_base) + + except: + + print("Exception in user code:") + print("-"*60) + traceback.print_exc(file=sys.stdout) + print("-"*60) + exit(1) + + with open('./settings/modules.py', 'w') as f: + f.write("".join(modules)) +""" + +if __name__=="__main__": + start() From 48a57570cbc655880d77b5c3457092c2e2efb84c Mon Sep 17 00:00:00 2001 From: Antonio de la Rosa Date: Sun, 10 Nov 2024 10:58:49 +0100 Subject: [PATCH 53/85] Fixes in pyproject --- pyproject.toml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 0d5b190..408216f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -43,7 +43,8 @@ Documentation = "https://docs.cuchulu.com/paramecio2/" [project.scripts] paramecio2 = "paramecio2.console:start" -paramecio2db = "parmecio2.libraries.db.dbadmin:start" +paramecio2db = "paramecio2.libraries.db.dbadmin:start" +paramecio2cm = "paramecio2.scripts.create_module:start" [tool.pytest.ini_options] testpaths = ["tests"] From b0881e7267a64eb58f718d6ff8d99cab6b8d30c5 Mon Sep 17 00:00:00 2001 From: Antonio de la Rosa Date: Sun, 10 Nov 2024 14:45:03 +0100 Subject: [PATCH 54/85] Fixes in change theme for users --- paramecio2/modules/admin/app.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/paramecio2/modules/admin/app.py b/paramecio2/modules/admin/app.py index c9b5b05..9f73647 100644 --- a/paramecio2/modules/admin/app.py +++ b/paramecio2/modules/admin/app.py @@ -445,10 +445,15 @@ def auth_check(): @admin_app.route('/admin/change_theme/') def change_theme(): + db=g.connection + theme_selected=str(request.args.get('theme', '0')) session['theme']=theme_selected + if not db.query('update useradmin set dark_theme=%s WHERE id=%s', [session['theme'], session['user_id']]): + error=1 + error=0 return {'error': error} From 348f3f06f1e03c76edd8f45056e8e3c7f724179e Mon Sep 17 00:00:00 2001 From: Antonio de la Rosa Date: Mon, 11 Nov 2024 01:22:43 +0100 Subject: [PATCH 55/85] Fixes in dateform --- paramecio2/libraries/db/extraforms/dateform.py | 2 +- paramecio2/libraries/templates/forms/dateform.phtml | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/paramecio2/libraries/db/extraforms/dateform.py b/paramecio2/libraries/db/extraforms/dateform.py index 09a8892..ea966f4 100644 --- a/paramecio2/libraries/db/extraforms/dateform.py +++ b/paramecio2/libraries/db/extraforms/dateform.py @@ -30,7 +30,7 @@ class DateForm(BaseForm): super().__init__(name, value) - self.yes_time=False + self.yes_time=True self.t=standard_t def form(self): diff --git a/paramecio2/libraries/templates/forms/dateform.phtml b/paramecio2/libraries/templates/forms/dateform.phtml index 6b6d852..deecc5b 100644 --- a/paramecio2/libraries/templates/forms/dateform.phtml +++ b/paramecio2/libraries/templates/forms/dateform.phtml @@ -4,9 +4,9 @@ ${add_js('jquery.min.js', 'admin')} % if yes_time==True: - - - + + + % endif From 59c1e30863a98b10b33a781d1b3065b63ef08ddf Mon Sep 17 00:00:00 2001 From: Antonio de la Rosa Date: Mon, 23 Dec 2024 00:37:27 +0100 Subject: [PATCH 56/85] Fixes in paramecio2 --- paramecio2/libraries/check_i18n.py | 70 ++++++++++++++++++++++++++++-- paramecio2/libraries/i18n.py | 29 +++++++++++++ paramecio2/libraries/mtemplates.py | 6 +++ 3 files changed, 101 insertions(+), 4 deletions(-) diff --git a/paramecio2/libraries/check_i18n.py b/paramecio2/libraries/check_i18n.py index 0a826f0..2082e51 100644 --- a/paramecio2/libraries/check_i18n.py +++ b/paramecio2/libraries/check_i18n.py @@ -28,6 +28,7 @@ import re from pathlib import Path from importlib import import_module from paramecio2.libraries.i18n import I18n +from paramecio2.libraries.slugify import slugify try: from settings import config except: @@ -45,6 +46,12 @@ ignored=re.compile(r'^[__|\.].*$') lang_p=re.compile(r"I18n\.lang\('(.*?)',\s+'(.*?)',\s+'(.*?)'\)") lang_t=re.compile(r"\${lang\('(.*?)',\s+'(.*?)',\s+'(.*?)'\)\}") +lang_s=re.compile(r"i18n\.slang\('(.*?)',\s+'(.*?)'\)") +lang_ts=re.compile(r"\${slang\('(.*?)',\s+'(.*?)'\)\}") + +lang_tl=re.compile(r"i18n\.tlang\('(.*?)'\)") +lang_ttl=re.compile(r"\${tlang\('(.*?)'\)\}") + tmp_lang={} def start(): @@ -53,12 +60,16 @@ def start(): global lang_p global lang_t + global lang_s + global lang_tl + global lang_ts + global lang_ttl # Module to search a file where save the file. parser = argparse.ArgumentParser(description='A tool for create python language files') - parser.add_argument('--module', help='The module where search lang files', required=False) + parser.add_argument('--module', help='The module where search lang files', required=True) args = parser.parse_args() @@ -86,7 +97,7 @@ def start(): exit(1) - scandir(path, path_save) + scandir(path, path_save, module_base) #Save the files @@ -155,7 +166,7 @@ def start(): pass -def scandir(path, module_search=''): +def scandir(path, module_search='', module_base=None): list=os.listdir(path) @@ -177,6 +188,19 @@ def scandir(path, module_search=''): match_p=lang_p.findall(line) match_t=lang_t.findall(line) + match_s=lang_s.findall(line) + match_ts=lang_ts.findall(line) + + match_tl=lang_tl.findall(line) + match_ttl=lang_ttl.findall(line) + + """ + global lang_s + global lang_tl + global lang_ts + global lang_ttl + """ + if match_p!=None: for m in match_p: @@ -207,7 +231,45 @@ def scandir(path, module_search=''): tmp_lang[module]=tmp_lang.get(module, {}) tmp_lang[module][symbol]=tmp_lang[module].get(symbol, text_default) - + + if module_base: + + if match_s!=None: + + for m in match_s: + module=base_module + symbol=m[0] + text_default=m[1] + + tmp_lang[module]=tmp_lang.get(module, {}) + tmp_lang[module][symbol]=tmp_lang[module].get(symbol, text_default) + + for m in match_ts: + module=base_module + symbol=m[0] + text_default=m[1] + + tmp_lang[module]=tmp_lang.get(module, {}) + tmp_lang[module][symbol]=tmp_lang[module].get(symbol, text_default) + + + for m in match_tl: + module=base_module + symbol=slugify(m[0]) + text_default=m[0] + + tmp_lang[module]=tmp_lang.get(module, {}) + tmp_lang[module][symbol]=tmp_lang[module].get(symbol, text_default) + + for m in match_ttl: + module=base_module + symbol=slugify(m[0][:40]) + text_default=m[0] + + tmp_lang[module]=tmp_lang.get(module, {}) + tmp_lang[module][symbol]=tmp_lang[module].get(symbol, text_default) + + f.close() diff --git a/paramecio2/libraries/i18n.py b/paramecio2/libraries/i18n.py index 516a879..42188f8 100644 --- a/paramecio2/libraries/i18n.py +++ b/paramecio2/libraries/i18n.py @@ -105,6 +105,35 @@ class I18n: l={} + def __init__(self, module): + + self.module=module + + def slang(self, symbol, text_default, lang=None): + """Method for get a string from selected language but object oriented + + Method for get a string from selected language but object oriented + + Args: + symbol (str): The symbol used for identify the text string. + text_default (str): The text default used. You have use how base for translations. + """ + return I18n.lang(self.module, symbol, text_default, lang) + + def tlang(self, text_default, lang=None): + """Method for get a string from selected language but object oriented and using module and symbol by default + + Method for get a string from selected language but object oriented and using module and symbol by default + + Args: + symbol (str): The symbol used for identify the text string. + text_default (str): The text default used. You have use how base for translations. + """ + + symbol=text_default[:60] + + return I18n.lang(self.module, symbol, text_default, lang) + #@staticmethod #def set_lang(code_lang): # if default_lang diff --git a/paramecio2/libraries/mtemplates.py b/paramecio2/libraries/mtemplates.py index 9b9f0b8..9eb44ff 100644 --- a/paramecio2/libraries/mtemplates.py +++ b/paramecio2/libraries/mtemplates.py @@ -159,6 +159,12 @@ class PTemplate: self.l=PGetText(module_env+'/app.py') self.add_filter(self._) + + self.i18n=I18n(base_name) + + self.add_filter(self.i18n.slang) + + self.add_filter(self.i18n.tlang) def _(self, text): From e10b5295bd5e726a91262c5b4b8da29ad510e003 Mon Sep 17 00:00:00 2001 From: Antonio de la Rosa Date: Sat, 5 Apr 2025 00:57:02 +0200 Subject: [PATCH 57/85] Fixes in admin --- .../libraries/db/extrafields/usernamefield.py | 2 +- paramecio2/libraries/i18n.py | 28 +++++++++++++++++++ paramecio2/libraries/mtemplates.py | 4 +++ paramecio2/modules/admin/__init__.py | 2 ++ paramecio2/modules/admin/media/css/admin.css | 3 ++ .../modules/admin/templates/dashboard.phtml | 1 + 6 files changed, 39 insertions(+), 1 deletion(-) diff --git a/paramecio2/libraries/db/extrafields/usernamefield.py b/paramecio2/libraries/db/extrafields/usernamefield.py index 0491858..1b79d9d 100644 --- a/paramecio2/libraries/db/extrafields/usernamefield.py +++ b/paramecio2/libraries/db/extrafields/usernamefield.py @@ -20,7 +20,7 @@ along with this program. If not, see . from paramecio2.libraries.db.corefields import PhangoField from paramecio2.libraries.db.coreforms import PasswordForm from hmac import compare_digest as compare_hash -import crypt +#import crypt import re class UserNameField(PhangoField): diff --git a/paramecio2/libraries/i18n.py b/paramecio2/libraries/i18n.py index 516a879..a36c4d4 100644 --- a/paramecio2/libraries/i18n.py +++ b/paramecio2/libraries/i18n.py @@ -108,7 +108,35 @@ class I18n: #@staticmethod #def set_lang(code_lang): # if default_lang + def __init__(self, module): + self.module=module + + def slang(self, symbol, text_default, lang=None): + """Method for get a string from selected language but object oriented + + Method for get a string from selected language but object oriented + + Args: + symbol (str): The symbol used for identify the text string. + text_default (str): The text default used. You have use how base for translations. + """ + return I18n.lang(self.module, symbol, text_default) + + def tlang(self, text_default, lang=None): + """Method for get a string from selected language but object oriented and using module and symbol by default + + Method for get a string from selected language but object oriented and using module and symbol by default + + Args: + symbol (str): The symbol used for identify the text string. + text_default (str): The text default used. You have use how base for translations. + """ + + symbol=text_default[:60] + + return I18n.lang(self.module, symbol, text_default) + @staticmethod def get_default_lang(): diff --git a/paramecio2/libraries/mtemplates.py b/paramecio2/libraries/mtemplates.py index 9b9f0b8..8c750fe 100644 --- a/paramecio2/libraries/mtemplates.py +++ b/paramecio2/libraries/mtemplates.py @@ -157,8 +157,12 @@ class PTemplate: #print(path.basename(module_env)+' '+base_name+'/languages/') self.l=PGetText(module_env+'/app.py') + + self.i18n=I18n(module_env) self.add_filter(self._) + + self.add_filter(self.i18n.tlang) def _(self, text): diff --git a/paramecio2/modules/admin/__init__.py b/paramecio2/modules/admin/__init__.py index bf4f1e8..4548b60 100644 --- a/paramecio2/modules/admin/__init__.py +++ b/paramecio2/modules/admin/__init__.py @@ -8,5 +8,7 @@ try: t=PTemplate(env) + wsgi_module=True + except: pass diff --git a/paramecio2/modules/admin/media/css/admin.css b/paramecio2/modules/admin/media/css/admin.css index 8cfd9b3..82aedd0 100644 --- a/paramecio2/modules/admin/media/css/admin.css +++ b/paramecio2/modules/admin/media/css/admin.css @@ -1039,6 +1039,7 @@ a.form_button_tab:hover box-sizing: border-box; /* border: solid #fff 1px;*/ float:left; + overflow:hidden; } @@ -1049,6 +1050,7 @@ a.form_button_tab:hover box-sizing: border-box; /*border: solid #f00 1px;*/ float:left; + overflow:hidden; } @@ -1058,6 +1060,7 @@ a.form_button_tab:hover box-sizing: border-box; /*border: solid #f00 1px;*/ float:left; + overflow:hidden; } diff --git a/paramecio2/modules/admin/templates/dashboard.phtml b/paramecio2/modules/admin/templates/dashboard.phtml index d6b5eef..9c3442c 100644 --- a/paramecio2/modules/admin/templates/dashboard.phtml +++ b/paramecio2/modules/admin/templates/dashboard.phtml @@ -17,6 +17,7 @@ if session.get('theme', '0')=='1': ${title} + From 07fd96e003386b8d264fc55bdd182ba87b9d1630 Mon Sep 17 00:00:00 2001 From: Antonio de la Rosa Date: Mon, 7 Apr 2025 23:55:16 +0200 Subject: [PATCH 58/85] Accept new version --- paramecio2/app.py | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/paramecio2/app.py b/paramecio2/app.py index cfaf077..aa9609e 100644 --- a/paramecio2/app.py +++ b/paramecio2/app.py @@ -100,7 +100,7 @@ def start_app(): for controller in dir_controllers: - if controller.find('.py')!=-1 and controller.find('__init__')==-1: + if controller.find('.py')!=-1 and not controller.startswith('__'): controller_py=controller.replace('.py', '') diff --git a/setup.py b/setup.py index 998439e..e9676f8 100644 --- a/setup.py +++ b/setup.py @@ -13,7 +13,7 @@ if sys.version_info < (3, 9): # If you install passlib and bcrypt, the password system will use bcrypt by default, if not, will use native crypt libc setup(name='paramecio2', - version='2.0.35', + version='2.0.36', description='Simple Web Framework based in flask and Mako.', long_description='This framework is a simple framework used for create web apps. Paramecio is modular and fast. By default have a module called admin that can be used for create admin sites', author='Antonio de la Rosa Caballero', From d7e6af231bb9eb411bbade01304866cc397925fb Mon Sep 17 00:00:00 2001 From: Antonio de la Rosa Date: Tue, 8 Apr 2025 00:06:33 +0200 Subject: [PATCH 59/85] Added __init__ --- paramecio2/__init__.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 paramecio2/__init__.py diff --git a/paramecio2/__init__.py b/paramecio2/__init__.py new file mode 100644 index 0000000..e69de29 From 9cc080f7216032cecbaf3fbf464ac40fab11b13a Mon Sep 17 00:00:00 2001 From: Antonio de la Rosa Date: Tue, 8 Apr 2025 00:07:52 +0200 Subject: [PATCH 60/85] Added __init__ --- paramecio2/__init__.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/paramecio2/__init__.py b/paramecio2/__init__.py index e69de29..9c5d19f 100644 --- a/paramecio2/__init__.py +++ b/paramecio2/__init__.py @@ -0,0 +1,19 @@ +""" +Paramecio2fm is a series of wrappers for Flask, mako and others and construct a simple headless cms. + +Copyright (C) 2025 Antonio de la Rosa Caballero + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program 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 Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +""" + From bb65975adf001afb946041760616d594c62358a0 Mon Sep 17 00:00:00 2001 From: Antonio de la Rosa Date: Tue, 8 Apr 2025 00:10:51 +0200 Subject: [PATCH 61/85] Added __init__ --- pyproject.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/pyproject.toml b/pyproject.toml index 408216f..70f87a2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,6 +6,7 @@ build-backend = "flit_core.buildapi" name = "paramecio2" authors = [{name = "Antonio de la Rosa", email = "antonio.delarosa@salirdelhoyo.com"}] readme = "README.md" +version = "2.0.36" dynamic = ["version", "description"] classifiers=['Development Status :: 4 - Beta', From 66070fdc41032d7b71dad80f912e332b99fd4dbe Mon Sep 17 00:00:00 2001 From: Antonio de la Rosa Date: Tue, 8 Apr 2025 00:14:15 +0200 Subject: [PATCH 62/85] Added __init__ --- pyproject.toml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 70f87a2..8280c8e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,7 +7,8 @@ name = "paramecio2" authors = [{name = "Antonio de la Rosa", email = "antonio.delarosa@salirdelhoyo.com"}] readme = "README.md" version = "2.0.36" -dynamic = ["version", "description"] +description = "A simple framework using flask and mako" +# dynamic = ["version", "description"] classifiers=['Development Status :: 4 - Beta', "Intended Audience :: Developers", From a84a2b51ff062b5e3eb3e6df4edaf9d93282eb88 Mon Sep 17 00:00:00 2001 From: Antonio de la Rosa Date: Mon, 21 Apr 2025 13:33:35 +0200 Subject: [PATCH 63/85] Fixes in fields for apidocs --- paramecio2/libraries/db/corefields.py | 19 +++++++++++++++++-- .../libraries/db/extrafields/arrayfield.py | 4 ++++ .../libraries/db/extrafields/colorfield.py | 2 ++ .../libraries/db/extrafields/datefield.py | 3 +++ .../libraries/db/extrafields/datetimefield.py | 4 ++++ .../libraries/db/extrafields/dictfield.py | 4 ++++ .../libraries/db/extrafields/emailfield.py | 4 +++- .../libraries/db/extrafields/ipfield.py | 6 ++++++ .../libraries/db/extrafields/jsonfield.py | 2 ++ .../libraries/db/extrafields/passwordfield.py | 1 + .../libraries/db/extrafields/urlfield.py | 5 +++++ 11 files changed, 51 insertions(+), 3 deletions(-) diff --git a/paramecio2/libraries/db/corefields.py b/paramecio2/libraries/db/corefields.py index d34a4f0..f94a6de 100644 --- a/paramecio2/libraries/db/corefields.py +++ b/paramecio2/libraries/db/corefields.py @@ -38,9 +38,12 @@ class IntegerField(PhangoField): super(IntegerField, self).__init__(name, size, required) self.default_value=0 - - self.type_sql='int({})'.format(self.size) + + self.default_value=0 + self.jtype='integer' + self.jformat='int64' + self.jexample='1' def check(self, value): @@ -117,6 +120,9 @@ class FloatField(PhangoField): self.default_value=0 self.type_sql='float'.format(self.size) + self.jtype='number' + self.jformat='float' + def check(self, value): """Method for check if value is integer @@ -160,6 +166,8 @@ class DecimalField(FloatField): super().__init__(name, size, required) self.type_sql='decimal(20,2)' + + self.jtype='number' def get_type_sql(self): @@ -173,6 +181,9 @@ class DoubleField(FloatField): super().__init__(name, size, required) self.type_sql='double' + self.jtype='number' + self.jformat='double' + def get_type_sql(self): return 'DOUBLE NOT NULL DEFAULT "0"' @@ -375,6 +386,10 @@ class BooleanField(IntegerField): self.default_value=0 self.type_sql='tinyint(1)' + + self.jtype='boolean' + #self.jformat='0' + self.jexample='0' def check(self, value): diff --git a/paramecio2/libraries/db/extrafields/arrayfield.py b/paramecio2/libraries/db/extrafields/arrayfield.py index b8c99c9..cf964da 100644 --- a/paramecio2/libraries/db/extrafields/arrayfield.py +++ b/paramecio2/libraries/db/extrafields/arrayfield.py @@ -40,6 +40,10 @@ class ArrayField(PhangoField): self.set_default='NOT NULL' self.type_sql='text' + + self.jtype='array' + + self.default_value='[]' def check(self, value): diff --git a/paramecio2/libraries/db/extrafields/colorfield.py b/paramecio2/libraries/db/extrafields/colorfield.py index d138ee7..160a2ca 100644 --- a/paramecio2/libraries/db/extrafields/colorfield.py +++ b/paramecio2/libraries/db/extrafields/colorfield.py @@ -31,6 +31,8 @@ class ColorField(IntegerField): super().__init__(name, size, required) self.name_form=ColorForm + self.jtype='string' + self.jexample='#f0f0f0' def check(self, value): diff --git a/paramecio2/libraries/db/extrafields/datefield.py b/paramecio2/libraries/db/extrafields/datefield.py index 7337222..740b2b2 100644 --- a/paramecio2/libraries/db/extrafields/datefield.py +++ b/paramecio2/libraries/db/extrafields/datefield.py @@ -38,6 +38,9 @@ class DateField(PhangoField): self.utc=True self.error_default='Error: Date format invalid' + + self.jtype='string' + self.jformat='date-time' def check(self, value): diff --git a/paramecio2/libraries/db/extrafields/datetimefield.py b/paramecio2/libraries/db/extrafields/datetimefield.py index 79eb4da..0c1d016 100644 --- a/paramecio2/libraries/db/extrafields/datetimefield.py +++ b/paramecio2/libraries/db/extrafields/datetimefield.py @@ -39,6 +39,10 @@ class DateTimeField(PhangoField): self.error_default='Error: Date format invalid' self.type_sql='datetime' + + self.jformat='date-time' + self.jtype='string' + self.jexample='2022-12-01 12:24:11' def check(self, value): diff --git a/paramecio2/libraries/db/extrafields/dictfield.py b/paramecio2/libraries/db/extrafields/dictfield.py index 118dccb..51ad54b 100644 --- a/paramecio2/libraries/db/extrafields/dictfield.py +++ b/paramecio2/libraries/db/extrafields/dictfield.py @@ -40,6 +40,10 @@ class DictField(PhangoField): self.set_default='NOT NULL' self.type_sql='longtext' + + self.jtype='object' + + self.default_value='{}' def check(self, value): diff --git a/paramecio2/libraries/db/extrafields/emailfield.py b/paramecio2/libraries/db/extrafields/emailfield.py index 549068d..99a6585 100644 --- a/paramecio2/libraries/db/extrafields/emailfield.py +++ b/paramecio2/libraries/db/extrafields/emailfield.py @@ -29,7 +29,9 @@ class EmailField(CharField): super().__init__(name, size, required) - self.error_default='Error: No valid format' + self.error_default='Error: No valid format' + + self.jformat='email' def check(self, value): diff --git a/paramecio2/libraries/db/extrafields/ipfield.py b/paramecio2/libraries/db/extrafields/ipfield.py index f221add..6257774 100644 --- a/paramecio2/libraries/db/extrafields/ipfield.py +++ b/paramecio2/libraries/db/extrafields/ipfield.py @@ -23,6 +23,12 @@ import ipaddress class IpField(CharField): """Field for save ip internet address values in db""" + def __init__(self, name, size=1024, required=False): + + super().__init__(name, size, required) + + self.jformat='ipV4' + def check(self, value): try: diff --git a/paramecio2/libraries/db/extrafields/jsonfield.py b/paramecio2/libraries/db/extrafields/jsonfield.py index d7e1fdd..2d7497c 100644 --- a/paramecio2/libraries/db/extrafields/jsonfield.py +++ b/paramecio2/libraries/db/extrafields/jsonfield.py @@ -45,6 +45,8 @@ class JsonField(PhangoField): self.set_default='NOT NULL' self.type_sql='longtext' + + self.jtype='object' def check(self, value): diff --git a/paramecio2/libraries/db/extrafields/passwordfield.py b/paramecio2/libraries/db/extrafields/passwordfield.py index 19957ee..33e0b42 100644 --- a/paramecio2/libraries/db/extrafields/passwordfield.py +++ b/paramecio2/libraries/db/extrafields/passwordfield.py @@ -38,6 +38,7 @@ class PasswordField(PhangoField): self.name_form=PasswordForm self.default_value='' self.encrypt_password=True + self.jformat='password' def check(self, value): diff --git a/paramecio2/libraries/db/extrafields/urlfield.py b/paramecio2/libraries/db/extrafields/urlfield.py index cc95fbe..533083e 100644 --- a/paramecio2/libraries/db/extrafields/urlfield.py +++ b/paramecio2/libraries/db/extrafields/urlfield.py @@ -32,6 +32,11 @@ check_url = re.compile( class UrlField(CharField): """Field for check and save strings in url format""" + def __init__(self, name, size=1024, required=False): + + super().__init__(name, size, required) + self.jformat='url' + def check(self, value): self.error=False From 7c5af27ecf8f3a9d1d3056955636431074cbe6c3 Mon Sep 17 00:00:00 2001 From: Antonio de la Rosa Date: Tue, 13 May 2025 01:56:55 +0200 Subject: [PATCH 64/85] Fixes for apidoc --- paramecio2/app.py | 6 +++++- paramecio2/libraries/db/webmodel.py | 7 +++++++ paramecio2/libraries/plugins.py | 2 +- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/paramecio2/app.py b/paramecio2/app.py index aa9609e..68999fa 100644 --- a/paramecio2/app.py +++ b/paramecio2/app.py @@ -135,8 +135,12 @@ def start_app(): if not os.path.isfile(file_path): #file_path=workdir+'/modules/'+module+'/media/'+media_file + + if not module in arr_module_path: + abort(404) + file_path=arr_module_path[module]+'/media/'+media_file - + if not os.path.isfile(file_path): abort(404) diff --git a/paramecio2/libraries/db/webmodel.py b/paramecio2/libraries/db/webmodel.py index 869429b..0f52b2c 100644 --- a/paramecio2/libraries/db/webmodel.py +++ b/paramecio2/libraries/db/webmodel.py @@ -25,6 +25,7 @@ class PhangoField: Attributes: name (str): The name of the field + jtype(Python type): The type of value in python label (str): A label or generic name for use in text labels used for representate the field required (bool): If the field is required or not. size (int): The size of sql field. @@ -54,6 +55,10 @@ class PhangoField: self.name=name + # The type of the field in javascript. Util for api documentation + + self.jtype='string' + # The label for the Field self.label=name.replace('_', ' ').title() @@ -147,6 +152,8 @@ class PhangoField: self.help='' self.type_sql='varchar({})'.format(self.size) + + def get_type_sql(self): """This method is used for describe the new field in a sql language format.""" diff --git a/paramecio2/libraries/plugins.py b/paramecio2/libraries/plugins.py index f44ca58..b29389f 100644 --- a/paramecio2/libraries/plugins.py +++ b/paramecio2/libraries/plugins.py @@ -32,7 +32,7 @@ def db(f): """Wrapper function for add db connection to your flask function - Wrapper function for add db connection to your flask function. Also close the connection if error or function exection is finished. + Wrapper function for add db connection to your flask function. Also close the connection if error or function exception is finished. Args: *args (mixed): The args of function From 779605ee7c5273a984961438b12382b9ac3ac47e Mon Sep 17 00:00:00 2001 From: Antonio de la Rosa Date: Wed, 14 May 2025 01:32:29 +0200 Subject: [PATCH 65/85] Added simplequery library --- paramecio2/libraries/db/simplequery.py | 44 ++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 paramecio2/libraries/db/simplequery.py diff --git a/paramecio2/libraries/db/simplequery.py b/paramecio2/libraries/db/simplequery.py new file mode 100644 index 0000000..7c8aaad --- /dev/null +++ b/paramecio2/libraries/db/simplequery.py @@ -0,0 +1,44 @@ + +# A more simple set for make queries + +def insert(model, db, dict_values): + + final_values={} + + for k in model.fields.keys(): + final_values[k]=model.fields[k].check(dict_values.get(k, '')) + + del final_values[model.name_field_id] + + str_fields="`"+"`, `".join(final_values.keys())+"`" + + str_query='insert into {} ({}) VALUES ({})'.format(model.name, str_fields, ", ".join(['%s']*len(final_values))) + + success=False + + with db.query(str_query, list(final_values.values())) as cursor: + + if cursor.rowcount>0: + + model.last_id=cursor.lastrowid + success=True + + return success + + +def select(model, db, dict_fields=[], where_sql='', limit='', dict_values=[]): + + if len(dict_fields)==0: + dict_fields=['`'+field+'`' for field in model.fields.keys()] + + str_fields=", ".join(dict_fields) + + str_query='select {} from {} {} limit 1'.format(str_fields, model.name, where_sql) + + arr_result=[] + + with db.query(str_query, dict_values) as cursor: + + arr_result=cursor.fetchall() + + return arr_result From f689dc5f63dff09070ae0f279e412fdb0dce8cff Mon Sep 17 00:00:00 2001 From: Antonio de la Rosa Date: Fri, 16 May 2025 19:52:01 +0200 Subject: [PATCH 66/85] Added admin_auth for apps independent of admin_app --- paramecio2/modules/admin/app.py | 19 +++-- .../modules/admin/libraries/admin_auth.py | 48 ++++++++++++ .../admin/libraries/check_login_tries.py | 74 +++++++++++++++++++ .../modules/admin/templates/dashboard.phtml | 13 +++- 4 files changed, 145 insertions(+), 9 deletions(-) create mode 100644 paramecio2/modules/admin/libraries/admin_auth.py create mode 100644 paramecio2/modules/admin/libraries/check_login_tries.py diff --git a/paramecio2/modules/admin/app.py b/paramecio2/modules/admin/app.py index 9f73647..b80dda4 100644 --- a/paramecio2/modules/admin/app.py +++ b/paramecio2/modules/admin/app.py @@ -16,6 +16,7 @@ from paramecio2.modules.admin import admin_app, t from paramecio2.libraries.sendmail import SendMail from paramecio2.libraries.formsutils import check_csrf from hmac import compare_digest as compare_hash +from paramecio2.modules.admin.libraries.admin_auth import admin_prepare, admin_finished try: import crypt @@ -47,7 +48,8 @@ if hasattr(config, 'email_address'): #admin_app=Blueprint('admin_app', __name__, static_folder='static') -@admin_app.before_request +#@admin_app.before_request +""" def admin_prepare(): g.connection=WebModel.connection() @@ -87,13 +89,12 @@ def admin_prepare(): return redirect(url_redirect) - - """ - if request.method=='POST': - check_csrf() - """ +""" +#home=welcome_app.route("/")(home) +admin_prepare=admin_app.before_request(admin_prepare) -@admin_app.after_request +#@admin_app.after_request +""" def admin_finished(response): #print('pepe') @@ -101,6 +102,9 @@ def admin_finished(response): g.connection.close() return response +""" + +admin_finished=admin_app.after_request(admin_finished) # Load modules from admin @@ -115,6 +119,7 @@ for app in config.apps: a=import_module(config_path) + arr_modules_admin={} for app_load in config_admin: diff --git a/paramecio2/modules/admin/libraries/admin_auth.py b/paramecio2/modules/admin/libraries/admin_auth.py new file mode 100644 index 0000000..fe0c9a9 --- /dev/null +++ b/paramecio2/modules/admin/libraries/admin_auth.py @@ -0,0 +1,48 @@ +from flask import g, request, redirect, session, url_for +from paramecio2.libraries.db.webmodel import WebModel +from settings import config + +def admin_prepare(): + + g.connection=WebModel.connection() + + if request.endpoint!='admin_app.login' and request.endpoint!='admin_app.signup' and request.endpoint!='admin_app.need_auth' and request.endpoint!='admin_app.auth_check': + + if 'login_admin' not in session: + + if 'remember_login_admin' in request.cookies: + + with g.connection.query('select count(id) as count_id from useradmin where token_login=%s', [request.cookies['remember_login_admin']]) as cursor: + + arr_count=cursor.fetchone() + + if arr_count['count_id']==0: + + url_redirect=config.domain_url+url_for('admin_app.login', _external=False) + + return redirect(url_redirect) + else: + + session['login_admin']=True + + else: + + url_redirect=config.domain_url+url_for('admin_app.login', _external=False) + + return redirect(url_redirect) + else: + + #print(session['verify_auth']) + if request.endpoint!='admin_app.logout': + + if not session.get('verify_auth', True): + + url_redirect=config.domain_url+url_for('admin_app.need_auth', _external=False) + + return redirect(url_redirect) + +def admin_finished(response): + + g.connection.close() + + return response diff --git a/paramecio2/modules/admin/libraries/check_login_tries.py b/paramecio2/modules/admin/libraries/check_login_tries.py new file mode 100644 index 0000000..2d6cb33 --- /dev/null +++ b/paramecio2/modules/admin/libraries/check_login_tries.py @@ -0,0 +1,74 @@ +from paramecio2.libraries.i18n import I18n, PGetText +from paramecio2.libraries.mtemplates import env_theme, PTemplate +from paramecio2.modules.admin.models.admin import UserAdmin, LoginTries +from paramecio2.libraries.db.webmodel import WebModel +from paramecio2.libraries.db import simplequery +from settings import config +from paramecio2.libraries.datetime import now, format_local_strtime, timestamp_to_datetime, obtain_timestamp +from paramecio2.libraries.keyutils import create_key_encrypt, create_key +from time import time +#from paramecio2.wsgiapp import app +#from paramecio2.modules.admin2 import admin_app +#from bottle import request, redirect, Bottle, response +from flask import request, redirect +#from paramecio2.modules.admin.libraries.loginplugin import check_login +#from paramecio2.libraries.sessionplugin import SessionPlugin +#from paramecio2.libraries.httputils import GetPostFiles +from paramecio2.libraries.formsutils import check_form, csrf_token +from paramecio2.libraries.db.coreforms import PasswordForm +from paramecio2.libraries.sendmail import SendMail +#from paramecio2.modules.admin.libraries.config import modules_admin + +login_tries=5 + +if hasattr(config, 'login_tries'): + login_tries=config.login_tries + +seconds_login=300 + +if hasattr(config, 'seconds_login'): + seconds_login=config.seconds_login + + +def check_login_tries(request, db): + + logintries=LoginTries(db) + + logintries.safe_query() + + #ip=request.environ.get('HTTP_X_FORWARDED_FOR') or request.environ.get('REMOTE_ADDR') + + + if 'x-real-ip' in request.headers: + ip=request.headers['x-real-ip'] + elif 'x-forwarded-for' in request.headers: + ip=request.headers['x-forwarded-for'] + else: + ip=request.client.host + + you_cannot_login=0 + + now_str=now() + date_now=format_local_strtime('YYYY-MM-DD HH:mm:ss', now_str) + + date_check=format_local_strtime('YYYY-MM-DD HH:mm:ss', timestamp_to_datetime(obtain_timestamp(now_str)-seconds_login)) + + logintries.query('delete from logintries where last_login<%s', [date_check]) + + arr_try=logintries.set_conditions('WHERE ip=%s', [ip]).select_a_row_where() + + if arr_try: + + if arr_try['num_tries']
-<%block name="logout"> Logout +<%block name="logout"> Logout
@@ -98,7 +98,16 @@ ${load_js()|n} %> -
  •  ${link_text}
  • + +
  •   + % if icon_module.startswith('fa-'): + + %else: + ${icon_module|n} + % endif + ${link_text} + +
  • % elif len(admin)==1: <% From 1ee7ebb23d6328e20bfa14f7f4db533c0c4609ec Mon Sep 17 00:00:00 2001 From: Antonio de la Rosa Date: Sat, 7 Jun 2025 10:52:57 +0200 Subject: [PATCH 67/85] Added check_login_tries to paramecio2 --- paramecio2/libraries/responsesapi.py | 47 +++++++++++++++++++ .../admin/libraries/check_login_tries.py | 5 +- 2 files changed, 50 insertions(+), 2 deletions(-) create mode 100644 paramecio2/libraries/responsesapi.py diff --git a/paramecio2/libraries/responsesapi.py b/paramecio2/libraries/responsesapi.py new file mode 100644 index 0000000..f707a2d --- /dev/null +++ b/paramecio2/libraries/responsesapi.py @@ -0,0 +1,47 @@ +from paramecio2.libraries.db import corefields +from paramecio2.libraries.db.extrafields.jsonfield import JsonField +from paramecio2.libraries.db.extrafields.dictfield import DictField +try: + import ujson as json +except: + import json + +"""A class for list objects with data fields +""" + +class ListItem: + pass + +"""Typical item """ + +class Items(ListItem): + + name=corefields.CharField('name') + + +class StandardResponse: + + error=corefields.BooleanField('error') + message=corefields.CharField('message') + code_error=corefields.IntegerField('code_error') + error_form=DictField('error_form', corefields.CharField('error_form')) + #items=JsonField('items', corefields.CharField) + + def __init__(self, error=0, message='', code_error=0): + + self.error=error + self.message=message + self.code_error=code_error + + def toDict(self): + + return self.__dict__ + + def toJSON(self): + return json.dumps( self, default=lambda o: o.__dict__, sort_keys=True, indent=4 ) + + + +class ResponseItems(StandardResponse): + pass + diff --git a/paramecio2/modules/admin/libraries/check_login_tries.py b/paramecio2/modules/admin/libraries/check_login_tries.py index 2d6cb33..bde1653 100644 --- a/paramecio2/modules/admin/libraries/check_login_tries.py +++ b/paramecio2/modules/admin/libraries/check_login_tries.py @@ -36,15 +36,16 @@ def check_login_tries(request, db): logintries.safe_query() - #ip=request.environ.get('HTTP_X_FORWARDED_FOR') or request.environ.get('REMOTE_ADDR') - + ip=request.environ.get('HTTP_X_FORWARDED_FOR') or request.environ.get('REMOTE_ADDR') + """ if 'x-real-ip' in request.headers: ip=request.headers['x-real-ip'] elif 'x-forwarded-for' in request.headers: ip=request.headers['x-forwarded-for'] else: ip=request.client.host + """ you_cannot_login=0 From 4c937fd54333cd3eb1fcb332ed07ad957d71eb42 Mon Sep 17 00:00:00 2001 From: Antonio de la Rosa Date: Tue, 10 Jun 2025 21:06:00 +0200 Subject: [PATCH 68/85] Fixes in pyproject.toml for dependencies --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 8280c8e..207b57f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -26,7 +26,7 @@ classifiers=['Development Status :: 4 - Beta', "Programming Language :: Python :: 3.12" ] requires-python = ">=3.9" -install_requires=[ +dependencies=[ "flask", "pymysql", "sqlalchemy", From 833e3219eac6d1b703cc6d7ee7ede7bbb0d4db16 Mon Sep 17 00:00:00 2001 From: Antonio de la Rosa Date: Fri, 4 Jul 2025 00:21:47 +0200 Subject: [PATCH 69/85] Fixes in sessions --- paramecio2/app.py | 17 +++++++++++++++++ paramecio2/modules/admin/admin/ausers.py | 4 ++-- paramecio2/modules/admin/app.py | 2 +- .../modules/admin/libraries/admin_auth.py | 2 ++ 4 files changed, 22 insertions(+), 3 deletions(-) diff --git a/paramecio2/app.py b/paramecio2/app.py index 68999fa..51affe3 100644 --- a/paramecio2/app.py +++ b/paramecio2/app.py @@ -29,6 +29,19 @@ try: except: import json +flask_session=False + +if hasattr(config, 'flask_session'): + + flask_session=config.flask_session + + if flask_session: + + from flask_session import Session + from redis import Redis + SESSION_TYPE='redis' + SESSION_REDIS=Redis(host='localhost', port=6379) + swagger_app=False if hasattr(config, 'swagger_app'): @@ -150,4 +163,8 @@ def start_app(): from flasgger import Swagger swagger=Swagger(app) + if flask_session: + app.config.from_object(__name__) + Session(app) + return app diff --git a/paramecio2/modules/admin/admin/ausers.py b/paramecio2/modules/admin/admin/ausers.py index cca37df..81ea1ee 100644 --- a/paramecio2/modules/admin/admin/ausers.py +++ b/paramecio2/modules/admin/admin/ausers.py @@ -31,7 +31,7 @@ def ausers(): user_admin.fields['dark_theme'].name_form=SelectForm - user_admin.create_forms(['username', 'password', 'email', 'privileges', 'lang', 'dark_theme', 'disabled', 'double_auth', 'last_login']) + user_admin.create_forms(['username', 'password', 'email', 'privileges', 'lang', 'dark_theme', 'disabled', 'double_auth', 'last_login', 'privileges']) user_admin.forms['privileges'].arr_select={0: _('Without privileges'), 1: _('Selected privileges'), 2: _('Administrator')} @@ -54,7 +54,7 @@ def ausers(): admin.list.search_fields=['username'] - admin.arr_fields_edit=['username', 'password', 'repeat_password', 'email', 'lang', 'dark_theme', 'double_auth', 'disabled', 'last_login'] + admin.arr_fields_edit=['username', 'password', 'repeat_password', 'email', 'lang', 'dark_theme', 'double_auth', 'disabled', 'last_login', 'privileges'] admin.post_update=update_lang diff --git a/paramecio2/modules/admin/app.py b/paramecio2/modules/admin/app.py index b80dda4..8e04a26 100644 --- a/paramecio2/modules/admin/app.py +++ b/paramecio2/modules/admin/app.py @@ -16,7 +16,7 @@ from paramecio2.modules.admin import admin_app, t from paramecio2.libraries.sendmail import SendMail from paramecio2.libraries.formsutils import check_csrf from hmac import compare_digest as compare_hash -from paramecio2.modules.admin.libraries.admin_auth import admin_prepare, admin_finished +from paramecio2.modules.admin.libraries.admin_auth import admin_prepare, admin_finished, modules_access try: import crypt diff --git a/paramecio2/modules/admin/libraries/admin_auth.py b/paramecio2/modules/admin/libraries/admin_auth.py index fe0c9a9..1e19f84 100644 --- a/paramecio2/modules/admin/libraries/admin_auth.py +++ b/paramecio2/modules/admin/libraries/admin_auth.py @@ -2,6 +2,8 @@ from flask import g, request, redirect, session, url_for from paramecio2.libraries.db.webmodel import WebModel from settings import config +modules_access=[] + def admin_prepare(): g.connection=WebModel.connection() From 4d82ddced0d26a72987bc0048c090ad29491bbbb Mon Sep 17 00:00:00 2001 From: Antonio de la Rosa Date: Sat, 5 Jul 2025 02:08:19 +0200 Subject: [PATCH 70/85] Fixes in dates --- .../libraries/db/extrafields/datetimefield.py | 1 + .../libraries/db/extraforms/dateform.py | 43 ++++++++++++------- .../libraries/templates/forms/dateform.phtml | 37 +++++++++++----- 3 files changed, 56 insertions(+), 25 deletions(-) diff --git a/paramecio2/libraries/db/extrafields/datetimefield.py b/paramecio2/libraries/db/extrafields/datetimefield.py index 0c1d016..73cfd03 100644 --- a/paramecio2/libraries/db/extrafields/datetimefield.py +++ b/paramecio2/libraries/db/extrafields/datetimefield.py @@ -77,6 +77,7 @@ class DateTimeField(PhangoField): def show_formatted(self, value): # Convert to paramecio value + value=str(value) value=value.replace('-', '').replace(':', '').replace(' ', '') diff --git a/paramecio2/libraries/db/extraforms/dateform.py b/paramecio2/libraries/db/extraforms/dateform.py index ea966f4..b1cb49a 100644 --- a/paramecio2/libraries/db/extraforms/dateform.py +++ b/paramecio2/libraries/db/extraforms/dateform.py @@ -35,23 +35,36 @@ class DateForm(BaseForm): def form(self): - y='' - m='' - d='' - h='' - min='' - s='' - min_time='' + if type(self.default_value).__name__!='datetime': - time=format_timedata(self.default_value) + y='' + m='' + d='' + h='' + min='' + s='' + min_time='' + + time=format_timedata(self.default_value) + + if time[0]: + y=int(time[0]) + m=int(time[1]) + d=int(time[2]) + h=int(time[3]) + min_time=int(time[4]) + s='00' #int(time[5]) - if time[0]: - y=int(time[0]) - m=int(time[1]) - d=int(time[2]) - h=int(time[3]) - min_time=int(time[4]) - s=int(time[5]) + else: + + y=self.default_value.year #"{:>10}".format(s) + m="{:02d}".format(self.default_value.month) + d="{:02d}".format(self.default_value.day) + h="{:02d}".format(self.default_value.hour) + min_time="{:02d}".format(self.default_value.minute) + s='00' + + pass return self.t.load_template('forms/dateform.phtml', yes_time=self.yes_time, form=self.name, y=y, m=m, d=d, h=h, min=min_time, s=s) diff --git a/paramecio2/libraries/templates/forms/dateform.phtml b/paramecio2/libraries/templates/forms/dateform.phtml index deecc5b..a56530e 100644 --- a/paramecio2/libraries/templates/forms/dateform.phtml +++ b/paramecio2/libraries/templates/forms/dateform.phtml @@ -1,38 +1,55 @@ ${add_js('jquery.min.js', 'admin')} - + +<% + +date='' + +if d!='': + date='-'.join((str(y), str(m), str(d))) + +time='' + +if h!='': + time=':'.join((str(h), str(min))) + +%> +${date} + % if yes_time==True: - + + % endif ', tags=self.trusted_tags) + value=bleach.clean(value, tags=self.trusted_tags) if self.escape: diff --git a/paramecio2/libraries/db/extrafields/jsonfield.py b/paramecio2/libraries/db/extrafields/jsonfield.py index baf21ff..44a2d0d 100644 --- a/paramecio2/libraries/db/extrafields/jsonfield.py +++ b/paramecio2/libraries/db/extrafields/jsonfield.py @@ -104,7 +104,7 @@ class JsonValueField(PhangoField): return 'JSON' def check(self, value): - + #print(value) try: final_value=json.dumps(value) diff --git a/paramecio2/libraries/db/webmodel.py b/paramecio2/libraries/db/webmodel.py index 0f52b2c..b908e05 100644 --- a/paramecio2/libraries/db/webmodel.py +++ b/paramecio2/libraries/db/webmodel.py @@ -1305,7 +1305,7 @@ class WebModel: self.arr_sql_set_index[self.name][field]='ALTER TABLE `'+self.name+'` ADD CONSTRAINT `'+field+'_'+self.name+'IDX` FOREIGN KEY ( `'+field+'` ) REFERENCES `'+table_related+'` (`'+id_table_related+'`) ON DELETE CASCADE ON UPDATE CASCADE;' - return "create table `"+self.name+"` (\n"+",\n".join(table_fields)+"\n) DEFAULT CHARSET=utf8;"; + return "create table `"+self.name+"` (\n"+",\n".join(table_fields)+"\n) DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_unicode_ci;"; def update_table(self, fields_to_add, fields_to_modify, fields_to_add_index, fields_to_add_constraint, fields_to_add_unique, fields_to_delete_index, fields_to_delete_unique, fields_to_delete_constraint, fields_to_delete): diff --git a/paramecio2/libraries/generate_admin_class.py b/paramecio2/libraries/generate_admin_class.py index 0e09cbf..4c8dbc9 100644 --- a/paramecio2/libraries/generate_admin_class.py +++ b/paramecio2/libraries/generate_admin_class.py @@ -220,7 +220,7 @@ class GenerateAdminClass: post=dict(request.form) else: post=self.request_post - + print(post) if pre_update_ret: if insert_row(post): diff --git a/paramecio2/modules/admin/libraries/admin_auth.py b/paramecio2/modules/admin/libraries/admin_auth.py index 5151605..640b3f3 100644 --- a/paramecio2/modules/admin/libraries/admin_auth.py +++ b/paramecio2/modules/admin/libraries/admin_auth.py @@ -53,12 +53,16 @@ def admin_prepare(): else: - url_redirect=config.domain_url+url_for('admin_app.logout', _external=False) + session.clear() + + url_redirect=config.domain_url+url_for('admin_app.login', _external=False) return redirect(url_redirect) else: - url_redirect=config.domain_url+url_for('admin_app.logout', _external=False) + session.clear() + + url_redirect=config.domain_url+url_for('admin_app.login', _external=False) return redirect(url_redirect) @@ -69,7 +73,7 @@ def admin_prepare(): return redirect(url_redirect) else: - #print(session['verify_auth']) + if request.endpoint!='admin_app.logout': if not session.get('verify_auth', True): diff --git a/pyproject.toml b/pyproject.toml index 091c964..c37698a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,7 +6,7 @@ build-backend = "flit_core.buildapi" name = "paramecio2" authors = [{name = "Antonio de la Rosa", email = "antonio.delarosa@salirdelhoyo.com"}] readme = "README.md" -version = "2.0.38" +version = "2.0.39" description = "A simple framework using flask and mako" # dynamic = ["version", "description"] diff --git a/setup.py b/setup.py index e9676f8..c4d8362 100644 --- a/setup.py +++ b/setup.py @@ -13,7 +13,7 @@ if sys.version_info < (3, 9): # If you install passlib and bcrypt, the password system will use bcrypt by default, if not, will use native crypt libc setup(name='paramecio2', - version='2.0.36', + version='2.0.39', description='Simple Web Framework based in flask and Mako.', long_description='This framework is a simple framework used for create web apps. Paramecio is modular and fast. By default have a module called admin that can be used for create admin sites', author='Antonio de la Rosa Caballero', From 22a964f0f5b266d8906074916f7571a5177445b7 Mon Sep 17 00:00:00 2001 From: Antonio de la Rosa Date: Sat, 15 Nov 2025 13:26:15 +0100 Subject: [PATCH 83/85] Fixes in sendmail --- paramecio2/libraries/sendmail.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/paramecio2/libraries/sendmail.py b/paramecio2/libraries/sendmail.py index 116dd2f..8dc4dc3 100644 --- a/paramecio2/libraries/sendmail.py +++ b/paramecio2/libraries/sendmail.py @@ -29,6 +29,7 @@ from email.mime.base import MIMEBase from email.mime.image import MIMEImage from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText +from email.utils import formataddr import ssl as ssl_module import sys @@ -129,7 +130,7 @@ class SendMail: return True - def send(self, from_address, to_address: list, subject, message, content_type='plain', attachments=[]): + def send(self, from_address, to_address: list, subject, message, content_type='plain', attachments=[], reply_to=()): """ Method that send email With this method you can send email to multiple address, html, and add attachments to email @@ -147,6 +148,10 @@ class SendMail: if not self.connect(): return False + if len(reply_to)==0: + reply_to=(from_address, from_address) + + COMMASPACE=', ' if len(attachments)==0: @@ -154,6 +159,9 @@ class SendMail: msg=MIMEText(message, content_type) msg['Subject']=subject + + msg['Reply-To']=formataddr(reply_to) + msg['From']=from_address msg['To']=COMMASPACE.join(to_address) @@ -169,6 +177,9 @@ class SendMail: outer=MIMEMultipart() outer['Subject']=subject + + msg['Reply-To']=formataddr(reply_to) + outer['From']=from_address outer['To']=COMMASPACE.join(to_address) From e2554b7539df4049418c17c5e6ef80652b006bde Mon Sep 17 00:00:00 2001 From: Antonio de la Rosa Date: Sat, 15 Nov 2025 13:54:15 +0100 Subject: [PATCH 84/85] Fix in mail function --- pyproject.toml | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index c37698a..e6a6771 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,7 +6,7 @@ build-backend = "flit_core.buildapi" name = "paramecio2" authors = [{name = "Antonio de la Rosa", email = "antonio.delarosa@salirdelhoyo.com"}] readme = "README.md" -version = "2.0.39" +version = "2.0.40" description = "A simple framework using flask and mako" # dynamic = ["version", "description"] diff --git a/setup.py b/setup.py index c4d8362..d55a6b3 100644 --- a/setup.py +++ b/setup.py @@ -13,7 +13,7 @@ if sys.version_info < (3, 9): # If you install passlib and bcrypt, the password system will use bcrypt by default, if not, will use native crypt libc setup(name='paramecio2', - version='2.0.39', + version='2.0.40', description='Simple Web Framework based in flask and Mako.', long_description='This framework is a simple framework used for create web apps. Paramecio is modular and fast. By default have a module called admin that can be used for create admin sites', author='Antonio de la Rosa Caballero', From 81c5b2aa995f8fb5557ed3eca3ff72da30fdd6f3 Mon Sep 17 00:00:00 2001 From: Antonio de la Rosa Date: Sun, 16 Nov 2025 23:33:17 +0100 Subject: [PATCH 85/85] Fix in email --- paramecio2/libraries/sendmail.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/paramecio2/libraries/sendmail.py b/paramecio2/libraries/sendmail.py index 8dc4dc3..e567b88 100644 --- a/paramecio2/libraries/sendmail.py +++ b/paramecio2/libraries/sendmail.py @@ -29,7 +29,7 @@ from email.mime.base import MIMEBase from email.mime.image import MIMEImage from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText -from email.utils import formataddr +from email.utils import formataddr, formatdate import ssl as ssl_module import sys @@ -184,6 +184,8 @@ class SendMail: outer['To']=COMMASPACE.join(to_address) + #outer['Date']=formatdate() + # Attach message text msg=MIMEText(message, content_type)