Added first files for admin and login/signup in admin
This commit is contained in:
parent
e0ed00af8c
commit
d9b62719d7
139 changed files with 18408 additions and 4 deletions
256
paramecio2/libraries/db/corefields.py
Normal file
256
paramecio2/libraries/db/corefields.py
Normal 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)
|
||||
193
paramecio2/libraries/db/coreforms.py
Normal file
193
paramecio2/libraries/db/coreforms.py
Normal 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('"', '"').replace("'", ''')
|
||||
|
||||
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)
|
||||
386
paramecio2/libraries/db/dbadmin.py
Normal file
386
paramecio2/libraries/db/dbadmin.py
Normal 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()
|
||||
0
paramecio2/libraries/db/extrafields/__init__.py
Normal file
0
paramecio2/libraries/db/extrafields/__init__.py
Normal file
59
paramecio2/libraries/db/extrafields/arrayfield.py
Normal file
59
paramecio2/libraries/db/extrafields/arrayfield.py
Normal 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
|
||||
47
paramecio2/libraries/db/extrafields/colorfield.py
Normal file
47
paramecio2/libraries/db/extrafields/colorfield.py
Normal 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;
|
||||
39
paramecio2/libraries/db/extrafields/datefield.py
Normal file
39
paramecio2/libraries/db/extrafields/datefield.py
Normal 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)
|
||||
60
paramecio2/libraries/db/extrafields/datetimefield.py
Normal file
60
paramecio2/libraries/db/extrafields/datetimefield.py
Normal 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'
|
||||
50
paramecio2/libraries/db/extrafields/dictfield.py
Normal file
50
paramecio2/libraries/db/extrafields/dictfield.py
Normal 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)
|
||||
|
||||
27
paramecio2/libraries/db/extrafields/emailfield.py
Normal file
27
paramecio2/libraries/db/extrafields/emailfield.py
Normal 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
|
||||
176
paramecio2/libraries/db/extrafields/filefield.py
Normal file
176
paramecio2/libraries/db/extrafields/filefield.py
Normal 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)
|
||||
|
||||
157
paramecio2/libraries/db/extrafields/i18nfield.py
Normal file
157
paramecio2/libraries/db/extrafields/i18nfield.py
Normal 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)
|
||||
276
paramecio2/libraries/db/extrafields/imagefield.py
Normal file
276
paramecio2/libraries/db/extrafields/imagefield.py
Normal 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)
|
||||
|
||||
19
paramecio2/libraries/db/extrafields/ipfield.py
Normal file
19
paramecio2/libraries/db/extrafields/ipfield.py
Normal 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
|
||||
27
paramecio2/libraries/db/extrafields/langfield.py
Normal file
27
paramecio2/libraries/db/extrafields/langfield.py
Normal 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
|
||||
26
paramecio2/libraries/db/extrafields/moneyfield.py
Normal file
26
paramecio2/libraries/db/extrafields/moneyfield.py
Normal 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)
|
||||
|
||||
42
paramecio2/libraries/db/extrafields/parentfield.py
Normal file
42
paramecio2/libraries/db/extrafields/parentfield.py
Normal 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
|
||||
119
paramecio2/libraries/db/extrafields/passwordfield.py
Normal file
119
paramecio2/libraries/db/extrafields/passwordfield.py
Normal 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:
|
||||
"""
|
||||
22
paramecio2/libraries/db/extrafields/percentfield.py
Normal file
22
paramecio2/libraries/db/extrafields/percentfield.py
Normal 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
|
||||
37
paramecio2/libraries/db/extrafields/slugifyfield.py
Normal file
37
paramecio2/libraries/db/extrafields/slugifyfield.py
Normal 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
|
||||
|
||||
|
||||
42
paramecio2/libraries/db/extrafields/urlfield.py
Normal file
42
paramecio2/libraries/db/extrafields/urlfield.py
Normal 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
|
||||
16
paramecio2/libraries/db/extrafields/usernamefield.py
Normal file
16
paramecio2/libraries/db/extrafields/usernamefield.py
Normal 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
|
||||
0
paramecio2/libraries/db/extraforms/__init__.py
Normal file
0
paramecio2/libraries/db/extraforms/__init__.py
Normal file
20
paramecio2/libraries/db/extraforms/checkform.py
Normal file
20
paramecio2/libraries/db/extraforms/checkform.py
Normal 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)]+'>'
|
||||
17
paramecio2/libraries/db/extraforms/colorform.py
Normal file
17
paramecio2/libraries/db/extraforms/colorform.py
Normal 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)
|
||||
39
paramecio2/libraries/db/extraforms/dateform.py
Normal file
39
paramecio2/libraries/db/extraforms/dateform.py
Normal 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
|
||||
|
||||
21
paramecio2/libraries/db/extraforms/fileform.py
Normal file
21
paramecio2/libraries/db/extraforms/fileform.py
Normal 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)
|
||||
32
paramecio2/libraries/db/extraforms/i18nform.py
Normal file
32
paramecio2/libraries/db/extraforms/i18nform.py
Normal 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)
|
||||
22
paramecio2/libraries/db/extraforms/texthtmlform.py
Normal file
22
paramecio2/libraries/db/extraforms/texthtmlform.py
Normal 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)
|
||||
22
paramecio2/libraries/db/extraforms/usernameform.py
Normal file
22
paramecio2/libraries/db/extraforms/usernameform.py
Normal 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)
|
||||
210
paramecio2/libraries/db/sqlalchemy.py
Normal file
210
paramecio2/libraries/db/sqlalchemy.py
Normal 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
|
||||
|
||||
|
||||
156
paramecio2/libraries/db/usermodel.py
Normal file
156
paramecio2/libraries/db/usermodel.py
Normal 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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
1369
paramecio2/libraries/db/webmodel.py
Normal file
1369
paramecio2/libraries/db/webmodel.py
Normal file
File diff suppressed because it is too large
Load diff
136
paramecio2/libraries/formsutils.py
Normal file
136
paramecio2/libraries/formsutils.py
Normal 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']
|
||||
|
||||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
19
paramecio2/libraries/keyutils.py
Normal file
19
paramecio2/libraries/keyutils.py
Normal 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]
|
||||
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
33
paramecio2/libraries/templates/forms/colorform.phtml
Normal file
33
paramecio2/libraries/templates/forms/colorform.phtml
Normal 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>
|
||||
71
paramecio2/libraries/templates/forms/dateform.phtml
Normal file
71
paramecio2/libraries/templates/forms/dateform.phtml
Normal 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>
|
||||
12
paramecio2/libraries/templates/forms/fileform.phtml
Normal file
12
paramecio2/libraries/templates/forms/fileform.phtml
Normal 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}"/>
|
||||
61
paramecio2/libraries/templates/forms/i18nform.phtml
Normal file
61
paramecio2/libraries/templates/forms/i18nform.phtml
Normal 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>
|
||||
5
paramecio2/libraries/templates/forms/modelform.html
Normal file
5
paramecio2/libraries/templates/forms/modelform.html
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
<div class="form">
|
||||
{% for form in forms.values() %}
|
||||
<p><label>{{form.label|safe}}</label>{{form.form()}}</p>
|
||||
{% endfor %}
|
||||
</div>
|
||||
21
paramecio2/libraries/templates/forms/modelform.phtml
Normal file
21
paramecio2/libraries/templates/forms/modelform.phtml
Normal 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>
|
||||
22
paramecio2/libraries/templates/forms/texthtmlform.phtml
Normal file
22
paramecio2/libraries/templates/forms/texthtmlform.phtml
Normal 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')}
|
||||
12
paramecio2/libraries/templates/utils/accept.phtml
Normal file
12
paramecio2/libraries/templates/utils/accept.phtml
Normal 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>
|
||||
4
paramecio2/libraries/templates/utils/admin.phtml
Normal file
4
paramecio2/libraries/templates/utils/admin.phtml
Normal 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}
|
||||
21
paramecio2/libraries/templates/utils/insertform.phtml
Normal file
21
paramecio2/libraries/templates/utils/insertform.phtml
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
<p><a href="${admin.url_redirect}">${admin.text_home|n}</a> >> \
|
||||
% 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>
|
||||
135
paramecio2/libraries/templates/utils/list.phtml
Normal file
135
paramecio2/libraries/templates/utils/list.phtml
Normal 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>
|
||||
85
paramecio2/libraries/templates/utils/translations.phtml
Normal file
85
paramecio2/libraries/templates/utils/translations.phtml
Normal 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>
|
||||
8
paramecio2/libraries/templates/utils/verify_delete.phtml
Normal file
8
paramecio2/libraries/templates/utils/verify_delete.phtml
Normal 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>
|
||||
Loading…
Add table
Add a link
Reference in a new issue