Added support for gettext #2

Merged
absurdo merged 7 commits from gettext into master 2023-12-19 22:27:44 +00:00
25 changed files with 348 additions and 83 deletions

2
.gitignore vendored
View file

@ -47,7 +47,7 @@ coverage.xml
.hypothesis/ .hypothesis/
# Translations # Translations
*.mo #*.mo
*.pot *.pot
# Django stuff: # Django stuff:

View file

@ -3,7 +3,7 @@
from paramecio2.libraries.db.webmodel import WebModel from paramecio2.libraries.db.webmodel import WebModel
from paramecio2.libraries.db.coreforms import PasswordForm from paramecio2.libraries.db.coreforms import PasswordForm
from paramecio2.libraries.i18n import I18n from paramecio2.libraries.i18n import I18n
from flask import request from flask import request, session
class UserModel(WebModel): class UserModel(WebModel):
"""Model used with basic things for users login and signup """Model used with basic things for users login and signup
@ -46,7 +46,7 @@ class UserModel(WebModel):
repeat_password.required=1 repeat_password.required=1
repeat_password.label=I18n.lang('common', 'repeat_password', 'Repeat Password') repeat_password.label=_('Repeat Password')
repeat_password.field=self.fields[self.password_field] repeat_password.field=self.fields[self.password_field]
@ -99,7 +99,7 @@ class UserModel(WebModel):
if dict_values['repeat_password']!=dict_values[self.password_field]: if dict_values['repeat_password']!=dict_values[self.password_field]:
self.fields[self.password_field].error=True 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') self.fields[self.password_field].txt_error=_('Error: passwords doesn\'t match')
error+=1 error+=1

View file

@ -5,6 +5,8 @@ from paramecio2.libraries.db.coreforms import PasswordForm
from paramecio2.libraries.i18n import I18n from paramecio2.libraries.i18n import I18n
from flask import session, request, abort from flask import session, request, abort
from paramecio2.libraries.keyutils import create_key_encrypt from paramecio2.libraries.keyutils import create_key_encrypt
from paramecio2.libraries.i18n import I18n, PGetText
# Need unittest # Need unittest
"""Functions and classes for process forms""" """Functions and classes for process forms"""
@ -178,7 +180,7 @@ def set_extra_forms_user(user_admin):
user_admin.forms['repeat_password'].required=True user_admin.forms['repeat_password'].required=True
user_admin.forms['repeat_password'].label=I18n.lang('common', 'repeat_password', 'Repeat Password') user_admin.forms['repeat_password'].label=_('Repeat Password')
def csrf_token(token_id='csrf_token'): def csrf_token(token_id='csrf_token'):

View file

