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/index.py

315 lines
9.4 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
import flask
import transport
from transport import providers
import cms
import sys
import os
import json
import copy
import io
import base64
from jinja2 import Environment, BaseLoader
import typer
import pandas as pd
_app = Flask(__name__)
cli = typer.Typer()
# @_app.route('/favicon.ico')
# def favicon():
# global _route
# _system = _route.get ().system()
# _handler = _route.get()
# _logo =_system['icon'] if 'icon' in _system else 'static/img/logo.svg'
# return _handler.get(_logo)
# # # _root = _route.get().config()['layout']['root']
# # # print ([_system])
# # # if 'source' in _system and 'id' in _system['source'] and (_system['source']['id'] == 'cloud'):
# # # uri = f'/api/cloud/downloads?doc=/{_logo}'
# # # print (['****' , uri])
# # # return redirect(uri,200) #,{'content-type':'application/image'}
# # # else:
# # # return send_from_directory(_root, #_app.root_path, 'static/img'),
# # _logo, mimetype='image/vnd.microsoft.icon')
@_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')
@_app.route("/")
def _index ():
global _config
global _route
_handler = _route.get()
_config = _route.config()
# _config = _handler.config()
# _system = _handler.system()
# _plugins= _handler.plugins()
# _args = {}
# # if 'plugins' in _config :
# # _args['routes']=_config['plugins']
# # _system = cms.components.get_system(_config) #copy.deepcopy(_config['system'])
# _html = ""
_args={'system':_handler.system(skip=['source','app','data']),'layout':_handler.layout()}
try:
uri = os.sep.join([_config['layout']['root'], _config['layout']['index']])
# # _html = _route.get().html(uri,'index',_config,_system)
# _html = _handler.html(uri,'index')
_index_page = "index.html"
_args = _route.render(uri,'index')
except Exception as e:
# print ()
print (e)
_index_page = "404.html"
# _args['uri'] = request.base_url
# pass
# # if 'source' in _system :
# # del _system['source']
# _args = {'layout':_config['layout'],'index':_html}
# _args['system'] = _handler.system(skip=['source','app','route'])
return render_template(_index_page,**_args),200 if _index_page != "404.html" else 200
# @_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('/dialog')
def _dialog ():
# 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')
_args['title'] = _id
return render_template('dialog.html',**_args) #title=_id,html=_html)
@_app.route("/caller/<app>/api/<module>/<name>")
def _delegate_call(app,module,name):
global _route
_handler = _route._apps[app]
return _delegate(_handler,module,name)
@_app.route('/api/<module>/<name>')
def _getproxy(module,name) :
"""
This endpoint will load a module and make a function call
:_module entry specified in plugins of the configuration
:_name name of the function to execute
"""
# global _config
global _route
_handler = _route.get()
return _delegate(_handler,module,name)
def _delegate(_handler,module,name):
global _route
uri = '/'.join(['api',module,name])
# _args = dict(request.args,**{})
# _args['config'] = _handler.config()
_plugins = _handler.plugins()
_context = _handler.system()['context']
if _context :
uri = f'{_context}/{uri}'
if uri not in _plugins :
_data = {}
_code = 404
else:
pointer = _plugins[uri]
# if _args :
# _data = pointer (**_args)
# else:
# _data = pointer()
_data = pointer(request=request,config=_handler.config())
if type(_data) == pd.DataFrame :
_data = _data.to_dict(orient='records')
if type(_data) == list:
_data = json.dumps(_data)
_code = 200 if _data else 500
return _data,_code
@_app.route("/api/<module>/<name>" , methods=['POST'])
def _post (module,name):
# global _config
global _route
_handler = _route.get()
return _delegate(_handler,module,name)
@_app.route('/version')
def _version ():
global _route
_handler = _route.get()
global _config
return _handler.system()['version']
@_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
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'])
def cms_page():
"""
return the content of a folder formatted for a menu
"""
# global _config
global _route
_handler = _route.get()
_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']
# _args = {'layout':_config['layout']}
# if 'plugins' in _config:
# _args['routes'] = _config['plugins']
# _system = _handler.system() #cms.components.get_system(_config)
# # _html = _handler.html(_uri,_id,_args,_system) #cms.components.html(_uri,_id,_args,_system)
# _html = _handler.html(_uri,_id)
# # _system = cms.components.get_system(_config)
# _args['system'] = _handler.system(skip=['source','app'])
# e = Environment(loader=BaseLoader()).from_string(_html)
# _html = e.render(**_args)
if 'read?uri=' in _uri or 'download?doc=' in _uri :
_uri = _uri.split('=')[1]
_args = _route.render(_uri,_id)
return _args[_id],200
# return _html,200
@_app.route('/page')
def _cms_page ():
# 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)
return _args[_title],200
@_app.route('/set/<id>')
def set(id):
global _route
_route.set(id)
_handler = _route.get()
_context = _handler.system()['context']
_uri = f'/{_context}'.replace('//','/')
return redirect(_uri)
@_app.route('/<id>')
def _open(id):
global _route
_handler = _route.get()
if id not in _route._apps :
_args = {'config':_handler.config(), 'layout':_handler.layout(),'system':_handler.system(skip=['source','app'])}
return render_template("404.html",**_args)
else:
_route.set(id)
return _index()
#
# Let us bootup the application
SYS_ARGS = {}
if len(sys.argv) > 1:
N = len(sys.argv)
for i in range(1,N):
value = None
if sys.argv[i].startswith('--'):
key = sys.argv[i][2:] #.replace('-','')
SYS_ARGS[key] = 1
if i + 1 < N:
value = sys.argv[i + 1] = sys.argv[i+1].strip()
if key and value and not value.startswith('--'):
SYS_ARGS[key] = value
i += 2
@cli.command()
def start (path:str='config.json',shared:bool=False) :
"""
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
# _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()
_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()