You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
cms/cms/index.py

275 lines
8.3 KiB
Python

__doc__ = """
arguments :
--config path of the configuration otherwise it will look for the default in the working directory
"""
from flask import Flask,render_template,send_from_directory,request, redirect, Response, session
import flask
import transport
from transport import providers
import cms
from cms import Plugin
import sys
import os
import json
import copy
import io
import base64
from jinja2 import Environment, BaseLoader
import typer
from typing_extensions import Annotated
from typing import Optional
import pandas as pd
import uuid
import datetime
import requests
from cms import disk, cloud, engine
_app = Flask(__name__)
cli = typer.Typer()
@_app.route('/favicon.ico')
@_app.route('/<id>/favicon.ico')
def favicon(id):
global _route
# _system = _route.get ().system()
# _handler = _route.get()
_handler = _getHandler(id)
_system = _handler.system()
_logo =_system['icon'] #if 'icon' in _system else 'static/img/logo.svg'
_stream = requests.get(''.join([request.host_url,_logo]))
return "_stream",200,{"Content-Type":"image/png"} #_handler.get(_logo),200,{"content-type":"image/png"}
def _getHandler (app_id,resource=None) :
global _route
_id = _getId(app_id,resource)
return _route._apps[_id]
def _getId(app_id,app_x):
if app_x not in [None,''] :
return '/'.join([app_id,app_x])
return app_id
def _setHandler (app_id,resource) :
session['app_id'] = _getId(app_id,resource)
@_app.route("/robots.txt")
def robots_txt():
"""
This function will generate a robots expression for a variety of crawlers, the paths will be provided by
menu options
"""
global _route
_system = _route.get ().system()
_info = ['''
User-agent: *
Allow: /
''']
if 'routes' in _system :
for _key in _system['routes'] :
_uri = '/'.join(['',_key])
_info.append(f'''
User-agent: *
Allow: {_uri}
''')
# return '\n'.join(_info),200,{'Content-Type':'plain/text'}
return Response('\n'.join(_info), mimetype='text/plain')
def _getIndex (app_id ,resource=None):
_handler = _getHandler(app_id,resource)
_layout = _handler.layout()
_status_code = 200
global _route
_index_page = 'index.html'
_args = {}
try :
_uri = os.sep.join([_layout['root'],_layout['index']])
_id = _getId(app_id,resource)
_args = _route.render(_uri,'index',_id)
except Exception as e:
_status_code = 404
_index_page = '404.html'
print(e)
return render_template(_index_page,**_args),_status_code
@_app.route("/")
def _index ():
return _getIndex('main')
@_app.route("/<app>/<resource>")
@_app.route("/<app>",defaults={'resource':None})
def _aindex (app,resource=None):
_handler = _getHandler(app,resource)
_setHandler(app,resource)
_html,_code = _getIndex(app,resource)
return _html,_code
# @_app.route('/id/<uid>')
# def people(uid):
# """
# This function will implement hardened links that can directly "do something"
# """
# global _config
# return "0",200
@_app.route('/<app>/dialog')
@_app.route('/dialog',defaults={'app':'main'})
def _dialog (app):
# global _config
global _route
_handler = _route.get()
_uri = request.headers['uri']
_id = request.headers['dom']
# _html = ''.join(["<div style='padding:1%'>",str( e.render(**_args)),'</div>'])
_args = _route.render(_uri,'html',app) #session.get('app_id','main'))
_args['title'] = _id
return render_template('dialog.html',**_args) #title=_id,html=_html)
@_app.route("/api/<module>/<name>",defaults={'app':'main','key':None},methods=['GET','POST','DELETE','PUT'])
@_app.route("/<app>/api/<module>/<name>",defaults={'key':None},methods=['GET','POST','DELETE','PUT'])
@_app.route("/<app>/<key>/api/<module>/<name>",methods=['GET','POST','DELETE','PUT'])
def _delegate_call(app,key,module,name):
_handler = _getHandler(app,key)
# print (_handler.config()/)
uri = f'api/{module}/{name}'
# return Plugin.call(uri=uri,handler=_handler,request=request)
_delegate = cms.delegate()
return _delegate(uri=uri,handler=_handler,request=request)
@_app.route('/version')
def _version ():
global _route
_handler = _route.get()
global _config
return _handler.system()['version']
@_app.route("/reload/<key>")
def _reload(key) :
global _route
_handler = _route.get_main()
_system = _handler.system()
if not 'source' in _system :
_systemKey = None
elif 'key' in _system['source'] and _system['source']['key']:
_systemKey = _system['source']['key']
# print ([key,_systemKey,_systemKey == key])
if key and _systemKey and _systemKey == key :
_handler.reload()
return "",200
pass
return "",403
@_app.route('/reload',methods=['POST'])
def reload():
# global _route
# _handler = _route.get_main()
# _system = _handler.system()
_key = request.headers['key'] if 'key' in request.headers else None
return _reload(_key)
# if not 'source' in _system :
# _systemKey = None
# elif 'key' in _system['source'] and _system['source']['key']:
# _systemKey = _system['source']['key']
# print ([_key,_systemKey,_systemKey == _key])
# if _key and _systemKey and _systemKey == _key :
# _handler.reload()
# return "",200
# pass
# return "",403
@_app.route('/page',methods=['POST'],defaults={'app_id':'main','key':None})
@_app.route('/<app_id>/page',methods=['POST'],defaults={'key':None})
@_app.route('/<app_id>/<key>/page',methods=['POST'])
def _POST_CMSPage(app_id,key):
"""
return the content of a folder formatted for a menu
"""
# global _config
global _route
# _handler = _route.get()
# _config = _handler.config()
_handler = _getHandler(app_id,key)
_setHandler(app_id,key)
_config = _handler.config()
# _uri = os.sep.join([_config['layout']['root'],request.headers['uri']])
_uri = request.headers['uri']
if 'dom' not in request.headers :
_id = _uri.split('/')[-1].split('.')[0]
else:
_id = request.headers['dom']
if 'read?uri=' in _uri or 'download?doc=' in _uri :
_uri = _uri.split('=')[1]
_args = _route.render(_uri,_id,_getId(app_id,key)) #session.get(app_id,'main'))
return _args[_id],200
# return _html,200
@_app.route('/page',defaults={'app_id':'main','resource':None})
@_app.route('/<app_id>/page',defaults={'resource':None},methods=['GET'])
@_app.route('/<app_id>/<resource>/page',methods=['GET'])
def _cms_page (app_id,resource):
# global _config
global _route
# _handler = _route.get()
# _config = _handler.config()
_uri = request.args['uri']
# _uri = os.sep.join([_config['layout']['root'],_uri])
_title = request.args['title'] if 'title' in request.args else ''
_args = _route.render(_uri,_title,session.get(app_id,'main'))
return _args[_title],200
@cli.command()
def start (
path:Annotated[str,typer.Argument(help="path of the manifest file")]='qcms-manifest.json',
port:int=typer.Option(default=None, help="port number to serve on (will override configuration)")
) :
"""
This function is designed to start the application with its associated manifest (configuration) location
:path path to the the manifest
:shared run in shared mode i.e
"""
global _route
if os.path.exists(path) and os.path.isfile(path):
_args = {'path':path}
# if shared :
# _args['location'] = path
# _args['shared'] = shared
_args['location'] = path
_args['shared'] = True
# _route = cms.engine.Router(**_args) #path=path,shared=shared)
_route = cms.engine.basic.CMS(**_args)
# dir(_route)
# _args = _route.get().get_app()
_args = _route.get().app()
if port :
_args['port'] = port
_app.secret_key = str(uuid.uuid4())
_app.config['PERMANENT_SESSION_LIFETIME'] = datetime.timedelta(hours=24)
_app.run(**_args)
_status = 'found'
else:
_status = 'not found'
print(f'''
manifest: {path}
status : {_status}
''')
@cli.command(name='help')
def _help() :
pass
if __name__ == '__main__' :
cli()