Added first files for admin and login/signup in admin

This commit is contained in:
Antonio de la Rosa 2020-01-25 23:57:17 +01:00
parent e0ed00af8c
commit d9b62719d7
139 changed files with 18408 additions and 4 deletions

View file

@ -0,0 +1,256 @@
from paramecio2.libraries.db.webmodel import PhangoField
from paramecio2.libraries.db import coreforms
from paramecio2.libraries.i18n import I18n
class IntegerField(PhangoField):
"""Class that figure an integer 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(IntegerField, self).__init__(name, size, required)
self.default_value=0
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 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
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 DoubleField(FloatField):
def get_type_sql(self):
return 'DOUBLE NOT NULL DEFAULT "0"'
class CharField(PhangoField):
pass
class TextField(PhangoField):
def __init__(self, name, required=False):
super().__init__(name, 11, required)
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 HTMLField(TextField):
def __init__(self, name, required=False):
super().__init__(name, required)
def check(self, value):
return re.sub('<.*?script?>', '', value)
class ForeignKeyField(IntegerField):
def __init__(self, name, related_table, size=11, required=False, identifier_field='id', named_field="id", select_fields=[]):
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='NULL'
return value
def get_type_sql(self):
"""Method for return the sql code for this type
"""
return 'INT NULL'
class BooleanField(IntegerField):
def __init__(self, name, size=1):
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
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
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)

View file

@ -0,0 +1,193 @@
#!/usr/bin/env python3
from collections import OrderedDict
from html import escape
#Forms para python3
class BaseForm:
def __init__(self, name, value):
self.label=name
self.name=name
self.default_value=value
self.css=''
self.type='text'
self.field=None
self.required=False
self.txt_error=''
self.name_field_id=self.name+'_form'
self.help=''
def form(self):
return '<input type="'+self.type+'" class="'+self.css+'" name="'+self.name+'" id="'+self.name_field_id+'" value="'+self.setform(self.default_value)+'" />'
def show_formatted(self, value):
return value
#Method for escape value for html input. DON'T CHANGE IF YOU DON'T KNOWN WHAT ARE YOU DOING
def setform(self, value):
value=str(value)
return value.replace('"', '&quot;').replace("'", '&#39;')
def change_name(self, new_name):
self.name=new_name
self.name_field_id=self.name+'_form'
return ""
class SimpleTextForm(BaseForm):
def __init__(self, name, value):
super().__init__(name, value)
self.after_text=''
def form(self):
return super().form()+' '+self.after_text
class TextForm(BaseForm):
def __init__(self, name, value):
super(TextForm, self).__init__(name, value)
def form(self):
return '<textarea class="'+self.css+'" name="'+self.name+'" id="'+self.name+'_form">'+self.setform(self.default_value)+'</textarea>'
class PasswordForm(BaseForm):
def __init__(self, name, value):
super(PasswordForm, self).__init__(name, value)
self.type='password'
def setform(self, value):
return ""
class HiddenForm(BaseForm):
def __init__(self, name, value):
super(HiddenForm, self).__init__(name, value)
self.type='hidden'
class SelectForm(BaseForm):
def __init__(self, name, value, elements=OrderedDict()):
super(SelectForm, self).__init__(name, value)
self.arr_select=elements
def form(self):
the_form='<select name="'+self.name+'" id="'+self.name_field_id+'">\n'
arr_selected={self.default_value: 'selected'}
for k,v in self.arr_select.items():
arr_selected[k]=arr_selected.get(k, '')
the_form+="<option value=\""+self.setform(str(k))+"\" "+arr_selected[k]+">"+self.setform(str(v))+"</option>"
the_form+='</select>\n'
return the_form
class SelectModelForm(SelectForm):
def __init__(self, name, value, model, field_name, field_value, field_parent=None):
super(SelectModelForm, self).__init__(name, value)
try:
self.default_value=int(self.default_value)
except:
self.default_value=0
self.arr_select=OrderedDict()
self.model=model
self.field_name=field_name
self.field_value=field_value
self.field_parent=field_parent
self.form=self.normal_form
if self.field_parent!=None:
self.form=self.parent_form
def normal_form(self):
self.arr_select['']=''
with self.model.select([self.field_name, self.field_value], True) as cur:
for arr_value in cur:
self.arr_select[arr_value[self.field_value]]=self.model.fields[self.field_name].show_formatted(arr_value[self.field_name])
try:
self.default_value=int(self.default_value)
except:
self.default_value=0
return super().form()
def parent_form(self):
self.arr_select['']=''
arr_son={}
old_conditions=self.model.conditions
old_limit=self.model.limit
self.model.limit=''
self.model.set_conditions('WHERE 1=1', [])
with self.model.select([self.field_name, self.field_value, self.field_parent], True) as cur:
for arr_value in cur:
if not arr_value[self.field_parent] in arr_son:
arr_son[arr_value[self.field_parent]]=[]
arr_son[arr_value[self.field_parent]].append([arr_value[self.field_value], arr_value[self.field_name]])
self.create_son(0, arr_son)
self.model.conditions=old_conditions
self.model.limit=old_limit
try:
self.default_value=int(self.default_value)
except:
self.default_value=0
return super().form()
def create_son(self, parent_id, arr_son, separator=''):
if parent_id in arr_son:
for son in arr_son[parent_id]:
self.arr_select[son[0]]=separator+son[1]
son_separator=separator
if son[0] in arr_son:
son_separator+='--'
self.create_son(son[0],arr_son, son_separator)

View file

@ -0,0 +1,386 @@
#!/usr/bin/env python3
import argparse
import os,traceback
import sys, inspect
import shutil
import re
from datetime import date
from pathlib import Path
from colorama import init, Fore, Back, Style
from importlib import import_module, reload
from paramecio2.libraries.db.webmodel import WebModel
from settings import config
#from models import books
def start():
connection=WebModel.connection()
#connection.connect_to_db(WebModel.connections['default'])
parser = argparse.ArgumentParser(description='A tool for create tables in databases using models from Cromosoma')
parser.add_argument('--model', help='Model python path', required=True)
parser.add_argument('--config', help='The config file', required=False)
args = parser.parse_args()
init()
#Import config
config_file='config'
if args.config!=None:
config_file=args.config
try:
config=import_module('settings.'+config_file)
except:
e = sys.exc_info()[0]
v = sys.exc_info()[1]
print(Fore.WHITE+Back.RED+Style.BRIGHT+"Config file not found: %s %s" % (e, v))
exit(1)
#print(WebModel.connections)
if '/' in args.model:
args.model=args.model.replace('/', '.')[:-3] #.replace('.py', '')
try:
model=import_module(args.model)
for name, obj in inspect.getmembers(sys.modules[model.__name__]):
if inspect.isclass(obj):
if obj.__module__==args.model and hasattr(obj, 'webmodel'):
WebModel.model[name.lower()]=obj(connection)
#WebModel.modelobj
except:
"""
e = sys.exc_info()[0]
v = sys.exc_info()[1]
print(Fore.WHITE+Back.RED+Style.BRIGHT +"Error, file with model not found: %s %s" % (e, v))
"""
print("Exception in user code:")
print("-"*60)
traceback.print_exc(file=sys.stdout)
print("-"*60)
exit(1)
#load the table of databases
cursor=connection.query("show tables")
table_exists=[]
for row in cursor:
table=list(row.values())[0]
if table in WebModel.model:
table_exists.append(table)
#If don't want order
#set([1,2,3,4]) - set([2,5])
tables=list(WebModel.model.keys())
#Array diff ordered
new_tables=[x for x in tables if x not in table_exists]
#If don't want order
#new_tables=set(tables)-set(table_exists)
#Need order new_tables
changes=0
#Create new tables
if len(new_tables)>0:
print(Style.BRIGHT+"Creating new tables...")
changes+=1
for table in new_tables:
print(Style.NORMAL+"--Creating table "+table+"...")
connection.query(WebModel.model[table].create_table())
for table in new_tables:
print("--Adding indexes and constraints for the new table "+table)
for k_field, index in WebModel.arr_sql_index[table].items():
print("---Added index to "+k_field)
connection.query(index)
for k_set, index_set in WebModel.arr_sql_set_index[table].items():
if index_set!="":
connection.query(index_set)
print("---Added constraint to "+k_set)
print("--Adding uniques elements for the new table")
#See if changes exists
#Check if created tables are modified.
try:
model_old=import_module('backups.'+args.model)
for name, obj in inspect.getmembers(sys.modules[model_old.__name__]):
if inspect.isclass(obj):
if obj.__module__=='backups.'+args.model and hasattr(obj, 'webmodel'):
WebModel.model['old_'+name.lower()]=obj(connection)
print(Style.BRIGHT+"Checking old versions of model for find changes...")
for table in tables:
#connection.query("")
#Check if new table
#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
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=[]
old_table='old_'+table
if not old_table in WebModel.model:
WebModel.model[old_table]=WebModel.model[table]
for f, v in WebModel.model[table].fields.items():
if not f in WebModel.model[old_table].fields:
fields_to_add.append(f)
#Add index
if v.indexed==True:
fields_to_add_index.append(f)
changes+=1
#Add unique
if v.unique==True:
fields_to_add_unique.append(f)
changes+=1
#Add constraint
if v.foreignkey==True:
fields_to_add_constraint.append(f)
changes+=1
changes+=1
#If exists field in old webmodel and new
else:
v_old=WebModel.model[old_table].fields[f]
if v.get_type_sql()!=v_old.get_type_sql():
fields_to_modify.append(f)
changes+=1
#Add index
if v.indexed==True and v_old.indexed==False:
fields_to_add_index.append(f)
changes+=1
if v.indexed==False and v_old.indexed==True:
fields_to_delete_index.append(f)
changes+=1
#Add unique
if v.unique==True and v_old.unique==False:
fields_to_add_unique.append(f)
changes+=1
if v.unique==False and v_old.unique==True:
fields_to_delete_unique.append(f)
changes+=1
#Add constraint
if v.foreignkey==True and v_old.foreignkey==False:
fields_to_add_constraint.append(f)
changes+=1
if v.foreignkey==False and v_old.foreignkey==True:
fields_to_delete_constraint.append(f)
changes+=1
for f, v in WebModel.model[old_table].fields.items():
if not f in WebModel.model[table].fields:
#Add constraint
if v.foreignkey==True:
fields_to_delete_constraint.append(f)
changes+=1
fields_to_delete.append(f)
changes+=1
WebModel.model[table].update_table(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)
#for field_update in arr_update:
#Make a for in fields, if the field not exist in old model, create, if is not same type, recreate. If no have index now, delete index, if is a new index, create, same thing with uniques
#for field in WebModel.model
except ImportError:
pass
except:
print("Exception in user code:")
print("-"*60)
traceback.print_exc(file=sys.stdout)
print("-"*60)
exit(1)
original_file_path=args.model.replace('.', '/')+'.py'
backup_path='backups/'+original_file_path
if changes>0:
print(Style.BRIGHT+"Creating backup of the model. WARNING: DON'T DELETE BACKUPS DIRECTORY IF YOU WANT MAKE CHANGES IN THE FUTURE WITHOUT MODIFY DIRECTLY THE DATABASE")
create_backup(original_file_path, backup_path)
else:
if not os.path.isfile(backup_path):
create_backup(original_file_path, backup_path)
# Execute script
arr_script_model=args.model.split('.')
arr_script_model.pop()
script_model='.'.join(arr_script_model)+'.scripts.install'
script_py=script_model.replace('.', '/')+'.py'
if os.path.isfile(script_py):
locked_file='/'.join(arr_script_model)+'/scripts/locked'
if not os.path.isfile(locked_file):
script_install=import_module(script_model)
script_install.run()
f=open(locked_file, 'w')
f.write('OK')
f.close()
connection.close()
#script_model=args.model+''
print(Style.BRIGHT+"All tasks finished")
def create_backup(original_file_path, file_path):
#Create copy
path=os.path.dirname(file_path)
p=Path(path)
if not p.is_dir():
p.mkdir(0o755, True)
with open(path+'/__init__.py', 'w') as f:
f.write("#!/usr/bin/env python3\n")
#Create path
if os.path.isfile(file_path):
today = date.today()
shutil.copy(file_path, file_path+'.'+today.strftime("%Y%M%d%H%M%S"))
new_file=""
f=open(original_file_path)
for line in f:
"""
new_line=line.replace("model[\"", "model[\"old_")
new_line=new_line.replace("model['", "model['old_")
new_line=new_line.replace("WebModel(\"", "WebModel(\"old_")
new_line=new_line.replace("WebModel('", "WebModel('old_")
"""
new_file+=line
f.close()
f=open(file_path, 'w')
f.write(new_file)
f.close()

View file

@ -0,0 +1,59 @@
from paramecio2.libraries.db.webmodel import PhangoField,WebModel
import json
class ArrayField(PhangoField):
def __init__(self, name, field_type, required=False):
super().__init__(name, required)
self.field_type=field_type
self.error_default='Sorry, the json array is invalid'
self.set_default='NOT NULL'
def check(self, value):
if type(value).__name__=='str':
try:
value=json.loads(value)
except json.JSONDecodeError:
value=[]
self.error=True
self.txt_error=self.error_default
elif type(value).__name__!='list':
value=[]
self.error=True
self.txt_error='Sorry, the json array is invalid'
if type(self.field_type).__name__!='ArrayField':
for k,v in enumerate(value):
value[k]=self.field_type.check(v)
final_value=json.dumps(value)
final_value=WebModel.escape_sql(final_value)
return final_value
def get_type_sql(self):
return 'TEXT '+self.set_default
def show_formatted(self, value):
return ", ".join(value)
def loads(self, value):
try:
return json.loads(value)
except:
return False

View file

@ -0,0 +1,47 @@
from paramecio2.libraries.db.corefields import IntegerField
from paramecio2.libraries.db.extraforms.colorform import ColorForm
class ColorField(IntegerField):
def __init__(self, name, size=11, required=False):
super().__init__(name, size, required)
self.name_form=ColorForm
def check(self, value):
value=str(value).replace('#', '0x')
value=int(value, 16)
if value<0 or value>0xffffff:
value=0
return value
def get_hex_color(self, value):
value=str(hex(int(value))).replace('0x', '')
c=len(value)
if(c<6):
repeat=6-c
value=('0'*repeat)+value
value='#'+value
return value
def show_formatted(self, value):
value=str(hex(int(value))).replace('0x', '')
c=len(value)
if(c<6):
repeat=6-c
value=('0'*repeat)+value
value='#'+value
return '<div style="width:50px;height:50px;background-color:%s;"></div>' % value;

View file

@ -0,0 +1,39 @@
from paramecio2.libraries.db.corefields import PhangoField
from paramecio.citoplasma import datetime
from paramecio2.libraries.db.extraforms.dateform import DateForm
class DateField(PhangoField):
def __init__(self, name, size=255, required=False):
super().__init__(name, size, required)
self.name_form=DateForm
self.utc=True
self.error_default='Error: Date format invalid'
def check(self, value):
if self.utc:
value=datetime.local_to_gmt(value)
elif not datetime.obtain_timestamp(value, False):
self.error=True
self.txt_error=self.error_default
return ''
if value==False:
self.error=True
self.txt_error=self.error_default
return ''
return value
def show_formatted(self, value):
return datetime.format_date(value)

View file

@ -0,0 +1,60 @@
from paramecio2.libraries.db.corefields import PhangoField
from paramecio.citoplasma import datetime
from paramecio2.libraries.db.extraforms.dateform import DateForm
class DateTimeField(PhangoField):
def __init__(self, name, size=255, required=False):
super().__init__(name, size, required)
self.name_form=DateForm
self.utc=False
self.error_default='Error: Date format invalid'
def check(self, value):
if self.utc:
value=datetime.local_to_gmt(value)
elif not datetime.obtain_timestamp(value, False):
self.error=True
self.txt_error=self.error_default
return ''
if value==False:
self.error=True
self.txt_error=self.error_default
return ''
else:
"""
format_date_txt="YYYY/MM/DD"
format_time_txt="HH:mm:ss"
"""
value=datetime.format_local_strtime('YYYY-MM-DD HH:mm:ss', value)
return value
def show_formatted(self, value):
# Convert to paramecio value
value=str(value)
value=value.replace('-', '').replace(':', '').replace(' ', '')
return datetime.format_date(value)
def get_type_sql(self):
"""Method for return the sql code for this type
"""
return 'DATETIME NOT NULL'

View file

@ -0,0 +1,50 @@
from paramecio2.libraries.db.webmodel import WebModel, PhangoField
import json
class DictField(PhangoField):
def __init__(self, name, field_type, required=False):
super().__init__(name, required)
self.field_type=field_type
self.error_default='Sorry, the json dict is invalid'
self.set_default='NOT NULL'
def check(self, value):
if type(value).__name__=='str':
try:
value=json.loads(value)
except json.JSONDecodeError:
value={}
self.error=True
self.txt_error=self.error_default
elif type(value).__name__!='dict':
value={}
self.error=True
self.txt_error=self.error_default
for k,v in value.items():
value[k]=self.field_type.check(v)
final_value=json.dumps(value)
#final_value=WebModel.escape_sql(final_value)
return final_value
def get_type_sql(self):
return 'TEXT '+self.set_default
def show_formatted(self, value):
return ", ".join(value)

View file

@ -0,0 +1,27 @@
from paramecio2.libraries.db.corefields import CharField
import re
mail_pattern=re.compile("\w[\w\.-]*@\w[\w\.-]+\.\w+")
class EmailField(CharField):
def __init__(self, name, size=1024, required=False):
super().__init__(name, size, required)
self.error_default='Error: No valid format'
def check(self, value):
value=super().check(value)
self.error=False
self.txt_error=''
if not mail_pattern.match(value):
self.error=True
value=""
self.txt_error=self.error_default
return value

View file

@ -0,0 +1,176 @@
import os
import sys
from pathlib import Path
from paramecio2.libraries.db.corefields import CharField
from paramecio2.libraries.db.extraforms.fileform import FileForm
from paramecio.citoplasma import httputils
from paramecio.citoplasma.keyutils import create_key
import traceback
from bottle import request
from uuid import uuid4
#from paramecio2.libraries.db.extraforms.fileform import FileForm
class FileField(CharField):
def __init__(self, name, save_folder='media/upload/files', sizes=None, module=None, size=255, required=False):
super().__init__(name, size, required)
self.yes_prefix=True
self.suffix=''
# Is relative to media folder of paramecio
#if module!=None:
self.save_folder=save_folder
self.file_related=True
self.sizes=sizes
self.name_form=FileForm
self.extra_parameters=[self.save_folder]
def change_folder(self, folder):
pass
def check(self, value):
files_uploaded=request.files
field_file=self.name+'_file'
#if not change
if not field_file in files_uploaded:
if value=='':
if self.model:
if self.model.updated:
old_reset=self.model.yes_reset_conditions
self.model.yes_reset_conditions=False
with self.model.select([self.name]) as cur:
for arr_image in cur:
if arr_image[self.name]!='':
try:
os.remove(arr_image[self.name])
except:
pass
#if arr_image[self.name]!=save_file and arr_image[self.name]!='':
#value=arr_image[self.name]
self.model.yes_reset_conditions=old_reset
self.txt_error='Field is empty'
self.error=True
return ''
else:
value=os.path.basename(value)
return self.save_folder+'/'+value
# Load image file
file_bytecode=files_uploaded[field_file].file
filename=files_uploaded[field_file].filename
realfilename, ext = os.path.splitext(filename)
prefix=''
if self.yes_prefix==True:
#prefix=uuid4().hex+'_'
prefix=create_key(5).replace('/', '-').replace('#', '-')+self.suffix+'_'
filename=prefix+filename
save_file=self.save_folder+'/'+filename
# Save file
try:
#Check if directory exists
if not os.path.isdir(self.save_folder):
# Try create if not
try:
p=Path(self.save_folder)
p.mkdir(mode=0o755, parents=True)
except:
self.error=True
self.txt_error='Error: cannot create the directory where save the image.Check permissions,'
return ""
#files_uploaded[field_file].save(self.save_folder, overwrite=True)
if os.path.isfile(save_file):
os.remove(save_file)
# Delete old files
if self.model!=None:
if self.model.updated:
#old_conditions=self.model.conditions
old_reset=self.model.yes_reset_conditions
self.model.yes_reset_conditions=False
with self.model.select([self.name]) as cur:
for arr_file in cur:
if arr_file[self.name]!=save_file and arr_file[self.name]!='':
if os.path.isfile(arr_file[self.name]):
os.remove(arr_file[self.name])
self.model.yes_reset_conditions=old_reset
#self.model.conditions=old_conditions
return save_file
except:
self.error=True
self.txt_error='Error: cannot save the image file, Exists directory for save the file? '+traceback.format_exc()
print(traceback.format_exc())
return ""
def show_formatted(self, value):
return os.path.basename(value)

View file

@ -0,0 +1,157 @@
#!/usr/bin/env python3
import json
from paramecio2.libraries.db.webmodel import PhangoField
from paramecio2.libraries.db.coreforms import BaseForm
from paramecio2.libraries.db.extraforms.i18nform import I18nForm
from paramecio.citoplasma.i18n import I18n
from paramecio.citoplasma.httputils import GetPostFiles
import json
import re
class I18nField(PhangoField):
def __init__(self, name, form=None):
super().__init__(name)
if form==None:
form=BaseForm(name, '')
self.name_form=I18nForm
self.extra_parameters=[form]
self.show_formatted_value=True
self.show_blank=False
arr_i18n={i:'' for i in I18n.dict_i18n}
self.default_value=json.dumps(arr_i18n)
def change_form(self, form):
self.extra_parameters=[form]
def check_value(self, value):
return super().check(value)
def check(self, value):
self.error=False
self.txt_error=''
arr_values={}
try:
arr_values=json.loads(value)
if not arr_values:
arr_values={}
except:
arr_values={}
arr_real_values={}
error_values=0
for lang in I18n.dict_i18n:
arr_real_values[lang]=arr_values.get(lang, '')
arr_real_values[lang]=self.check_value(arr_real_values[lang])
if not arr_real_values[lang] or arr_real_values[lang]=='None':
arr_real_values[lang]=''
error_values+=1
self.error=False
arr_values=arr_real_values
if error_values:
if error_values==len(arr_values):
self.error=True
self.txt_error='Sorry, You field language is empty'
return json.dumps(arr_values)
"""
if arr_values[I18n.default_lang]=='':
self.error=True
self.txt_error='Sorry, You need default language '+I18n.default_lang
return json.dumps(arr_values)
"""
return json.dumps(arr_values)
def get_type_sql(self):
return 'TEXT NOT NULL'
def obtain_lang_value(self, lang, value):
return value.get(self.name+'_'+lang, '')
def obtain_lang_from_post(self, lang, value):
#getpost=GetPostFiles()
#getpost.obtain_post()
return "" #GetPostFiles.post.get(self.name+'_'+lang, '')
def show_formatted(self, value):
if value=='':
value='{"en-US": "", "es-ES": ""}'
value=json.loads(value)
lang=I18n.get_default_lang()
if value[lang]!='' or self.show_blank:
return value[lang]
lang_value=value[I18n.default_lang]
if value[I18n.default_lang]=='':
for l in value:
if value[l]!='':
lang_value=value[l]
break
return lang_value
@staticmethod
def get_value(value):
value=json.loads(value)
lang=I18n.get_default_lang()
if value[lang]!='':
return value[lang]
return value[I18n.default_lang]
class I18nHTMLField(I18nField):
def check_value(self, value):
return re.sub('<.*?script?>', '', value)
class I18nPhangoField(I18nField):
def __init__(self, name, field_class, form=None):
super().__init__(name, form)
self.field_class=field_class
def check_value(self, value):
f=self.field_class
return f.check(value)

View file

@ -0,0 +1,276 @@
import os
import sys
from pathlib import Path
from paramecio2.libraries.db.corefields import CharField
from paramecio2.libraries.db.extraforms.fileform import FileForm
from paramecio.citoplasma import httputils
from paramecio.citoplasma.keyutils import create_key
import traceback
from bottle import request
try:
from PIL import Image
except:
print("Unexpected error:", sys.exc_info()[0])
raise
from uuid import uuid4
#from paramecio2.libraries.db.extraforms.fileform import FileForm
class ImageField(CharField):
def __init__(self, name, save_folder='media/upload/images', sizes=None, module=None, size=255, required=False):
super().__init__(name, size, required)
self.yes_prefix=True
#self.name_form=FileForm
self.thumbnail={'mini_': 150}
self.yes_thumbnail=False
self.default_quality_thumb=95
self.suffix=''
# Is relative to media folder of paramecio
#if module!=None:
self.save_folder=save_folder
self.file_related=True
self.sizes=sizes
self.name_form=FileForm
self.extra_parameters=[self.save_folder]
def change_folder(self, folder):
pass
def check(self, value):
files_uploaded=request.files
field_file=self.name+'_file'
#if not change
if not field_file in files_uploaded:
if value=='':
if self.model:
if self.model.updated:
old_reset=self.model.yes_reset_conditions
self.model.yes_reset_conditions=False
with self.model.select([self.name]) as cur:
for arr_image in cur:
if arr_image[self.name]!='':
try:
os.remove(arr_image[self.name])
except:
pass
#if arr_image[self.name]!=save_file and arr_image[self.name]!='':
#value=arr_image[self.name]
self.model.yes_reset_conditions=old_reset
self.txt_error='Field is empty'
self.error=True
return ''
else:
value=os.path.basename(value)
return self.save_folder+'/'+value
# Load image file
file_bytecode=files_uploaded[field_file].file
filename=files_uploaded[field_file].filename
try:
im=Image.open(file_bytecode)
except IOError:
self.error=True
self.txt_error='Error, file not have a valid format'
return ""
real_width=im.size[0]
real_height=im.size[1]
if self.sizes:
if 'maximum' in self.sizes:
if self.sizes['maximum'][0]<real_width or self.sizes['maximum'][1]<real_height:
self.error=True
self.txt_error='Wrong size. Maximum size is '+str(self.sizes['maximum'][0])+'x'+str(self.sizes['maximum'][1])
im.close()
return ""
if 'minimum' in self.sizes:
if self.sizes['minimum'][0]>real_width or self.sizes['minimum'][1]>real_height:
self.error=True
self.txt_error='Wrong size. Minimum size is '+str(self.sizes['minimum'][0])+'x'+str(self.sizes['minimum'][1])
im.close()
return ""
if 'resize' in self.sizes:
height_t=0
width_t=0
if real_height<=self.sizes['resize'][1]:
height_t=self.sizes['resize'][1]
if real_width>self.sizes['resize'][0]:
width_t=self.sizes['resize'][0]
if height_t==0:
ratio=(real_width/width_t)
height_t=round(real_height/ratio)
size=(width_t, height_t)
if width_t>0 and height_t>0:
im.thumbnail(size, 3)
format_image=im.format
if format_image!='JPEG' and format_image!='GIF' and format_image!='PNG':
self.error=True
self.txt_error='Format is wrong. Requires JPEG or PNG formats'
im.close()
return ""
# Create thumbnails and move file
realfilename, ext = os.path.splitext(filename)
prefix=''
if self.yes_prefix==True:
#prefix=uuid4().hex+'_'
prefix=create_key(5).replace('/', '-').replace('#', '-')+self.suffix+'_'
filename=prefix+filename
save_file=self.save_folder+'/'+filename
if self.yes_thumbnail:
for name, width_t in self.thumbnail.items():
im_thumb=im.copy()
ratio=(real_width/width_t)
height_t=round(real_height/ratio)
size=(width_t, height_t)
save_file_thumb=self.save_folder+'/'+name+filename
im_thumb.thumbnail(size, Image.ANTIALIAS)
im_thumb.save(save_file_thumb, "JPEG", quality=self.default_quality_thumb)
im_thumb.close()
# Save file
try:
#Check if directory exists
if not os.path.isdir(self.save_folder):
# Try create if not
try:
p=Path(self.save_folder)
p.mkdir(mode=0o755, parents=True)
except:
im.close()
self.error=True
self.txt_error='Error: cannot create the directory where save the image.Check permissions,'
return ""
#files_uploaded[field_file].save(self.save_folder, overwrite=True)
if os.path.isfile(save_file):
os.remove(save_file)
im.save(save_file)
# Delete old files
if self.model!=None:
if self.model.updated:
#old_conditions=self.model.conditions
old_reset=self.model.yes_reset_conditions
self.model.yes_reset_conditions=False
with self.model.select([self.name]) as cur:
for arr_image in cur:
if arr_image[self.name]!=save_file and arr_image[self.name]!='':
if os.path.isfile(arr_image[self.name]):
os.remove(arr_image[self.name])
self.model.yes_reset_conditions=old_reset
#self.model.conditions=old_conditions
im.close()
return save_file
except:
im.close()
self.error=True
self.txt_error='Error: cannot save the image file, Exists directory for save the file? '+traceback.format_exc()
print(traceback.format_exc())
return ""
def show_formatted(self, value):
return os.path.basename(value)

View file

@ -0,0 +1,19 @@
from paramecio2.libraries.db.corefields import CharField
import ipaddress
class IpField(CharField):
def check(self, value):
try:
value=str(ipaddress.ip_address(value))
except:
self.error=True
self.txt_error='No Valid IP'
value=""
return value

View file

@ -0,0 +1,27 @@
#!/usr/bin/env python3
from paramecio2.libraries.db.corefields import CharField
from paramecio2.libraries.db import coreforms
from paramecio2.libraries.i18n import I18n
class LangField(CharField):
def __init__(self, name, size=255, required=False):
super(CharField, self).__init__(name, size, required)
select_lang={}
for lang in I18n.dict_i18n:
select_lang[lang]=lang
self.change_form(coreforms.SelectForm, [select_lang])
self.default_value=I18n.default_lang
def check(self, value):
if value not in I18n.dict_i18n:
value=I18n.default_lang
return value

View file

@ -0,0 +1,26 @@
from paramecio2.libraries.db.corefields import FloatField
from decimal import Decimal, getcontext
from locale import format_string
getcontext().prec=2
class MoneyField(FloatField):
def __init__(self, name, required=False):
super().__init__(name, 11, required)
def check(self, value):
value=Decimal(value)
return value
def show_formatted(self, value):
return format_string('%.2f', Decimal(value), grouping=True)
@staticmethod
def format_money(value):
return format_string('%.2f', Decimal(value), grouping=True)

View file

@ -0,0 +1,42 @@
#!/usr/bin/env python3
#from paramecio2.libraries.db.webmodel import PhangoField
from paramecio2.libraries.db.corefields import IntegerField
from paramecio2.libraries.db.coreforms import SelectModelForm
from paramecio.citoplasma.httputils import GetPostFiles
class ParentField(IntegerField):
def __init__(self, name, size=11, required=False, field_name='name'):
super().__init__(name, size, required)
#self.foreignkey=True
self.indexed=True
self.field_name=field_name
def post_register(self):
if self.model!=None:
self.change_form(SelectModelForm, [self.model, self.field_name, self.model.name_field_id, self.name])
def check(self, value):
value=super().check(value)
if self.model!=None:
if self.model.updated==True:
if self.model.name_field_id in self.model.post:
GetPostFiles.obtain_get()
model_id=GetPostFiles.get.get(self.model.name_field_id, '0')
if model_id==value:
self.error=True
self.txt_error='A field cannot be its own father'
self.required=True
value=0
return value
return value

View file

@ -0,0 +1,119 @@
from paramecio2.libraries.db.corefields import PhangoField
from paramecio2.libraries.db.coreforms import PasswordForm
from hmac import compare_digest as compare_hash
import crypt
class PasswordField(PhangoField):
def __init__(self, name, size=1024, required=False):
super(PasswordField, self).__init__(name, size, required)
self.protected=True
self.name_form=PasswordForm
self.default_value=''
self.encrypt_password=True
def check(self, value):
self.txt_error=''
self.error=False
value.strip()
if value=='':
if self.model!=None:
if self.model.updated==True:
self.required=False
self.check_blank=True
return ""
else:
self.txt_error=self.error_default
self.error=True
else:
self.txt_error=self.error_default
self.error=True
else:
#if crypt.METHOD_SHA512 in crypt.methods:
#salt=crypt.mksalt(crypt.METHOD_SHA512)
if self.encrypt_password:
value=crypt.crypt(value)
"""
else:
self.txt_error="You need the SHA512 method"
self.error=True
return ""
"""
return value
@staticmethod
def verify( password, h):
#return bcrypt_sha256.verify(password, h)
return compare_hash(h, crypt.crypt(password, h))
# Old function bcrypt
"""
try:
from passlib.hash import bcrypt
from passlib.hash import bcrypt_sha256
class PasswordField(PhangoField):
def __init__(self, name, size=1024, required=False):
super(PasswordField, self).__init__(name, size, required)
self.protected=True
self.name_form=PasswordForm
self.default_value=''
def check(self, value):
self.txt_error=''
self.error=False
value.strip()
if value=='':
if self.model!=None:
if self.model.updated==True:
self.required=False
self.check_blank=True
return ""
else:
self.txt_error="The field is empty"
self.error=True
else:
self.txt_error="The field is empty"
self.error=True
else:
#if crypt.METHOD_SHA512 in crypt.methods:
#value = bcrypt_sha256.encrypt(value)
value = bcrypt_sha256.hash(value)
return value
@staticmethod
def verify( password, h):
return bcrypt_sha256.verify(password, h)
except:
"""

View file

@ -0,0 +1,22 @@
from paramecio2.libraries.db.corefields import IntegerField
class PercentField(IntegerField):
def __init__(self, name, required=False):
super().__init__(name, 2, required)
def check(self, value):
try:
value=int(value)
if value<0:
value=0
if value>100:
value=100
except:
value=0
return value

View file

@ -0,0 +1,37 @@
#!/usr/bin/env python3
from paramecio2.libraries.db.corefields import CharField
from paramecio.citoplasma.slugify import slugify
from paramecio2.libraries.db.coreforms import HiddenForm
class SlugifyField(CharField):
def __init__(self, name, size=255, field_related=None, required=False):
super(SlugifyField, self).__init__(name, size, required)
self.name_form=HiddenForm
self.field_related=field_related
def check(self, value):
value=slugify(value)
if value=='':
if self.model!=None and self.field_related!=None:
self.model.post[self.field_related]=self.model.post.get(self.field_related, '')
value=slugify(self.model.post[self.field_related])
if value=='':
self.error=True
self.error_txt='Value is empty'
return ''
return value

View file

@ -0,0 +1,42 @@
from paramecio2.libraries.db.corefields import CharField
import re
check_url = re.compile(
r'^(?:http|ftp)s?://' # http:// or https://
r'(?:(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+(?:[A-Z]{2,6}\.?|[A-Z0-9-]{2,}\.?)|' #domain...
r'localhost|' #localhost...
r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})' # ...or ip
r'(?::\d+)?' # optional port
r'(?:/?|[/?]\S+)$', re.IGNORECASE)
class UrlField(CharField):
def check(self, value):
self.error=False
self.txt_error=''
if not check_url.match(value):
self.error=True
value=""
self.txt_error='No valid URL format'
return value
check_domain=re.compile('^(([a-zA-Z]{1})|([a-zA-Z]{1}[a-zA-Z]{1})|([a-zA-Z]{1}[0-9]{1})|([0-9]{1}[a-zA-Z]{1})|([a-zA-Z0-9][a-zA-Z0-9-_]{1,61}[a-zA-Z0-9]))\.([a-zA-Z]{2,6}|[a-zA-Z0-9-]{2,30}\.[a-zA-Z]{2,3})$')
class DomainField(CharField):
def check(self, value):
self.error=False
self.txt_error=''
if not check_domain.match(value):
self.error=True
value=""
self.txt_error='No valid domain format'
return value

View file

@ -0,0 +1,16 @@
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 re
class UserNameField(PhangoField):
def check(self, value):
if not re.match("^[A-Za-z0-9_-]+$", value):
self.txt_error='Error: use only letters, numbers, underscores and dashes for this field'
self.error=1
value=''
return value

View file

@ -0,0 +1,20 @@
#!/usr/bin/env python3
from paramecio2.libraries.db.coreforms import BaseForm
class CheckForm(BaseForm):
def __init__(self, name, value, real_value=1):
super(CheckForm, self).__init__(name, value)
self.real_value=real_value
def form(self):
arr_value={}
arr_value[self.setform(self.default_value)]=''
arr_value[self.setform(self.real_value)]='checked'
return '<input type="checkbox" class="'+self.css+'" name="'+self.name+'" id="'+self.name_field_id+'" value="'+str(self.real_value)+'" '+arr_value[self.setform(self.default_value)]+'>'

View file

@ -0,0 +1,17 @@
#!/usr/bin/env python3
from paramecio2.libraries.db.coreforms import BaseForm
from paramecio2.libraries.mtemplates import standard_t
class ColorForm(BaseForm):
def __init__(self, name, value):
super().__init__(name, value)
self.t=standard_t
def form(self):
return self.t.load_template('forms/colorform.phtml', name_form=self.name_field_id, default_value=self.default_value, form=self)

View file

@ -0,0 +1,39 @@
#!/usr/bin/env python3
from paramecio2.libraries.db.coreforms import BaseForm
from paramecio2.libraries.mtemplates import standard_t
from paramecio2.libraries.datetime import format_timedata
class DateForm(BaseForm):
def __init__(self, name, value):
super().__init__(name, value)
self.yes_time=False
self.t=standard_t
def form(self):
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=int(time[5])
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)
#def

View file

@ -0,0 +1,21 @@
#!/usr/bin/env python3
from paramecio2.libraries.db.coreforms import BaseForm
from paramecio2.libraries.mtemplates import env_theme, PTemplate
env=env_theme(__file__)
t=PTemplate(env)
class FileForm(BaseForm):
def __init__(self, name, value, path):
super().__init__(name, value)
self.t=t
self.enctype=True
def form(self):
return self.t.load_template('forms/fileform.phtml', form=self)

View file

@ -0,0 +1,32 @@
#!/usr/bin/env python3
from paramecio2.libraries.db.coreforms import BaseForm
from paramecio2.libraries.i18n import I18n
from paramecio2.libraries.mtemplates import standard_t
import json
class I18nForm(BaseForm):
def __init__(self, name, value, form):
super().__init__(name, value)
self.form_child=form
self.t=standard_t
def form(self):
lang_selected=I18n.get_default_lang()
try:
self.default_value=json.loads(self.default_value)
except:
self.default_value={}
if type(self.default_value).__name__!='dict':
self.default_value={}
for lang in I18n.dict_i18n:
self.default_value[lang]=self.default_value.get(lang, '')
return standard_t.load_template('forms/i18nform.phtml', name_form=self.name_field_id, real_name_form=self.name, form=self.form_child, arr_i18n=I18n.dict_i18n, lang_selected=lang_selected, default_value=self.default_value)

View file

@ -0,0 +1,22 @@
from paramecio2.libraries.db.coreforms import BaseForm
from paramecio2.libraries.mtemplates import env_theme, PTemplate
env=env_theme(__file__)
t=PTemplate(env)
class TextHTMLForm(BaseForm):
def __init__(self, name, value, t_add=None):
super().__init__(name, value)
self.t=t_add
if t_add==None:
self.t=t
def form(self):
return self.t.load_template('forms/texthtmlform.phtml', form=self)

View file

@ -0,0 +1,22 @@
from paramecio2.libraries.db.coreforms import BaseForm
from paramecio2.libraries.mtemplates import env_theme, PTemplate
env=env_theme(__file__)
t=PTemplate(env)
class TextHTMLForm(BaseForm):
def __init__(self, name, value, t_add=None):
super().__init__(name, value)
self.t=t_add
if t_add==None:
self.t=t
def form(self):
return self.t.load_template('forms/texthtmlform.phtml', form=self)

View file

@ -0,0 +1,210 @@
#!/usr/bin/env python3
import sys
#import pymysql.cursors
#pymysql.install_as_MySQLdb
#import sqlalchemy.pool as pool
from sqlalchemy import create_engine
import traceback
#mypool=None
#engine = create_engine('sqlite:///:memory:', echo=True)
engine=None
class SqlClass:
cursors_connect=None
disable_pool=False
pymysql_install=False
pool_size=15
def __init__(self, connection):
self.max_overflow=-1
self.error_connection=""
# Data of connection
self.connection=connection
# Sql connection
self.conn=None
self.connected=False
self.pool_recycle=3600
self.connect()
def connect(self):
global engine
if not SqlClass.disable_pool:
if not engine:
try:
if self.connection['db_type']=='pymysql':
import pymysql.cursors
SqlClass.cursors_connect=pymysql.cursors.DictCursor
else:
import MySQLdb.cursors
SqlClass.cursors_connect=MySQLdb.cursors.DictCursor
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)
except:
e = sys.exc_info()[0]
v = sys.exc_info()[1]
self.error_connection="Error in connection: %s %s" % (e, v)
#self.conn.close()
raise NameError(self.error_connection)
self.conn=engine.raw_connection()
#self.conn.ping(True)
else:
if self.connection['db_type']=='pymysql':
import pymysql.cursors
if not SqlClass.pymysql_install:
pymysql.install_as_MySQLdb
SqlClass.pymysql_install=True
self.conn=pymysql.connect(self.connection['host'],
user=self.connection['user'],
passwd=self.connection['password'],
db=self.connection['db'],
charset='utf8mb4',
cursorclass=pymysql.cursors.DictCursor)
else:
import MySQLdb.cursors
self.conn=MySQLdb.connect(self.connection['host'],
user=self.connection['user'],
passwd=self.connection['password'],
db=self.connection['db'],
charset='utf8mb4',
cursorclass=MySQLdb.cursors.DictCursor)
pass
"""
if self.conn==None:
try:
def getconn():
return pymysql.connect(self.connection['host'],
user=self.connection['user'],
passwd=self.connection['password'],
db=self.connection['db'],
charset='utf8mb4',
cursorclass=pymysql.cursors.DictCursor)
if mypool==None:
mypool=pool.QueuePool(getconn, max_overflow=self.max_overflow, pool_size=self.pool_size, recycle=self.pool_recycle, use_threadlocal=True)
self.conn=mypool.connect()
self.conn.ping(True)
self.connected=True
except:
e = sys.exc_info()[0]
v = sys.exc_info()[1]
self.error_connection="Error in connection: %s %s" % (e, v)
self.conn.close()
raise NameError(self.error_connection)
"""
#Make def query more simple if not debugging.
def query(self, sql_query, arguments=[], name_connection="default"):
cursor=self.conn.cursor(SqlClass.cursors_connect)
try:
cursor.execute(sql_query, arguments)
self.conn.commit()
return cursor
except:
e = sys.exc_info()[0]
v = sys.exc_info()[1]
if hasattr(cursor, '_last_executed'):
sql_query=cursor._last_executed
self.error_connection="Error in query ||%s||Values: %s" % (sql_query, str(arguments))
self.conn.close()
#return False
raise NameError(self.error_connection)
#self.connect()
#if fetch_type=="ASSOC":
#fetch_type=MySQLdb.cursors.DictCursor
#with self.conn.cursor(MySQLdb.cursors.DictCursor) as cursor:
"""
cursor=self.conn.cursor(pymysql.cursors.DictCursor)
try:
cursor.execute(sql_query, arguments)
self.conn.commit()
return cursor
except:
e = sys.exc_info()[0]
v = sys.exc_info()[1]
if hasattr(cursor, '_last_executed'):
sql_query=cursor._last_executed
#, traceback.format_exc()
self.error_connection="Error in query ||%s||Values: %s" % (sql_query, str(arguments))
#return False
raise NameError(self.error_connection)
"""
#Fetcho row return dictionary if is defined in query.
#def fetch(self, cursor):
#return cursor.fetchone()
def __del__(self):
if self.conn:
self.conn.close()
def close(self, name_connection="default"):
if self.conn:
self.conn.close()
self.conn=None
pass

View file

@ -0,0 +1,156 @@
#!/usr/bin/env python3
from paramecio2.libraries.db.webmodel import WebModel
from paramecio2.libraries.db.coreforms import PasswordForm
from paramecio2.libraries.i18n import I18n
from flask import request
class UserModel(WebModel):
def __init__(self, name_field_id="id"):
super().__init__(name_field_id)
self.password_field='password'
self.email_field='email'
self.username_field='username'
self.yes_repeat_password=True
self.check_user=True
self.check_email=True
def create_forms(self, arr_fields=[]):
# Add password_repeat to forms from the model
arr_fields=super().create_forms(arr_fields)
if self.password_field in arr_fields and self.yes_repeat_password:
repeat_password=PasswordForm('repeat_password', '')
repeat_password.required=1
repeat_password.label=I18n.lang('common', 'repeat_password', 'Repeat Password')
repeat_password.field=self.fields['password']
self.create_form_after(self.password_field, repeat_password)
return arr_fields
"""
def insert(self, dict_values, external_agent=True):
if 'password' in dict_values:
dict_values['repeat_password']=dict_values.get('repeat_password', '')
if dict_values['repeat_password']!=dict_values[self.password_field]:
self.fields[self.password_field].error=True
self.fields['password'].txt_error=I18n.lang('common', 'error_passwords_no_match', 'Error: passwords doesn\'t match')
return super().insert(dict_values, external_agent)
"""
def check_all_fields(self, dict_values, external_agent, yes_update=False, errors_set="insert"):
error=0
try:
fields, values, update_values=super().check_all_fields(dict_values, external_agent, yes_update, errors_set)
except:
error+=1
if self.check_user==True:
# Check if passwords matches
if self.password_field in dict_values:
dict_values['repeat_password']=dict_values.get('repeat_password', '')
if dict_values[self.password_field].strip()!="":
if dict_values['repeat_password']!=dict_values[self.password_field]:
self.fields[self.password_field].error=True
self.fields[self.password_field].txt_error=I18n.lang('common', 'error_passwords_no_match', 'Error: passwords doesn\'t match')
error+=1
# Check if exists user with same email or password
get_id=0
if self.updated:
# Need the id
#GetPostFiles.obtain_get()
#GetPostFiles.obtain_post()
"""
getpostfiles=GetPostFiles()
getpostfiles.obtain_get()
"""
#get_id=getpostfiles.get.get(self.name_field_id, '0')
get_id=requests.args.get(self.name_field_id, '0')
#post_id=getpostfiles.post.get(self.name_field_id, '0')
post_id=requests.form.get(self.name_field_id, '0')
if get_id!='0':
get_id=int(get_id)
if post_id!='0':
get_id=int(post_id)
pass
get_id=int(get_id)
sql_id=''
original_conditions=self.conditions
self.reset_conditions()
if self.username_field in dict_values:
self.conditions=['WHERE username=%s AND '+self.name_field_id+'!=%s', [dict_values[self.username_field], get_id]]
if self.select_count()>0:
self.fields[self.username_field].error=True
self.fields[self.username_field].txt_error=I18n.lang('common', 'error_username_exists', 'Error: username already exists')
self.fields_errors[self.username_field].append(self.fields[self.username_field].txt_error)
error+=1
if self.check_email:
if self.email_field in dict_values:
self.conditions=['WHERE email=%s AND '+self.name_field_id+'!=%s', [dict_values[self.email_field], get_id]]
if self.select_count()>0:
self.fields[self.email_field].error=True
self.fields[self.email_field].txt_error=I18n.lang('common', 'error_email_exists', 'Error: this email is already being used')
self.fields_errors[self.email_field].append(self.fields[self.email_field].txt_error)
error+=1
self.conditions=original_conditions
if error>0:
self.query_error+='Error:if is not expected, please, check that you disabled the special checkings of this model'
return False
return fields, values, update_values

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,136 @@
#!/usr/bin/env python3
from paramecio2.libraries.db import corefields
from paramecio2.libraries.db.coreforms import PasswordForm
from paramecio2.libraries.i18n import I18n
from flask import session
from paramecio2.libraries.keyutils import create_key_encrypt
# Need unittest
def pass_values_to_form(post, arr_form, yes_error=True, pass_values=True):
if pass_values:
def get_value(key):
return post[key]
else:
def get_value(key):
return arr_form[key].default_value
for key, value in arr_form.items():
post[key]=post.get(key, '')
#if arr_form[key].default_value=='':
arr_form[key].default_value=get_value(key)
if arr_form[key].field==None:
arr_form[key].field=corefields.CharField(key, 255, required=False)
# Recheck value if no set error field
if arr_form[key].field.error == None:
arr_form[key].field.check(post[key])
#arr_form[key].txt_error=""
if arr_form[key].required==True and arr_form[key].field.error==True and yes_error==True:
arr_form[key].txt_error=arr_form[key].field.txt_error
# Reset error on field.
arr_form[key].field.error=None
return arr_form
class CheckForm():
def __init__(self):
self.error=0
def check(self, post, arr_form):
for k in arr_form.keys():
post[k]=post.get(k, '')
if arr_form[k].field==None:
arr_form[k].field=corefields.CharField(k, 255, required=False)
post[k]=arr_form[k].field.check(post[k])
arr_form[k].txt_error=arr_form[k].field.txt_error
if arr_form[k].field.error==True and arr_form[k].required==True:
self.error+=1
return post, arr_form
def check_form(post, arr_form, sufix_form='_error'):
error=0
error_form={}
for k in arr_form.keys():
post[k]=post.get(k, '')
if arr_form[k].field==None:
arr_form[k].field=corefields.CharField(k, 255, required=False)
post[k]=arr_form[k].field.check(post[k])
arr_form[k].txt_error=arr_form[k].field.txt_error
if arr_form[k].field.error==True and arr_form[k].required==True:
error_form['#'+k+sufix_form]=arr_form[k].txt_error
error+=1
return error, error_form, post, arr_form
def show_form(post, arr_form, t, yes_error=True, pass_values=True, modelform_tpl='forms/modelform.phtml'):
# Create csrf_token in session
generate_csrf()
if pass_values==True:
pass_values_to_form(post, arr_form, yes_error, pass_values)
return t.load_template(modelform_tpl, forms=arr_form)
#Simple Function for add repeat_password form to user model
def set_extra_forms_user(user_admin):
user_admin.fields['password'].required=True
user_admin.fields['email'].required=True
user_admin.create_forms(['username', 'email', 'password'])
user_admin.forms['repeat_password']=PasswordForm('repeat_password', '')
user_admin.forms['repeat_password'].required=True
user_admin.forms['repeat_password'].label=I18n.lang('common', 'repeat_password', 'Repeat Password')
#Function for initial values for necessary fields.
def ini_fields(fields):
pass
def csrf_token(token_id='csrf_token'):
#s=get_session()
if not 'csrf_token' in session:
session['csrf_token']=create_key_encrypt()
return '<input type="hidden" name="csrf_token" class="csrf_token" id="'+token_id+'" value="'+session['csrf_token']+'" />'
def generate_csrf():
if not 'csrf_token' in session:
session['csrf_token']=create_key_encrypt()
return session['csrf_token']

View file

@ -44,10 +44,8 @@ class I18n:
def get_default_lang():
lang=I18n.default_lang
s=session
lang=s.get('lang', lang)
#lang=session.get('lang', lang)
return lang

View file

@ -0,0 +1,19 @@
from hashlib import sha512, sha256
from base64 import b64encode
from os import urandom
# Functions for create random strings usando urandom
def create_key_encrypt(n=10):
return sha512(urandom(n)).hexdigest()
def create_key_encrypt_256(n=10):
return sha256(urandom(n)).hexdigest()
def create_key(n=10):
rand_bytes=urandom(n)
return b64encode(rand_bytes).decode('utf-8')[0:-2]

View file

@ -9,6 +9,7 @@ import gettext
import sys
from paramecio2.libraries.i18n import I18n
from paramecio2.libraries.urls import make_url, make_media_url
from paramecio2.libraries.formsutils import csrf_token
def env_theme(module, cache_enabled=True, cache_impl='', cache_args={}, module_directory="./tmp/modules"):
@ -49,12 +50,14 @@ class PTemplate:
self.add_filter(I18n.lang)
self.add_filter(make_url)
#self.add_filter(make_url)
self.add_filter(make_media_url)
self.add_filter(url_for)
self.add_filter(csrf_token)
"""
def gettext(self, text):
return gettext.dgettext(self.domain_gettext, text)
@ -102,3 +105,7 @@ class PTemplate:
self.filters[filter_name.__name__]=filter_name
env=env_theme(__file__)
standard_t=PTemplate(env)

