"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 @@ -296,18 +227,7 @@ class HTMLField(TextField): return value - """ - - value=bleach.clean(value, tags=self.trusted_tags) - - if self.escape: - - return value.replace('"', '"') - else: - - return value - - + class ForeignKeyField(IntegerField): """Subclass of IntegerField for create Foreign keys @@ -385,12 +305,6 @@ class BooleanField(IntegerField): self.default_error="Need 0 or 1 value" self.default_value=0 - self.type_sql='tinyint(1)' - - self.jtype='boolean' - #self.jformat='0' - self.jexample='0' - def check(self, value): self.error=False diff --git a/paramecio2/libraries/db/coreforms.py b/paramecio2/libraries/db/coreforms.py index 427090f..6a37dd8 100644 --- a/paramecio2/libraries/db/coreforms.py +++ b/paramecio2/libraries/db/coreforms.py @@ -1,24 +1,5 @@ #!/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"trial"
')=='<p>"trial"</p><script></script>' + assert field.check('"trial"
')=='"trial"' field.escape=True - assert field.check('"trial"
')=='<p>"trial"</p><script></script>' + assert field.check('"trial"
')=='"trial"' field.trusted_tags=['p'] - assert field.check('"trial"
')=='"trial"
<script></script>' + assert field.check('"trial"
')=='"trial"
' #field. def test_test_foreignkeyfield(): field=corefields.ForeignKeyField('foreign', ExampleModel()) - assert field.check('dsd')==None + assert field.check('dsd')=='NULL' def test_test_booleanfield(): @@ -133,7 +131,7 @@ def test_test_datetimefield(): assert field.check('20201230121011')=='2020-12-30 12:10:11' - assert field.check('20201290121011')=='0000-00-00 00:00:00' + assert field.check('20201290121011')=='' def test_test_dictfield(): @@ -155,11 +153,7 @@ 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 diff --git a/tests/webmodel_test.py b/paramecio2/tests/webmodel_test.py similarity index 100% rename from tests/webmodel_test.py rename to paramecio2/tests/webmodel_test.py diff --git a/pyproject.toml b/pyproject.toml deleted file mode 100644 index e6a6771..0000000 --- a/pyproject.toml +++ /dev/null @@ -1,56 +0,0 @@ -[build-system] -requires = ["flit_core >=3.2,<4"] -build-backend = "flit_core.buildapi" - -[project] -name = "paramecio2" -authors = [{name = "Antonio de la Rosa", email = "antonio.delarosa@salirdelhoyo.com"}] -readme = "README.md" -version = "2.0.40" -description = "A simple framework using flask and mako" -# dynamic = ["version", "description"] - -classifiers=['Development Status :: 4 - Beta', - "Intended Audience :: Developers", - "License :: OSI Approved :: GNU Affero General Public License v3", - "Topic :: Internet :: WWW/HTTP :: Dynamic Content :: CGI Tools/Libraries", - "Topic :: Internet :: WWW/HTTP :: HTTP Servers", - "Topic :: Internet :: WWW/HTTP :: WSGI", - "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", - "Topic :: Internet :: WWW/HTTP :: WSGI :: Server", - "Topic :: Software Development :: Libraries :: Application Frameworks", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.11", - "Programming Language :: Python :: 3.12" -] -requires-python = ">=3.9" -dependencies=[ - "flask", - "pymysql", - "sqlalchemy", - "colorama", - "python-slugify", - "mako", - "pillow", - "arrow", - "bleach", - "argon2-cffi" -] - -[project.urls] -Home = "https://git.cuchulu.com/paramecio/paramecio2fm/" -Documentation = "https://docs.cuchulu.com/paramecio2/" - -[project.scripts] -paramecio2 = "paramecio2.console:start" -paramecio2db = "paramecio2.libraries.db.dbadmin:start" -paramecio2cm = "paramecio2.scripts.create_module:start" -paramecio2dm = "paramecio2.scripts.install_module:start" - -[tool.pytest.ini_options] -testpaths = ["tests"] -filterwarnings = [ - "error", -] diff --git a/setup.py b/setup.py index d55a6b3..151c07b 100644 --- a/setup.py +++ b/setup.py @@ -5,32 +5,32 @@ import os from setuptools import setup, find_packages -if sys.version_info < (3, 9): - raise NotImplementedError("Sorry, you need at least Python 3.9 for use paramecio2.") +if sys.version_info < (3, 8): + raise NotImplementedError("Sorry, you need at least Python 3.8 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.40', + version='2.0.28', 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://git.cuchulu.com/paramecio/paramecio2fm/', + author_email='antonio.delarosa@coesinfo.com', + url='https://bitbucket.org/paramecio/paramecio2fm/', packages=['paramecio2'], include_package_data=True, - install_requires=['flask', 'pymysql', 'sqlalchemy', 'colorama', 'python-slugify', 'mako', 'pillow', 'arrow', 'bleach', 'argon2-cffi'], + install_requires=['flask', 'pymysql', 'sqlalchemy', 'colorama', 'python-slugify', 'mako', 'pillow', 'arrow', 'beautifulsoup4'], entry_points={'console_scripts': [ 'paramecio2 = paramecio2.console:start', 'paramecio2db = paramecio2.libraries.db.dbadmin:start', 'paramecio2lang = paramecio2.libraries.check_i18n:start', ]}, zip_safe=False, - license='AGPLV3', + license='GPLV3', platforms = 'any', - classifiers=['Development Status :: 4 - Beta', + classifiers=['Development Status :: 1 - Beta', 'Intended Audience :: Developers', - 'License :: OSI Approved :: GNU Affero General Public License v3', + 'License :: OSI Approved :: GPLV3 License', 'Topic :: Internet :: WWW/HTTP :: Dynamic Content :: CGI Tools/Libraries', 'Topic :: Internet :: WWW/HTTP :: HTTP Servers', 'Topic :: Internet :: WWW/HTTP :: WSGI', @@ -38,9 +38,9 @@ setup(name='paramecio2', 'Topic :: Internet :: WWW/HTTP :: WSGI :: Server', 'Topic :: Software Development :: Libraries :: Application Frameworks', 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3.9', - 'Programming Language :: Python :: 3.10', - 'Programming Language :: Python :: 3.11', - 'Programming Language :: Python :: 3.12' + 'Programming Language :: Python :: 3.8' + 'Programming Language :: Python :: 3.9' + 'Programming Language :: Python :: 3.10' + 'Programming Language :: Python :: 3.11' ], ) diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/test.sh b/tests/test.sh deleted file mode 100644 index 890ee43..0000000 --- a/tests/test.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh - -pytest --mysql_host=127.0.0.1 --mysql_user=root --mysql_password=password --mysql_type=pymysql - diff --git a/tests/test_sendmailtest.py b/tests/test_sendmailtest.py new file mode 100644 index 0000000..5c29c93 --- /dev/null +++ b/tests/test_sendmailtest.py @@ -0,0 +1,25 @@ +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 new file mode 100644 index 0000000..7c45dad --- /dev/null +++ b/tests/test_urlstest.py @@ -0,0 +1,55 @@ +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 new file mode 100644 index 0000000..cc3ff8a --- /dev/null +++ b/tests/test_webmodeltest.py @@ -0,0 +1,305 @@ +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() +