master
Harald Wolff 2018-03-29 13:13:56 +02:00
parent 871cca4b6a
commit 9af5bd2229
16 changed files with 205 additions and 41 deletions

View File

@ -38,3 +38,5 @@
border-right: 1px solid black; border-right: 1px solid black;
float: left; float: left;
} }

View File

@ -84,5 +84,9 @@ body,p,div {
min-height: 400px; min-height: 400px;
} }
#preview {
float: right;
right: 25px;
}

View File

@ -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 )

View File

@ -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

View File

@ -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 = {}

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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">

View File

@ -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%;

View File

@ -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>

View File

@ -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

View File

@ -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>

View File

@ -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