@ -3,14 +3,22 @@ from flask import request, redirect, flash
from paramecio2.libraries.urls import add_get_parameters from paramecio2.libraries.urls import add_get_parameters
#from paramecio.citoplasma.mtemplates import set_flash_message #from paramecio.citoplasma.mtemplates import set_flash_message
from paramecio2.libraries.formsutils import show_form from paramecio2.libraries.formsutils import show_form
from paramecio2.libraries.i18n import I18n from paramecio2.libraries.mtemplates import env_theme, PTemplate
from paramecio2.libraries.i18n import I18n, PGetText
from collections import OrderedDict from collections import OrderedDict
pgettext=PGetText(__file__)
_=pgettext.gettext
#env=env_theme(__file__)
#t=PTemplate(env)
class GenerateAdminClass: class GenerateAdminClass:
"""Class for insert, update and list items of a model """Class for insert, update and list items of a model
""" """
def __init__(self, model, url, t): def __init__(self, model, url, t=None):
"""A class for generate forms, insert and update items from a database model """A class for generate forms, insert and update items from a database model
For an easy and fast access to database data, you can use this class for get a simple database model of paramecio and get list of items, add forms, edit forms and more. For an easy and fast access to database data, you can use this class for get a simple database model of paramecio and get list of items, add forms, edit forms and more.
@ -38,9 +46,20 @@ class GenerateAdminClass:
self.model=model self.model=model
self.t=t if t:
self.t=t
else:
env=env_theme(__file__)
self.list=SimpleList(model, url, t) self.t=PTemplate(env)
#self.t.l=pgettext
#self.t.add_filter(self.t._)
self.list=SimpleList(model, url, self.t)
self.arr_fields_edit=list(model.fields.keys()) self.arr_fields_edit=list(model.fields.keys())
@ -76,7 +95,7 @@ class GenerateAdminClass:
self.post_update=None self.post_update=None
self.text_home=I18n.lang('common', 'home', 'Home') self.text_home=_('Home')
def show(self): def show(self):
""" Method for show the admin model """ Method for show the admin model
@ -106,13 +125,13 @@ class GenerateAdminClass:
post=None post=None
title_edit=I18n.lang('common', 'add_new_item', 'Add new item') title_edit=_('Add new item')
pass_value=False pass_value=False
if item_id!='0': if item_id!='0':
post=self.model.select_a_row(item_id, [], True) post=self.model.select_a_row(item_id, [], True)
title_edit=I18n.lang('common', 'edit_new_item', 'Edit item') title_edit=_('Edit item')
pass_value=True pass_value=True
if post==None or post==False: if post==None or post==False:
@ -149,12 +168,12 @@ class GenerateAdminClass:
item_id='0' item_id='0'
title_edit=I18n.lang('common', 'add_new_item', 'Add new item') title_edit=_('Add new item')
if item_id!='0': if item_id!='0':
insert_row=self.model.update insert_row=self.model.update
title_edit=I18n.lang('common', 'edit_new_item', 'Edit item') title_edit=_('Edit item')
self.model.conditions=['WHERE `'+self.model.name+'`.`'+self.model.name_field_id+'`=%s', [item_id]] self.model.conditions=['WHERE `'+self.model.name+'`.`'+self.model.name_field_id+'`=%s', [item_id]]
post=dict(request.form) post=dict(request.form)
@ -162,7 +181,7 @@ class GenerateAdminClass:
if pre_update_ret: if pre_update_ret:
if insert_row(post): if insert_row(post):
flash(I18n.lang('common', 'task_successful', 'Task successful')) flash(_('Task successful'))
if self.post_update: if self.post_update:
if item_id=='0': if item_id=='0':
@ -203,7 +222,7 @@ class GenerateAdminClass:
if item_id!='0': if item_id!='0':
self.model.conditions=['WHERE `'+self.model.name+'`.`'+self.model.name_field_id+'`=%s', [item_id]] self.model.conditions=['WHERE `'+self.model.name+'`.`'+self.model.name_field_id+'`=%s', [item_id]]
self.model.delete() self.model.delete()
flash(I18n.lang('common', 'task_successful', 'Task successful')) flash(_('Task successful'))
return redirect(self.url_redirect) return redirect(self.url_redirect)
else: else:
@ -282,7 +301,7 @@ class GenerateConfigClass:
self.post_update=None self.post_update=None
self.text_home=I18n.lang('common', 'home', 'Home') self.text_home=_('Home')
def show(self): def show(self):
@ -298,7 +317,7 @@ class GenerateConfigClass:
self.model.create_forms() self.model.create_forms()
title_edit=I18n.lang('common', 'edit', 'Edit')+' '+self.title_name title_edit=_('Edit')+' '+self.title_name
edit_forms=OrderedDict() edit_forms=OrderedDict()
@ -323,7 +342,7 @@ class GenerateConfigClass:
post=dict(request.form) post=dict(request.form)
if insert_model(post): if insert_model(post):
set_flash_message(I18n.lang('common', 'task_successful', 'Task successful')) set_flash_message(_('Task successful'))
self.model.yes_reset_conditions=True self.model.yes_reset_conditions=True
if self.post_update: if self.post_update:

View file

@ -1,9 +1,11 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
from importlib import import_module from importlib import import_module
import gettext
#from paramecio.citoplasma.sessions import get_session #from paramecio.citoplasma.sessions import get_session
import json import json
from flask import session, has_request_context from flask import session, has_request_context
import os
yes_session=False yes_session=False
@ -27,7 +29,45 @@ def load_lang(*args):
pass pass
# here load the language # here load the language
class PGetText:
# Dict where all gettext domain are saved -> domain=name, example, admin, libraries, pastafari2, etc...
l={}
def __init__(self, module_file):
module_dir=os.path.dirname(os.path.realpath(module_file))
module_name=os.path.basename(module_dir)
if module_name not in PGetText.l:
PGetText.l[module_name]={}
for i in I18n.dict_i18n:
if i not in PGetText.l[module_name]:
PGetText.l[module_name][i]=gettext.translation(module_name, module_dir+'/languages/', languages=[i], fallback=True)
PGetText.l[module_name][i].install()
self.module=module_name
def gettext(self, text):
return PGetText.l[self.module][I18n.get_default_lang()].gettext(text)
def pgettext(module_file):
module=os.path.dirname(os.path.realpath(module_file))
base_name=os.path.dirname(os.path.realpath(module))
l=gettext.translation(os.path.basename(base_name), module+'/languages/', languages=I18n.get_default_lang(), fallback=True)
return l.gettext
class I18n: class I18n:
"""Class for i18n tasks """Class for i18n tasks
@ -130,3 +170,4 @@ class I18n:
return json.dumps(arr_final) return json.dumps(arr_final)
common_pgettext=PGetText(__file__)

View file

