From e93adee075dd82253dbdffdfe547ec779edfd54a Mon Sep 17 00:00:00 2001 From: Antonio de la Rosa Date: Sun, 29 Sep 2024 01:07:58 +0200 Subject: [PATCH] Fixes in docs --- paramecio/citoplasma/mtemplates.py | 98 ++++++++++++++++++++- paramecio/cromosoma/databases/sqlalchemy.py | 74 ++++++++++++---- 2 files changed, 154 insertions(+), 18 deletions(-) diff --git a/paramecio/citoplasma/mtemplates.py b/paramecio/citoplasma/mtemplates.py index 8327d20..2685f45 100644 --- a/paramecio/citoplasma/mtemplates.py +++ b/paramecio/citoplasma/mtemplates.py @@ -1,10 +1,29 @@ #!/usr/bin/python +""" +Parameciofm is a series of wrappers for Bottle.py, mako and others and construct a simple headless cms. + +Copyright (C) 2024 Antonio de la Rosa Caballero + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +""" + from bottle import hook from mako.template import Template from mako.lookup import TemplateLookup from paramecio.citoplasma.urls import make_url, make_url_domain, make_media_url, make_media_url_module, add_get_parameters -from paramecio.citoplasma.i18n import I18n +from paramecio.citoplasma.i18n import I18n, PGetText from paramecio.citoplasma.sessions import get_session from paramecio.citoplasma.adminutils import make_admin_url from paramecio.cromosoma.formsutils import csrf_token @@ -17,6 +36,22 @@ from collections import OrderedDict def env_theme(module, cache_enabled=True, cache_impl='', cache_args={}, module_directory="./tmp/modules"): + """Function for create an environment for mako templates + + Function for create an environment for mako templates. Really is a shortcut for TemplateLookup mako function. You can define cache options and module_directory for templates compiled + + Args: + module (str): The module where the templates can be founded + cache_enabled (boolean): If True then mako template cache is enabled, is False, mako template cache is disabled. + cache_args (dict): Cache Args dict parameter for TemplateLookup function from Mako templates. View Mako Templates documentation. + module_directory (str): Module directory parameter for TemplateLookup function from Mako templates. View Mako Templates documentation. + + Returns: + + template (TemplateLookup): Return TemplateLookup object + + """ + ext=module[len(module)-3:] if ext=='.py': @@ -51,11 +86,28 @@ def preload_templates(template_files, env): return templates class PTemplate: + """A class used how shortcuts for Mako template functions. + """ templates_loaded={} def __init__(self, environment): + """A class used how shortcuts for Mako template functions. + + This class is used to have a set of shortcuts and hooks to Mako templates functions and methods over a series of default options. + + Args: + environment (TemplateLookup): A TemplateLookup object generated with env_theme function + + Attributes: + autoescape_ext (set): A set of extensions file where automatic autoescape is used + environment (TemplateLookup): A TemplateLookup object generated with env_theme function + filters (list): A list of functions used for add filters to your templates. + js (list): A list of javascript sources for generate js html load tags. + + """ + # A simple method used in internal things of paramecio self.show_basic_template=True @@ -130,6 +182,20 @@ class PTemplate: self.env=environment + # Loading language domain for gettext in templates + + base_name=path.dirname(path.realpath(__file__)) + + module_env=self.env.directories[1].replace('/templates', '') + + self.l=PGetText(module_env+'/index.py') + + self.add_filter(self._) + + def _(self, text): + + return self.l.gettext(text) + #self.auto_reload=True # Clean HeaderHTML @@ -144,6 +210,12 @@ class PTemplate: def guess_autoescape(self, template_name): + """Simple helper method for get an extension from filename + + Args: + template_name (str): The template name + """ + if template_name is None or '.' not in template_name: return False @@ -180,6 +252,18 @@ class PTemplate: def load_template(self, template_file, **arguments): + """Load a mako template and return the result + + Load a mako template and return the results with different arguments applied + + Args: + template_file (str): The name of template file. The template is searched using configuration defined in self.env + **arguments (mixed): Extra arguments with variables passed to template + + Returns: + template (str): Return a template rendered using mako class from self.env + """ + template = self.env.get_template(template_file) arguments.update(self.filters) @@ -190,6 +274,18 @@ class PTemplate: def render_template(self, template_file, **arguments): + """Experimental method for parse a template + + Experimental method for parse a template, similar to load_template but try cache the template loaded + + Args: + template_file (str): The name of template file. The template is searched using configuration defined in self.env + **arguments (mixed): Extra arguments with variables passed to template + + Returns: + dummy (str): Dummy return necessary because mako expect return something + """ + 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) diff --git a/paramecio/cromosoma/databases/sqlalchemy.py b/paramecio/cromosoma/databases/sqlalchemy.py index 257fdb8..9dcf592 100644 --- a/paramecio/cromosoma/databases/sqlalchemy.py +++ b/paramecio/cromosoma/databases/sqlalchemy.py @@ -12,6 +12,14 @@ import traceback engine=None class SqlClass: + """Class used how interface to sqlalchemy for connect to mysql engine + + Attributes: + cursors_connect (pymysql.cursors.DictCursor): Cursor dict connection to database + disable_pool (boolean): If True then not exists mysql pool, if False, use sql pool for better connections. + pymsql_install (boolean): If True, pymysql is used how mysqldb classic python module. + pool_size (int): The size of the mysql pool. + """ cursors_connect=None disable_pool=False @@ -19,8 +27,18 @@ class SqlClass: pool_size=15 def __init__(self, connection): + """ + Args: + connection (dict): A dict with the configurations of SqlClass connection + Attributes: + error_connection (str): A string where errors are saved + connection (dict): A dict with the configurations of SqlClass connection + conn (MySQL Connection): A PyMySQL or Mysqldb connection + connected (bool): Simple bool for check if was connected to mysql + pool_recycle (int): Time limite for recycle the pool by inactivity + """ - self.max_overflow=-1 + #self.max_overflow=-1 self.error_connection="" # Data of connection self.connection=connection @@ -28,11 +46,13 @@ class SqlClass: self.conn=None self.connected=False self.pool_recycle=3600 - self.connect() self.last_query='' + self.connect() def connect(self): + """Method for connect to mysql db using pymysql or mysqldb + """ global engine @@ -45,7 +65,8 @@ class SqlClass: if self.connection['db_type']=='pymysql': import pymysql.cursors - + pymysql.install_as_MySQLdb + SqlClass.pymysql_install=True SqlClass.cursors_connect=pymysql.cursors.DictCursor else: import MySQLdb.cursors @@ -53,6 +74,9 @@ class SqlClass: 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) + #Postgre + #engine = create_engine("postgresql+psycopg2://scott:tiger@localhost:5432/mydatabase") + except: e = sys.exc_info()[0] v = sys.exc_info()[1] @@ -77,18 +101,22 @@ class SqlClass: 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) + """ + connection = pymysql.connect(host='localhost', + user='user', + password='passwd', + database='db', + charset='utf8mb4', + cursorclass=pymysql.cursors.DictCursor) + """ + + self.conn=pymysql.connect(host=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'], + self.conn=MySQLdb.connect(host=self.connection['host'], user=self.connection['user'], passwd=self.connection['password'], db=self.connection['db'], @@ -132,26 +160,34 @@ class SqlClass: #Make def query more simple if not debugging. def query(self, sql_query, arguments=[], name_connection="default"): + """Method for send a sql query to mysql server + + Args: + sql_query (str): The sql sentence to execute. For data you should use %s character. + arguments (list): The data used in sql sentence. This data substitute the %s characters. + name_connection (str): The name of dict element with the configuration of connection, without used in this moment. + """ - cursor=self.conn.cursor(SqlClass.cursors_connect) try: cursor.execute(sql_query, arguments) - self.conn.commit() - if hasattr(cursor, '_last_executed'): - self.last_query=cursor._last_executed + self.conn.commit() + + #if hasattr(cursor, '_executed'): + # self.last_query=cursor._executed + return cursor except: e = sys.exc_info()[0] v = sys.exc_info()[1] - if hasattr(cursor, '_last_executed'): - sql_query=cursor._last_executed + #if hasattr(cursor, '_executed'): + # self.last_query=cursor._executed - self.error_connection="Error in query ||%s||Values: %s" % (sql_query, str(arguments)) + self.error_connection="Error in query ||%s||Values: %s" % (self.last_query, str(arguments)) self.conn.close() @@ -196,12 +232,16 @@ class SqlClass: #return cursor.fetchone() def __del__(self): + """Typical method used when class is deleted from memory. Close the connextion if exists. + """ if self.conn: self.conn.close() def close(self, name_connection="default"): + """Method used for close the connection if you want close connection and open other. + """ if self.conn: