""" 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 #from bs4 import BeautifulSoup import bleach class IntegerField(PhangoField): """Class that figure an integer sql type field. """ def __init__(self, name, size=11, required=False): """ Args: name (str): The name of field size (int): The size of the new field in database. By default 11. required (bool): Boolean for define if field is required or not """ super(IntegerField, self).__init__(name, size, required) self.default_value=0 self.type_sql='int({})'.format(self.size) def check(self, value): """Method for check if value is integer Args: value (int): The value to check """ self.error=False self.txt_error='' try: value=str(int(value)) if value=="0" and self.required==True: self.txt_error="The value is zero" self.error=True except: value="0" self.txt_error="The value is zero" self.error=True return value def get_type_sql(self): """Method for return the sql code for this type """ return 'INT('+str(self.size)+') NOT NULL DEFAULT "0"' class BigIntegerField(IntegerField): """Class that figure an big integer sql type field. Only change the sql type with respect to IntegerField """ def __init__(self, name, size=11, required=False): super().__init__(name, size, required) self.type_sql='bigint({})'.format(self.size) def get_type_sql(self): """Method for return the sql code for this type """ return 'BIGINT('+str(self.size)+') NOT NULL DEFAULT "0"' class FloatField(PhangoField): """Class that figure an float sql type field. Args: name (str): The name of new field size (int): The size of the new field in database. By default 11. required (bool): Boolean for define if """ def __init__(self, name, size=11, required=False): super(FloatField, self).__init__(name, size, required) self.error_default="The value is zero" self.default_value=0 self.type_sql='float'.format(self.size) def check(self, value): """Method for check if value is integer Args: value (float): The value to check """ self.error=False self.txt_error='' try: value=str(value) if value.find(',')!=-1: value=value.replace(',', '.') value=str(float(value)) if value==0 and self.required==True: self.txt_error=self.error_default self.error=True except: value="0" self.txt_error=self.error_default self.error=True return value def get_type_sql(self): return 'FLOAT NOT NULL DEFAULT "0"' class DecimalField(FloatField): """PhangoField field for Decimals fields.""" def __init__(self, name, size=11, required=False): super().__init__(name, size, required) self.type_sql='decimal(20,2)' def get_type_sql(self): return 'DECIMAL(20, 2) NOT NULL DEFAULT "0"' class DoubleField(FloatField): """PhangoField field for Double fields.""" def __init__(self, name, size=11, required=False): super().__init__(name, size, required) self.type_sql='double' def get_type_sql(self): return 'DOUBLE NOT NULL DEFAULT "0"' class CharField(PhangoField): """Simple alias for PhangoField""" pass class TextField(PhangoField): """Class used for text fields Class used for text fields, use TEXT sql type for the this field. """ def __init__(self, name, required=False): """Init TextField class different to standard PhangoField Args: name (str): The name of new field required (bool): Boolean for define if field is required or not Attributes: set_default (str): Set if the value es NOT NULL or not """ super().__init__(name, 11, required) self.type_sql='text' self.set_default='NOT NULL' def get_type_sql(self): """Method for return the sql code for this type """ return 'TEXT '+self.set_default class LongTextField(TextField): """Class used for long text fields (32 bits size, 4G) Class used for text fields, use LONGTEXT sql type for the this field. """ def __init__(self, name, required=False): """Init TextField class different to standard PhangoField Args: name (str): The name of new field required (bool): Boolean for define if field is required or not Attributes: set_default (str): Set if the value es NOT NULL or not """ super().__init__(name, required) self.type_sql='longtext' def get_type_sql(self): """Method for return the sql code for this type """ return 'LONGTEXT '+self.set_default class HTMLField(TextField): """Class used for html fields Class used for html fields, use TEXT sql type for the this field because is children of TextField. In this method self.escape is used for convert " to " """ def __init__(self, name, required=False): """Init HTMLField class different to standard PhangoField Args: name (str): The name of new field required (bool): Boolean for define if field is required or not Attributes: trusted_tags (list): A list with safe tags. """ super().__init__(name, required) self.trusted_tags=[] def check(self, value): """Check method for html values 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 value=soup.renderContents().decode('utf-8') if self.escape: return value.replace('"', '"') else: 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 A subclass of IntegerField used for create foreign keys in related tables. """ def __init__(self, name, related_table, size=11, required=False, identifier_field='id', named_field="id", select_fields=[]): """ Args: name (str): Name of field related_table (WebModel): The table-model related with this foreign key size (int): The size of the new field in database. By default 11. required (bool): Boolean for define if field is required or not identifier_field (str): The Id field name from related table named_field (str): The field from related table used for identify the row seleted from related table select_fields (list): A series of fields names from related """ super(ForeignKeyField, self).__init__(name, size, required) self.table_id=related_table.name_field_id self.table_name=related_table.name self.related_model=related_table self.identifier_field=identifier_field self.named_field=named_field self.select_fields=select_fields self.foreignkey=True self.change_form(coreforms.SelectModelForm, [related_table, self.named_field, self.identifier_field]) self.default_value=None def check(self, value): value=super().check(value) if value=='0' or value==0: value=None return value def get_type_sql(self): """Method for return the sql code for this type """ return 'INT NULL' class BooleanField(IntegerField): """Field for boolean values """ def __init__(self, name, size=1): """ Args: name (str): Name of field size (int): The size of the new field in database. By default 11. """ required=False self.yes_text=I18n.lang('common', 'yes', 'Yes') self.no_text=I18n.lang('common', 'no', 'No') super(IntegerField, self).__init__(name, size, required) self.default_error="Need 0 or 1 value" self.default_value=0 self.type_sql='tinyint(1)' def check(self, value): self.error=False self.txt_error='' try: value=int(value) if value<0 or value>1: self.txt_error=self.default_error self.error=True value=0 except: self.error=True self.txt_error=self.default_error value=0 value=str(value) return value def get_type_sql(self): """Method for return the sql code for this type """ return 'BOOLEAN NOT NULL DEFAULT "0"' def show_formatted(self, value): value=int(value) if value==0: value=self.no_text else: value=self.yes_text return str(value)