def shownodelist(req, nodes, publishwarn=1, markunpublished=0, dir=None): req.session["nodelist"] = EditorNodeList(nodes) script_array = "allobjects = new Array();\n" nodelist = [] user = users.getUserFromRequest(req) for child in nodes: try: if isDirectory(child) or isCollection(child): continue script_array += "allobjects['%s'] = 0;\n" % child.id nodelist.append(child) except TypeError: continue chkjavascript = "" notpublished = {} if publishwarn or markunpublished: homedir = getHomeDir(user) homedirs = getAllSubDirs(homedir) if markunpublished: chkjavascript = """<script language="javascript">""" for node in nodes: ok = 0 for p in node.getParents(): if p not in homedirs: ok = 1 if not ok: if markunpublished: chkjavascript += """allobjects['check%s'] = 1; document.getElementById('check%s').checked = true; """ % (node.id, node.id) notpublished[node] = node chkjavascript += """</script>""" # if all nodes are properly published, don't bother # to warn the user if not notpublished: publishwarn = 0 unpublishedlink = None if publishwarn: user = users.getUserFromRequest(req) if dir: uploaddir = dir else: uploaddir = getUploadDir(user) unpublishedlink = "edit_content?tab=publish&id=" "" + uploaddir.id return req.getTAL("web/edit/edit_common.html", { "notpublished": notpublished, "chkjavascript": chkjavascript, "unpublishedlink": unpublishedlink, "nodelist": nodelist, "script_array": script_array, "language": lang(req) }, macro="show_nodelist")
def shownodelist(req, nodes, publishwarn=1, markunpublished=0, dir=None): req.session["nodelist"] = EditorNodeList(nodes) script_array = "allobjects = new Array();\n" nodelist = [] user = users.getUserFromRequest(req) for child in nodes: try: if isDirectory(child) or isCollection(child): continue script_array += "allobjects['%s'] = 0;\n" % child.id nodelist.append(child) except TypeError: continue chkjavascript = "" notpublished = {} if publishwarn or markunpublished: homedir = getHomeDir(user) homedirs = getAllSubDirs(homedir) if markunpublished: chkjavascript = """<script language="javascript">""" for node in nodes: ok = 0 for p in node.getParents(): if p not in homedirs: ok = 1 if not ok: if markunpublished: chkjavascript += """allobjects['check%s'] = 1; document.getElementById('check%s').checked = true; """ % (node.id, node.id) notpublished[node] = node chkjavascript += """</script>""" # if all nodes are properly published, don't bother # to warn the user if not notpublished: publishwarn = 0 unpublishedlink = None if publishwarn: user = users.getUserFromRequest(req) if dir: uploaddir = dir else: uploaddir = getUploadDir(user) unpublishedlink = "edit_content?tab=publish&id=""" + uploaddir.id return req.getTAL("web/edit/edit_common.html", {"notpublished": notpublished, "chkjavascript": chkjavascript, "unpublishedlink": unpublishedlink, "nodelist": nodelist, "script_array": script_array, "language": lang(req)}, macro="show_nodelist")
def content(req): user = current_user language = lang(req) if not user.is_editor: return req.writeTAL("web/edit/edit.html", {}, macro="error") if 'id' in req.params and len(req.params) == 1: nid = long(req.params.get('id')) node = q(Data).get(nid) if node is not None: cmd = "cd (%s %r, %r)" % (nid, node.name, node.type) logg.info("%s: %s", user.login_name, cmd) else: cmd = "ERROR-cd to non-existing id=%r" % nid logg.error("%s: %s", user.login_name, cmd) if 'action' in req.params and req.params['action'] == 'upload': pass content = {'script': '', 'body': ''} v = {'dircontent': '', 'notdirectory': 0, 'operations': ''} try: v['nodeiconpath'] = getEditorIconPath(node) except: v['nodeiconpath'] = "webtree/directory.gif" path = req.path[1:].split("/") if len(path) >= 4: req.params["style"] = "popup" req.params["id"] = path[1] req.params["tab"] = path[2] req.params["option"] = path[3] getEditModules() if not user.is_editor: return req.writeTAL("web/edit/edit.html", {}, macro="error") # remove all caches for the frontend area- we might make changes there for sessionkey in ["contentarea", "navframe"]: with suppress(Exception, warn=False): del req.session[sessionkey] ids = getIDs(req) if req.params.get("type", "") == "help" and req.params.get("tab", "") == "upload": return upload_help(req) if len(ids) > 0: if ids[0] == "all": ids = get_ids_from_req(req) node = q(Node).get(long(ids[0])) tabs = "content" if isinstance(node, Root): tabs = "content" elif node is user.upload_dir: tabs = "upload" else: tabs = node.get_default_edit_tab() v["notdirectory"] = 0 current = req.params.get("tab", tabs) logg.debug("... %s inside %s.%s: -> !!! current = %s !!!", get_user_id(req), __name__, funcname(), current) msg = "%s selected editor module is %s" % (user.login_name, current) jsfunc = req.params.get("func", "") if jsfunc: msg = msg + (', js-function: %r' % jsfunc) logg.info(msg) # some tabs operate on only one file # if current in ["files", "view", "upload"]: if current in ["files", "upload"]: ids = ids[0:1] # display current images if not isinstance(q(Data).get(ids[0]), Container): v["notdirectory"] = 1 items = [] if current != "view": for id in ids: node = q(Data).get(id) if hasattr(node, "show_node_image"): if not isDirectory(node) and not node.isContainer(): items.append((id, node.show_node_image())) else: items.append(("", node.show_node_image())) v["items"] = items if logg.isEnabledFor(logging.DEBUG): logg.debug("... %s inside %s.%s: -> display current images: items: %s", get_user_id(req), __name__, funcname(), [_t[0] for _t in items]) nid = req.params.get('src', req.params.get('id')) if nid is None: raise ValueError("invalid request, neither 'src' not 'id' parameter is set!") folders_only = False if nid.find(',') > 0: # more than one node selected # use the first one for activateEditorTreeNode # and display only folders nid = nid.split(',')[0] folders_only = True n = q(Data).get(nid) if current == 'metadata' and 'save' in req.params: pass s = [] while n: if not folders_only: s = ['<a onClick="activateEditorTreeNode(%r); return false;" href="/edit/edit_content?id=%s">%s</a>' % (n.id, n.id, get_edit_label(n, language))] + s folders_only = False; p = n.parents # XXX: we only check the first parent. This is wrong, how could be solve this? # first_parent = p[0] if isinstance(first_parent, Data) and first_parent.has_read_access(): n = p[0] else: n = None v["dircontent"] = ' <b>»</b> '.join(s) else: # or current directory n = q(Data).get(long(ids[0])) s = [] while n: if len(s) == 0: s = ['%s' % (get_edit_label(n, language))] else: s = ['<a onClick="activateEditorTreeNode(%r); return false;" href="/edit/edit_content?id=%s">%s</a>' % (n.id, n.id, get_edit_label(n, language))] + s p = n.parents if p and not isinstance(p[0], Root): n = p[0] else: n = None v["dircontent"] = ' <b>»</b> '.join(s) if current == "globals": basedir = config.get("paths.datadir") file_to_edit = None if "file_to_edit" in req.params: file_to_edit = req.params["file_to_edit"] if not file_to_edit: # todo: getstartpagedict doesnt exist d = node.getStartpageDict() if d and language in d: file_to_edit = d[language] found = False for f in node.files: if f.mimetype == 'text/html': filepath = f.abspath.replace(basedir, '') if file_to_edit == filepath: found = True break else: t2 = current.split("_")[-1] if t2 in editModules.keys(): c = editModules[t2].getContent(req, ids) if isinstance(c, int): # module returned a custom http status code instead of HTML content return c elif c: content["body"] += c else: logg.debug('empty content') return else: req.setStatus(httpstatus.HTTP_INTERNAL_SERVER_ERROR) content["body"] += req.getTAL("web/edit/edit.html", {"module": current}, macro="module_error") if req.params.get("style", "") != "popup": # normal page with header v["tabs"] = handletabs(req, ids, tabs) v["script"] = content["script"] v["body"] = content["body"] v["paging"] = showPaging(req, current, ids) v["node"] = node v["ids"] = req.params.get("ids", "").split(",") if req.params.get("ids", "") == "": v["ids"] = req.params.get("id", "").split(",") v["tab"] = current v["operations"] = req.getTAL("web/edit/edit_common.html", {'iscontainer': node.isContainer()}, macro="show_operations") v['user'] = user v['language'] = lang(req) v['t'] = t # add icons to breadcrumbs ipath = 'webtree/directory.gif' if node and node.isContainer(): if node.name == 'home' or 'Arbeitsverzeichnis' in node.name or node == current_user.home_dir: ipath = 'webtree/homeicon.gif' elif node.name in ('Uploads', 'upload'): ipath = 'webtree/uploadicon.gif' elif node.name in ('Papierkorb', 'trash'): ipath = 'webtree/trashicon.gif' else: ipath = getEditorIconPath(node) v["dircontent"] += ' <img src="' + '/img/' + ipath + '" />' return req.writeTAL("web/edit/edit.html", v, macro="frame_content")
def action(req): global editModules language = lang(req) user = current_user trashdir = user.trash_dir uploaddir = user.upload_dir trashdir_parents = trashdir.parents action = req.params.get("action", "") changednodes = {} if not user.is_editor: req.write("""permission denied""") req.setStatus(httpstatus.HTTP_FORBIDDEN) return if "tab" in req.params: tab = req.params.get("tab").split("_")[-1] return editModules[tab].getContent(req, [req.params.get("id")]) if action == "getlabels": nids = req.params.get('ids', []) nids = [nid.strip() for nid in nids.split(',') if nid.strip()] for nid in set(nids + [_n.id for _n in [trashdir, uploaddir]]): try: changednodes[nid] = getTreeLabel(q(Node).get(nid), language) except: logg.exception("exception ignored: could not make fancytree label for node %s", nid) res_dict = {'changednodes': changednodes} req.write(json.dumps(res_dict, indent=4, ensure_ascii=False)) return else: # all 'action's except 'getlabels' require a base dir (src) # but expanding of a subdir in the edit-tree via fancytree has # not a srcid, so no action is necessary srcid = req.params.get("src") if not srcid: return try: src = q(Node).get(srcid) except: req.writeTAL( "web/edit/edit.html", {"edit_action_error": srcid}, macro="edit_action_error") return if req.params.get('action') == 'addcontainer': node = q(Node).get(srcid) if not node.has_write_access(): # deliver errorlabel req.writeTALstr( '<tal:block i18n:translate="edit_nopermission"/>', {}) return # create new container newnode_type = req.params.get('type') if newnode_type in ['bare_collection', 'bare_directory']: newnode_type = newnode_type.replace('bare_', '') translated_label = t(lang(req), 'edit_add_' + newnode_type) if translated_label.startswith('edit_add_'): translated_label = t( lang(req), 'edit_add_container_default') + newnode_type content_class = Node.get_class_for_typestring(newnode_type) newnode = content_class(name=translated_label) node.children.append(newnode) newnode.set("creator", user.login_name) newnode.set("creationtime", unicode( time.strftime('%Y-%m-%dT%H:%M:%S', time.localtime(time.time())))) newnode.set("nodename", translated_label) # set attribute named "nodename" to label text # place newnode at top of the children by setting the orderpos to the lowest orderpos - 1 # if the orderpos gets negative, shift the oderpos of all children by incrementing with a positive number # make this number large enough, to avoid the next shifting of orderpos if more containers are added if len(node.children) == 1: # newnode is the only one child newnode.orderpos = 1000 else: newnode.orderpos = node.children[0].orderpos newnode.orderpos = min([c.orderpos for c in node.children]) - 1 while newnode.orderpos < 0: # in order to avoid negative orderpos, add a positive number to the orderpos of all children # make this number large enough, so there is no shift of orderpos is necessary if the next # container is added to the children for c in node.children: c.orderpos += 1000 db.session.commit() req.params["dest"] = newnode.id label = getTreeLabel(newnode, lang=language) fancytree_nodedata = { 'title': label, 'key': newnode.id, 'isLazy': False, 'isFolder': True, 'icon': getEditorIconPath(newnode), 'readonly': 0, 'tooltip': '%s (%s)' % (label, newnode.id), 'children': [], } req.write(json.dumps(fancytree_nodedata, ensure_ascii=False)) logg.info("%s adding new container %s (%s) to %s (%s, %s)", user.login_name, newnode.id, newnode.type, node.id, node.name, node.type) return try: destid = req.params.get("dest", None) dest = q(Node).get(destid) folderid = destid except: destid = None dest = None folderid = srcid idlist = getIDs(req) mysrc = None errorobj = None # try: if action == "clear_trash": for n in trashdir.children: # if trashdir is it's sole parent, remove file from disk # attn: this will not touch files from children of deleted # containers if len(n.parents) == 1: logg.info("%s going to remove files from disk for node %s (%s, %s)", user.login_name, n.id, n.name, n.type) for f in n.files: # dangerous ??? check this f_path = f.abspath if os.path.exists(f_path): logg.info("%s going to remove file %r from disk", user.login_name, f_path) os.remove(f_path) trashdir.children.remove(n) db.session.commit() dest = trashdir changednodes[trashdir.id] = 1 _parent_descr = [(p.name, p.id, p.type) for p in trashdir_parents] logg.info("%s cleared trash folder with id %s, child of %s", user.login_name, trashdir.id, _parent_descr) # return else: for id in idlist: obj = q(Node).get(id) mysrc = src if isDirectory(obj) or isCollection(obj): mysrc = obj.parents[0] if action == "delete": if mysrc.has_write_access() and obj.has_write_access(): if mysrc.id != trashdir.id: mysrc.children.remove(obj) changednodes[mysrc.id] = 1 trashdir.children.append(obj) db.session.commit() changednodes[trashdir.id] = 1 logg.info("%s moved to trash bin %s (%s, %s) from %s (%s, %s)", user.login_name, obj.id, obj.name, obj.type, mysrc.id, mysrc.name, mysrc.type) dest = mysrc else: logg.info("%s has no write access for node %s", user.login_name, mysrc.id) req.writeTALstr( '<tal:block i18n:translate="edit_nopermission"/>', {}) dest = mysrc elif action in ["move", "copy"]: if (dest != mysrc) and \ mysrc.has_write_access() and \ dest.has_write_access() and \ obj.has_write_access() and \ isinstance(dest, Container): if not dest.is_descendant_of(obj): if action == "move": mysrc.children.remove(obj) changednodes[mysrc.id] = 1 # getLabel(mysrc) dest.children.append(obj) changednodes[dest.id] = 1 # getLabel(dest) db.session.commit() if logg.isEnabledFor(logging.INFO): _what = "%s %s %r (%s, %s) " % ( user.login_name, action, obj.id, obj.name, obj.type) _from = "from %s (%s, %s) " % ( mysrc.id, mysrc.name, mysrc.type) _to = "to %s (%s, %s)" % ( dest.id, dest.name, dest.type) logg.info(_what + _from + _to) else: logg.error("%s could not %s %s from %s to %s", user.login_name, action, obj.id, mysrc.id, dest.id) else: return mysrc = None if not mysrc: mysrc = src if action in ["move", "copy", "delete", "clear_trash"]: for nid in changednodes: try: changednodes[nid] = getTreeLabel( q(Node).get(nid), lang=language) except: logg.exception("exception ignored: could not make fancytree label for node %s", nid) res_dict = {'changednodes': changednodes} req.write(json.dumps(res_dict, indent=4, ensure_ascii=False)) else: try: if dest is not None: req.write(dest.id) else: req.write('no-node-id-specified (web.edit.edit.action)') except: req.write('no-node-id-specified (web.edit.edit.action)') logg.exception('exception ignored, no-node-id-specified (web.edit.edit.action)') return
def feedback(self, req): Portlet.feedback(self, req) self.lang = lang(req) if "dir" in req.params or "id" in req.params: id = req.params.get("id", req.params.get("dir")) try: node = tree.getNode(id) if isCollection(node): self.collection = node self.directory = node else: if isDirectory(node): self.directory = node else: if not isDirectory(self.directory) or not isParentOf(node, self.directory): self.directory = getDirectory(node) if self.collection.type == "collections" or not isParentOf(node, self.collection): self.collection = getCollection(node) except tree.NoSuchNodeError: pass try: self.hide_empty = self.collection.get("style_hide_empty") == "1" except: self.hide_empty = False access = AccessData(req) # open all parents, so we see that node opened = {} parents = [self.directory] counter = 0 while parents: counter += 1 if counter > 50: raise RecursionException p = parents.pop() opened[p.id] = 1 parents += p.getParents() m = {} def f(m, node, indent, hide_empty): if indent > 15: raise RecursionException if not access.hasReadAccess(node): return count = -1 m[node.id] = e = NavTreeEntry(self, node, indent, node.type == "directory", hide_empty=hide_empty, lang=self.lang) if node.id in opened or e.defaultopen: m[node.id].folded = 0 for c in node.getContainerChildren(): if c.get("style_hide_empty") == "1": hide_empty = 1 f(m, c, indent + 1, hide_empty) f(m, tree.getRoot("collections"), 0, self.hide_empty) if "cunfold" in req.params: id = req.params["cunfold"] if id in m: m[id].folded = 0 if self.directory.id in m: m[self.directory.id].folded = 0 m[self.directory.id].active = 1 if self.collection.id in m: m[self.collection.id].active = 1 col_data = [] def f(col_data, node, indent): if indent > 15: raise RecursionException if node.id not in m: return data = m[node.id] col_data += [data] if not data.folded or data.defaultopen: for c in node.getContainerChildren().sort_by_orderpos(): f(col_data, c, indent + 1) f(col_data, tree.getRoot("collections"), 0) self.col_data = col_data
def getContent(req, ids): user = users.getUserFromRequest(req) publishdir = tree.getNode(ids[0]) explicit = tree.getNodesByAttribute("writeaccess", user.getName()) ret = "" actionerror = [] changes = [] if "dopublish" in req.params.keys(): access = AccessData(req) objlist = [] for key in req.params.keys(): if key.isdigit(): objlist.append(key) src = tree.getNode(req.params.get("id")) for obj_id in objlist: faultylist = [] obj = tree.getNode(obj_id) for mask in obj.getType().getMasks( type="edit"): # check required fields if access.hasReadAccess(mask) and mask.getName() == obj.get( "edit.lastmask"): for f in mask.validateNodelist([obj]): faultylist.append(f) if len(faultylist) > 0: # object faulty actionerror.append(obj_id) continue for dest_id in req.params.get("destination", "").split(","): if dest_id == "": # no destination given continue dest = tree.getNode(dest_id) if dest != src and access.hasReadAccess( src) and access.hasWriteAccess( dest) and access.hasWriteAccess( obj) and isDirectory(dest): if not nodeIsChildOfNode(dest, obj): dest.addChild(obj) src.removeChild(obj) if dest.id not in changes: changes.append(dest.id) if src.id not in changes: changes.append(src.id) log.info( "%s published %s (%r, %r) from src %s (%r, %r) to dest %s (%r, %r)" % ( user.getName(), obj.id, obj.name, obj.type, src.id, src.name, src.type, dest.id, dest.name, dest.type, )) else: actionerror.append(obj.id) log.error( "Error in publishing of node %r: Destination node %r is child of node." % (obj_id, dest.id)) if not access.hasReadAccess(src): log.error( "Error in publishing of node %r: source position %r has no read access." % (obj.id, src.id)) if not access.hasWriteAccess(dest): log.error( "Error in publishing of node %r: destination %r has no write access." % (obj.id, dest.id)) if not access.hasWriteAccess(obj): log.error( "Error in publishing of node %r: object has no write access." % obj.id) if not isDirectory(dest): log.error( "Error in publishing of node %r: destination %r is not a directory." % (obj.id, dest.id)) v = {} v["id"] = publishdir.id v["change"] = changes ret += req.getTAL("web/edit/modules/publish.html", v, macro="reload") # build normal window stddir = "" stdname = "" l = [] for n in explicit: if str(getHomeDir(user).id) != str(n): l.append(n) if len(l) == 1: stddir = str(l[0]) + "," stdname = "- " + tree.getNode(l[0]).getName() #v = {"id":publishdir.id,"stddir":stddir, "stdname":stdname, "showdir":showdir(req, publishdir, publishwarn=0, markunpublished=1, nodes=[])} v = { "id": publishdir.id, "stddir": stddir, "stdname": stdname, "showdir": showdir(req, publishdir, publishwarn=None, markunpublished=1, nodes=[]) } v["basedir"] = tree.getRoot('collections') v["script"] = "var currentitem = '%s';\nvar currentfolder = '%s'" % ( publishdir.id, publishdir.id) v["idstr"] = ids v["faultylist"] = actionerror ret += req.getTAL("web/edit/modules/publish.html", v, macro="publish_form") return ret
def action(req): global editModules access = AccessData(req) language = lang(req) user = users.getUserFromRequest(req) trashdir = users.getTrashDir(user) uploaddir = users.getUploadDir(user) faultydir = users.getFaultyDir(user) importdir = users.getImportDir(user) trashdir_parents = trashdir.getParents() action = req.params.get("action", "") changednodes = {} if not access.user.isEditor(): req.write("""permission denied""") req.setStatus(httpstatus.HTTP_FORBIDDEN) return if "tab" in req.params: tab = req.params.get("tab").split("_")[-1] return editModules[tab].getContent(req, [req.params.get("id")]) if action == "getlabels": nids = req.params.get("ids", []) nids = [nid.strip() for nid in nids.split(",") if nid.strip()] for nid in set(nids + [_n.id for _n in [trashdir, uploaddir, importdir, faultydir]]): try: changednodes[nid] = getTreeLabel(tree.getNode(nid), lang=language) except: msg = "could not make fancytree label for node %r" % nid logger.error(msg) res_dict = {"changednodes": changednodes} req.write(json.dumps(res_dict, indent=4)) return else: # all 'action's except 'getlabels' require a base dir (src) srcid = req.params.get("src") try: src = tree.getNode(srcid) except: req.writeTAL("web/edit/edit.html", {"edit_action_error": srcid}, macro="edit_action_error") return if req.params.get("action") == "addcontainer": node = tree.getNode(srcid) if not access.hasWriteAccess(node): # deliver errorlabel req.writeTALstr('<tal:block i18n:translate="edit_nopermission"/>', {}) return # create new container newnode_type = req.params.get("type") if newnode_type in ["bare_collection", "bare_directory"]: newnode_type = newnode_type.replace("bare_", "") translated_label = t(lang(req), "edit_add_" + newnode_type) if translated_label.startswith("edit_add_"): translated_label = t(lang(req), "edit_add_container_default") + newnode_type newnode = node.addChild(tree.Node(name=translated_label, type=newnode_type)) newnode.set("creator", user.getName()) newnode.set("creationtime", str(time.strftime("%Y-%m-%dT%H:%M:%S", time.localtime(time.time())))) clearFromCache(node) req.params["dest"] = newnode.id # try: # label = newnode.getLabel() # except: # label = newnode.getName() # # c = len(newnode.getContentChildren()) # if c>0: # label += ' <small>(%s)</small>' %(c) label = getTreeLabel(newnode, lang=language) fancytree_nodedata = { "title": label, "key": newnode.id, "isLazy": False, "isFolder": True, "icon": getEditorIconPath(newnode), "readonly": 0, "tooltip": "%s (%s)" % (label, newnode.id), "children": [], } req.write(json.dumps(fancytree_nodedata)) msg = "%s adding new container %r (%r) to %r (%r, %r)" % ( access.user.name, newnode.id, newnode.type, node.id, node.name, node.type, ) logging.getLogger("usertracing").info(msg) logger.info(msg) return try: destid = req.params.get("dest", None) dest = tree.getNode(destid) folderid = destid except: destid = None dest = None folderid = srcid idlist = getIDs(req) mysrc = None errorobj = None # try: if action == "clear_trash": for n in trashdir.getChildren(): # if trashdir is it's sole parent, remove file from disk # attn: this will not touch files from children of deleted # containers if len(n.getParents()) == 1: logger.info( "%s going to remove files from disk for node %r (%r, %r)" % (user.getName(), n.id, n.name, n.type) ) for f in n.getFiles(): # dangerous ??? check this f_path = f.retrieveFile() if os.path.exists(f_path): logger.info("%s going to remove file %r from disk" % (user.getName(), f_path)) os.remove(f_path) trashdir.removeChild(n) dest = trashdir clearFromCache(trashdir) changednodes[trashdir.id] = 1 _parent_descr = [(p.name, p.id, p.type) for p in trashdir_parents] msg = "%s cleared trash folder with id %s, child of %r" % (user.getName(), trashdir.id, _parent_descr) logger.info(msg) logging.getLogger("usertracing").info(msg) # return else: for id in idlist: obj = tree.getNode(id) mysrc = src if isDirectory(obj): mysrc = obj.getParents()[0] if action == "delete": if access.hasWriteAccess(mysrc) and access.hasWriteAccess(obj): if mysrc.id != trashdir.id: mysrc.removeChild(obj) changednodes[mysrc.id] = 1 trashdir.addChild(obj) changednodes[trashdir.id] = 1 clearFromCache(mysrc) logger.info( "%s moved to trash bin %s (%r, %r) from %s (%r, %r)" % (user.getName(), obj.id, obj.name, obj.type, mysrc.id, mysrc.name, mysrc.type) ) logging.getLogger("usertracing").info( "%s removed %s (%r, %r) from %s (%r, %r)" % (user.getName(), obj.id, obj.name, obj.type, mysrc.id, mysrc.name, mysrc.type) ) dest = mysrc else: logger.info("%s has no write access for node %s" % (user.getName(), mysrc.id)) req.writeTALstr('<tal:block i18n:translate="edit_nopermission"/>', {}) dest = mysrc elif action in ["move", "copy"]: if ( dest != mysrc and access.hasWriteAccess(mysrc) and access.hasWriteAccess(dest) and access.hasWriteAccess(obj) and isDirectory(dest) ): if not nodeIsChildOfNode(dest, obj): if action == "move": mysrc.removeChild(obj) changednodes[mysrc.id] = 1 # getLabel(mysrc) dest.addChild(obj) changednodes[dest.id] = 1 # getLabel(dest) clearFromCache(dest) _what = "%s %s %r (%r, %r) " % (access.user.name, action, obj.id, obj.name, obj.type) _from = "from %r (%r, %r) " % (mysrc.id, mysrc.name, mysrc.type) _to = "to %r (%r, %r)" % (dest.id, dest.name, dest.type) msg = _what + _from + _to logging.getLogger("usertracing").info(msg) logger.info(msg) else: logger.error( "%s could not %s %s from %s to %s" % (user.getName(), action, obj.id, mysrc.id, dest.id) ) else: return mysrc = None if not mysrc: mysrc = src if action in ["move", "copy", "delete", "clear_trash"]: for nid in changednodes: try: changednodes[nid] = getTreeLabel(tree.getNode(nid), lang=language) except: msg = "could not make fancytree label for node %r" % nid logger.error(msg) res_dict = {"changednodes": changednodes} req.write(json.dumps(res_dict, indent=4)) else: try: req.write(dest.id) except: req.write("no-node-id-specified (web.edit.edit.action)") logger.warning("no-node-id-specified (web.edit.edit.action)") return
def content(req): user = users.getUserFromRequest(req) access = AccessData(req) language = lang(req) if not access.user.isEditor(): return req.writeTAL("web/edit/edit.html", {}, macro="error") if "id" in req.params and len(req.params) == 1: nid = req.params.get("id") try: node = tree.getNode(nid) except: node = None if node: cmd = "cd (%s %r, %r)" % (nid, node.name, node.type) logger.info("%s: %s" % (user.getName(), cmd)) # logging.getLogger("usertracing").info("%s: in editor %s" % (user.getName(), cmd)) else: cmd = "ERROR-cd to non-existing id=%r" % nid logger.error("%s: %s") % (user.getName(), cmd) if "action" in req.params and req.params["action"] == "upload": pass content = {"script": "", "body": ""} v = {"dircontent": "", "notdirectory": 0, "operations": ""} try: v["nodeiconpath"] = getEditorIconPath(node) except: v["nodeiconpath"] = "webtree/directory.gif" path = req.path[1:].split("/") if len(path) >= 4: req.params["style"] = "popup" req.params["id"] = path[1] req.params["tab"] = path[2] req.params["option"] = path[3] getEditModules() if not access.user.isEditor(): return req.writeTAL("web/edit/edit.html", {}, macro="error") # remove all caches for the frontend area- we might make changes there for sessionkey in ["contentarea", "navframe"]: try: del req.session[sessionkey] except: pass ids = getIDs(req) if req.params.get("type", "") == "help" and req.params.get("tab", "") == "upload": return upload_help(req) if len(ids) > 0: node = tree.getNode(ids[0]) tabs = "content" if node.type == "root": tabs = "content" elif node.id == users.getUploadDir(access.getUser()).id: tabs = "upload" elif node.id == users.getImportDir(access.getUser()).id: tabs = "imports" elif hasattr(node, "getDefaultEditTab"): tabs = node.getDefaultEditTab() v["notdirectory"] = 0 current = req.params.get("tab", tabs) logger.debug("... %s inside %s.%s: -> !!! current = %r !!!" % (get_user_id(req), __name__, funcname(), current)) msg = "%s selected editor module is %r" % (user.getName(), current) jsfunc = req.params.get("func", "") if jsfunc: msg = msg + (", js-function: %r" % jsfunc) logger.info(msg) # some tabs operate on only one file # if current in ["files", "view", "upload"]: if current in ["files", "upload"]: ids = ids[0:1] # display current images if not tree.getNode(ids[0]).isContainer(): v["notdirectory"] = 1 items = [] if current != "view": for id in ids: node = tree.getNode(id) if hasattr(node, "show_node_image"): if not isDirectory(node) and not node.isContainer(): items.append((id, node.show_node_image())) else: items.append(("", node.show_node_image())) v["items"] = items logger.debug( "... %s inside %s.%s: -> display current images: items: %r" % (get_user_id(req), __name__, funcname(), [_t[0] for _t in items]) ) try: n = tree.getNode(req.params.get("src", req.params.get("id"))) if current == "metadata" and "save" in req.params: pass s = [] while n: try: s = [ '<a onClick="activateEditorTreeNode(%r); return false;" href="/edit/edit_content?id=%s">%s</a>' % (n.id, n.id, n.getLabel(lang=language)) ] + s except: s = [ '<a onClick="activateEditorTreeNode(%r); return false;" href="/edit/edit_content?id=%s">%s</a>' % (n.id, n.id, n.name) ] + s p = n.getParents() if p: n = p[0] else: n = None v["dircontent"] = " <b>»</b> ".join(s[1:]) except: logger.exception("ERROR displaying current images") else: # or current directory n = tree.getNode(ids[0]) s = [] while n: if len(s) == 0: try: s = ["%s" % (n.getLabel(lang=language))] except: s = ["%s" % (n.name)] else: try: s = [ '<a onClick="activateEditorTreeNode(%r); return false;" href="/edit/edit_content?id=%s">%s</a>' % (n.id, n.id, n.getLabel(lang=language)) ] + s except: s = [ '<a onClick="activateEditorTreeNode(%r); return false;" href="/edit/edit_content?id=%s">%s</a>' % (n.id, n.id, n.name) ] + s p = n.getParents() if p: n = p[0] else: n = None v["dircontent"] = " <b>»</b> ".join(s[1:]) if current == "globals": basedir = config.get("paths.datadir") file_to_edit = None if "file_to_edit" in req.params: file_to_edit = req.params["file_to_edit"] if not file_to_edit: d = node.getStartpageDict() if d and lang(req) in d: file_to_edit = d[lang(req)] found = False for f in node.getFiles(): if f.mimetype == "text/html": filepath = f.retrieveFile().replace(basedir, "") if file_to_edit == filepath: found = True result = edit_editor(req, node, f) if result == "error": logger.error("error editing %r" % f.retrieveFile()) break if not found: edit_editor(req, node, None) elif current == "tab_metadata": edit_metadata(req, ids) # undefined elif current == "tab_upload": edit_upload(req, ids) # undefined elif current == "tab_import": edit_import(req, ids) # undefined elif current == "tab_globals": req.write("") elif current == "tab_lza": edit_lza(req, ids) # undefined elif current == "tab_logo": edit_logo(req, ids) # undefined else: t = current.split("_")[-1] if t in editModules.keys(): c = editModules[t].getContent(req, ids) if c: content["body"] += c # use standard method of module else: logger.debug("empty content") return else: req.setStatus(httpstatus.HTTP_INTERNAL_SERVER_ERROR) content["body"] += req.getTAL("web/edit/edit.html", {"module": current}, macro="module_error") if req.params.get("style", "") != "popup": # normal page with header v["tabs"] = handletabs(req, ids, tabs) v["script"] = content["script"] v["body"] = content["body"] v["paging"] = showPaging(req, current, ids) v["node"] = node v["ids"] = req.params.get("ids", "").split(",") if req.params.get("ids", "") == "": v["ids"] = req.params.get("id", "").split(",") v["tab"] = current v["operations"] = req.getTAL( "web/edit/edit_common.html", {"iscontainer": node.isContainer()}, macro="show_operations" ) user = users.getUserFromRequest(req) v["user"] = user v["language"] = lang(req) v["t"] = translation_t v["spc"] = [Menu("sub_header_frontend", "../", target="_parent")] if user.isAdmin(): v["spc"].append(Menu("sub_header_administration", "../admin", target="_parent")) if user.isWorkflowEditor(): v["spc"].append(Menu("sub_header_workflow", "../publish", target="_parent")) v["spc"].append(Menu("sub_header_logout", "../logout", target="_parent")) # add icons to breadcrumbs ipath = "webtree/directory.gif" if node and node.isContainer(): if node.name == "home" or "Arbeitsverzeichnis" in node.name: ipath = "webtree/homeicon.gif" elif node.name == "Uploads": ipath = "webtree/uploadicon.gif" elif node.name == "Importe": ipath = "webtree/importicon.gif" elif node.name == "Inkonsistente Daten": ipath = "webtree/faultyicon.gif" elif node.name == "Papierkorb": ipath = "webtree/trashicon.gif" else: ipath = getEditorIconPath(node) v["dircontent"] += ' <img src="' + "/img/" + ipath + '" />' return req.writeTAL("web/edit/edit.html", v, macro="frame_content")
def content(req): user = users.getUserFromRequest(req) access = AccessData(req) language = lang(req) if not access.user.isEditor(): return req.writeTAL("web/edit/edit.html", {}, macro="error") if 'id' in req.params and len(req.params) == 1: nid = req.params.get('id') try: node = tree.getNode(nid) except: node = None if node: cmd = "cd (%s %r, %r)" % (nid, node.name, node.type) logger.info("%s: %s" % (user.getName(), cmd)) #logging.getLogger("usertracing").info("%s: in editor %s" % (user.getName(), cmd)) else: cmd = "ERROR-cd to non-existing id=%r" % nid logger.error("%s: %s") % (user.getName(), cmd) if 'action' in req.params and req.params['action'] == 'upload': pass content = {'script': '', 'body': ''} v = {'dircontent': '', 'notdirectory': 0, 'operations': ''} try: v['nodeiconpath'] = getEditorIconPath(node) except: v['nodeiconpath'] = "webtree/directory.gif" path = req.path[1:].split("/") if len(path) >= 4: req.params["style"] = "popup" req.params["id"] = path[1] req.params["tab"] = path[2] req.params["option"] = path[3] getEditModules() if not access.user.isEditor(): return req.writeTAL("web/edit/edit.html", {}, macro="error") # remove all caches for the frontend area- we might make changes there for sessionkey in ["contentarea", "navframe"]: try: del req.session[sessionkey] except: pass ids = getIDs(req) if req.params.get("type", "") == "help" and req.params.get("tab", "") == "upload": return upload_help(req) if len(ids) > 0: node = tree.getNode(ids[0]) tabs = "content" if node.type == "root": tabs = "content" elif node.id == users.getUploadDir(access.getUser()).id: tabs = "upload" elif node.id == users.getImportDir(access.getUser()).id: tabs = "imports" elif hasattr(node, "getDefaultEditTab"): tabs = node.getDefaultEditTab() v["notdirectory"] = 0 current = req.params.get("tab", tabs) logger.debug("... %s inside %s.%s: -> !!! current = %r !!!" % (get_user_id(req), __name__, funcname(), current)) msg = "%s selected editor module is %r" % (user.getName(), current) jsfunc = req.params.get("func", "") if jsfunc: msg = msg + (', js-function: %r' % jsfunc) logger.info(msg) # some tabs operate on only one file # if current in ["files", "view", "upload"]: if current in ["files", "upload"]: ids = ids[0:1] # display current images if not tree.getNode(ids[0]).isContainer(): v["notdirectory"] = 1 items = [] if current != "view": for id in ids: node = tree.getNode(id) if hasattr(node, "show_node_image"): if not isDirectory(node) and not node.isContainer(): items.append((id, node.show_node_image())) else: items.append(("", node.show_node_image())) v["items"] = items logger.debug("... %s inside %s.%s: -> display current images: items: %r" % (get_user_id(req), __name__, funcname(), [_t[0] for _t in items])) try: n = tree.getNode(req.params.get('src', req.params.get('id'))) if current == 'metadata' and 'save' in req.params: pass s = [] while n: try: s = ['<a onClick="activateEditorTreeNode(%r); return false;" href="/edit/edit_content?id=%s">%s</a>' % (n.id, n.id, n.getLabel(lang=language))] + s except: s = ['<a onClick="activateEditorTreeNode(%r); return false;" href="/edit/edit_content?id=%s">%s</a>' % (n.id, n.id, n.name)] + s p = n.getParents() if p: n = p[0] else: n = None v["dircontent"] = ' <b>»</b> '.join(s[1:]) except: logger.exception('ERROR displaying current images') else: # or current directory n = tree.getNode(ids[0]) s = [] while n: if len(s) == 0: try: s = ['%s' % (n.getLabel(lang=language))] except: s = ['%s' % (n.name)] else: try: s = ['<a onClick="activateEditorTreeNode(%r); return false;" href="/edit/edit_content?id=%s">%s</a>' % (n.id, n.id, n.getLabel(lang=language))] + s except: s = ['<a onClick="activateEditorTreeNode(%r); return false;" href="/edit/edit_content?id=%s">%s</a>' % (n.id, n.id, n.name)] + s p = n.getParents() if p: n = p[0] else: n = None v["dircontent"] = ' <b>»</b> '.join(s[1:]) if current == "globals": basedir = config.get("paths.datadir") file_to_edit = None if "file_to_edit" in req.params: file_to_edit = req.params["file_to_edit"] if not file_to_edit: d = node.getStartpageDict() if d and lang(req) in d: file_to_edit = d[lang(req)] found = False for f in node.getFiles(): if f.mimetype == 'text/html': filepath = f.retrieveFile().replace(basedir, '') if file_to_edit == filepath: found = True result = edit_editor(req, node, f) if result == "error": logger.error("error editing %r" % f.retrieveFile()) break if not found: edit_editor(req, node, None) elif current == "tab_metadata": edit_metadata(req, ids) # undefined elif current == "tab_upload": edit_upload(req, ids) # undefined elif current == "tab_import": edit_import(req, ids) # undefined elif current == "tab_globals": req.write("") elif current == "tab_lza": edit_lza(req, ids) # undefined elif current == "tab_logo": edit_logo(req, ids) # undefined else: t = current.split("_")[-1] if t in editModules.keys(): c = editModules[t].getContent(req, ids) if c: content["body"] += c # use standard method of module else: logger.debug('empty content') return else: req.setStatus(httpstatus.HTTP_INTERNAL_SERVER_ERROR) content["body"] += req.getTAL("web/edit/edit.html", {"module": current}, macro="module_error") if req.params.get("style", "") != "popup": # normal page with header v["tabs"] = handletabs(req, ids, tabs) v["script"] = content["script"] v["body"] = content["body"] v["paging"] = showPaging(req, current, ids) v["node"] = node v["ids"] = req.params.get("ids", "").split(",") if req.params.get("ids", "") == "": v["ids"] = req.params.get("id", "").split(",") v["tab"] = current v["operations"] = req.getTAL("web/edit/edit_common.html", {'iscontainer': node.isContainer()}, macro="show_operations") user = users.getUserFromRequest(req) v['user'] = user v['language'] = lang(req) v['t'] = translation_t v['spc'] = [Menu("sub_header_frontend", "../", target="_parent")] if user.isAdmin(): v['spc'].append(Menu("sub_header_administration", "../admin", target="_parent")) if user.isWorkflowEditor(): v['spc'].append(Menu("sub_header_workflow", "../publish", target="_parent")) v['spc'].append(Menu("sub_header_logout", "../logout", target="_parent")) # add icons to breadcrumbs ipath = 'webtree/directory.gif' if node and node.isContainer(): if node.name == 'home' or 'Arbeitsverzeichnis' in node.name: ipath = 'webtree/homeicon.gif' elif node.name == 'Uploads': ipath = 'webtree/uploadicon.gif' elif node.name == 'Importe': ipath = 'webtree/importicon.gif' elif node.name == 'Inkonsistente Daten': ipath = 'webtree/faultyicon.gif' elif node.name == 'Papierkorb': ipath = 'webtree/trashicon.gif' else: ipath = getEditorIconPath(node) v["dircontent"] += ' <img src="' + '/img/' + ipath + '" />' return req.writeTAL("web/edit/edit.html", v, macro="frame_content")
def action(req): global editModules access = AccessData(req) language = lang(req) user = users.getUserFromRequest(req) trashdir = users.getTrashDir(user) uploaddir = users.getUploadDir(user) faultydir = users.getFaultyDir(user) importdir = users.getImportDir(user) trashdir_parents = trashdir.getParents() action = req.params.get("action", "") changednodes = {} if not access.user.isEditor(): req.write("""permission denied""") req.setStatus(httpstatus.HTTP_FORBIDDEN) return if "tab" in req.params: tab = req.params.get("tab").split("_")[-1] return editModules[tab].getContent(req, [req.params.get("id")]) if action == "getlabels": nids = req.params.get('ids', []) nids = [nid.strip() for nid in nids.split(',') if nid.strip()] for nid in set(nids + [_n.id for _n in [trashdir, uploaddir, importdir, faultydir]]): try: changednodes[nid] = getTreeLabel( tree.getNode(nid), lang=language) except: msg = "could not make fancytree label for node %r" % nid logger.error(msg) res_dict = {'changednodes': changednodes} req.write(json.dumps(res_dict, indent=4)) return else: # all 'action's except 'getlabels' require a base dir (src) srcid = req.params.get("src") try: src = tree.getNode(srcid) except: req.writeTAL( "web/edit/edit.html", {"edit_action_error": srcid}, macro="edit_action_error") return if req.params.get('action') == 'addcontainer': node = tree.getNode(srcid) if not access.hasWriteAccess(node): # deliver errorlabel req.writeTALstr( '<tal:block i18n:translate="edit_nopermission"/>', {}) return # create new container newnode_type = req.params.get('type') if newnode_type in ['bare_collection', 'bare_directory']: newnode_type = newnode_type.replace('bare_', '') translated_label = t(lang(req), 'edit_add_' + newnode_type) if translated_label.startswith('edit_add_'): translated_label = t( lang(req), 'edit_add_container_default') + newnode_type newnode = node.addChild( tree.Node(name=translated_label, type=newnode_type)) newnode.set("creator", user.getName()) newnode.set("creationtime", str( time.strftime('%Y-%m-%dT%H:%M:%S', time.localtime(time.time())))) clearFromCache(node) req.params["dest"] = newnode.id # try: # label = newnode.getLabel() # except: # label = newnode.getName() # # c = len(newnode.getContentChildren()) # if c>0: # label += ' <small>(%s)</small>' %(c) label = getTreeLabel(newnode, lang=language) fancytree_nodedata = { 'title': label, 'key': newnode.id, 'isLazy': False, 'isFolder': True, 'icon': getEditorIconPath(newnode), 'readonly': 0, 'tooltip': '%s (%s)' % (label, newnode.id), 'children': [], } req.write(json.dumps(fancytree_nodedata)) msg = "%s adding new container %r (%r) to %r (%r, %r)" % ( access.user.name, newnode.id, newnode.type, node.id, node.name, node.type) logging.getLogger('usertracing').info(msg) logger.info(msg) return try: destid = req.params.get("dest", None) dest = tree.getNode(destid) folderid = destid except: destid = None dest = None folderid = srcid idlist = getIDs(req) mysrc = None errorobj = None # try: if action == "clear_trash": for n in trashdir.getChildren(): # if trashdir is it's sole parent, remove file from disk # attn: this will not touch files from children of deleted # containers if len(n.getParents()) == 1: logger.info("%s going to remove files from disk for node %r (%r, %r)" % ( user.getName(), n.id, n.name, n.type)) for f in n.getFiles(): # dangerous ??? check this f_path = f.retrieveFile() if os.path.exists(f_path): logger.info( "%s going to remove file %r from disk" % (user.getName(), f_path)) os.remove(f_path) trashdir.removeChild(n) dest = trashdir clearFromCache(trashdir) changednodes[trashdir.id] = 1 _parent_descr = [(p.name, p.id, p.type) for p in trashdir_parents] msg = "%s cleared trash folder with id %s, child of %r" % ( user.getName(), trashdir.id, _parent_descr) logger.info(msg) logging.getLogger('usertracing').info(msg) # return else: for id in idlist: obj = tree.getNode(id) mysrc = src if isDirectory(obj): mysrc = obj.getParents()[0] if action == "delete": if access.hasWriteAccess(mysrc) and access.hasWriteAccess(obj): if mysrc.id != trashdir.id: mysrc.removeChild(obj) changednodes[mysrc.id] = 1 trashdir.addChild(obj) changednodes[trashdir.id] = 1 clearFromCache(mysrc) logger.info("%s moved to trash bin %s (%r, %r) from %s (%r, %r)" % ( user.getName(), obj.id, obj.name, obj.type, mysrc.id, mysrc.name, mysrc.type)) logging.getLogger('usertracing').info("%s removed %s (%r, %r) from %s (%r, %r)" % ( user.getName(), obj.id, obj.name, obj.type, mysrc.id, mysrc.name, mysrc.type)) dest = mysrc else: logger.info( "%s has no write access for node %s" % (user.getName(), mysrc.id)) req.writeTALstr( '<tal:block i18n:translate="edit_nopermission"/>', {}) dest = mysrc elif action in ["move", "copy"]: if dest != mysrc and \ access.hasWriteAccess(mysrc) and \ access.hasWriteAccess(dest) and \ access.hasWriteAccess(obj) and \ isDirectory(dest): if not nodeIsChildOfNode(dest, obj): if action == "move": mysrc.removeChild(obj) changednodes[mysrc.id] = 1 # getLabel(mysrc) dest.addChild(obj) changednodes[dest.id] = 1 # getLabel(dest) clearFromCache(dest) _what = "%s %s %r (%r, %r) " % ( access.user.name, action, obj.id, obj.name, obj.type) _from = "from %r (%r, %r) " % ( mysrc.id, mysrc.name, mysrc.type) _to = "to %r (%r, %r)" % ( dest.id, dest.name, dest.type) msg = _what + _from + _to logging.getLogger('usertracing').info(msg) logger.info(msg) else: logger.error("%s could not %s %s from %s to %s" % ( user.getName(), action, obj.id, mysrc.id, dest.id)) else: return mysrc = None if not mysrc: mysrc = src if action in ["move", "copy", "delete", "clear_trash"]: for nid in changednodes: try: changednodes[nid] = getTreeLabel( tree.getNode(nid), lang=language) except: msg = "could not make fancytree label for node %r" % nid logger.error(msg) res_dict = {'changednodes': changednodes} req.write(json.dumps(res_dict, indent=4)) else: try: req.write(dest.id) except: req.write('no-node-id-specified (web.edit.edit.action)') logger.warning('no-node-id-specified (web.edit.edit.action)') return
def getContent(req, ids): user = users.getUserFromRequest(req) publishdir = tree.getNode(ids[0]) explicit = tree.getNodesByAttribute("writeaccess", user.getName()) ret = "" actionerror = [] changes = [] if "dopublish" in req.params.keys(): access = AccessData(req) objlist = [] for key in req.params.keys(): if key.isdigit(): objlist.append(key) src = tree.getNode(req.params.get("id")) for obj_id in objlist: faultylist = [] obj = tree.getNode(obj_id) for mask in obj.getType().getMasks(type="edit"): # check required fields if access.hasReadAccess(mask) and mask.getName()==obj.get("edit.lastmask"): for f in mask.validateNodelist([obj]): faultylist.append(f) if len(faultylist)>0: # object faulty actionerror.append(obj_id) continue for dest_id in req.params.get("destination", "").split(","): if dest_id=="": # no destination given continue dest = tree.getNode(dest_id) if dest != src and access.hasReadAccess(src) and access.hasWriteAccess(dest) and access.hasWriteAccess(obj) and isDirectory(dest): if not nodeIsChildOfNode(dest,obj): dest.addChild(obj) src.removeChild(obj) if dest.id not in changes: changes.append(dest.id) if src.id not in changes: changes.append(src.id) log.info("%s published %s (%r, %r) from src %s (%r, %r) to dest %s (%r, %r)" % ( user.getName(), obj.id, obj.name, obj.type, src.id, src.name, src.type, dest.id, dest.name, dest.type,)) else: actionerror.append(obj.id) log.error("Error in publishing of node %r: Destination node %r is child of node." % (obj_id, dest.id)) if not access.hasReadAccess(src): log.error("Error in publishing of node %r: source position %r has no read access." % (obj.id, src.id)) if not access.hasWriteAccess(dest): log.error("Error in publishing of node %r: destination %r has no write access." % (obj.id, dest.id)) if not access.hasWriteAccess(obj): log.error("Error in publishing of node %r: object has no write access." % obj.id) if not isDirectory(dest): log.error("Error in publishing of node %r: destination %r is not a directory." % (obj.id, dest.id)) v = {} v["id"] = publishdir.id v["change"] = changes ret += req.getTAL("web/edit/modules/publish.html", v, macro="reload") # build normal window stddir = "" stdname = "" l = [] for n in explicit: if str(getHomeDir(user).id)!=str(n): l.append(n) if len(l)==1: stddir = str(l[0])+"," stdname = "- " + tree.getNode(l[0]).getName() #v = {"id":publishdir.id,"stddir":stddir, "stdname":stdname, "showdir":showdir(req, publishdir, publishwarn=0, markunpublished=1, nodes=[])} v = {"id":publishdir.id,"stddir":stddir, "stdname":stdname, "showdir":showdir(req, publishdir, publishwarn=None, markunpublished=1, nodes=[])} v["basedir"] = tree.getRoot('collections') v["script"] = "var currentitem = '%s';\nvar currentfolder = '%s'" %(publishdir.id, publishdir.id) v["idstr"] = ids v["faultylist"] = actionerror ret += req.getTAL("web/edit/modules/publish.html", v, macro="publish_form") return ret
def content(req): user = current_user language = lang(req) if not user.is_editor: return req.writeTAL("web/edit/edit.html", {}, macro="error") if 'id' in req.params and len(req.params) == 1: nid = long(req.params.get('id')) node = q(Data).get(nid) if node is not None: cmd = "cd (%s %r, %r)" % (nid, node.name, node.type) logg.info("%s: %s", user.login_name, cmd) else: cmd = "ERROR-cd to non-existing id=%r" % nid logg.error("%s: %s", user.login_name, cmd) if 'action' in req.params and req.params['action'] == 'upload': pass content = {'script': '', 'body': ''} v = {'dircontent': '', 'notdirectory': 0, 'operations': ''} try: v['nodeiconpath'] = getEditorIconPath(node) except: v['nodeiconpath'] = "webtree/directory.gif" path = req.path[1:].split("/") if len(path) >= 4: req.params["style"] = "popup" req.params["id"] = path[1] req.params["tab"] = path[2] req.params["option"] = path[3] getEditModules() if not user.is_editor: return req.writeTAL("web/edit/edit.html", {}, macro="error") # remove all caches for the frontend area- we might make changes there for sessionkey in ["contentarea", "navframe"]: try: del req.session[sessionkey] except: pass ids = getIDs(req) if req.params.get("type", "") == "help" and req.params.get("tab", "") == "upload": return upload_help(req) if len(ids) > 0: if ids[0] == "all": ids = get_ids_from_req(req) node = q(Node).get(long(ids[0])) tabs = "content" if isinstance(node, Root): tabs = "content" elif node is user.upload_dir: tabs = "upload" else: tabs = node.get_default_edit_tab() v["notdirectory"] = 0 current = req.params.get("tab", tabs) logg.debug("... %s inside %s.%s: -> !!! current = %s !!!", get_user_id(req), __name__, funcname(), current) msg = "%s selected editor module is %s" % (user.login_name, current) jsfunc = req.params.get("func", "") if jsfunc: msg = msg + (', js-function: %r' % jsfunc) logg.info(msg) # some tabs operate on only one file # if current in ["files", "view", "upload"]: if current in ["files", "upload"]: ids = ids[0:1] # display current images if not isinstance(q(Data).get(ids[0]), Container): v["notdirectory"] = 1 items = [] if current != "view": for id in ids: node = q(Data).get(id) if hasattr(node, "show_node_image"): if not isDirectory(node) and not node.isContainer(): items.append((id, node.show_node_image())) else: items.append(("", node.show_node_image())) v["items"] = items if logg.isEnabledFor(logging.DEBUG): logg.debug( "... %s inside %s.%s: -> display current images: items: %s", get_user_id(req), __name__, funcname(), [_t[0] for _t in items]) nid = req.params.get('src', req.params.get('id')) if nid is None: raise ValueError( "invalid request, neither 'src' not 'id' parameter is set!") folders_only = False if nid.find(',') > 0: # more than one node selected # use the first one for activateEditorTreeNode # and display only folders nid = nid.split(',')[0] folders_only = True n = q(Data).get(nid) if current == 'metadata' and 'save' in req.params: pass s = [] while n: if not folders_only: s = [ '<a onClick="activateEditorTreeNode(%r); return false;" href="/edit/edit_content?id=%s">%s</a>' % (n.id, n.id, get_edit_label(n, language)) ] + s folders_only = False p = n.parents # XXX: we only check the first parent. This is wrong, how could be solve this? # first_parent = p[0] if isinstance(first_parent, Data) and first_parent.has_read_access(): n = p[0] else: n = None v["dircontent"] = ' <b>»</b> '.join(s) else: # or current directory n = q(Data).get(long(ids[0])) s = [] while n: if len(s) == 0: s = ['%s' % (get_edit_label(n, language))] else: s = [ '<a onClick="activateEditorTreeNode(%r); return false;" href="/edit/edit_content?id=%s">%s</a>' % (n.id, n.id, get_edit_label(n, language)) ] + s p = n.parents if p and not isinstance(p[0], Root): n = p[0] else: n = None v["dircontent"] = ' <b>»</b> '.join(s) if current == "globals": basedir = config.get("paths.datadir") file_to_edit = None if "file_to_edit" in req.params: file_to_edit = req.params["file_to_edit"] if not file_to_edit: # todo: getstartpagedict doesnt exist d = node.getStartpageDict() if d and language in d: file_to_edit = d[language] found = False for f in node.files: if f.mimetype == 'text/html': filepath = f.abspath.replace(basedir, '') if file_to_edit == filepath: found = True break else: t2 = current.split("_")[-1] if t2 in editModules.keys(): c = editModules[t2].getContent(req, ids) if isinstance(c, int): # module returned a custom http status code instead of HTML content return c elif c: content["body"] += c else: logg.debug('empty content') return else: req.setStatus(httpstatus.HTTP_INTERNAL_SERVER_ERROR) content["body"] += req.getTAL("web/edit/edit.html", {"module": current}, macro="module_error") if req.params.get("style", "") != "popup": # normal page with header v["tabs"] = handletabs(req, ids, tabs) v["script"] = content["script"] v["body"] = content["body"] v["paging"] = showPaging(req, current, ids) v["node"] = node v["ids"] = req.params.get("ids", "").split(",") if req.params.get("ids", "") == "": v["ids"] = req.params.get("id", "").split(",") v["tab"] = current v["operations"] = req.getTAL("web/edit/edit_common.html", {'iscontainer': node.isContainer()}, macro="show_operations") v['user'] = user v['language'] = lang(req) v['t'] = t # add icons to breadcrumbs ipath = 'webtree/directory.gif' if node and node.isContainer(): if node.name == 'home' or 'Arbeitsverzeichnis' in node.name or node == current_user.home_dir: ipath = 'webtree/homeicon.gif' elif node.name in ('Uploads', 'upload'): ipath = 'webtree/uploadicon.gif' elif node.name in ('Papierkorb', 'trash'): ipath = 'webtree/trashicon.gif' else: ipath = getEditorIconPath(node) v["dircontent"] += ' <img src="' + '/img/' + ipath + '" />' return req.writeTAL("web/edit/edit.html", v, macro="frame_content")
def action(req): global editModules language = lang(req) user = current_user trashdir = user.trash_dir uploaddir = user.upload_dir trashdir_parents = trashdir.parents action = req.params.get("action", "") changednodes = {} if not user.is_editor: req.write("""permission denied""") req.setStatus(httpstatus.HTTP_FORBIDDEN) return if "tab" in req.params: tab = req.params.get("tab").split("_")[-1] return editModules[tab].getContent(req, [req.params.get("id")]) if action == "getlabels": nids = req.params.get('ids', []) nids = [nid.strip() for nid in nids.split(',') if nid.strip()] for nid in set(nids + [_n.id for _n in [trashdir, uploaddir]]): try: changednodes[nid] = getTreeLabel(q(Node).get(nid), language) except: logg.exception( "exception ignored: could not make fancytree label for node %s", nid) res_dict = {'changednodes': changednodes} req.write(json.dumps(res_dict, indent=4, ensure_ascii=False)) return else: # all 'action's except 'getlabels' require a base dir (src) # but expanding of a subdir in the edit-tree via fancytree has # not a srcid, so no action is necessary srcid = req.params.get("src") if not srcid: return try: src = q(Node).get(srcid) except: req.writeTAL("web/edit/edit.html", {"edit_action_error": srcid}, macro="edit_action_error") return if req.params.get('action') == 'addcontainer': node = q(Node).get(srcid) if not node.has_write_access(): # deliver errorlabel req.writeTALstr('<tal:block i18n:translate="edit_nopermission"/>', {}) return # create new container newnode_type = req.params.get('type') if newnode_type in ['bare_collection', 'bare_directory']: newnode_type = newnode_type.replace('bare_', '') translated_label = t(lang(req), 'edit_add_' + newnode_type) if translated_label.startswith('edit_add_'): translated_label = t(lang(req), 'edit_add_container_default') + newnode_type content_class = Node.get_class_for_typestring(newnode_type) newnode = content_class(name=translated_label) node.children.append(newnode) newnode.set("creator", user.login_name) newnode.set( "creationtime", unicode( time.strftime('%Y-%m-%dT%H:%M:%S', time.localtime(time.time())))) newnode.set( "nodename", translated_label) # set attribute named "nodename" to label text # place newnode at top of the children by setting the orderpos to the lowest orderpos - 1 # if the orderpos gets negative, shift the oderpos of all children by incrementing with a positive number # make this number large enough, to avoid the next shifting of orderpos if more containers are added if len(node.children) == 1: # newnode is the only one child newnode.orderpos = 1000 else: newnode.orderpos = node.children[0].orderpos newnode.orderpos = min([c.orderpos for c in node.children]) - 1 while newnode.orderpos < 0: # in order to avoid negative orderpos, add a positive number to the orderpos of all children # make this number large enough, so there is no shift of orderpos is necessary if the next # container is added to the children for c in node.children: c.orderpos += 1000 db.session.commit() req.params["dest"] = newnode.id label = getTreeLabel(newnode, lang=language) fancytree_nodedata = { 'title': label, 'key': newnode.id, 'isLazy': False, 'isFolder': True, 'icon': getEditorIconPath(newnode), 'readonly': 0, 'tooltip': '%s (%s)' % (label, newnode.id), 'children': [], } req.write(json.dumps(fancytree_nodedata, ensure_ascii=False)) logg.info("%s adding new container %s (%s) to %s (%s, %s)", user.login_name, newnode.id, newnode.type, node.id, node.name, node.type) return try: destid = req.params.get("dest", None) dest = q(Node).get(destid) folderid = destid except: destid = None dest = None folderid = srcid idlist = getIDs(req) mysrc = None errorobj = None # try: if action == "clear_trash": for n in trashdir.children: # if trashdir is it's sole parent, remove file from disk # attn: this will not touch files from children of deleted # containers if len(n.parents) == 1: logg.info( "%s going to remove files from disk for node %s (%s, %s)", user.login_name, n.id, n.name, n.type) for f in n.files: # dangerous ??? check this f_path = f.abspath if os.path.exists(f_path): logg.info("%s going to remove file %r from disk", user.login_name, f_path) os.remove(f_path) trashdir.children.remove(n) db.session.commit() dest = trashdir changednodes[trashdir.id] = 1 _parent_descr = [(p.name, p.id, p.type) for p in trashdir_parents] logg.info("%s cleared trash folder with id %s, child of %s", user.login_name, trashdir.id, _parent_descr) # return else: for id in idlist: obj = q(Node).get(id) mysrc = src if isDirectory(obj) or isCollection(obj): mysrc = obj.parents[0] if action == "delete": if mysrc.has_write_access() and obj.has_write_access(): if mysrc.id != trashdir.id: mysrc.children.remove(obj) changednodes[mysrc.id] = 1 trashdir.children.append(obj) db.session.commit() changednodes[trashdir.id] = 1 logg.info( "%s moved to trash bin %s (%s, %s) from %s (%s, %s)", user.login_name, obj.id, obj.name, obj.type, mysrc.id, mysrc.name, mysrc.type) dest = mysrc else: logg.info("%s has no write access for node %s", user.login_name, mysrc.id) req.writeTALstr( '<tal:block i18n:translate="edit_nopermission"/>', {}) dest = mysrc elif action in ["move", "copy"]: if (dest != mysrc) and \ mysrc.has_write_access() and \ dest.has_write_access() and \ obj.has_write_access() and \ isinstance(dest, Container): if not dest.is_descendant_of(obj): if action == "move": mysrc.children.remove(obj) changednodes[mysrc.id] = 1 # getLabel(mysrc) dest.children.append(obj) changednodes[dest.id] = 1 # getLabel(dest) db.session.commit() if logg.isEnabledFor(logging.INFO): _what = "%s %s %r (%s, %s) " % (user.login_name, action, obj.id, obj.name, obj.type) _from = "from %s (%s, %s) " % ( mysrc.id, mysrc.name, mysrc.type) _to = "to %s (%s, %s)" % (dest.id, dest.name, dest.type) logg.info(_what + _from + _to) else: logg.error("%s could not %s %s from %s to %s", user.login_name, action, obj.id, mysrc.id, dest.id) else: return mysrc = None if not mysrc: mysrc = src if action in ["move", "copy", "delete", "clear_trash"]: for nid in changednodes: try: changednodes[nid] = getTreeLabel(q(Node).get(nid), lang=language) except: logg.exception( "exception ignored: could not make fancytree label for node %s", nid) res_dict = {'changednodes': changednodes} req.write(json.dumps(res_dict, indent=4, ensure_ascii=False)) else: try: req.write(dest.id) except: req.write('no-node-id-specified (web.edit.edit.action)') logg.exception( 'exception ignored, no-node-id-specified (web.edit.edit.action)' ) return