View file

@ -0,0 +1,33 @@
${add_js_home_local('jquery.min.js', 'admin')}
${add_js_home_local('spectrum.js', 'admin')}
${add_css_home_local('spectrum.css', 'admin')}
<%
form.default_value=str(hex(int(form.default_value))).replace('0x', '')
c=len(form.default_value)
if(c<6):
repeat=6-c
form.default_value=('0'*repeat)+form.default_value
form.default_value='#'+form.default_value
%>
<input type='text' id="${form.name_field_id}_field_form" name="${form.name}" value="${form.default_value}" />
<script>
$("#${form.name_field_id}_field_form").spectrum({
allowEmpty: true
});
$("#${form.name_field_id}_field_form").closest('form').submit( function () {
var t=$("#${form.name_field_id}_field_form").spectrum("get");
$('#${form.name_field_id}_field_form').val(t.toHexString());
});
</script>

View file

@ -0,0 +1,71 @@
${add_js_home_local('jquery.min.js', 'admin')}
<input type="number" min="1" max="31" name="${form}_day" id="time_${form}_day" class="form_day" value="${d}" size="2" maxlength="2"/>
<input type="number" min="1" max="12" name="${form}_month" id="time_${form}_month" class="form_month" value="${m}" size="2" maxlength="2"/>
<input type="number" name="${form}_year" id="time_${form}_year" class="form_year" value="${y}" size="4" maxlength="4"/>
% if yes_time==True:
<input type="text" min="0" max="23" name="${form}_hour" id="time_${form}_hour" class="form_hour" value="${h}" size="2" maxlength="2"/>
<input type="text" min="0" max="60" name="${form}_minute" id="time_${form}_minute" class="form_minute" value="${min}" size="2" maxlength="2"/>
<input type="text" min="0" max="60" name="${form}_second" id="time_${form}_second" class="form_second" value="${s}" size="2" maxlength="2"/>
% endif
<input type="hidden" name="${form}" id="time_${form}" value="" />
<script language="javascript">
$(document).submit(function () {
year=$("#time_${form}_year").val().toString();
month=$("#time_${form}_month").val().toString();
day=$("#time_${form}_day").val().toString();
year=add_extra_length(year, 4);
month=add_extra_length(month, 2);
day=add_extra_length(day, 2);
final_time=year+month+day
% if yes_time==True:
hour=$("#time_${form}_hour").val().toString();
minute=$("#time_${form}_minute").val().toString();
second=$("#time_${form}_second").val().toString();
hour=add_extra_length(hour, 2);
minute=add_extra_length(minute, 2);
second=add_extra_length(second, 2);
final_time+=final_time;
% else:
final_time+='000000';
% endif
$("#time_${form}").val(final_time);
});
function add_extra_length(str_number, total_length)
{
if(str_number.length<total_length)
{
c=total_length-str_number.length;
extra_number='';
for(x=0;x<c;x++)
{
extra_number+='0';
}
str_number=extra_number+str_number;
}
return str_number;
}
</script>

