Compare commits
10 commits
a2bd05536f
...
edf9b1bd30
| Author | SHA1 | Date | |
|---|---|---|---|
| edf9b1bd30 | |||
| faf4c14e2b | |||
| 65ddc6f32f | |||
| e874bace60 | |||
| 7f1a3adf22 | |||
| deeec158d6 | |||
| bc05d7725e | |||
| a741e51a76 | |||
| 2f3ee90e26 | |||
| de51f0356f |
16 changed files with 179 additions and 118 deletions
|
|
@ -1,4 +1,4 @@
|
|||
from flask import Flask, session, url_for, escape, request, send_file, abort
|
||||
from flask import Flask, session, url_for, request, send_file, abort
|
||||
from settings import config
|
||||
from importlib import import_module
|
||||
import os
|
||||
|
|
@ -24,11 +24,15 @@ def start_app():
|
|||
application_root='/'
|
||||
|
||||
if hasattr(config, 'application_root'):
|
||||
#print(config.application_root)
|
||||
application_root=config.application_root
|
||||
|
||||
|
||||
app.config.update(
|
||||
APPLICATION_ROOT=application_root
|
||||
)
|
||||
|
||||
#app.config['APPLICATION_ROOT']=application_root
|
||||
|
||||
if hasattr(config, 'json_sort_keys'):
|
||||
app.config.update(
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import re
|
|||
from pathlib import Path
|
||||
from base64 import b64encode
|
||||
from paramecio2.libraries.db.webmodel import WebModel
|
||||
from paramecio2.modules.admin.models.admin import UserAdmin
|
||||
from paramecio2.modules.admin.models.admin import UserAdmin, LoginTries
|
||||
from subprocess import call
|
||||
from urllib.parse import urlparse
|
||||
|
||||
|
|
@ -80,49 +80,7 @@ def start():
|
|||
|
||||
print('Error: cannot copy the file index.py to app.py. Check if exists and if you have permissions for this task')
|
||||
|
||||
"""
|
||||
try:
|
||||
|
||||
shutil.copy(workdir+'/frontend/padmin.py', args.path+'/padmin.py')
|
||||
|
||||
except:
|
||||
|
||||
print('Error: cannot copy the file padmin.py. Check if exists and if you have permissions for this task')
|
||||
|
||||
try:
|
||||
|
||||
shutil.copy(workdir+'/frontend/i18nadmin.py', args.path+'/i18nadmin.py')
|
||||
|
||||
except:
|
||||
|
||||
print('Error: cannot copy the file i18nadmin.py. Check if exists and if you have permissions for this task')
|
||||
|
||||
try:
|
||||
|
||||
shutil.copy(workdir+'/frontend/regenerate.py', args.path+'/regenerate.py')
|
||||
|
||||
except:
|
||||
|
||||
print('Error: cannot copy the file regenerate.py. Check if exists and if you have permissions for this task')
|
||||
|
||||
try:
|
||||
|
||||
shutil.copy(workdir+'/frontend/create_module.py', args.path+'/create_module.py')
|
||||
|
||||
except:
|
||||
|
||||
print('Error: cannot copy the file create_module.py. Check if exists and if you have permissions for this task')
|
||||
|
||||
|
||||
try:
|
||||
|
||||
shutil.copy(workdir+'/settings/modules.py', path_settings+'/modules.py')
|
||||
|
||||
except:
|
||||
|
||||
print('Error: cannot copy the file modules.py. Check if exists and if you have permissions for this task')
|
||||
|
||||
"""
|
||||
|
||||
if args.symlink==True:
|
||||
try:
|
||||
os.symlink(workdir, args.path+'/paramecio2', True)
|
||||
|
|
@ -178,6 +136,15 @@ def start():
|
|||
|
||||
conf=conf.replace("domain_url='http://localhost:5000'", "domain_url='"+domain_url+"'")
|
||||
|
||||
# Question about email
|
||||
|
||||
e_q=input('Email for site: ')
|
||||
|
||||
conf=conf.replace("no-reply@example.com", e_q)
|
||||
|
||||
#if e_q=='':
|
||||
|
||||
|
||||
#domain_url='http://localhost:8080'
|
||||
|
||||
with open(path_settings+'/config.py', 'w') as f:
|
||||
|
|
@ -225,6 +192,7 @@ def start():
|
|||
conn=WebModel.connection()
|
||||
|
||||
useradmin=UserAdmin(conn)
|
||||
logintries=LoginTries(conn)
|
||||
|
||||
# Check if db exists
|
||||
|
||||
|
|
@ -261,6 +229,9 @@ def start():
|
|||
print('Error: cannot create table admin, you can create this table with padmin.py')
|
||||
else:
|
||||
|
||||
sql_login=logintries.create_table()
|
||||
logintries.query(sql_login)
|
||||
|
||||
# Add admin module to config
|
||||
with open(path_settings+'/config.py', 'r') as f:
|
||||
|
||||
|
|
|
|||
|
|
@ -664,6 +664,15 @@ class TimeClass:
|
|||
"""
|
||||
|
||||
return self.t.format(self.format_date_full)
|
||||
|
||||
def format_datetime(self):
|
||||
"""Method for get datetime formatted using format_time attribute
|
||||
|
||||
Returns:
|
||||
Datetime formatted with format_time attribute
|
||||
"""
|
||||
|
||||
return self.t.format(self.format_time)
|
||||
|
||||
def local_to_utc(self):
|
||||
"""Method for convert datetime from actual timezone to UTC"""
|
||||
|
|
|
|||
|
|
@ -172,6 +172,20 @@ class TextField(PhangoField):
|
|||
|
||||
return 'TEXT '+self.set_default
|
||||
|
||||
class LongTextField(TextField):
|
||||
"""Class used for long text fields (32 bits size, 4G)
|
||||
|
||||
Class used for text fields, use LONGTEXT sql type for the this field.
|
||||
"""
|
||||
|
||||
def get_type_sql(self):
|
||||
|
||||
"""Method for return the sql code for this type
|
||||
|
||||
"""
|
||||
|
||||
return 'LONGTEXT '+self.set_default
|
||||
|
||||
class HTMLField(TextField):
|
||||
"""Class used for html fields
|
||||
|
||||
|
|
|
|||
|
|
@ -42,12 +42,13 @@ class BaseForm:
|
|||
self.error=False
|
||||
self.name_field_id=self.name+'_form'
|
||||
self.help=''
|
||||
self.placeholder=''
|
||||
|
||||
def form(self):
|
||||
"""Method for returm the html code of the form
|
||||
"""
|
||||
|
||||
return '<input type="'+self.type+'" class="'+self.css+'" name="'+self.name+'" id="'+self.name_field_id+'" value="'+self.setform(self.default_value)+'" />'
|
||||
return '<input type="'+self.type+'" class="'+self.css+'" name="'+self.name+'" id="'+self.name_field_id+'" value="'+self.setform(self.default_value)+'" placeholder="'+self.placeholder+'" />'
|
||||
|
||||
def show_formatted(self, value):
|
||||
"""Method for show the value of form formatted
|
||||
|
|
|
|||
|
|
@ -26,16 +26,17 @@ class DateTimeField(PhangoField):
|
|||
value=datetime.local_to_gmt(value)
|
||||
|
||||
elif not datetime.obtain_timestamp(value):
|
||||
|
||||
|
||||
self.error=True
|
||||
self.txt_error=self.error_default
|
||||
return ''
|
||||
|
||||
return '0000-00-00 00:00:00'
|
||||
|
||||
if value==False:
|
||||
|
||||
self.error=True
|
||||
self.txt_error=self.error_default
|
||||
return ''
|
||||
return '0000-00-00 00:00:00'
|
||||
else:
|
||||
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -5,8 +5,10 @@ from paramecio2.libraries.db.corefields import CharField
|
|||
from paramecio2.libraries.db.extraforms.fileform import FileForm
|
||||
from paramecio2.libraries.keyutils import create_key
|
||||
import traceback
|
||||
from flask import request
|
||||
from werkzeug.utils import secure_filename
|
||||
|
||||
from bottle import request
|
||||
# from bottle import request
|
||||
try:
|
||||
from PIL import Image
|
||||
except:
|
||||
|
|
@ -63,61 +65,67 @@ class ImageField(CharField):
|
|||
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 field_file in files_uploaded:
|
||||
|
||||
if files_uploaded[field_file].filename=='':
|
||||
|
||||
if self.model:
|
||||
if value=='':
|
||||
|
||||
if self.model.updated:
|
||||
if self.model:
|
||||
|
||||
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 ''
|
||||
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
|
||||
else:
|
||||
|
||||
value=os.path.basename(value)
|
||||
|
||||
return self.save_folder+'/'+value
|
||||
else:
|
||||
|
||||
value=os.path.basename(value)
|
||||
|
||||
return self.save_folder+'/'+value
|
||||
|
||||
# Load image file
|
||||
|
||||
file_bytecode=files_uploaded[field_file].file
|
||||
#file_bytecode=files_uploaded[field_file].file
|
||||
|
||||
filename=files_uploaded[field_file].filename
|
||||
filename=secure_filename(files_uploaded[field_file].filename)
|
||||
|
||||
try:
|
||||
|
||||
im=Image.open(file_bytecode)
|
||||
im=Image.open(files_uploaded[field_file])
|
||||
|
||||
except IOError:
|
||||
|
||||
|
|
|
|||
|
|
@ -72,6 +72,7 @@ class JsonValueField(PhangoField):
|
|||
super().__init__(name, required)
|
||||
|
||||
self.error_default='Sorry, the json dict is invalid'
|
||||
self.default_value={}
|
||||
|
||||
#self.set_default='NOT NULL'
|
||||
|
||||
|
|
@ -86,7 +87,7 @@ class JsonValueField(PhangoField):
|
|||
|
||||
except json.JSONDecodeError:
|
||||
|
||||
final_value={}
|
||||
final_value='{}'
|
||||
self.error=True
|
||||
self.txt_error=self.error_default
|
||||
|
||||
|
|
|
|||
|
|
@ -72,6 +72,8 @@ class GenerateAdminClass:
|
|||
|
||||
self.url_redirect=self.url
|
||||
|
||||
self.pre_update=None
|
||||
|
||||
self.post_update=None
|
||||
|
||||
self.text_home=I18n.lang('common', 'home', 'Home')
|
||||
|
|
@ -131,6 +133,13 @@ class GenerateAdminClass:
|
|||
|
||||
insert_row=self.model.insert
|
||||
|
||||
pre_update_ret=False
|
||||
|
||||
if not self.pre_update:
|
||||
pre_update_ret=True
|
||||
else:
|
||||
pre_update_ret=self.pre_update(self)
|
||||
|
||||
try:
|
||||
|
||||
item_id=str(int(request.args.get('id', '0')))
|
||||
|
|
@ -149,21 +158,36 @@ class GenerateAdminClass:
|
|||
|
||||
post=dict(request.form)
|
||||
|
||||
if insert_row(post):
|
||||
flash(I18n.lang('common', 'task_successful', 'Task successful'))
|
||||
|
||||
if self.post_update:
|
||||
if item_id=='0':
|
||||
item_id=self.model.insert_id()
|
||||
self.post_update(self, item_id)
|
||||
|
||||
return redirect(self.url_redirect)
|
||||
if pre_update_ret:
|
||||
|
||||
if insert_row(post):
|
||||
flash(I18n.lang('common', 'task_successful', 'Task successful'))
|
||||
|
||||
if self.post_update:
|
||||
if item_id=='0':
|
||||
item_id=self.model.insert_id()
|
||||
self.post_update(self, item_id)
|
||||
|
||||
return redirect(self.url_redirect)
|
||||
|
||||
else:
|
||||
|
||||
url_action=add_get_parameters(self.url, op_admin=2, id=item_id)
|
||||
|
||||
post=dict(request.form)
|
||||
|
||||
form=show_form(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=item_id, url_action=url_action, enctype=self.model.enctype)
|
||||
|
||||
|
||||
else:
|
||||
url_action=add_get_parameters(self.url, op_admin=2, id=item_id)
|
||||
|
||||
post=dict(request.form)
|
||||
|
||||
form=show_form(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=item_id, url_action=url_action, enctype=self.model.enctype)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
from flask import g
|
||||
from flask import g, session, redirect, url_for
|
||||
from functools import wraps
|
||||
from paramecio2.libraries.db.webmodel import WebModel
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ from paramecio2.modules.admin.models.admin import UserAdmin
|
|||
from paramecio2.libraries.generate_admin_class import GenerateAdminClass
|
||||
from paramecio2.libraries.i18n import I18n
|
||||
from paramecio2.libraries.db.coreforms import SelectForm
|
||||
from paramecio2.libraries.db.coreforms import HiddenForm
|
||||
import copy
|
||||
from paramecio2.modules.admin import admin_app, t as admin_t
|
||||
|
||||
|
|
@ -22,7 +23,9 @@ def ausers():
|
|||
|
||||
user_admin.fields['double_auth'].name_form=SelectForm
|
||||
|
||||
user_admin.create_forms(['username', 'password', 'email', 'privileges', 'lang', 'disabled', 'double_auth'])
|
||||
user_admin.fields['last_login'].name_form=HiddenForm
|
||||
|
||||
user_admin.create_forms(['username', 'password', 'email', 'privileges', 'lang', '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')}
|
||||
|
||||
|
|
@ -43,7 +46,7 @@ def ausers():
|
|||
|
||||
admin.list.search_fields=['username']
|
||||
|
||||
admin.arr_fields_edit=['username', 'password', 'repeat_password', 'email', 'lang', 'double_auth', 'disabled']
|
||||
admin.arr_fields_edit=['username', 'password', 'repeat_password', 'email', 'lang', 'double_auth', 'disabled', 'last_login']
|
||||
|
||||
form_admin=admin.show()
|
||||
|
||||
|
|
|
|||
|
|
@ -239,6 +239,8 @@ def login():
|
|||
|
||||
#user_admin.set_conditions('WHERE id=%s', [arr_user['id']]).update({'token_auth': token_auth})
|
||||
|
||||
user_admin.fields['token_auth'].protected=False
|
||||
|
||||
arr_update['token_auth']=token_auth
|
||||
|
||||
# Send email
|
||||
|
|
@ -303,7 +305,9 @@ def signup():
|
|||
|
||||
forms['privileges']=2
|
||||
|
||||
user_admin.valid_fields=['username', 'email', 'password', 'privileges']
|
||||
forms['last_login']=now()
|
||||
|
||||
user_admin.valid_fields=['username', 'email', 'password', 'privileges', 'last_login']
|
||||
|
||||
user_admin.create_forms()
|
||||
|
||||
|
|
@ -357,6 +361,8 @@ def auth_check():
|
|||
|
||||
check_csrf()
|
||||
|
||||
you_cannot_login=0
|
||||
|
||||
if 'login_admin' in session:
|
||||
|
||||
code=request.form.get('code', '')
|
||||
|
|
@ -365,23 +371,35 @@ def auth_check():
|
|||
|
||||
user_admin.check_user=False
|
||||
|
||||
c=user_admin.set_conditions('WHERE id=%s AND token_auth=%s', [session['user_id'], code]).select_count()
|
||||
arr_user=user_admin.set_conditions('WHERE id=%s', [session.get('user_id', 0)]).select_a_row_where()
|
||||
|
||||
if c==1:
|
||||
if arr_user:
|
||||
|
||||
user_admin.safe_query()
|
||||
if user_admin.fields['token_auth'].verify(code, arr_user['token_auth']):
|
||||
|
||||
user_admin.set_conditions('WHERE id=%s', [session['user_id']]).update({'token_auth': ''})
|
||||
user_admin.safe_query()
|
||||
|
||||
user_admin.set_conditions('WHERE id=%s', [session['user_id']]).update({'token_auth': ''})
|
||||
|
||||
session['verify_auth']=True
|
||||
error=0
|
||||
|
||||
else:
|
||||
|
||||
session['verify_auth']=True
|
||||
error=0
|
||||
you_cannot_login=check_login_tries()
|
||||
|
||||
else:
|
||||
|
||||
you_cannot_login=check_login_tries()
|
||||
|
||||
return {'error': error}
|
||||
return {'error': error, 'you_cannot_login': you_cannot_login}
|
||||
|
||||
"""
|
||||
@admin_app.route('/admin/recovery_password/')
|
||||
def recovery_password():
|
||||
|
||||
return ""
|
||||
"""
|
||||
|
||||
def check_login_tries():
|
||||
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ class UserAdmin(UserModel):
|
|||
|
||||
self.register(corefields.CharField('token_login'))
|
||||
|
||||
self.register(corefields.CharField('token_auth'))
|
||||
self.register(PasswordField('token_auth'))
|
||||
|
||||
self.register(PrivilegesField('privileges'))
|
||||
|
||||
|
|
|
|||
|
|
@ -38,7 +38,8 @@ ${load_js()|n}
|
|||
|
||||
portal_admin_name_set=('Paramecio', 'Framework!')
|
||||
|
||||
#if hasattr(config, 'portal_admin_name_set'):
|
||||
if hasattr(config, 'portal_admin_name_set'):
|
||||
portal_admin_name_set=('Paramecio', 'Framework!')
|
||||
|
||||
%>
|
||||
<span id="title_phango">${portal_admin_name_set[0]}</span> <span id="title_framework">${portal_admin_name_set[1]}</span>
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@
|
|||
}
|
||||
else
|
||||
{
|
||||
$('#code_submit').prop('disabled', true);
|
||||
$('#code_submit').prop('disabled', false);
|
||||
|
||||
// Firefox have a horrible and stupid bug and you need attr for set de new csrf_token
|
||||
|
||||
|
|
@ -68,6 +68,12 @@
|
|||
|
||||
}
|
||||
|
||||
if(data.you_cannot_login) {
|
||||
|
||||
$('#code_error').html("${lang('common', 'error_tries_disabled', 'Error, excessive tries, wait some minutes for login again')}");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
|
|
|||
14
setup.py
14
setup.py
|
|
@ -5,15 +5,15 @@ import os
|
|||
from setuptools import setup, find_packages
|
||||
|
||||
|
||||
if sys.version_info < (3, 6):
|
||||
raise NotImplementedError("Sorry, you need at least Python 3.6 for use paramecio2.")
|
||||
if sys.version_info < (3, 8):
|
||||
raise NotImplementedError("Sorry, you need at least Python 3.8 for use paramecio2.")
|
||||
|
||||
#import paramecio
|
||||
# Pillow should be installed after if you need ImageField
|
||||
# If you install passlib and bcrypt, the password system will use bcrypt by default, if not, will use native crypt libc
|
||||
|
||||
setup(name='paramecio2',
|
||||
version='2.0.21',
|
||||
version='2.0.27',
|
||||
description='Simple Web Framework based in flask and Mako.',
|
||||
long_description='This framework is a simple framework used for create web apps. Paramecio is modular and fast. By default have a module called admin that can be used for create admin sites',
|
||||
author='Antonio de la Rosa Caballero',
|
||||
|
|
@ -38,9 +38,9 @@ setup(name='paramecio2',
|
|||
'Topic :: Internet :: WWW/HTTP :: WSGI :: Server',
|
||||
'Topic :: Software Development :: Libraries :: Application Frameworks',
|
||||
'Programming Language :: Python :: 3',
|
||||
'Programming Language :: Python :: 3.5',
|
||||
'Programming Language :: Python :: 3.6',
|
||||
'Programming Language :: Python :: 3.7',
|
||||
'Programming Language :: Python :: 3.6'
|
||||
'Programming Language :: Python :: 3.8'
|
||||
'Programming Language :: Python :: 3.9'
|
||||
'Programming Language :: Python :: 3.10'
|
||||
'Programming Language :: Python :: 3.11'
|
||||
],
|
||||
)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue