Many fixes for more performance

This commit is contained in:
Antonio de la Rosa 2016-12-06 04:01:32 +01:00
parent 425af99428
commit 6dc5a61699
13 changed files with 340 additions and 257 deletions

View file

@ -47,7 +47,7 @@ def base_admin(func_view, env, title, **args):
content_index=func_view(connection, t, s, **args) content_index=func_view(connection, t, s, **args)
return t.load_template('admin/content.html', title=title, content_index=content_index, menu=menu, lang_selected=lang_selected, arr_i18n=I18n.dict_i18n) return t.render_template('admin/content.html', title=title, content_index=content_index, menu=menu, lang_selected=lang_selected, arr_i18n=I18n.dict_i18n)
else: else:
redirect(make_url(config.admin_folder)) redirect(make_url(config.admin_folder))

View file

@ -85,7 +85,7 @@ class GenerateAdminClass:
form=show_form(post, edit_forms, self.t, False) form=show_form(post, edit_forms, self.t, False)
return self.t.load_template(self.template_insert, admin=self, title_edit=title_edit, form=form, model=self.model, id=getpostfiles.get['id']) return self.t.render_template(self.template_insert, admin=self, title_edit=title_edit, form=form, model=self.model, id=getpostfiles.get['id'])
elif getpostfiles.get['op_admin']=='2': elif getpostfiles.get['op_admin']=='2':
@ -118,7 +118,7 @@ class GenerateAdminClass:
redirect(self.url) redirect(self.url)
else: else:
form=show_form(getpostfiles.post, edit_forms, self.t, True) form=show_form(getpostfiles.post, edit_forms, self.t, True)
return self.t.load_template(self.template_insert, admin=self, title_edit=title_edit, form=form, model=self.model, id=getpostfiles.get['id']) return self.t.render_template(self.template_insert, admin=self, title_edit=title_edit, form=form, model=self.model, id=getpostfiles.get['id'])
pass pass
@ -137,8 +137,8 @@ class GenerateAdminClass:
else: else:
return self.t.load_template(self.template_verify_delete, url=self.url, item_id=getpostfiles.get['id'], op_admin=3, verified=1) return self.t.render_template(self.template_verify_delete, url=self.url, item_id=getpostfiles.get['id'], op_admin=3, verified=1)
else: else:
return self.t.load_template(self.template_admin, admin=self) return self.t.render_template(self.template_admin, admin=self)

View file

@ -33,18 +33,19 @@ class I18n:
l={} l={}
#@staticmethod
#def set_lang(code_lang):
# if default_lang
@staticmethod @staticmethod
def get_default_lang(): def get_default_lang():
lang=I18n.default_lang lang=I18n.default_lang
s=get_session() #s=get_session()
if s==None: #lang=s.get('lang', lang)
s={'lang': lang}
lang=s.get('lang', lang)
return lang return lang

View file

@ -197,7 +197,7 @@ class SimpleList:
self.model.yes_reset_conditions=True self.model.yes_reset_conditions=True
listing=self.t.load_template('utils/list.phtml', simplelist=self, list=list_items, pages=pages) listing=self.t.render_template('utils/list.phtml', simplelist=self, list=list_items, pages=pages)
list_items.close() list_items.close()

View file

