Added first files

This commit is contained in:
Antonio de la Rosa 2025-11-14 19:41:18 +01:00
commit d325960160
12 changed files with 510 additions and 0 deletions

104
.gitignore vendored Normal file
View file

@ -0,0 +1,104 @@
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
env/
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
*.egg-info/
.installed.cfg
*.egg
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
.hypothesis/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
target/
# Jupyter Notebook
.ipynb_checkpoints
# pyenv
.python-version
# celery beat schedule file
celerybeat-schedule
# SageMath parsed files
*.sage.py
# dotenv
.env
# virtualenv
.venv
venv/
ENV/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
# Images
media/images/editor

3
__init__.py Normal file
View file

@ -0,0 +1,3 @@
from flask import Blueprint, g, request, session, redirect, url_for
pages2_app=Blueprint('pages2_app', __name__)

0
admin/__init__.py Normal file
View file

77
admin/pages.py Normal file
View file

@ -0,0 +1,77 @@
import os
from paramecio2.libraries.generate_admin_class import GenerateAdminClass
#from paramecio2.libraries.db.adminutils import make_admin_url
#from paramecio.citoplasma.urls import make_url
from paramecio2.libraries.i18n import I18n
from settings import config
from modules.pages2.models import pages
from paramecio2.libraries.db.coreforms import BaseForm
from paramecio2.modules.admin import admin_app, t as admin_t
from flask import url_for, g
from paramecio2.libraries.mtemplates import env_theme, PTemplate
env=env_theme(__file__)
t=PTemplate(env)
t.env.directories=admin_t.env.directories
t.env.directories.insert(1, os.path.dirname(__file__).replace('/admin', '')+'/templates/admin')
@admin_app.route('/admin/pages2/', methods=['GET', 'POST'])
def admin_pages2():
#t=admin_t
conn=g.connection
page=pages.Page2(conn)
page.enctype=True
page.fields['slugify'].name_form=BaseForm
page.fields['text'].name_form=TextEditorJsForm
#page.fields['text'].extra_parameters[0].t=t
#url=make_admin_url('pages')
url=url_for('admin_app.admin_pages2')
admin=GenerateAdminClass(page, url, t)
admin.list.fields_showed=['id', 'title', 'slugify']
form_admin=admin.show()
#return admin.show()
if type(form_admin).__name__=='str':
return t.load_template('content.phtml', title=I18n.lang('pages', 'pages', 'Pages'), contents=form_admin, path_module='admin_app.admin_pages2')
else:
return form_admin
class TextEditorJsForm(BaseForm):
"""Form for html texts, based in tinycme javascript library"""
def __init__(self, name, value, t_add=None):
"""
Args:
name (str): The html name for this form
value (str): The default value of this html form.
t_add (PTemplate): If you want change the standard html form, use other template loader
"""
super().__init__(name, value)
self.t=t_add
if t_add==None:
self.t=t
def form(self):
return self.t.load_template('editorjsform.phtml', form=self)

133
app.py Normal file
View file

@ -0,0 +1,133 @@
#!/usr/bin/env python3
#from paramecio.wsgiapp import app
from paramecio2.libraries.mtemplates import PTemplate, env_theme
from modules.pages2.models.pages import Page2
from paramecio2.libraries.db.webmodel import WebModel
from settings import config
#from bottle import abort
from flask import abort, request
from modules.pages2 import pages2_app
from paramecio2.libraries.db.coreforms import BaseForm
from paramecio2.libraries.mtemplates import env_theme, PTemplate
from paramecio2.libraries.urls import make_media_url
import os
from werkzeug.utils import secure_filename
import pathlib
try:
import ujson as json
except:
import json
env=env_theme(__file__)
t=PTemplate(env)
pages_modules_to_search=[]
if hasattr(config, 'pages_modules_to_search'):
pages_modules_to_search=config.pages_modules_to_search
for mod in pages_modules_to_search:
t.env.directories.insert(0, mod.replace('.', '/')+'/templates')
@pages2_app.route('/page/<int:page_id>/')
@pages2_app.route('/page/<path:slug>/')
def pages2_home(page_id=0, slug=''):
conn=WebModel.connection()
page=Page2(conn)
page.show_formatted=True
if page_id:
page.set_conditions('WHERE id=%s', [page_id])
if slug:
page.set_conditions('WHERE slugify=%s', [slug])
arr_page=page.select_a_row_where()
conn.close()
if arr_page:
arr_final_text=[]
arr_text=json.loads(arr_page['text'])
#print(arr_text)
"""
for jtext in arr_text['blocks']:
#{'id': 'Vp0iLVnqq4', 'type': 'image', 'data': {'caption': 'Hi my friends', 'withBorder': False, 'withBackground': False, 'stretched': False, 'file': {'url': '/mediafrom/pages2/images/editor/33abad83-a37b-4d74-b83d-ba7283f0f952.jpg'}}}
#if jtext['type']=='paragraph':
# arr_final_text.append('<p>'+jtext['data']['text']+'</p>')
match jtext['type']:
case 'paragraph':
arr_final_text.append('<p>'+jtext['data']['text']+'</p>')
case 'image':
arr_final_text.append('<p align="center"><img src="{}" style="width:50%;" title="{}" /><br /><strong>{}</strong></p>'.format(jtext['data']['file']['url'], jtext['data']['caption'], jtext['data']['caption']))
"""
return t.load_template('page.phtml', title_page=arr_page['title'], content_page=arr_text)
else:
abort(404)
@pages2_app.route('/pages/upload_image/', methods=['POST'])
def pages2_upload_image():
"""
{
"success" : 1,
"file": {
"url" : "https://www.tesla.com/tesla_theme/assets/img/_vehicle_redesign/roadster_and_semi/roadster/hero.jpg",
// ... and any additional fields you want to store, such as width, height, color, extension, etc
}
}
"""
#print(request.files.keys())
success=0
new_url=''
if 'image' in request.files:
file=request.files['image']
images_dir='./modules/pages2/media/images/editor'
if not os.path.isdir(images_dir):
#os.mkdir(images_dir)
pathlib.Path(images_dir).mkdir(0o755, True)
filename=secure_filename(file.filename)
file.save(os.path.join(images_dir, filename))
success=1
new_url=make_media_url('images/editor/'+filename, 'pages2')
print({'success': success, 'file': {'url': new_url}})
return {'success': success, 'file': {'url': new_url}}
@pages2_app.route('/home/')
def pages_home():
return ""
if config.default_module=="pages2":
home=pages2_app.route("/")(pages2_home)