@ -2,12 +2,15 @@
from paramecio2.libraries.pages import Pages from paramecio2.libraries.pages import Pages
from paramecio2.libraries.urls import add_get_parameters from paramecio2.libraries.urls import add_get_parameters
from paramecio2.libraries.i18n import I18n from paramecio2.libraries.i18n import I18n, PGetText
#from flask import request, session #from flask import request, session
from paramecio2.libraries.get_data import get_query_args from paramecio2.libraries.get_data import get_query_args
import sys import sys
import re import re
pgettext=PGetText(__file__)
_=pgettext.gettext
class SimpleList: class SimpleList:
"""Class for create item list from a model table """Class for create item list from a model table
""" """
@ -107,7 +110,7 @@ class SimpleList:
#self.yes_options=True #self.yes_options=True
self.arr_extra_fields=[I18n.lang('common', 'options', 'Options')] self.arr_extra_fields=[_('Options')]
self.arr_extra_options=[SimpleList.standard_options] self.arr_extra_options=[SimpleList.standard_options]
@ -216,8 +219,8 @@ class SimpleList:
options (list): Return a list of basic options for items row options (list): Return a list of basic options for items row
""" """
options=[] options=[]
options.append('<a href="'+add_get_parameters(url, op_admin=1, id=id)+'">'+I18n.lang('common', 'edit', 'Edit')+'</a>') options.append('<a href="'+add_get_parameters(url, op_admin=1, id=id)+'">'+_('Edit')+'</a>')
options.append('<a href="'+add_get_parameters(url, op_admin=3, id=id)+'">'+I18n.lang('common', 'delete', 'Delete')+'</a>') options.append('<a href="'+add_get_parameters(url, op_admin=3, id=id)+'">'+_('Delete')+'</a>')
return options return options
def show(self): def show(self):
@ -286,7 +289,7 @@ class AjaxList(SimpleList):
"""Class for make a list from a table based in Ajax """Class for make a list from a table based in Ajax
""" """
# Fields example: [[I18n.lang('cuchulu', 'hostname', 'Hostname'), True], ['IP', True], [I18n.lang('cuchulu', 'options', 'Options'), False]] # Fields example: [['Hostname', True], ['IP', True], ['Options', False]]
# arr_order_fields=['server.hostname', 'server.ip'] # arr_order_fields=['server.hostname', 'server.ip']
@ -389,7 +392,7 @@ class AjaxList(SimpleList):
pages=Pages() pages=Pages()
html_pages=I18n.lang('cuchulu', 'pages', 'Pages')+': '+pages.show( begin_page, total_elements, limit, '#' ,initial_num_pages=self.initial_num_pages, variable='begin_page', label='', func_jscript='') html_pages=_('Pages')+': '+pages.show( begin_page, total_elements, limit, '#' ,initial_num_pages=self.initial_num_pages, variable='begin_page', label='', func_jscript='')
with self.db.query(str_query, params) as cursor: with self.db.query(str_query, params) as cursor:
for row in cursor: for row in cursor:

View file