View file

@ -0,0 +1,12 @@
<%
import os
name_file=os.path.basename(form.default_value)
%>
<input type="file" name="${form.name}_file" id="${form.name}_file_field_form" />
% if name_file:
${name_file}
% endif
<input type="hidden" name="${form.name}" id="${form.name}_field_form" value="${form.default_value}"/>

View file

@ -0,0 +1,61 @@
${add_js_home_local('tools.js', 'admin')}
<%
choose=''
%>
<div id="languages_form">
<%def name="select_lang(i18n, lang_selected)">
% if i18n==lang_selected:
<%
return "choose_flag"
%>
% else:
<%
return "no_choose_flag"
%>
% endif
</%def>
<%def name="hide_lang(i18n, lang_selected)">
% if i18n!=lang_selected:
style="display:none;"
% endif
</%def>
<input type="hidden" name="${real_name_form}" id="${name_form}_i18n_value" value="" />
% if lang_selected!=None:
% for i18n in arr_i18n:
${form.change_name(name_form+'_'+i18n)}
<%
form.default_value=default_value[i18n]
%>
<span id="${name_form}_${i18n}_switch" class="${name_form}_i18n_form">${form.form()|n}</span> <a class="choose_flag ${name_form}_i18n_flag lang_form" id="${name_form}_${i18n}_element" href="#"><img src="${make_media_url_module('images/languages/'+i18n+'.png', 'admin')}" alt="${name_form}_${i18n}"/></a>
% endfor
% endif
</div>
<script>
//In submit convert in json
$(".${name_form}_i18n_flag").closest('form').submit( function () {
arr_i18n={}
$(".${name_form}_i18n_form").each(function () {
var lang=$(this).attr('id').replace('${name_form}_','').replace('_switch', '');
var child_input=$('#${name_form}_'+lang+'_form');
arr_i18n[lang]=child_input.val();
});
document.getElementById("${name_form}_i18n_value").value=JSON.stringify(arr_i18n);
return true;
});
</script>

