Added first files
This commit is contained in:
commit
d325960160
12 changed files with 510 additions and 0 deletions
104
.gitignore
vendored
Normal file
104
.gitignore
vendored
Normal 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
3
__init__.py
Normal 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
0
admin/__init__.py
Normal file
77
admin/pages.py
Normal file
77
admin/pages.py
Normal 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
133
app.py
Normal 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
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
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
42
models/pages.py
Normal 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
0
settings/__init__.py
Normal file
13
settings/config_admin.py
Normal file
13
settings/config_admin.py
Normal 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'])
|
||||||
41
templates/admin/editorjsform.phtml
Normal file
41
templates/admin/editorjsform.phtml
Normal 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
16
templates/page.phtml
Normal 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>
|
||||||
Loading…
Add table
Add a link
Reference in a new issue