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;
float: left;
}

View File

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

View File

@ -23,10 +23,14 @@ class FileObject(WebObject):
class DiskFolder(WebObject,Persistence):
def __init__(self,path):
self._path = path
def __init__(self, path, readOnly = False):
self.__path = path
self.__readOnly = readOnly
self.__files = {}
def __dir__(self):
return os.listdir( self._path)
return os.listdir( self.__path )

View File

@ -15,3 +15,6 @@ class WebCallable:
else:
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 hserver.api.WebCallable import WebCallable
from hserver.api.WebCallable import WebCallable,WebCallableObject
from hserver.types.FormApplyable import FormApplyable
from hserver.session.SessionHandler import SessionHandler
import hserver
import hserver.api
class WebObject(WebCallable,Aquisition):
from simplelog import log
class WebObject(WebCallableObject,FormApplyable,Aquisition):
WO_Accepts = None
FA_Names = { "title": "title" }
@ -65,6 +68,7 @@ class WebObject(WebCallable,Aquisition):
return ls
def walk(self,request):
log("walk: {0}".format(self))
for shandler in self.__sessionhandlers:
shandler.applySession(request)
@ -76,7 +80,9 @@ class WebObject(WebCallable,Aquisition):
raise hserver.HttpException(404,"%s in /%s" % (next,request.pathwalker().walked(-1)))
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)
else:
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):
setattr( self, n, t() )
class NavWebObject(WebObject):
class NavWebObject(WebObject,Persistence):
def __init__(self,title = None):
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):
nav = {}

View File

@ -6,6 +6,8 @@ from hserver.api.WebObject import WebObject,NavWebObject
from hserver.api.FileObject import FileObject
from hserver.api.SimpleObject import SimpleObject
from hserver.types.FormApplyable import FormApplyable
from hserver.api.SessionHandlerObject import SessionHandlerObject
from hserver.api.CookieSessionHandler import CookieSessionHandler

View File

@ -8,11 +8,17 @@ from hserver.templates.Template import Template
import hserver
from simplelog import log
import simplelog
from objectbroker import Serializer,XMLStore
import os
import os.path
import json
import xml.etree.ElementTree
class RootFolder(WebObject,Persistence):
@ -51,6 +57,8 @@ class RootFolder(WebObject,Persistence):
except Exception as ex:
log("JSON-RPC: Exception")
simplelog.logException(ex)
reply["result"] = None
reply["exception"] = repr(ex)
@ -59,6 +67,8 @@ class RootFolder(WebObject,Persistence):
log("JReply: {0}".format(jreply))
request.getContentFile().write( jreply )
_hm_json = WebCallable( method = hm_json )
def objCreate(self,request,objTypeName,objName,objPath):
if (objTypeName == ""):
raise Exception("objTypeName must contain a valid type")
@ -83,8 +93,16 @@ class RootFolder(WebObject,Persistence):
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):
o = self

View File

@ -89,7 +89,7 @@ function editorApply(objPath){
if (hm.editor.fields.hasOwnProperty( field )){
formData.append( field, hm.editor.fields[ field ].value );
}
}
}
var reply = callURL( objPath + "/_hm_apply", formData, null, "POST" );
} catch (e){
alert(e);
@ -102,6 +102,28 @@ function editorSave(){
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){
var ctlObjName = "objName-" + parentID;
var objName = $(ctlObjName).value;

View File

@ -3,8 +3,14 @@
<form onsubmit="return editorSave();">
<div class="block">
<div class="block right side">
<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 class="section">

View File

@ -14,11 +14,35 @@ h1,h2,h3,h4,h5 {
display: inline-block;
}
input {
padding: 3px;
min-width: 400px;
}
textarea {
min-width: 50%;
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 {
position: absolute;
left: 75%;
@ -60,8 +84,76 @@ div:hover > .pulldown {
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 {
display: block;
padding-bottom: 10px;
}
.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 {
width: 14px;
height: 14px;
}
input {
padding: 3px;
min-width: 400px;
}
input.small {
min-width: 200px;
}
@ -114,6 +196,24 @@ textarea {
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 {
width: 90%;

View File

@ -1,4 +1,3 @@
<%define node%>
<div class="treenode">
<div class="row">
@ -8,6 +7,7 @@
<%end%>
<div class="button small">
<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()%>">
<%iterate ot node.wo_accepts()%>
<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 ...%>")
def findTemplate(self, expr):
log("findTemplate({0})".format(expr))
if isinstance(expr, Template):
return expr
elif isinstance(expr[0], Template):
@ -445,7 +447,7 @@ class Template(WebCallable):
elif (not self.__provider is None) and (expr[0] in self.__provider):
return self.__provider.provide( expr[0] )
else:
log("Template missing for <%include ...%>")
log("Template missing for <%frame ...%>")
return None

View File

@ -33,13 +33,16 @@ function saveSource(){
</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>
<textarea id="dpage_source" name="source" oninput="sourcechanged();"><%=self.source()%></textarea><br/>
<script type="text/javascript">
editorDeclareControl($("dpage_source"));
</script>

View File

@ -15,7 +15,7 @@ class FormApplyable:
FA_Names = {}
def formApply(self,request):
def formApply(self,request,o):
fa_names = self.__collectNames()
for name in fa_names:
@ -23,12 +23,13 @@ class FormApplyable:
if fa_attr in request.form():
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 ):
log("call-intf")
oval( request.form()[ fa_attr ].value() )
else:
setattr( self, name, request.form()[ fa_attr ].value())
setattr( self, name, request.form()[ fa_attr ].value() )
def __collectNames(self):
@ -43,6 +44,6 @@ class FormApplyable:
return fa_names
def __apply(self,request, o = None):
self.formApply(request)
self.formApply(request,o)
_hm_apply = WebCallable( method = __apply )

@ -1 +0,0 @@
Subproject commit b0ab3694e3903b178a57b1ba95d7a8932671d828

@ -1 +0,0 @@
Subproject commit 729bbd81d755b830e6562ea52e006297511a15b6