View file

@ -0,0 +1,5 @@
<div class="form">
{% for form in forms.values() %}
<p><label>{{form.label|safe}}</label>{{form.form()}}</p>
{% endfor %}
</div>

View file

@ -0,0 +1,21 @@
<%def name="check_required(required)">
% if required:
${'*'} \
% endif
</%def>
<%def name="help(help, name)">
% if help:
<i class="fa fa-question-circle tooltip" data-tooltip-content="#tooltip_${name}_content" style="cursor:pointer;"></i> \
<div class="tooltip_templates" style="display:none;"><div id="tooltip_${name}_content">${help|n}</div></div>
% endif
</%def>
<div class="form">
% for form in forms.values():
% if form.type!='hidden':
<p><label>${form.label} ${check_required(form.required)} ${help(form.help, form.name)}</label>${form.form()|n} <span class="error" id="${form.name}_error">${form.txt_error}</span></p>
% else:
${form.form()|n}
% endif
% endfor
${csrf_token()|n}
</div>

View file

@ -0,0 +1,22 @@
<p>
<textarea name="${form.name}" id="${form.name_field_id}">
${form.default_value}
</textarea>
</p>
<script>
tinymce.init({
selector: '#${form.name_field_id}',
height: 500,
menubar: true,
plugins: 'print preview searchreplace autolink directionality visualblocks visualchars fullscreen image link media template codesample table charmap hr pagebreak nonbreaking anchor insertdatetime advlist lists textcolor wordcount imagetools contextmenu colorpicker textpattern',
toolbar: 'formatselect | fontsizeselect bold italic underline strikethrough forecolor backcolor | link | alignleft aligncenter alignright alignjustify | numlist bullist outdent indent | removeformat',
fontsize_formats: "8pt 10pt 12pt 14pt 18pt 24pt 36pt 48pt 64pt 100pt 120pt",
content_css: '//www.tinymce.com/css/codepen.min.css',
setup: function (editor) {
editor.on('change', function () {
tinymce.triggerSave();
});
}
});
</script>
${add_js_home_local('tinymce/tinymce.min.js', 'admin')}