@ -63,8 +63,20 @@ def env_theme(module, cache_enabled=True, cache_impl='', cache_args={}, module_d
#print(standard_templates) #print(standard_templates)
return TemplateLookup(directories=search_folders, default_filters=['h'], input_encoding='utf-8', encoding_errors='replace', cache_enabled=cache_enabled, cache_impl=cache_impl, cache_args=cache_args, module_directory=module_directory) return TemplateLookup(directories=search_folders, default_filters=['h'], input_encoding='utf-8', encoding_errors='replace', cache_enabled=cache_enabled, cache_impl=cache_impl, cache_args=cache_args, module_directory=module_directory)
def preload_templates(template_files, env):
templates={}
for template_file in template_files:
templates[template_file]=env.get_template(template_file)
return templates
class PTemplate: class PTemplate:
templates_loaded={}
def __init__(self, environment): def __init__(self, environment):
# A simple method used in internal things of paramecio # A simple method used in internal things of paramecio
@ -193,9 +205,12 @@ class PTemplate:
def render_template(self, template_file, **arguments): def render_template(self, template_file, **arguments):
if not str(self.env.directories)+'/'+template_file in PTemplate.templates_loaded:
PTemplate.templates_loaded[str(self.env.directories)+'/'+template_file]=self.env.get_template(template_file)
arguments.update(self.filters) arguments.update(self.filters)
return self.templates[template_file].render(**arguments) return PTemplate.templates_loaded[str(self.env.directories)+'/'+template_file].render(**arguments)
def add_filter(self, filter_name): def add_filter(self, filter_name):

View file

@ -1,8 +1,10 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
from itsdangerous import JSONWebSignatureSerializer from itsdangerous import URLSafeSerializer
from paramecio.citoplasma.keyutils import create_key_encrypt, create_key_encrypt_256, create_key from paramecio.citoplasma.keyutils import create_key_encrypt, create_key_encrypt_256, create_key
from bottle import request, response from bottle import request, response
import os
import json
try: try:
@ -11,22 +13,22 @@ try:
except: except:
class config: class config:
cookie_name='paramecio_session' cookie_name='paramecio.session'
key_encrypt=create_key_encrypt_256(30) key_encrypt=create_key_encrypt_256(30)
""" # Cookie session
# This save the session in a cookie for maximum performance. In next version i can use memcached or something for session
# In next versions have two secret_keys for more security.
class ParamecioSession: class ParamecioSession:
def __init__(self): def __init__(self, session_dict):
self.session=request.environ.get(config.cookie_name) self.session=session_dict
#self.token=request.get_cookie(config.cookie_name)
def get(self, name, default_value): def get(self, name, default_value):
if not name in self.session: if not name in self.session:
self.session[name]=default_value self.session[name]=default_value
request.environ[config.cookie_name]=self.session
request.environ[config.cookie_name]['save']=True
return self.session[name] return self.session[name]
@ -37,14 +39,11 @@ class ParamecioSession:
def __setitem__(self, key, value): def __setitem__(self, key, value):
self.session[key]=value self.session[key]=value
request.environ[config.cookie_name]=self.session
request.environ[config.cookie_name]['save']=True
def __delitem__(self, key): def __delitem__(self, key):
if key!='token':
del self.session[key] del self.session[key]
request.environ[config.cookie_name]=self.session
request.environ[config.cookie_name]['save']=True
def __contains__(self, key): def __contains__(self, key):
@ -65,13 +64,73 @@ class ParamecioSession:
def remove(self): def remove(self):
response.delete_cookie(config.cookie_name, path="/") response.delete_cookie(config.cookie_name, path="/")
def generate_session(): def delete(self):
self.remove()
def save(self):
path_cookie=config.session_opts['session.data_dir']+'/session_'+self.session['token']
with open(path_cookie, 'w') as f:
f.write(json.dumps(self.session))
def generate_session(session={}):
#secret=URLSafeSerializer(config.key_encrypt)
#session=secret.dumps(session)
token=create_key(30).replace('/', '#')
response.set_cookie(config.cookie_name, token, path=config.session_opts['session.path'])
s={'token': token}
request.environ['session']=s
return s
def get_session():
s={}
if request.environ:
if not 'session' in request.environ:
cookie=None
if request.cookies.get(config.cookie_name):
cookie=request.get_cookie(config.cookie_name)
if not cookie:
s=generate_session()
else:
path_cookie=config.session_opts['session.data_dir']+'/session_'+cookie
if os.path.isfile(path_cookie):
with open(path_cookie) as f:
s=json.loads(f.read())
else:
s={'token': cookie}
request.environ['session']=s
else:
s=request.environ['session']
return ParamecioSession(s)
random_text=create_key_encrypt_256(30)
response.set_cookie(config.cookie_name, random_text, secret=config.key_encrypt, path="/")
request.environ[config.cookie_name]={'token': random_text}
""" """
def generate_session(): def generate_session():
s=request.environ.get(config.cookie_name) s=request.environ.get(config.cookie_name)
s.invalidate() s.invalidate()
@ -90,8 +149,8 @@ def get_session():
except: except:
return None return None
"""
""" """
try: try:
# Check if session was loaded, if loaded, get cache # Check if session was loaded, if loaded, get cache

View file

@ -11,8 +11,8 @@ class SqlClass:
def __init__(self): def __init__(self):
self.max_overflow=45 self.max_overflow=65
self.pool_size=30 self.pool_size=45
self.error_connection="" self.error_connection=""
self.connection={} self.connection={}
self.connected=False self.connected=False

View file

@ -70,7 +70,7 @@ def show_form(post, arr_form, t, yes_error=True, pass_values=True, modelform_tpl
if pass_values==True: if pass_values==True:
pass_values_to_form(post, arr_form, yes_error) pass_values_to_form(post, arr_form, yes_error)
return t.load_template(modelform_tpl, forms=arr_form) return t.render_template(modelform_tpl, forms=arr_form)
#Simple Function for add repeat_password form to user model #Simple Function for add repeat_password form to user model

View file

@ -5,10 +5,194 @@ import re
import uuid import uuid
from importlib import import_module, reload from importlib import import_module, reload
from collections import OrderedDict from collections import OrderedDict
from paramecio.cromosoma.databases.pymysql import SqlClass from paramecio.cromosoma.databases.mysqldb import SqlClass
from paramecio.cromosoma.coreforms import BaseForm, HiddenForm from paramecio.cromosoma.coreforms import BaseForm, HiddenForm
import traceback import traceback
class PhangoField:
def __init__(self, name, size=255, required=False):
# The name of the field in database table
self.name=name
# The label for the Field
self.label=name.replace('_', ' ').title()
# If field is required, self.required is True
self.required=required
# The size of field in database
self.size=size
# Protected, if this value != False, cannot use it in insert or update.
self.protected=False
# $quote_open is used if you need a more flexible sql sentence,
# @warning USE THIS FUNCTION IF YOU KNOW WHAT YOU ARE DOING
self.quot_open='\''
# $quote_close is used if you need a more flexible sql sentence,
# @warning USE THIS PROPERTY IF YOU KNOW WHAT YOU ARE DOING
self.quot_close='\''
# Variable where the basic text error is saved
self.error=None
self.txt_error=""
# Themodel where this component or field live
self.model=None
# Property used for set this field how indexed in the database table.
self.indexed=False
# Property used for set this field how unique value in the database table.
self.unique=False
# Simple property for make more easy identify foreignkeyfields.
self.foreignkey=False
# Property that define the default value for this field
self.default_value=""
# Property that define if this field is in an update operation or insert operation
self.update=False
# Property used for check if this value cannot change if is in blank and is filled
self.check_blank=False
# Define the form, when is created forms with create_forms you can change the properties of this class
self.name_form=BaseForm
# Property that define if make escape in show_formatted. This property control the html transformation of <>" characters in html entities.If false, convert.
self.escape=False
# File related: if the field have a file related, delete the file
self.file_related=False
# Extra parameters for the form
self.extra_parameters=[]
# Template manager for the form if needed
self.t=None
# This method is used for describe the new field in a sql language format.
def get_type_sql(self):
return 'VARCHAR('+str(self.size)+') NOT NULL DEFAULT "'+self.default_value+'"'
def show_formatted(self, value):
return value
# This method for check the value
def check(self, value):
self.error=False
self.txt_error=''
value=str(value)
if self.escape==False:
value=value.replace('<', '&lt;')
value=value.replace('>', '&gt;')
value=value.replace('"', '&quot;')
#value=WebModel.escape_sql(value)
if value=="":
self.txt_error="The field is empty"
self.error=True
return value
def set_relationships(self):
pass
def create_form(self):
#self.name, self.default_value,
self.extra_parameters.insert(0, self.name)
self.extra_parameters.insert(1, self.default_value)
form=self.name_form(*self.extra_parameters)
form.default_value=self.default_value
form.required=self.required
form.label=self.label
form.field=self
return form
def change_form(self, new_form, parameters):
self.name_form=new_form
self.extra_parameters=parameters
def post_register(self):
pass
class PrimaryKeyField(PhangoField):
def __init__(self, name, size=11, required=False):
super(PrimaryKeyField, self).__init__(name, size, required)
self.protected=True
self.name_form=HiddenForm
self.required=True
def check(self, value):
self.error=None
self.txt_error=''
if value=='':
value='0'
try:
value=str(int(value))
except:
value=0
if value==0:
self.txt_error="The value is zero"
self.error=True
return value
def get_type_sql(self):
return 'INT NOT NULL PRIMARY KEY AUTO_INCREMENT'
# The most important class for the framework # The most important class for the framework
# #
# Webmodel is a class for create objects that represent models. This models are a mirage of SQL tables. You can create fields, add indexes, foreign keys, and more. # Webmodel is a class for create objects that represent models. This models are a mirage of SQL tables. You can create fields, add indexes, foreign keys, and more.
@ -26,6 +210,7 @@ class WebModel:
arr_sql_set_unique={} arr_sql_set_unique={}
last_query="" last_query=""
connection_pool=[] connection_pool=[]
first_primary_key=PrimaryKeyField('id')
#A dictionary for add models here #A dictionary for add models here
@ -103,13 +288,20 @@ class WebModel:
self.required_save={} self.required_save={}
#Create id field #Create id field
primary_key=WebModel.first_primary_key
primary_key.name=self.name_field_id
self.register(primary_key)
self.register(PrimaryKeyField(self.name_field_id)) self.register(PrimaryKeyField(self.name_field_id))
#self.model[name]=self #self.model[name]=self
self.yes_reset_conditions=True self.yes_reset_conditions=True
self.create_fields() #self.create_fields()
self.updated=False self.updated=False
@ -955,190 +1147,3 @@ class WebModel:
self.close() self.close()
""" """
class PhangoField:
def __init__(self, name, size=255, required=False):
# The name of the field in database table
self.name=name
# The label for the Field
self.label=name.replace('_', ' ').title()
# If field is required, self.required is True
self.required=required
# The size of field in database
self.size=size
# Protected, if this value != False, cannot use it in insert or update.
self.protected=False
# $quote_open is used if you need a more flexible sql sentence,
# @warning USE THIS FUNCTION IF YOU KNOW WHAT YOU ARE DOING
self.quot_open='\''
# $quote_close is used if you need a more flexible sql sentence,
# @warning USE THIS PROPERTY IF YOU KNOW WHAT YOU ARE DOING
self.quot_close='\''
# Variable where the basic text error is saved
self.error=None
self.txt_error=""
# Themodel where this component or field live
self.model=None
# Property used for set this field how indexed in the database table.
self.indexed=False
# Property used for set this field how unique value in the database table.
self.unique=False
# Simple property for make more easy identify foreignkeyfields.
self.foreignkey=False
# Property that define the default value for this field
self.default_value=""
# Property that define if this field is in an update operation or insert operation
self.update=False
# Property used for check if this value cannot change if is in blank and is filled
self.check_blank=False
# Define the form, when is created forms with create_forms you can change the properties of this class
self.name_form=BaseForm
# Property that define if make escape in show_formatted. This property control the html transformation of <>" characters in html entities.If false, convert.
self.escape=False
# File related: if the field have a file related, delete the file
self.file_related=False
# Extra parameters for the form
self.extra_parameters=[]
# Template manager for the form if needed
self.t=None
# This method is used for describe the new field in a sql language format.
def get_type_sql(self):
return 'VARCHAR('+str(self.size)+') NOT NULL DEFAULT "'+self.default_value+'"'
def show_formatted(self, value):
return value
# This method for check the value
def check(self, value):
self.error=False
self.txt_error=''
value=str(value)
if self.escape==False:
value=value.replace('<', '&lt;')
value=value.replace('>', '&gt;')
value=value.replace('"', '&quot;')
#value=WebModel.escape_sql(value)
if value=="":
self.txt_error="The field is empty"
self.error=True
return value
def set_relationships(self):
pass
def create_form(self):
#self.name, self.default_value,
self.extra_parameters.insert(0, self.name)
self.extra_parameters.insert(1, self.default_value)
form=self.name_form(*self.extra_parameters)
form.default_value=self.default_value
form.required=self.required
form.label=self.label
form.field=self
return form
def change_form(self, new_form, parameters):
self.name_form=new_form
self.extra_parameters=parameters
def post_register(self):
pass
class PrimaryKeyField(PhangoField):
def __init__(self, name, size=11, required=False):
super(PrimaryKeyField, self).__init__(name, size, required)
self.protected=True
self.name_form=HiddenForm
self.required=True
def check(self, value):
self.error=None
self.txt_error=''
if value=='':
value='0'
try:
value=str(int(value))
except:
value=0
if value==0:
self.txt_error="The value is zero"
self.error=True
return value
def get_type_sql(self):
return 'INT NOT NULL PRIMARY KEY AUTO_INCREMENT'

View file

@ -59,22 +59,18 @@ routes={}
module_loaded=None module_loaded=None
#Import modules to load #Getting paths for loaded modules for use in media load files
for module in config.modules: for module in config.modules:
controller_path=load(module) #controller_path=sys.modules[module]
controller_base=os.path.dirname(controller_path.__file__) controller_base=sys.modules[module].__path__[0]
base_module=module.split('.')[-1] base_module=module.split('.')[-1]
arr_module_path[base_module]=controller_base arr_module_path[base_module]=controller_base
dir_controllers=os.listdir(controller_base)
#add_func_static_module(controller_base)
#Prepare ssl #Prepare ssl
if config.ssl==True: if config.ssl==True:
@ -166,7 +162,7 @@ if config.session_enabled==True:
app.add_hook('after_request', save_session) app.add_hook('after_request', save_session)
#def #def
""" """
app = SessionMiddleware(app, config.session_opts, environ_key=config.cookie_name) #app = SessionMiddleware(app, config.session_opts, environ_key=config.cookie_name)
# Clean last slash # Clean last slash
@ -185,7 +181,7 @@ set_timezone()
def run_app(app): def run_app(app):
run(app=app, host=config.host, server=config.server_used, port=config.port, debug=config.debug, reloader=config.reloader) run(app=app, host=config.host, server=config.server_used, port=config.port, debug=config.debug, reloader=config.reloader, interval=0.5)
""" """
if __name__ == "__main__": if __name__ == "__main__":
run(app=app, host=config.host, server=config.server_used, port=config.port, debug=config.debug, reloader=config.reloader) run(app=app, host=config.host, server=config.server_used, port=config.port, debug=config.debug, reloader=config.reloader)

View file

@ -140,18 +140,23 @@ def home(module='', submodule=''):
title_module=content_index[0] title_module=content_index[0]
content_index=content_index[1] content_index=content_index[1]
return t.load_template('admin/content.html', title=title_module, content_index=content_index, menu=menu, lang_selected=lang_selected, arr_i18n=I18n.dict_i18n) return t.render_template('admin/content.html', title=title_module, content_index=content_index, menu=menu, lang_selected=lang_selected, arr_i18n=I18n.dict_i18n)
else: else:
return content_index return content_index
else: else:
return t.load_template('admin/index.html', title=I18n.lang('admin', 'welcome_to_paramecio', 'Welcome to Paramecio Admin!!!'), menu=menu, lang_selected=lang_selected, arr_i18n=I18n.dict_i18n) return t.render_template('admin/index.html', title=I18n.lang('admin', 'welcome_to_paramecio', 'Welcome to Paramecio Admin!!!'), menu=menu, lang_selected=lang_selected, arr_i18n=I18n.dict_i18n)
return ""
else: else:
logout() logout()
return ""
else: else:
user_admin.conditions=['WHERE privileges=%s', [2]] user_admin.conditions=['WHERE privileges=%s', [2]]
@ -198,7 +203,7 @@ def home(module='', submodule=''):
#connection.close() #connection.close()
return t.load_template('admin/login.phtml', forms=forms, yes_recovery_login=yes_recovery_login) return t.render_template('admin/login.phtml', forms=forms, yes_recovery_login=yes_recovery_login)
else: else:
@ -208,7 +213,9 @@ def home(module='', submodule=''):
forms=show_form(post, user_admin.forms, t, yes_error=False) forms=show_form(post, user_admin.forms, t, yes_error=False)
return t.load_template('admin/register.phtml', forms=forms) return t.render_template('admin/register.phtml', forms=forms)
return ""
@post('/'+config.admin_folder+'/login') @post('/'+config.admin_folder+'/login')
def login(): def login():
@ -413,7 +420,7 @@ def recovery_password():
#connection.close() #connection.close()
return t.load_template('admin/recovery.phtml', forms=forms) return t.render_template('admin/recovery.phtml', forms=forms)
@post('/'+config.admin_folder+'/recovery_password') @post('/'+config.admin_folder+'/recovery_password')
def send_password(): def send_password():
@ -462,7 +469,7 @@ def send_password():
send_mail=SendMail() send_mail=SendMail()
content_mail=t.load_template('admin/recovery_mail.phtml', token=token) content_mail=t.render_template('admin/recovery_mail.phtml', token=token)
if not send_mail.send(email_address, [email], I18n.lang('admin', 'send_email', 'Email for recovery your password'), content_mail): if not send_mail.send(email_address, [email], I18n.lang('admin', 'send_email', 'Email for recovery your password'), content_mail):
return {'email': 'Error: i cannot send mail', 'error': 1} return {'email': 'Error: i cannot send mail', 'error': 1}
@ -475,7 +482,7 @@ def send_password():
def check_token(): def check_token():
t=PTemplate(env) t=PTemplate(env)
return t.load_template('admin/check_token.phtml') return t.render_template('admin/check_token.phtml')
@post('/'+config.admin_folder+'/check_token') @post('/'+config.admin_folder+'/check_token')
def check_code_token(): def check_code_token():
@ -518,7 +525,7 @@ def check_code_token():
send_mail=SendMail() send_mail=SendMail()
content_mail=t.load_template('admin/recovery_password.phtml', password=new_password) content_mail=t.render_template('admin/recovery_password.phtml', password=new_password)
if not send_mail.send(email_address, [arr_user['email']], I18n.lang('admin', 'send_password_email', 'Your new password'), content_mail): if not send_mail.send(email_address, [arr_user['email']], I18n.lang('admin', 'send_password_email', 'Your new password'), content_mail):
return {'token': 'Error: i cannot send mail', 'error': 1} return {'token': 'Error: i cannot send mail', 'error': 1}

View file

@ -13,14 +13,14 @@ def home():
t=PTemplate(env) t=PTemplate(env)
return t.load_template('welcome.html', title="Welcome to Paramecio!!!", content="The simple web framework writed in Python3!!!") return t.render_template('welcome.html', title="Welcome to Paramecio!!!", content="The simple web framework writed in Python3!!!")
@route('/welcome/<id:int>') @route('/welcome/<id:int>')
def page(id): def page(id):
t=PTemplate(env) t=PTemplate(env)
return t.load_template('index.html', title="A simple example of a page", id=id, value=request.query.value) return t.render_template('index.html', title="A simple example of a page", id=id, value=request.query.value)
@route('/welcome/test/<id:int>') @route('/welcome/test/<id:int>')
def test(id): def test(id):