Added first files for admin and login/signup in admin

This commit is contained in:
Antonio de la Rosa 2020-01-25 23:57:17 +01:00
parent e0ed00af8c
commit d9b62719d7
139 changed files with 18408 additions and 4 deletions

View 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

View 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;

View 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)

View 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'

View 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)

View 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

View 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)

View 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)

View 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)

View 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

View 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

View 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)

View 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

View 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:
"""

View 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

View 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

View 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

View 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