View file

@ -0,0 +1,12 @@
${question_text}: <input type="button" value="Yes" id="accept"/>
<script language="javascript">
$('#accept').click( function () {
location.href='${url_redirect|n}'
});
</script>
<%block name="form">
</%block>

View file

@ -0,0 +1,4 @@
${show_flash_message()|n}
<!--<h1>${admin.title}</h1>-->
<p><a href="${add_get_parameters(admin.url, op_admin='1')}">${lang('common', 'add_item', 'Add new item')}</a></p>
${admin.list.show()|n}

View file

@ -0,0 +1,21 @@
<p><a href="${admin.url_redirect}">${admin.text_home|n}</a> &gt;&gt; \
% if id!='0':
${title_edit} \
%else:
${title_edit} \
%endif
<%
enctype_txt=''
if enctype:
enctype_txt='enctype="multipart/form-data"'
%>
</p>
<form method="post" action="${url_action}" ${enctype_txt|n}>
<h2>${title_edit}</h2>
<span class="error">${model.query_error}</span>
${ form|n }
<p><input type="submit" value="${lang('common', 'send', 'Send') }"></p>
</form>

View file

@ -0,0 +1,135 @@
<%def name="select_field(field)">
% if simplelist.search_field==field:
selected \
% endif
</%def>
<%def name="set_css_arrow(simplelist, field)">
% if simplelist.order_field==field:
<i class="fa fa-arrow-${simplelist.order_class[simplelist.order]}" aria-hidden="true"></i>
% endif
</%def>
% if simplelist.yes_search:
<div class="form">
<form method="get" action="${simplelist.url}">
${lang('common','search', 'Search')}: <input type="text" name="search_text" value="${simplelist.search_text|n}">
<select name="search_field">
% for field in simplelist.search_fields:
<option value="${simplelist.model.fields[field].name}" ${select_field(field)}>${simplelist.model.fields[field].label}</option>
% endfor
</select>
<input type="submit" value="${lang('common', 'search', 'Search')}" />
</form>
</div>
% endif
% if not simplelist.table_div:
<table class="table_list" id="${simplelist.model.name}_table">
<tr class="title_list">
% for field in simplelist.fields_showed:
<td class="${simplelist.model.fields[field].name}_td"><a href="${add_get_parameters(simplelist.url, order_field=field, begin_page=simplelist.begin_page, order=simplelist.change_order[field], search_text=simplelist.search_text, search_field=simplelist.search_field)}" class="">${set_css_arrow(simplelist, field)}${simplelist.model.fields[field].label}</a></td>
% endfor
% for extra_field in simplelist.arr_extra_fields:
<td class="options_td">${ extra_field }</td>
% endfor
</tr>
<%
pos=0
%>
% for row in list:
<%
if not 'pos' in row:
row['pos']=pos
%>
<tr class="row_list">
% for field in simplelist.fields_showed:
% if simplelist.model.fields[field].escape==True:
%if type(simplelist.model.fields[field]).__name__!='ForeignKeyField':
<td class="${simplelist.model.fields[field].name}_td">${simplelist.model.fields[field].show_formatted(row[field])}</td>
% else:
<td class="${simplelist.model.fields[field].name}_td">${simplelist.model.fields[field].show_formatted(row[field])}${str(simplelist.model.fields[field].related_model.fields[simplelist.model.fields[field].named_field].show_formatted(row[field]))}</td>
% endif
% else:
%if type(simplelist.model.fields[field]).__name__!='ForeignKeyField':
<td class="${simplelist.model.fields[field].name}_td">${str(simplelist.model.fields[field].show_formatted(row[field]))|n}</td>
% else:
<td class="${simplelist.model.fields[field].name}_td">${str(simplelist.model.fields[field].related_model.fields[simplelist.model.fields[field].named_field].show_formatted(row[field]))|n}</td>
% endif
% endif
% endfor
% for extra_field_func in simplelist.arr_extra_options:
<td class="options_td">${ simplelist.set_options(extra_field_func, row)|n }</td>
% endfor
</tr>
<%
pos+=1
%>
% endfor
</table>
% else:
<%
size_td=round(100/(len(simplelist.fields_showed)+len(simplelist.arr_extra_options)))
%>
<div class="table_list" id="${simplelist.model.name}_table">
<div class="${simplelist.model.name}_tr tr_list_div">
% for field in simplelist.fields_showed:
<div class="${simplelist.model.fields[field].name}_td fields_span_title" style="width: ${size_td}%;"><a href="${add_get_parameters(simplelist.url, order_field=field, begin_page=simplelist.begin_page, order=simplelist.change_order[field], search_text=simplelist.search_text, search_field=simplelist.search_field)}" class="">${set_css_arrow(simplelist, field)}${simplelist.model.fields[field].label}</a></div>
% endfor
% for extra_field in simplelist.arr_extra_fields:
<div class="fields_span_title options_td" style="width: ${size_td}%;">${ extra_field }</div>
% endfor
</div>
<div class="table_rows ${simplelist.model.name}_table_rows" id="${simplelist.model.name}_table_rows">
<%
pos=0
%>
% for row in list:
<div id="${simplelist.model.name}_table_${row['id']}" class="${simplelist.model.name}_table_row" style="clear: both;overflow: hidden;">
<%
if not 'pos' in row:
row['pos']=pos
%>
% for field in simplelist.fields_showed:
% if simplelist.model.fields[field].escape==True:
<div class="${simplelist.model.fields[field].name}_td fields_span_table_data" style="width: ${size_td}%;">
%if type(simplelist.model.fields[field]).__name__!='ForeignKeyField':
${simplelist.model.fields[field].show_formatted(row[field])}
% else:
${str(simplelist.model.fields[field].related_model.fields[simplelist.model.fields[field].named_field].show_formatted(row[field]))}
% endif
</div>
% else:
<div class="${simplelist.model.fields[field].name}_td fields_span_table_data" style="width: ${size_td}%;">
%if type(simplelist.model.fields[field]).__name__!='ForeignKeyField':
${str(simplelist.model.fields[field].show_formatted(row[field]))|n}
% else:
${str(simplelist.model.fields[field].related_model.fields[simplelist.model.fields[field].named_field].show_formatted(row[field]))|n}
% endif
</div>
% endif
% endfor
% for extra_field_func in simplelist.arr_extra_options:
<div class="options_td fields_span_table_data" style="width: ${size_td}%;">${ simplelist.set_options(extra_field_func, row)|n }</div>
% endfor
<%
pos+=1
%>
</div>
% endfor
</div>
<br clear="all" />
</div>
% endif
<p>
% if pages!='':
${lang('common', 'pages', 'Pages')}: ${pages|n}
% endif
</p>