51
media/js/editorjs.umd.js Normal file

File diff suppressed because one or more lines are too long

30
media/js/image.umd.js Normal file

File diff suppressed because one or more lines are too long

42
models/pages.py Normal file
View file

@ -0,0 +1,42 @@
from paramecio2.libraries.db.extrafields.i18nfield import I18nHTMLField, I18nField
from paramecio2.libraries.db.extrafields.jsonfield import JsonField, JsonValueField
from paramecio2.libraries.db.extrafields.slugifyfield import SlugifyField
from paramecio2.libraries.db.webmodel import WebModel
from paramecio2.libraries.db.extraforms.texthtmlform import TextHTMLForm
from paramecio2.libraries.db import corefields
from paramecio2.libraries.i18n import I18n
import json
class Page2(WebModel):
def create_fields(self):
self.register(corefields.HTMLField('title'), True)
#self.register(I18nHTMLField('text', TextHTMLForm('text', '')), True)
self.register(JsonValueField('text'), True)
self.register(SlugifyField('slugify'), True)
"""
def insert(self, dict_values, external_agent=True):
slugify=json.loads(dict_values.get('title', '{}'))
lang=I18n.get_default_lang()
dict_values['slugify']=slugify.get(lang, '')
return super().insert(dict_values, external_agent)
def update(self, dict_values, external_agent=True):
slugify=json.loads(dict_values.get('title', '{}'))
lang=I18n.get_default_lang()
dict_values['slugify']=slugify.get(lang, '')
return super().update(dict_values, external_agent)
"""

0
settings/__init__.py Normal file
View file

13
settings/config_admin.py Normal file
View file

@ -0,0 +1,13 @@
from paramecio2.libraries.i18n import I18n, load_lang
from paramecio2.libraries.config_admin import config_admin
#from modules.pokermind.i18n import runchained
#modules_other=[I18n.lang('pages', 'pages', 'Pages'), 'modules.pages.admin.pages', 'pages']
#modules_admin.append(modules_other)
config_admin.append([_('Pages Editor')])
config_admin.append([_('Edit pages'), 'modules.pages2.admin.pages', 'admin_app.admin_pages2'])

View file

@ -0,0 +1,41 @@
<p>
<div id="${form.name_field_id}_editor" style="background: #454545; color: #fbfbfb;">
</div>
<input type="hidden" name="${form.name}" id="${form.name_field_id}" />
</p>
<script>
const editor = new EditorJS( {holder : '${form.name_field_id}_editor', data: ${form.default_value|n} ,
tools: {
image: {
class: ImageTool,
config: {
endpoints: {
byFile: "${url_for('pages2_app.pages2_upload_image')}", // Your backend file uploader endpoint
//byUrl: "${url_for('pages2_app.pages2_upload_image')}", // Your endpoint that provides uploading by Url
}
}
}
}
}
);
$('form').submit(function (e) {
editor.save().then((outputData) => {
console.log('Article data: ', outputData)
$('#${form.name_field_id}').val(JSON.stringify(outputData));
}).catch((error) => {
console.log('Saving failed: ', error)
});
});
</script>
${add_js('editorjs.umd.js', 'pages2')}
${add_js('image.umd.js', 'pages2')}

16
templates/page.phtml Normal file
View file

@ -0,0 +1,16 @@
<div class="title">${title_page}</div>
<div class="content">
% for jtext in content_page['blocks']:
% if jtext['type']=='paragraph':
<p>${jtext['data']['text']|n}</p>
% elif jtext['type']=='image':
<p align="center"><img src="${jtext['data']['file']['url']}" style="width:50%;" title="${jtext['data']['caption']}" /><br /><strong>${jtext['data']['caption']|n}</strong></p>
% endif
% endfor
</div>