@ -1,6 +1,6 @@
# Template frontend from mako. # Template frontend from mako.
import gettext #import gettext
from mako.template import Template from mako.template import Template
from flask import session, url_for from flask import session, url_for
from mako.lookup import TemplateLookup from mako.lookup import TemplateLookup
@ -12,15 +12,17 @@ except:
theme='default' theme='default'
reloader=False reloader=False
import gettext #import gettext
import sys import sys
from paramecio2.libraries.i18n import I18n from paramecio2.libraries.i18n import I18n, PGetText
from paramecio2.libraries.urls import make_url, make_media_url, add_get_parameters from paramecio2.libraries.urls import make_url, make_media_url, add_get_parameters
from paramecio2.libraries.formsutils import csrf_token from paramecio2.libraries.formsutils import csrf_token
"""
def _(text): def _(text):
return gettext.gettext(text) return gettext.gettext(text)
"""
def env_theme(module, cache_enabled=True, cache_impl='', cache_args={}, module_directory="./tmp/modules"): 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
@ -46,6 +48,8 @@ def env_theme(module, cache_enabled=True, cache_impl='', cache_args={}, module_d
module=path.dirname(module) module=path.dirname(module)
standard_templates=path.dirname(__file__)+'/templates' standard_templates=path.dirname(__file__)+'/templates'
standard_languages=path.dirname(__file__)+'/languages'
module_directory+='/'+module module_directory+='/'+module
@ -94,8 +98,6 @@ class PTemplate:
self.add_filter(I18n.lang) self.add_filter(I18n.lang)
self.add_filter(_)
#self.add_filter(make_url) #self.add_filter(make_url)
self.add_filter(make_media_url) self.add_filter(make_media_url)
@ -109,6 +111,22 @@ class PTemplate:
self.add_filter(self.add_js) self.add_filter(self.add_js)
self.add_filter(self.load_js) self.add_filter(self.load_js)
# Loading language domain for gettext in templates
base_name=path.dirname(path.realpath(__file__))
module_env=self.env.directories[1].replace('/templates', '')
#print(path.basename(module_env)+' '+base_name+'/languages/')
self.l=PGetText(module_env+'/app.py')
self.add_filter(self._)
def _(self, text):
return self.l.gettext(text)
def add_js(self, js, module=''): def add_js(self, js, module=''):
"""Function for add js to self.js attribute """Function for add js to self.js attribute

View file

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

View file

@ -11,13 +11,13 @@
% if simplelist.yes_search: % if simplelist.yes_search:
<div class="form"> <div class="form">
<form method="get" action="${simplelist.url}"> <form method="get" action="${simplelist.url}">
${lang('common','search', 'Search')}: <input type="text" name="search_text" value="${simplelist.search_text|n}"> ${_('Search')}: <input type="text" name="search_text" value="${simplelist.search_text|n}">
<select name="search_field"> <select name="search_field">
% for field in simplelist.search_fields: % for field in simplelist.search_fields:
<option value="${simplelist.model.fields[field].name}" ${select_field(field)}>${simplelist.model.fields[field].label}</option> <option value="${simplelist.model.fields[field].name}" ${select_field(field)}>${simplelist.model.fields[field].label}</option>
% endfor % endfor
</select> </select>
<input type="submit" value="${lang('common', 'search', 'Search')}" /> <input type="submit" value="${_('Search')}" />
</form> </form>
</div> </div>
% endif % endif
@ -130,6 +130,6 @@ size_td=round(100/(len(simplelist.fields_showed)+len(simplelist.arr_extra_option
% endif % endif
<p> <p>
% if pages!='': % if pages!='':
${lang('common', 'pages', 'Pages')}: ${pages|n} ${_('Pages')}: ${pages|n}
% endif % endif
</p> </p>

View file

@ -3,6 +3,6 @@
<!-- <input type="hidden" name="id" value="${item_id}"> <!-- <input type="hidden" name="id" value="${item_id}">
<input type="hidden" name="op_admin" value="${op_admin}"> <input type="hidden" name="op_admin" value="${op_admin}">
<input type="hidden" name="verified" value="${verified}">--> <input type="hidden" name="verified" value="${verified}">-->
<input type="submit" value="${lang('common', 'delete_item_you_sure', 'Are you sure for delete this item?')}" /> <input type="submit" value="${_('Are you sure for delete this item?')}" />
</div> </div>
</form> </form>

View file

@ -4,7 +4,6 @@ try:
admin_app=Blueprint('admin_app', __name__, static_folder='static') admin_app=Blueprint('admin_app', __name__, static_folder='static')
env=env_theme(__file__) env=env_theme(__file__)
t=PTemplate(env) t=PTemplate(env)

View file

@ -1,13 +1,17 @@
from settings import config from settings import config
from flask import g, url_for from flask import g, url_for, session
from paramecio2.modules.admin.models.admin import UserAdmin from paramecio2.modules.admin.models.admin import UserAdmin
from paramecio2.libraries.generate_admin_class import GenerateAdminClass from paramecio2.libraries.generate_admin_class import GenerateAdminClass
from paramecio2.libraries.i18n import I18n from paramecio2.libraries.i18n import I18n, PGetText
from paramecio2.libraries.db.coreforms import SelectForm from paramecio2.libraries.db.coreforms import SelectForm
from paramecio2.libraries.db.coreforms import HiddenForm from paramecio2.libraries.db.coreforms import HiddenForm
import copy import copy
from paramecio2.modules.admin import admin_app, t as admin_t from paramecio2.modules.admin import admin_app, t as admin_t
pgettext=PGetText(__file__+'/../')
_=pgettext.gettext
t=copy.copy(admin_t) t=copy.copy(admin_t)
@admin_app.route('/admin/ausers/', methods=['GET', 'POST']) @admin_app.route('/admin/ausers/', methods=['GET', 'POST'])
@ -29,22 +33,22 @@ def ausers():
user_admin.create_forms(['username', 'password', 'email', 'privileges', 'lang', 'dark_theme', 'disabled', 'double_auth', 'last_login']) user_admin.create_forms(['username', 'password', 'email', 'privileges', 'lang', 'dark_theme', 'disabled', 'double_auth', 'last_login'])
user_admin.forms['privileges'].arr_select={0: I18n.lang('admin', 'without_privileges', 'Without privileges'), 1: I18n.lang('admin', 'selected_privileges', 'Selected privileges'), 2: I18n.lang('admin', 'administrator', 'Administrator')} user_admin.forms['privileges'].arr_select={0: _('Without privileges'), 1: _('Selected privileges'), 2: _('Administrator')}
user_admin.forms['disabled'].arr_select={0: I18n.lang('admin', 'user_enabled', 'User enabled'), 1: I18n.lang('admin', 'user_disabled', 'User disabled')} user_admin.forms['disabled'].arr_select={0: _('User enabled'), 1: _('User disabled')}
user_admin.forms['double_auth'].arr_select={0: I18n.lang('admin', 'no', 'No'), 1: I18n.lang('admin', 'yes', 'Yes')} user_admin.forms['double_auth'].arr_select={0: _('No'), 1: _('Yes')}
user_admin.fields['password'].protected=False user_admin.fields['password'].protected=False
user_admin.forms['dark_theme'].arr_select={0: I18n.lang('admin', 'light_theme', 'Light theme'), 1: I18n.lang('admin', 'dark_theme', 'Dark theme')} user_admin.forms['dark_theme'].arr_select={0: _('Light theme'), 1: _('Dark theme')}
user_admin.check_user=False user_admin.check_user=False
user_admin.check_email=False user_admin.check_email=False
url=url_for('admin_app.ausers') url=url_for('admin_app.ausers')
admin=GenerateAdminClass(user_admin, url, t) admin=GenerateAdminClass(user_admin, url)
admin.list.fields_showed=['username'] admin.list.fields_showed=['username']
@ -52,12 +56,22 @@ def ausers():
admin.arr_fields_edit=['username', 'password', 'repeat_password', 'email', 'lang', 'dark_theme', 'double_auth', 'disabled', 'last_login'] admin.arr_fields_edit=['username', 'password', 'repeat_password', 'email', 'lang', 'dark_theme', 'double_auth', 'disabled', 'last_login']
admin.post_update=update_lang
form_admin=admin.show() form_admin=admin.show()
if type(form_admin).__name__=='str': if type(form_admin).__name__=='str':
return t.load_template('content.phtml', title=I18n.lang('admin', 'users_edit', 'Users edit'), contents=form_admin, path_module='admin_app.ausers') return t.load_template('content.phtml', title=_('Users edit'), contents=form_admin, path_module='admin_app.ausers')
else: else:
return form_admin return form_admin
def update_lang(admin, item_id):
arr_row=admin.model.select_a_row(item_id)
session['lang']=arr_row.get('lang', I18n.get_default_lang())
return True

View file

@ -1,6 +1,6 @@
from flask import Blueprint, redirect, session, url_for, request, g, make_response, abort from flask import Blueprint, redirect, session, url_for, request, g, make_response, abort
from settings import config from settings import config
from paramecio2.libraries.i18n import I18n from paramecio2.libraries.i18n import I18n, PGetText
from paramecio2.libraries.datetime import now, format_local_strtime, timestamp_to_datetime, obtain_timestamp from paramecio2.libraries.datetime import now, format_local_strtime, timestamp_to_datetime, obtain_timestamp
from paramecio2.libraries.formsutils import show_form, generate_csrf, set_extra_forms_user, pass_values_to_form from paramecio2.libraries.formsutils import show_form, generate_csrf, set_extra_forms_user, pass_values_to_form
from paramecio2.libraries.db.webmodel import WebModel from paramecio2.libraries.db.webmodel import WebModel
@ -15,6 +15,13 @@ from os import path
from paramecio2.modules.admin import admin_app, t from paramecio2.modules.admin import admin_app, t
from paramecio2.libraries.sendmail import SendMail from paramecio2.libraries.sendmail import SendMail
from paramecio2.libraries.formsutils import check_csrf from paramecio2.libraries.formsutils import check_csrf
#import gettext
#_=pgettext(__file__)
gtext=PGetText(__file__)
_=gtext.gettext
yes_recovery_login=False yes_recovery_login=False
email_address='localhost' email_address='localhost'
@ -116,7 +123,7 @@ for app_load in config_admin:
@admin_app.route('/admin/') @admin_app.route('/admin/')
def admin(): def admin():
return t.load_template('home.phtml', title=I18n.lang('admin', 'admin', 'Admin')) return t.load_template('home.phtml', title=_('Admin'))
""" """
@admin_app.route('/admin/') @admin_app.route('/admin/')
@ -250,7 +257,7 @@ def login():
# def send(self, from_address, to_address: list, subject, message, content_type='plain', attachments=[]): # def send(self, from_address, to_address: list, subject, message, content_type='plain', attachments=[]):
sendmail.send(config.portal_email, [arr_user['email']], I18n.lang('admin', 'code_for_complete_login', 'Code for complete login'), I18n.lang('admin', 'code_for_complete_login_explain', 'We send to you a code for activate your account using double authentication:')+"\n"+token_auth, content_type='plain', attachments=[]) sendmail.send(config.portal_email, [arr_user['email']], _('Code for complete login'), _('We send to you a code for activate your account using double authentication:')+"\n"+token_auth, content_type='plain', attachments=[])
if arr_user['dark_theme']: if arr_user['dark_theme']:
session['theme']='1' session['theme']='1'
@ -259,6 +266,8 @@ def login():
arr_update['last_login']=now() arr_update['last_login']=now()
session['lang']=arr_user.get('lang', I18n.default_lang)
if len(arr_update)>0: if len(arr_update)>0:
user_admin.set_conditions('WHERE id=%s', [arr_user['id']]).update(arr_update) user_admin.set_conditions('WHERE id=%s', [arr_user['id']]).update(arr_update)

View file

@ -0,0 +1,132 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-12-19 15:30+0100\n"
"PO-Revision-Date: 2023-12-19 15:32+0100\n"
"Last-Translator: \n"
"Language-Team: \n"
"Language: es\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Poedit 3.4.1\n"
#: admin/modules.py:51
msgid "Error: git url wrong"
msgstr "Error: Url git equivocada"
#: admin/modules.py:58
msgid "Error: cannot install the module, view the error in wsgi server log"
msgstr "Error: no puedo instalar el módulo, ver el error en el servidor wsgi"
#: admin/ausers.py:36
msgid "Without privileges"
msgstr "Sin privilegios"
#: admin/ausers.py:36
msgid "Selected privileges"
msgstr "Privilegios seleccionados"
#: admin/ausers.py:36
msgid "Administrator"
msgstr "Administrador"
#: admin/ausers.py:38
msgid "User enabled"
msgstr "Usuario activado"
#: admin/ausers.py:38
msgid "User disabled"
msgstr "Usuario desactivado"
#: admin/ausers.py:40
msgid "No"
msgstr "No"
#: admin/ausers.py:40
msgid "Yes"
msgstr "Sí"
#: admin/ausers.py:44
msgid "Light theme"
msgstr "Tema claro"
#: admin/ausers.py:44 templates/dashboard.phtml:110
msgid "Dark theme"
msgstr "Tema oscuro"
#: admin/ausers.py:63 settings/config_admin.py:11
msgid "Users edit"
msgstr "Editar usuarios"
#: app.py:126
msgid "Admin"
msgstr "Admin"
#: app.py:260
msgid "Code for complete login"
msgstr "Código para completar login"
#: app.py:260
msgid ""
"We send to you a code for activate your account using double authentication:"
msgstr ""
"Te enviaremos un código para activr tu cuenta usando doble autenticación"
#: settings/config_admin.py:9
msgid "Users"
msgstr "Usuarios"
#: templates/modules.phtml:3
msgid "Add new module"
msgstr "Añadir nuevo módulo"
#: templates/home.phtml:4 templates/users.phtml:4
msgid "Welcome to Paramecio Admin"
msgstr "Bienvenido a Paramecio Admin"
#: templates/home.phtml:7 templates/users.phtml:7
msgid "From here you can admin your site"
msgstr "Desde aquí puedes administrar tu sitio"
#: templates/login.phtml:4 templates/login.phtml:99 templates/need_auth.phtml:2
#: templates/need_auth.phtml:6
msgid "Paramecio Login"
msgstr "Paramecio login"
#: templates/login.phtml:103
msgid "Remember login?"
msgstr "¿Recordar login?"
#: templates/login.phtml:110
msgid "Recovery password?"
msgstr "¿Recuperar contraseña?"
#: templates/login.phtml:112
msgid "Remember that only have 3 attempts"
msgstr "Recuera que sólo tienes 3 intentos"
#: templates/register.phtml:51 templates/register.phtml:55
msgid "Paramecio Sign up"
msgstr "Paramecio Registro"
#: templates/dashboard.phtml:66
msgid "Applications"
msgstr "Aplicaciones"
#: templates/need_auth.phtml:9
msgid ""
"Check your email for get instructions for complete login with double auth or"
msgstr ""
"Mira tu email para obtener instrucciones para completar el login con doble "
"autenticación o"
#: templates/need_auth.phtml:10
msgid "Code"
msgstr "Código"

View file

@ -1,11 +1,22 @@
from paramecio2.libraries.config_admin import config_admin from paramecio2.libraries.config_admin import config_admin
from paramecio2.libraries.i18n import I18n from paramecio2.libraries.i18n import I18n, PGetText
#modules_admin=[[I18n.lang('admin', 'users_admin', 'User\'s Admin'), 'paramecio.modules.admin.admin.ausers', 'ausers']] #modules_admin=[[I18n.lang('admin', 'users_admin', 'User\'s Admin'), 'paramecio.modules.admin.admin.ausers', 'ausers']]
config_admin.append([I18n.lang('admin', 'users', 'Users')]) pgettext=PGetText(__file__+'/../')
_=pgettext.gettext
config_admin.append([I18n.lang('admin', 'users_edit', 'Users edit'), 'paramecio2.modules.admin.admin.ausers', 'admin_app.ausers', 'fa-user']) def users_text():
return _('Users')
def users_edit():
return _('Users edit')
config_admin.append([users_text])
config_admin.append([users_edit, 'paramecio2.modules.admin.admin.ausers', 'admin_app.ausers', 'fa-user'])
#config_admin.append([I18n.lang('admin', 'modules', 'Modules')]) #config_admin.append([I18n.lang('admin', 'modules', 'Modules')])

View file

@ -63,7 +63,7 @@ ${load_js()|n}
<nav id="menu" class="nav-collapse"> <nav id="menu" class="nav-collapse">
<ul> <ul>
<li class="menu_title"><%block name="applications"><i class="fa fa-gear" aria-hidden="true"></i>${lang('admin', 'applications', 'Applications')}</li></%block> <li class="menu_title"><%block name="applications"><i class="fa fa-gear" aria-hidden="true"></i>${_('Applications')}</li></%block>
<%block name="menu_list"> <%block name="menu_list">
<% <%
@ -75,6 +75,7 @@ ${load_js()|n}
<% <%
class_selected='' class_selected=''
link_text=''
%> %>
@ -89,13 +90,24 @@ ${load_js()|n}
if len(admin)>3: if len(admin)>3:
icon_module=admin[3] icon_module=admin[3]
if type(admin[0]).__name__=='function':
link_text=admin[0]()
else:
link_text=admin[0]
%> %>
<li><a href="${url_for(admin[2])}" class="${class_selected}">&nbsp;<i class="fa ${icon_module}" aria-hidden="true"></i>${admin[0]}</a></li> <li><a href="${url_for(admin[2])}" class="${class_selected}">&nbsp;<i class="fa ${icon_module}" aria-hidden="true"></i>${link_text}</a></li>
% elif len(admin)==1: % elif len(admin)==1:
<%
if type(admin[0]).__name__=='function':
link_text=admin[0]()
else:
link_text=admin[0]
%>
<li><div class="father_admin">${admin[0]}</div></li> <li><div class="father_admin">${link_text}</div></li>
% endif % endif
@ -107,7 +119,7 @@ ${load_js()|n}
<h1>${title}</h1> <h1>${title}</h1>
<div class="switch-btn"> <div class="switch-btn">
<div class="switch-text"> <div class="switch-text">
Dark Mode ${_('Dark theme')}
</div> </div>
<div class="switch-slider"> <div class="switch-slider">
<label class="switch"> <label class="switch">

View file

@ -1,9 +1,9 @@
<%inherit file="dashboard.phtml"/> <%inherit file="dashboard.phtml"/>
<%block name="content"> <%block name="content">
<div class="title"> <div class="title">
Welcome to Paramecio Admin ${_('Welcome to Paramecio Admin')}
</div> </div>
<div class="cont"> <div class="cont">
From here you can admin your site ${_('From here you can admin your site')}
</div> </div>
</%block> </%block>

View file

@ -1,9 +1,9 @@
<%inherit file="home.html"/> <%inherit file="home.html"/>
<%block name="content"> <%block name="content">
<div class="title"> <div class="title">
${lang('admin', 'welcome_to_admin_dashboard', 'Welcome to Admin dashboard')} ${_('Welcome to Admin dashboard')}
</div> </div>
<div class="cont"> <div class="cont">
${lang('admin', 'from_here_you_can_configure_your_site', 'From here you can configure your site')}. ${_('From here you can configure your site')}.
</div> </div>
</%block> </%block>

View file

@ -1,7 +1,7 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<title><%block name="title">${lang('admin', 'login', 'Paramecio Login')}</%block></title> <title><%block name="title">${_('Paramecio Login')}</%block></title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8"> <meta http-equiv="content-type" content="text/html; charset=UTF-8">
<link href='https://fonts.googleapis.com/css?family=Open+Sans' rel='stylesheet' type='text/css'> <link href='https://fonts.googleapis.com/css?family=Open+Sans' rel='stylesheet' type='text/css'>
<link href="${make_media_url('css/login.css', 'admin')}" rel='stylesheet' type='text/css'> <link href="${make_media_url('css/login.css', 'admin')}" rel='stylesheet' type='text/css'>
@ -58,25 +58,25 @@
if(data.hasOwnProperty('disable')) { if(data.hasOwnProperty('disable')) {
$('#username_error').html("${lang('common', 'error_disabled', 'Error, your user is disabled, you need support of web administration')}"); $('#username_error').html("${_('Error, your user is disabled, you need support of web administration')}");
} if(data.hasOwnProperty('you_cannot_login')) { } if(data.hasOwnProperty('you_cannot_login')) {
if(data.you_cannot_login) { if(data.you_cannot_login) {
$('#username_error').html("${lang('common', 'error_tries_disabled', 'Error, excessive tries, wait some minutes for login again')}"); $('#username_error').html("${_('Error, excessive tries, wait some minutes for login again')}");
} }
else { else {
$('#username_error').html("${lang('common', 'error_login', 'Error, wrong username or password')}"); $('#username_error').html("${_('Error, wrong username or password')}");
} }
} }
else { else {
$('#username_error').html("${lang('common', 'error_login', 'Error, wrong username or password')}"); $('#username_error').html("${_('Error, wrong username or password')}");
} }
@ -96,20 +96,20 @@
<%block name="content"> <%block name="content">
<form id="login"> <form id="login">
<div id="title"> <div id="title">
${lang('admin', 'login', 'Paramecio Login')} ${_('Paramecio Login')}
</div> </div>
${forms|n} ${forms|n}
<div class="form"> <div class="form">
${lang('admin', 'remember_login', 'Remember login?')} <input type="checkbox" id="remember_login" name="remember_login" value="1"> ${_('Remember login?')} <input type="checkbox" id="remember_login" name="remember_login" value="1">
</div> </div>
<div id="submit_block"> <div id="submit_block">
<input type="submit" value="${lang('common', 'login', 'Login')}" class="submit" id="login_submit"/> <input type="submit" value="${_('Login')}" class="submit" id="login_submit"/>
<span id="loading">&nbsp;</span> <span id="loading">&nbsp;</span>
</div> </div>
% if yes_recovery_login: % if yes_recovery_login:
<div class="form"><a href="${url_for('.recovery_password')}">${lang('admin', 'recovery_password', 'Recovery password?')}</a></div> <div class="form"><a href="${url_for('.recovery_password')}">${_('Recovery password?')}</a></div>
% endif % endif
<div class="form">${lang('admin', 'remember_tries', 'Remember that only have 3 attempts')}</div> <div class="form">${_('Remember that only have 3 attempts')}</div>
</form> </form>
</%block> </%block>
</body> </body>

View file

@ -1,17 +1,17 @@
<%inherit file="login.phtml"/> <%inherit file="login.phtml"/>
<%block name="title">${lang('admin', 'login', 'Paramecio Login')}</%block> <%block name="title">${_('Paramecio Login')}</%block>
<%block name="content"> <%block name="content">
<form id="login"> <form id="login">
<div id="title"> <div id="title">
${lang('admin', 'login', 'Paramecio Login')} ${_('Paramecio Login')}
</div> </div>
<div class="form"> <div class="form">
<p align="center">${lang('admin', 'check_your_email', 'Check your email for get instructions for complete login with double auth or')} <a href="${url_for('.logout')}">logout</a> and login again with other user</p> <p align="center">${_('Check your email for get instructions for complete login with double auth or')} <a href="${url_for('.logout')}">logout</a> and login again with other user</p>
<p><label>${lang('admin', 'code', 'Code')} *</label><input type="text" class="" name="code" id="code_form" value="" /> <span class="error" id="code_error"></span></p> <p><label>${_('Code')} *</label><input type="text" class="" name="code" id="code_form" value="" /> <span class="error" id="code_error"></span></p>
${csrf_token()|n} ${csrf_token()|n}
</div> </div>
<div id="submit_block"> <div id="submit_block">
<input type="submit" value="${lang('common', 'send_code', 'Send code')}" class="submit" id="code_submit"/> <input type="submit" value="${_('Send code')}" class="submit" id="code_submit"/>
<span id="loading">&nbsp;</span> <span id="loading">&nbsp;</span>
</div> </div>
</form> </form>
@ -60,17 +60,17 @@
if(data.hasOwnProperty('disable')) { if(data.hasOwnProperty('disable')) {
$('#code_error').html("${lang('common', 'error_disabled', 'Error, your user is disabled, you need support of web administration')}"); $('#code_error').html("${_('Error, your user is disabled, you need support of web administration')}");
} else { } else {
$('#code_error').html("${lang('common', 'error_wrong_code', 'Error, wrong code')}"); $('#code_error').html("${_('Error, wrong code')}");
} }
if(data.you_cannot_login) { if(data.you_cannot_login) {
$('#code_error').html("${lang('common', 'error_tries_disabled', 'Error, excessive tries, wait some minutes for login again')}"); $('#code_error').html("${_('Error, excessive tries, wait some minutes for login again')}");
} }

View file

@ -48,16 +48,16 @@
}); });
</script> </script>
</%block> </%block>
<%block name="title">${lang('admin', 'sign_up', 'Paramecio Sign up')}</%block> <%block name="title">${_('Paramecio Sign up')}</%block>
<%block name="content"> <%block name="content">
<form id="login"> <form id="login">
<div id="title"> <div id="title">
${lang('admin', 'sign_up', 'Paramecio Sign up')} ${_('Paramecio Sign up')}
</div> </div>
${forms|n} ${forms|n}
<div id="result_register"></div> <div id="result_register"></div>
<div id="submit_block"> <div id="submit_block">
<input type="submit" value="${lang('common', 'sign_up', 'Sign up')}" class="submit" id="register_submit"/> <input type="submit" value="${_('Sign up')}" class="submit" id="register_submit"/>
<span id="loading">&nbsp;</span> <span id="loading">&nbsp;</span>
</div> </div>
</form> </form>

