WIP
parent
871cca4b6a
commit
9af5bd2229
|
@ -38,3 +38,5 @@
|
||||||
border-right: 1px solid black;
|
border-right: 1px solid black;
|
||||||
float: left;
|
float: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -84,5 +84,9 @@ body,p,div {
|
||||||
min-height: 400px;
|
min-height: 400px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#preview {
|
||||||
|
float: right;
|
||||||
|
right: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -23,10 +23,14 @@ class FileObject(WebObject):
|
||||||
|
|
||||||
class DiskFolder(WebObject,Persistence):
|
class DiskFolder(WebObject,Persistence):
|
||||||
|
|
||||||
def __init__(self,path):
|
def __init__(self, path, readOnly = False):
|
||||||
self._path = path
|
self.__path = path
|
||||||
|
self.__readOnly = readOnly
|
||||||
|
self.__files = {}
|
||||||
|
|
||||||
def __dir__(self):
|
def __dir__(self):
|
||||||
return os.listdir( self._path)
|
return os.listdir( self.__path )
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -15,3 +15,6 @@ class WebCallable:
|
||||||
else:
|
else:
|
||||||
request.getContentFile().write("<html><head><title>No Content</title></head><body>Sorry, no content here!</body></html>")
|
request.getContentFile().write("<html><head><title>No Content</title></head><body>Sorry, no content here!</body></html>")
|
||||||
|
|
||||||
|
class WebCallableObject(WebCallable):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,15 @@
|
||||||
from objectbroker import Persistence,NoPersistence,Aquisition,AquisitionProxy
|
from objectbroker import Persistence,NoPersistence,Aquisition,AquisitionProxy
|
||||||
from hserver.api.WebCallable import WebCallable
|
from hserver.api.WebCallable import WebCallable,WebCallableObject
|
||||||
|
from hserver.types.FormApplyable import FormApplyable
|
||||||
|
|
||||||
from hserver.session.SessionHandler import SessionHandler
|
from hserver.session.SessionHandler import SessionHandler
|
||||||
|
|
||||||
import hserver
|
import hserver
|
||||||
import hserver.api
|
import hserver.api
|
||||||
|
|
||||||
class WebObject(WebCallable,Aquisition):
|
from simplelog import log
|
||||||
|
|
||||||
|
class WebObject(WebCallableObject,FormApplyable,Aquisition):
|
||||||
|
|
||||||
WO_Accepts = None
|
WO_Accepts = None
|
||||||
FA_Names = { "title": "title" }
|
FA_Names = { "title": "title" }
|
||||||
|
@ -65,6 +68,7 @@ class WebObject(WebCallable,Aquisition):
|
||||||
return ls
|
return ls
|
||||||
|
|
||||||
def walk(self,request):
|
def walk(self,request):
|
||||||
|
log("walk: {0}".format(self))
|
||||||
|
|
||||||
for shandler in self.__sessionhandlers:
|
for shandler in self.__sessionhandlers:
|
||||||
shandler.applySession(request)
|
shandler.applySession(request)
|
||||||
|
@ -76,7 +80,9 @@ class WebObject(WebCallable,Aquisition):
|
||||||
raise hserver.HttpException(404,"%s in /%s" % (next,request.pathwalker().walked(-1)))
|
raise hserver.HttpException(404,"%s in /%s" % (next,request.pathwalker().walked(-1)))
|
||||||
|
|
||||||
if (len(stack)==0) or (not isinstance(no,WebObject)):
|
if (len(stack)==0) or (not isinstance(no,WebObject)):
|
||||||
if (isinstance(no,WebCallable)):
|
if (isinstance(no,WebCallableObject)):
|
||||||
|
no(request, o=no)
|
||||||
|
elif (isinstance(no,WebCallable)):
|
||||||
no(request, o=self)
|
no(request, o=self)
|
||||||
else:
|
else:
|
||||||
raise hserver.HttpException(404,"%s in /%s" % (next,request.pathwalker().walked(-1)))
|
raise hserver.HttpException(404,"%s in /%s" % (next,request.pathwalker().walked(-1)))
|
||||||
|
@ -126,18 +132,10 @@ class WebObject(WebCallable,Aquisition):
|
||||||
elif not hasattr(self, n):
|
elif not hasattr(self, n):
|
||||||
setattr( self, n, t() )
|
setattr( self, n, t() )
|
||||||
|
|
||||||
class NavWebObject(WebObject):
|
class NavWebObject(WebObject,Persistence):
|
||||||
|
|
||||||
def __init__(self,title = None):
|
def __init__(self,title = None):
|
||||||
WebObject.__init__(self)
|
WebObject.__init__(self)
|
||||||
self.title = title
|
|
||||||
|
|
||||||
def title(self):
|
|
||||||
t = getattr(self,"title",None)
|
|
||||||
if t is None:
|
|
||||||
return self.__aq_name
|
|
||||||
return t
|
|
||||||
|
|
||||||
|
|
||||||
def navigation(self,levels = 1):
|
def navigation(self,levels = 1):
|
||||||
nav = {}
|
nav = {}
|
||||||
|
|
|
@ -6,6 +6,8 @@ from hserver.api.WebObject import WebObject,NavWebObject
|
||||||
from hserver.api.FileObject import FileObject
|
from hserver.api.FileObject import FileObject
|
||||||
from hserver.api.SimpleObject import SimpleObject
|
from hserver.api.SimpleObject import SimpleObject
|
||||||
|
|
||||||
|
from hserver.types.FormApplyable import FormApplyable
|
||||||
|
|
||||||
from hserver.api.SessionHandlerObject import SessionHandlerObject
|
from hserver.api.SessionHandlerObject import SessionHandlerObject
|
||||||
from hserver.api.CookieSessionHandler import CookieSessionHandler
|
from hserver.api.CookieSessionHandler import CookieSessionHandler
|
||||||
|
|
||||||
|
|
|
@ -8,11 +8,17 @@ from hserver.templates.Template import Template
|
||||||
import hserver
|
import hserver
|
||||||
|
|
||||||
from simplelog import log
|
from simplelog import log
|
||||||
|
import simplelog
|
||||||
|
|
||||||
|
|
||||||
|
from objectbroker import Serializer,XMLStore
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import os.path
|
import os.path
|
||||||
import json
|
import json
|
||||||
|
|
||||||
|
import xml.etree.ElementTree
|
||||||
|
|
||||||
|
|
||||||
class RootFolder(WebObject,Persistence):
|
class RootFolder(WebObject,Persistence):
|
||||||
|
|
||||||
|
@ -51,6 +57,8 @@ class RootFolder(WebObject,Persistence):
|
||||||
|
|
||||||
|
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
|
log("JSON-RPC: Exception")
|
||||||
|
simplelog.logException(ex)
|
||||||
reply["result"] = None
|
reply["result"] = None
|
||||||
reply["exception"] = repr(ex)
|
reply["exception"] = repr(ex)
|
||||||
|
|
||||||
|
@ -59,6 +67,8 @@ class RootFolder(WebObject,Persistence):
|
||||||
log("JReply: {0}".format(jreply))
|
log("JReply: {0}".format(jreply))
|
||||||
request.getContentFile().write( jreply )
|
request.getContentFile().write( jreply )
|
||||||
|
|
||||||
|
_hm_json = WebCallable( method = hm_json )
|
||||||
|
|
||||||
def objCreate(self,request,objTypeName,objName,objPath):
|
def objCreate(self,request,objTypeName,objName,objPath):
|
||||||
if (objTypeName == ""):
|
if (objTypeName == ""):
|
||||||
raise Exception("objTypeName must contain a valid type")
|
raise Exception("objTypeName must contain a valid type")
|
||||||
|
@ -83,8 +93,16 @@ class RootFolder(WebObject,Persistence):
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
def objExport(self,request, objPath):
|
||||||
|
xs = XMLStore(None)
|
||||||
|
s = Serializer(xs)
|
||||||
|
|
||||||
|
o = self.objPathWalk( request, objPath )
|
||||||
|
|
||||||
|
s.serialize( o._aq_object )
|
||||||
|
|
||||||
|
return xml.etree.ElementTree.tostring( xs.lastXml() ).decode("utf-8")
|
||||||
|
|
||||||
_hm_json = WebCallable( method = hm_json )
|
|
||||||
|
|
||||||
def objPathWalk(self, request, path):
|
def objPathWalk(self, request, path):
|
||||||
o = self
|
o = self
|
||||||
|
|
|
@ -89,7 +89,7 @@ function editorApply(objPath){
|
||||||
if (hm.editor.fields.hasOwnProperty( field )){
|
if (hm.editor.fields.hasOwnProperty( field )){
|
||||||
formData.append( field, hm.editor.fields[ field ].value );
|
formData.append( field, hm.editor.fields[ field ].value );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var reply = callURL( objPath + "/_hm_apply", formData, null, "POST" );
|
var reply = callURL( objPath + "/_hm_apply", formData, null, "POST" );
|
||||||
} catch (e){
|
} catch (e){
|
||||||
alert(e);
|
alert(e);
|
||||||
|
@ -102,6 +102,28 @@ function editorSave(){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function editorExport(){
|
||||||
|
var objPath = hm.editor.objPath;
|
||||||
|
var reply = callJson( "objExport", { "objPath" : pathSplit(objPath) } )
|
||||||
|
|
||||||
|
var a = document.createElement("a");
|
||||||
|
a.setAttribute('href', "data:text/xml," + escape(reply.result));
|
||||||
|
a.setAttribute('download', 'object.xml');
|
||||||
|
|
||||||
|
document.body.appendChild(a);
|
||||||
|
a.click();
|
||||||
|
document.body.removeChild(a);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function editorImport(){
|
||||||
|
var files = $("importxmlfile").files;
|
||||||
|
if (files.length == 0){
|
||||||
|
alert("First, you need to select a file to import into this node!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -117,6 +139,7 @@ function objRemove( objPath ){
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function onAddObjectButton(button,objPath,parentID){
|
function onAddObjectButton(button,objPath,parentID){
|
||||||
var ctlObjName = "objName-" + parentID;
|
var ctlObjName = "objName-" + parentID;
|
||||||
var objName = $(ctlObjName).value;
|
var objName = $(ctlObjName).value;
|
||||||
|
|
|
@ -3,8 +3,14 @@
|
||||||
|
|
||||||
<form onsubmit="return editorSave();">
|
<form onsubmit="return editorSave();">
|
||||||
|
|
||||||
<div class="block">
|
<div class="block right side">
|
||||||
<button class="button" onclick="editorSave();">Speichern</button>
|
<button class="button" onclick="editorSave();">Speichern</button>
|
||||||
|
<button class="button" onclick="editorExport();">Exportieren</button>
|
||||||
|
<div class="button slider right">Importieren
|
||||||
|
<div>Importiere <input type="file" id="importxmlfile" name="importxmlfile"><br/>
|
||||||
|
als <input type="text" id="objNameImport" value=""/>
|
||||||
|
<button class="button" onclick="editorImport();">Importieren...</button></div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="section">
|
<div class="section">
|
||||||
|
|
|
@ -14,11 +14,35 @@ h1,h2,h3,h4,h5 {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
input {
|
||||||
|
padding: 3px;
|
||||||
|
min-width: 400px;
|
||||||
|
}
|
||||||
|
|
||||||
textarea {
|
textarea {
|
||||||
min-width: 50%;
|
min-width: 50%;
|
||||||
min-height: 400px;
|
min-height: 400px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
button, .button, input[type=button], textarea {
|
||||||
|
position: relative;
|
||||||
|
display: inline-block;
|
||||||
|
background-color: #E0E0FF;
|
||||||
|
|
||||||
|
border: 1px solid #202040;
|
||||||
|
border-radius: 3px;
|
||||||
|
|
||||||
|
font-size: 12px;
|
||||||
|
text-align: center;
|
||||||
|
vertical-align: middle;
|
||||||
|
height: 32px;
|
||||||
|
|
||||||
|
width: 100px;
|
||||||
|
|
||||||
|
padding: 4px;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
.popup {
|
.popup {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 75%;
|
left: 75%;
|
||||||
|
@ -60,8 +84,76 @@ div:hover > .pulldown {
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.side {
|
||||||
|
width: 110px;
|
||||||
|
min-height: 40%;
|
||||||
|
background-color: #0786BD;
|
||||||
|
}
|
||||||
|
|
||||||
|
.side.right {
|
||||||
|
position: fixed;
|
||||||
|
right: 0px;
|
||||||
|
padding: 8px;
|
||||||
|
padding-left: 14px;
|
||||||
|
border-left: 2px solid #0786BD;
|
||||||
|
border-top: 2px solid #0786BD;
|
||||||
|
border-bottom: 2px solid #0786BD;
|
||||||
|
border-radius: 10px 0 0 10px;
|
||||||
|
}
|
||||||
|
.side.left {
|
||||||
|
padding-right: 14px;
|
||||||
|
border-right: 1px solid #0786BD;
|
||||||
|
border-top: 1px solid #0786BD;
|
||||||
|
border-bottom: 1px solid #0786BD;
|
||||||
|
border-radius: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.slider {
|
||||||
|
|
||||||
|
background-color: #61c1fe;
|
||||||
|
padding: 5px;
|
||||||
|
border-radius: 5px;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
transition: width 0.5s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.slider:hover {
|
||||||
|
padding: 10px;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.slider * {
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
.slider:hover * {
|
||||||
|
visibility: visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
.slider.right {
|
||||||
|
float: none;
|
||||||
|
right: 0px;
|
||||||
|
width: 90px;
|
||||||
|
height: 22px;
|
||||||
|
}
|
||||||
|
.slider.right:hover {
|
||||||
|
width: 600%;
|
||||||
|
max-height: 1000%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.slider > div {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.slider > div > input {
|
||||||
|
width: 160px;
|
||||||
|
min-width: 120px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
.section {
|
.section {
|
||||||
display: block;
|
display: block;
|
||||||
|
padding-bottom: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.section > div {
|
.section > div {
|
||||||
|
@ -84,22 +176,12 @@ div:hover > .pulldown {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.button, input, textarea {
|
|
||||||
position: relative;
|
|
||||||
display: inline-block;
|
|
||||||
border: 1px solid #202040;
|
|
||||||
background-color: #E0E0FF;
|
|
||||||
border-radius: 3px;
|
|
||||||
}
|
|
||||||
.button.small {
|
.button.small {
|
||||||
width: 14px;
|
width: 14px;
|
||||||
height: 14px;
|
height: 14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
input {
|
|
||||||
padding: 3px;
|
|
||||||
min-width: 400px;
|
|
||||||
}
|
|
||||||
input.small {
|
input.small {
|
||||||
min-width: 200px;
|
min-width: 200px;
|
||||||
}
|
}
|
||||||
|
@ -114,6 +196,24 @@ textarea {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.side > * {
|
||||||
|
display: block;
|
||||||
|
position: relative;
|
||||||
|
width: 100px;
|
||||||
|
min-width: initial;
|
||||||
|
padding: 4px;
|
||||||
|
margin: 0;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
|
||||||
|
background-color: #61c1fe;
|
||||||
|
color: white;
|
||||||
|
|
||||||
|
border: 1px solid #044357;
|
||||||
|
border-radius: 4px;
|
||||||
|
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#menu {
|
#menu {
|
||||||
width: 90%;
|
width: 90%;
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
<%define node%>
|
<%define node%>
|
||||||
<div class="treenode">
|
<div class="treenode">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
@ -8,6 +7,7 @@
|
||||||
<%end%>
|
<%end%>
|
||||||
<div class="button small">
|
<div class="button small">
|
||||||
<div class="popup">
|
<div class="popup">
|
||||||
|
Neues Objekt in <div class="bold"><%='/'.join([x._aq_name for x in node._aq_path])%></div> erstellen.
|
||||||
<select size="1" id="objTypeName-<%=node._persistence_id()%>">
|
<select size="1" id="objTypeName-<%=node._persistence_id()%>">
|
||||||
<%iterate ot node.wo_accepts()%>
|
<%iterate ot node.wo_accepts()%>
|
||||||
<option value="<%='{0}.{1}'.format(ot.__module__,ot.__name__)%>"><%=ot.__name__%></option>
|
<option value="<%='{0}.{1}'.format(ot.__module__,ot.__name__)%>"><%=ot.__name__%></option>
|
||||||
|
|
|
@ -438,6 +438,8 @@ class Template(WebCallable):
|
||||||
log("Template missing for <%include ...%>")
|
log("Template missing for <%include ...%>")
|
||||||
|
|
||||||
def findTemplate(self, expr):
|
def findTemplate(self, expr):
|
||||||
|
log("findTemplate({0})".format(expr))
|
||||||
|
|
||||||
if isinstance(expr, Template):
|
if isinstance(expr, Template):
|
||||||
return expr
|
return expr
|
||||||
elif isinstance(expr[0], Template):
|
elif isinstance(expr[0], Template):
|
||||||
|
@ -445,7 +447,7 @@ class Template(WebCallable):
|
||||||
elif (not self.__provider is None) and (expr[0] in self.__provider):
|
elif (not self.__provider is None) and (expr[0] in self.__provider):
|
||||||
return self.__provider.provide( expr[0] )
|
return self.__provider.provide( expr[0] )
|
||||||
else:
|
else:
|
||||||
log("Template missing for <%include ...%>")
|
log("Template missing for <%frame ...%>")
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -33,13 +33,16 @@ function saveSource(){
|
||||||
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
<div class="section">
|
||||||
|
<div class="section-title">Quelltext</div>
|
||||||
|
<div id="preview">
|
||||||
|
<iframe id="preview-frame" name="preview" src=""></iframe>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<textarea id="dpage_source" name="source" oninput="sourcechanged();"><%=self.source()%></textarea><br/>
|
||||||
|
|
||||||
<div id="preview">
|
|
||||||
<iframe id="preview-frame" name="preview" src=""></iframe>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<textarea id="dpage_source" name="source" oninput="sourcechanged();"><%=self.source()%></textarea><br/>
|
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
editorDeclareControl($("dpage_source"));
|
editorDeclareControl($("dpage_source"));
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -15,7 +15,7 @@ class FormApplyable:
|
||||||
|
|
||||||
FA_Names = {}
|
FA_Names = {}
|
||||||
|
|
||||||
def formApply(self,request):
|
def formApply(self,request,o):
|
||||||
fa_names = self.__collectNames()
|
fa_names = self.__collectNames()
|
||||||
|
|
||||||
for name in fa_names:
|
for name in fa_names:
|
||||||
|
@ -23,12 +23,13 @@ class FormApplyable:
|
||||||
if fa_attr in request.form():
|
if fa_attr in request.form():
|
||||||
oval = getattr( self, name, None)
|
oval = getattr( self, name, None)
|
||||||
|
|
||||||
log("formApply(): {0} = {1}".format( name, oval ))
|
log("formApply(): {3} {0} = {1} : {2}".format( name, oval, request.form()[ fa_attr ].value(), o ))
|
||||||
|
|
||||||
if callable( oval ):
|
if callable( oval ):
|
||||||
|
log("call-intf")
|
||||||
oval( request.form()[ fa_attr ].value() )
|
oval( request.form()[ fa_attr ].value() )
|
||||||
else:
|
else:
|
||||||
setattr( self, name, request.form()[ fa_attr ].value())
|
setattr( self, name, request.form()[ fa_attr ].value() )
|
||||||
|
|
||||||
|
|
||||||
def __collectNames(self):
|
def __collectNames(self):
|
||||||
|
@ -43,6 +44,6 @@ class FormApplyable:
|
||||||
return fa_names
|
return fa_names
|
||||||
|
|
||||||
def __apply(self,request, o = None):
|
def __apply(self,request, o = None):
|
||||||
self.formApply(request)
|
self.formApply(request,o)
|
||||||
|
|
||||||
_hm_apply = WebCallable( method = __apply )
|
_hm_apply = WebCallable( method = __apply )
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
Subproject commit b0ab3694e3903b178a57b1ba95d7a8932671d828
|
|
|
@ -1 +0,0 @@
|
||||||
Subproject commit 729bbd81d755b830e6562ea52e006297511a15b6
|
|
Loading…
Reference in New Issue