View file

@ -0,0 +1,85 @@
<div id="container_translation">
<div class="flash" style="display:none;">${lang('admin', 'translation_saved_sucessfully', 'Translation saved sucessfully')}</div>
<br />
<form method="get" action="">
${lang('admin', 'modules', 'Modules')}
${form_module.form()|n}
<input type="submit" value="${lang('admin', 'change_module_to_translate', 'Change module to translate')}" />
</form>
<div id="saving" style="display:none;"><i class="fa fa-circle-o-notch fa-2x fa-spin fa-fw"></i> ${lang('admin', 'saving_translation', 'Saving translation')}</div>
<form method="post" action="#" id="send_text">
% if len(arr_i18n_form):
<p><input type="submit" value="${lang('admin', 'send', 'Send')}" /></p>
% for i18n_form in arr_i18n_form:
<p>${i18n_form.form()|n}</p>
% endfor
<p><input type="submit" value="${lang('admin', 'send', 'Send')}" /></p>
% endif
${csrf_token("csrf_token")|n}
</form>
</div>
<script>
$('#send_text').submit( function () {
$('#send_text').hide();
$('#saving').show();
url="${make_admin_url('lang/translations',{'module_admin': selected_module, 'op': '1'})}";
/*data=$(this).serializeArray().reduce(function(obj, item) {
obj[item.name] = item.value;
return obj;
}, {});*/
data=$(this).serialize()
$.ajax({
type: "POST",
url: url,
data: data,
contentType: "application/x-www-form-urlencoded;charset=UTF-8",
success: function (data) {
$('#saving').hide();
if(!data.error) {
$('#send_text').show();
$('.flash').show();
setTimeout(function () {
$(".flash").fadeOut(1000)
}, 3000);
}
else
{
alert('Error: cannot update the translations');
}
},
error: function (data) {
alert(JSON.stringify(data));
$('#send_text').show();
},
dataType: 'json'
});
return false;
});
</script>

View file

@ -0,0 +1,8 @@
<form method="post" action="${add_get_parameters(url, id=item_id, op_admin=op_admin, verified=verified)}">
<div class="form">
<!-- <input type="hidden" name="id" value="${item_id}">
<input type="hidden" name="op_admin" value="${op_admin}">
<input type="hidden" name="verified" value="${verified}">-->
<input type="submit" value="${lang('common', 'delete_item_you_sure', 'Are you sure for delete this item?')}" />
</div>
</form>