View file

@ -1,9 +1,9 @@
<%inherit file="dashboard.phtml"/> <%inherit file="dashboard.phtml"/>
<%block name="content"> <%block name="content">
<div class="title"> <div class="title">
Welcome to Paramecio Admin ${_('Welcome to Paramecio Admin')}
</div> </div>
<div class="cont"> <div class="cont">
From here you can admin your site ${_('From here you can admin your site')}
</div> </div>
</%block> </%block>

View file

@ -2,6 +2,11 @@
from settings import config from settings import config
from paramecio2.libraries.mtemplates import PTemplate, env_theme from paramecio2.libraries.mtemplates import PTemplate, env_theme
from paramecio2.modules.welcome import welcome_app from paramecio2.modules.welcome import welcome_app
from paramecio2.libraries.i18n import PGetText
pgettext=PGetText(__file__)
_=pgettext.gettext
env=env_theme(__file__) env=env_theme(__file__)
@ -10,7 +15,7 @@ t=PTemplate(env)
@welcome_app.route('/welcome') @welcome_app.route('/welcome')
def home(): def home():
return t.load_template('welcome.phtml', title="Welcome", content='Welcome to the real world') return t.load_template('welcome.phtml', title=_("Welcome"), content=_('Welcome to the real world'))
#return render_template('welcome.html', title="Welcome") #return render_template('welcome.html', title="Welcome")
""" """

View file

@ -72,7 +72,7 @@
${content} ${content}
</div> </div>
<div class="footer">Paramecio, a system created for create webapps</div> <div class="footer">${_('Paramecio, a system created for create webapps')}</div>
</div> </div>
</body> </body>