Ejemplo n.º 1
0
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
Ejemplo n.º 2
0
def getContent(req, ids):
    ret = ""
    user = users.getUserFromRequest(req)

    if "metadata" in users.getHideMenusForUser(user):
        print "error 1"
        req.setStatus(httpstatus.HTTP_FORBIDDEN)
        return req.getTAL("web/edit/edit.html", {}, macro="access_error")

    access = AccessData(req)
    faultydir = users.getFaultyDir(user)
    metatypes = []
    nodes = []
    masklist = []
    err = 0

    # flag indicating change of node.name (fancytree node may have to be updated)
    # keep as integer
    # negative -> no change
    # else -> id of changed node
    flag_nodename_changed = -1

    for id in ids:
        node = tree.getNode(id)
        if not access.hasWriteAccess(node):
            print "error 2"
            req.setStatus(httpstatus.HTTP_FORBIDDEN)
            return req.getTAL("web/edit/edit.html", {}, macro="access_error")

        schema = node.getSchema()
        if schema not in metatypes:
            metatypes.append(schema)
        if len(nodes) == 0 or nodes[0].getSchema() == schema:
            nodes += [node]

    idstr = ",".join(ids)
    action = req.params.get('action', '').strip()

    logger.info("%s in editor metadata (action=%r): %r" %
                (user.getName(), action, [[n.id, n.name, n.type]for n in nodes]))

    for m in node.getType().getMasks(type="edit"):
        if access.hasReadAccess(m):
            masklist.append(m)

    if hasattr(node, "metaFields"):

        class SystemMask:

            def __init__(self, name, description, fields):
                self.name, self.description, self.fields = name, description, fields

            def getName(self):
                return self.name

            def getDescription(self):
                return self.description

            def getDefaultMask(self):
                return False

            def metaFields(self, lang=None):
                return self.fields

            def i_am_not_a_mask():
                pass
        masklist = [SystemMask(
            "settings", t(req, "settings"), node.metaFields(lang(req)))] + masklist

    default = None
    for m in masklist:
        if m.getDefaultMask():
            default = m
            break
    if not default and len(masklist):
        default = masklist[0]

    maskname = req.params.get("mask", node.get("edit.lastmask") or "editmask")
    if maskname == "":
        maskname = default.getName()

    mask = None
    for m in masklist:
        if maskname == m.getName():
            mask = m
            break

    if not mask and default:
        mask = default
        maskname = default.getName()

    for n in nodes:
        n.set("edit.lastmask", maskname)

    if not mask:
        return req.getTAL("web/edit/modules/metadata.html", {}, macro="no_mask")

    # context default for TAL interpreter
    ctx = {}
    ctx["user"] = user
    ctx["access"] = access
    ctx["metatypes"] = metatypes
    ctx["idstr"] = idstr
    ctx["node"] = nodes[0]  # ?
    ctx["flag_nodename_changed"] = flag_nodename_changed
    ctx["nodes"] = nodes
    ctx["masklist"] = masklist
    ctx["maskname"] = maskname
    ctx["language"] = lang(req)
    ctx["t"] = t

    if action == 'restore':
        vid = req.params.get('vid', '0')
        node = nodes[0].getActiveVersion()
        if (vid != '0' and vid != node.id):
            n = tree.getNode(vid)
            # Not active version
            if n.next_nid != '0':

                next = tree.getNode(n.next_nid)
                if next.prev_nid != '0':
                    next.removeChild(tree.getNode(next.prev_nid))
                next.setPrevID(n.prev_nid)

                if n.prev_nid != '0':
                    prev = tree.getNode(n.prev_nid)
                    prev.setNextID(n.next_nid)
                    n.removeChild(prev)
                    next.addChild(prev)
                node.setNextID(n.id)

                n.setPrevID(node.id)
                n.setNextID('0')

                for pid in db.getParents(node.id):
                    parentNode = tree.getNode(pid)
                    parentNode.addChild(n)
                    parentNode.removeChild(node)
                n.addChild(node)

                nodes = [n]
                ids = [n.id]

                node_versions = nodes[0].getVersionList()
                update_date, creation_date = get_datelists(nodes)

                data = {'url': '?id=' + n.id + '&tab=metadata', 'pid':
                        None, 'flag_nodename_changed': flag_nodename_changed}

                data["versions"] = node_versions
                data["creation_date"] = creation_date
                data["update_date"] = update_date

                _maskform, _fields = get_maskform_and_fields(nodes, mask, req)
                data["maskform"] = _maskform
                data["fields"] = _fields

                data.update(ctx)

                return req.getTAL("web/edit/modules/metadata.html", data, macro="redirect")

    if action == 'delete':
        vid = req.params.get('vid', '0')
        if (vid != '0'):
            node = nodes[0].getActiveVersion()
            n = tree.getNode(vid)

            if (vid != node.id):
                n.set("deleted", "true")
                for pid in db.getParents(n.id):
                    parentNode = tree.getNode(pid)
                    parentNode.removeChild(n)
                for cid in db.getChildren(n.id):
                    n.removeChild(tree.getNode(cid))
                if n.next_nid != '0' and n.prev_nid != '0':
                    _next = tree.getNode(n.next_nid)
                    _next.addChild(tree.getNode(n.prev_nid))

                if n.next_nid != '0':
                    _next = tree.getNode(n.next_nid)
                    if n.prev_nid != '0':
                        _next.setPrevID(n.prev_nid)

                if n.prev_nid != '0':
                    _prev = tree.getNode(n.prev_nid)
                    if n.next_nid != '0':
                        _prev.setNextID(n.next_nid)
            else:
                pids = db.getParents(n.id)

                # Active version
                prev = None
                if n.prev_nid != '0':
                    prev = tree.getNode(n.prev_nid)
                    while prev.prev_nid != None and prev.prev_nid != '0' and prev.get("deleted") == "true":
                        prev = tree.getNode(prev.prev_nid)

                if prev != None and prev.get("deleted") != "true":
                    prev.setNextID('0')
                    for pid in pids:
                        parentNode = tree.getNode(pid)
                        parentNode.addChild(prev)
                    nodes = [prev]
                    ids = [prev.id]
                    n.set("deleted", "true")
                    for pid in pids:
                        parentNode = tree.getNode(pid)
                        parentNode.removeChild(n)

                    for cid in db.getChildren(n.id):
                        n.removeChild(tree.getNode(cid))

                    if n.next_nid != '0' and n.prev_nid != '0':
                        _next = tree.getNode(n.next_nid)
                        _next.addChild(tree.getNode(n.prev_nid))

                    node_versions = nodes[0].getVersionList()
                    update_date, creation_date = get_datelists(nodes)

                    data = {'url': '?id=' + prev.id + '&tab=metadata', 'pid':
                            None, 'flag_nodename_changed': flag_nodename_changed}

                    data["versions"] = node_versions
                    data["creation_date"] = creation_date
                    data["update_date"] = update_date

                    _maskform, _fields = get_maskform_and_fields(
                        nodes, mask, req)
                    data["maskform"] = _maskform
                    data["fields"] = _fields

                    data.update(ctx)

                    return req.getTAL("web/edit/modules/metadata.html", data, macro="redirect")
                else:
                    # Version 0
                    # Move node to trash
                    trashdir = users.getTrashDir(user)
                    trashdir.addChild(n)
                    for pid in pids:
                        parentNode = tree.getNode(pid)
                        parentNode.removeChild(n)

                    node_versions = nodes[0].getVersionList()
                    update_date, creation_date = get_datelists(nodes)

                    data = {'url': '?id=' + pids[0] + '&tab=content', 'pid': pids[
                        0], 'flag_nodename_changed': flag_nodename_changed}

                    data["versions"] = node_versions
                    data["creation_date"] = creation_date
                    data["update_date"] = update_date

                    _maskform, _fields = get_maskform_and_fields(
                        nodes, mask, req)
                    data["maskform"] = _maskform
                    data["fields"] = _fields

                    data.update(ctx)

                    return req.getTAL("web/edit/modules/metadata.html", data, macro="redirect")

    if "edit_metadata" in req.params:
        # check and save items
        userdir = users.getHomeDir(users.getUserFromRequest(req))

        for node in nodes:
            if not access.hasWriteAccess(node) or node.id == userdir.id:
                print "error 3"
                req.setStatus(httpstatus.HTTP_FORBIDDEN)
                return req.getTAL("web/edit/edit.html", {}, macro="access_error")

        logging.getLogger('usertracing').info(
            access.user.name + " change metadata " + idstr)
        logging.getLogger('editor').info(
            access.user.name + " change metadata " + idstr)
        logging.getLogger('editor').debug(pf(req.params))

        for node in nodes:
            node.set("updateuser", user.getName())
            if node.get('updatetime') < str(now()):
                node.set("updatetime", str(format_date()))

        if not hasattr(mask, "i_am_not_a_mask"):
            if (req.params.get('generate_new_version')):
                # Create new node version
                _ids = []
                _nodes = []
                for node in nodes:
                    n = node.createNewVersion(user)
                    n.set("system.version.comment", '(' + t(req, "document_new_version_comment") +
                          ')\n' + req.params.get('version_comment', ''))

                    # add all existing attributes to the new version node
                    for attr, value in node.items():
                        # do not overwrite existing attributes
                        # do not copy system attributes
                        if n.get(attr) != "" or attr.startswith("system."):
                            pass
                        else:
                            n.set(attr, value)

                    _nodes.append(n)
                    _ids.append(n.id)

                ids = _ids
                idstr = ",".join(ids)
                nodes = _nodes
                nodes = mask.updateNode(nodes, req)

                node_versions = nodes[0].getVersionList()
                update_date, creation_date = get_datelists(nodes)

                data = {
                    'url': '?id=' + nodes[0].id + '&tab=metadata',
                    'pid': None,
                }

                data["versions"] = node_versions
                data["creation_date"] = creation_date
                data["update_date"] = update_date

                _maskform, _fields = get_maskform_and_fields(
                    nodes, mask, req)
                data["maskform"] = _maskform
                data["fields"] = _fields

                data.update(ctx)

                ret += req.getTAL("web/edit/modules/metadata.html",
                                  data, macro="redirect")
            else:
                if nodes:
                    old_nodename = nodes[0].name
                nodes = mask.updateNode(nodes, req)
                if nodes:
                    new_nodename = nodes[0].name
                    if (old_nodename != new_nodename) and hasattr(nodes[0], 'isContainer') and nodes[0].isContainer():
                        # for updates of node label in editor tree
                        flag_nodename_changed = str(node.id)

        else:
            for field in mask.metaFields():
                msg = "in %s.%s: (hasattr(mask,'i_am_not_a_mask')) field: %r, field.id: %r, field.name: %r, mask: %r, maskname: %r" % (
                    __name__, funcname(), field, field.id, field.getName(), mask, maskname)
                logger.debug(msg)
                field_name = field.getName()

                if field_name == 'nodename' and maskname == 'settings':
                    if '__nodename' in req.params:
                        field_name = '__nodename'  # no multilang here !
                    elif getDefaultLanguage() + '__nodename' in req.params:
                        # no multilang here !
                        field_name = getDefaultLanguage() + '__nodename'
                    value = req.params.get(field_name, None)
                    if value:
                        if value != node.name:
                            flag_nodename_changed = str(node.id)
                        for node in nodes:
                            node.setName(value)
                elif field_name in ('repec.code', 'repec.provider') and maskname == 'settings':
                    if '__' + field_name in req.params:
                        field_name = '__' + field_name  # no multilang here!
                    elif getDefaultLanguage() + '__' + field_name in req.params:
                        field_name = getDefaultLanguage() + '__' + field_name  # no multilang here!

                value = req.params.get(field_name, None)

                if value is not None:
                    for node in nodes:
                        node.set(field.getName(), value)
                else:
                    node.set(field.getName(), "")

    if "edit_metadata" in req.params or node.get("faulty") == "true":
        if not hasattr(mask, "i_am_not_a_mask"):
            req.params["errorlist"] = mask.validate(nodes)

    node_versions = nodes[0].getVersionList()
    update_date, creation_date = get_datelists(nodes)

    data = {}
    data["versions"] = node_versions
    data["creation_date"] = creation_date
    data["update_date"] = update_date
    data["err"] = err

    _maskform, _fields = get_maskform_and_fields(nodes, mask, req)
    data["maskform"] = _maskform
    data["fields"] = _fields

    data.update(ctx)
    data["flag_nodename_changed"] = flag_nodename_changed

    ret += req.getTAL("web/edit/modules/metadata.html",
                      data, macro="edit_metadata")
    return ret
Ejemplo n.º 3
0
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
Ejemplo n.º 4
0
def getContent(req, ids):
    ret = ""
    user = users.getUserFromRequest(req)

    if "metadata" in users.getHideMenusForUser(user):
        print "error 1"
        req.setStatus(httpstatus.HTTP_FORBIDDEN)
        return req.getTAL("web/edit/edit.html", {}, macro="access_error")

    access = AccessData(req)
    faultydir = users.getFaultyDir(user)
    metatypes = []
    nodes = []
    masklist = []
    err = 0

    # flag indicating change of node.name (fancytree node may have to be updated)
    # keep as integer
    # negative -> no change
    # else -> id of changed node
    flag_nodename_changed = -1

    for id in ids:
        node = tree.getNode(id)
        if not access.hasWriteAccess(node):
            print "error 2"
            req.setStatus(httpstatus.HTTP_FORBIDDEN)
            return req.getTAL("web/edit/edit.html", {}, macro="access_error")

        schema = node.getSchema()
        if schema not in metatypes:
            metatypes.append(schema)
        if len(nodes) == 0 or nodes[0].getSchema() == schema:
            nodes += [node]

    idstr = ",".join(ids)
    action = req.params.get('action', '').strip()

    logger.info("%s in editor metadata (action=%r): %r" %
                (user.getName(), action, [[n.id, n.name, n.type]for n in nodes]))

    for m in node.getType().getMasks(type="edit"):
        if access.hasReadAccess(m):
            masklist.append(m)

    if hasattr(node, "metaFields"):

        class SystemMask:

            def __init__(self, name, description, fields):
                self.name, self.description, self.fields = name, description, fields

            def getName(self):
                return self.name

            def getDescription(self):
                return self.description

            def getDefaultMask(self):
                return False

            def metaFields(self, lang=None):
                return self.fields

            def i_am_not_a_mask():
                pass
        masklist = [SystemMask(
            "settings", t(req, "settings"), node.metaFields(lang(req)))] + masklist

    default = None
    for m in masklist:
        if m.getDefaultMask():
            default = m
            break
    if not default and len(masklist):
        default = masklist[0]

    maskname = req.params.get("mask", node.get("edit.lastmask") or "editmask")
    if maskname == "":
        maskname = default.getName()

    mask = None
    for m in masklist:
        if maskname == m.getName():
            mask = m
            break

    if not mask and default:
        mask = default
        maskname = default.getName()

    for n in nodes:
        n.set("edit.lastmask", maskname)

    if not mask:
        return req.getTAL("web/edit/modules/metadata.html", {}, macro="no_mask")

    # context default for TAL interpreter
    ctx = {}
    ctx["user"] = user
    ctx["access"] = access
    ctx["metatypes"] = metatypes
    ctx["idstr"] = idstr
    ctx["node"] = nodes[0]  # ?
    ctx["flag_nodename_changed"] = flag_nodename_changed
    ctx["nodes"] = nodes
    ctx["masklist"] = masklist
    ctx["maskname"] = maskname
    ctx["language"] = lang(req)
    ctx["t"] = t

    if action == 'restore':
        vid = req.params.get('vid', '0')
        node = nodes[0].getActiveVersion()
        if (vid != '0' and vid != node.id):
            n = tree.getNode(vid)
            # Not active version
            if n.next_nid != '0':

                next = tree.getNode(n.next_nid)
                if next.prev_nid != '0':
                    next.removeChild(tree.getNode(next.prev_nid))
                next.setPrevID(n.prev_nid)

                if n.prev_nid != '0':
                    prev = tree.getNode(n.prev_nid)
                    prev.setNextID(n.next_nid)
                    n.removeChild(prev)
                    next.addChild(prev)
                node.setNextID(n.id)

                n.setPrevID(node.id)
                n.setNextID('0')

                for pid in db.getParents(node.id):
                    parentNode = tree.getNode(pid)
                    parentNode.addChild(n)
                    parentNode.removeChild(node)
                n.addChild(node)

                nodes = [n]
                ids = [n.id]

                node_versions = nodes[0].getVersionList()
                update_date, creation_date = get_datelists(nodes)

                data = {'url': '?id=' + n.id + '&tab=metadata', 'pid':
                        None, 'flag_nodename_changed': flag_nodename_changed}

                data["versions"] = node_versions
                data["creation_date"] = creation_date
                data["update_date"] = update_date

                _maskform, _fields = get_maskform_and_fields(nodes, mask, req)
                data["maskform"] = _maskform
                data["fields"] = _fields

                data.update(ctx)

                return req.getTAL("web/edit/modules/metadata.html", data, macro="redirect")

    if action == 'delete':
        vid = req.params.get('vid', '0')
        if (vid != '0'):
            node = nodes[0].getActiveVersion()
            n = tree.getNode(vid)

            if (vid != node.id):
                n.set("deleted", "true")
                for pid in db.getParents(n.id):
                    parentNode = tree.getNode(pid)
                    parentNode.removeChild(n)
                for cid in db.getChildren(n.id):
                    n.removeChild(tree.getNode(cid))
                if n.next_nid != '0' and n.prev_nid != '0':
                    _next = tree.getNode(n.next_nid)
                    _next.addChild(tree.getNode(n.prev_nid))

                if n.next_nid != '0':
                    _next = tree.getNode(n.next_nid)
                    if n.prev_nid != '0':
                        _next.setPrevID(n.prev_nid)

                if n.prev_nid != '0':
                    _prev = tree.getNode(n.prev_nid)
                    if n.next_nid != '0':
                        _prev.setNextID(n.next_nid)
            else:
                pids = db.getParents(n.id)

                # Active version
                prev = None
                if n.prev_nid != '0':
                    prev = tree.getNode(n.prev_nid)
                    while prev.prev_nid != None and prev.prev_nid != '0' and prev.get("deleted") == "true":
                        prev = tree.getNode(prev.prev_nid)

                if prev != None and prev.get("deleted") != "true":
                    prev.setNextID('0')
                    for pid in pids:
                        parentNode = tree.getNode(pid)
                        parentNode.addChild(prev)
                    nodes = [prev]
                    ids = [prev.id]
                    n.set("deleted", "true")
                    for pid in pids:
                        parentNode = tree.getNode(pid)
                        parentNode.removeChild(n)

                    for cid in db.getChildren(n.id):
                        n.removeChild(tree.getNode(cid))

                    if n.next_nid != '0' and n.prev_nid != '0':
                        _next = tree.getNode(n.next_nid)
                        _next.addChild(tree.getNode(n.prev_nid))

                    node_versions = nodes[0].getVersionList()
                    update_date, creation_date = get_datelists(nodes)

                    data = {'url': '?id=' + prev.id + '&tab=metadata', 'pid':
                            None, 'flag_nodename_changed': flag_nodename_changed}

                    data["versions"] = node_versions
                    data["creation_date"] = creation_date
                    data["update_date"] = update_date

                    _maskform, _fields = get_maskform_and_fields(
                        nodes, mask, req)
                    data["maskform"] = _maskform
                    data["fields"] = _fields

                    data.update(ctx)

                    return req.getTAL("web/edit/modules/metadata.html", data, macro="redirect")
                else:
                    # Version 0
                    # Move node to trash
                    trashdir = users.getTrashDir(user)
                    trashdir.addChild(n)
                    for pid in pids:
                        parentNode = tree.getNode(pid)
                        parentNode.removeChild(n)

                    node_versions = nodes[0].getVersionList()
                    update_date, creation_date = get_datelists(nodes)

                    data = {'url': '?id=' + pids[0] + '&tab=content', 'pid': pids[
                        0], 'flag_nodename_changed': flag_nodename_changed}

                    data["versions"] = node_versions
                    data["creation_date"] = creation_date
                    data["update_date"] = update_date

                    _maskform, _fields = get_maskform_and_fields(
                        nodes, mask, req)
                    data["maskform"] = _maskform
                    data["fields"] = _fields

                    data.update(ctx)

                    return req.getTAL("web/edit/modules/metadata.html", data, macro="redirect")

    if "edit_metadata" in req.params:
        # check and save items
        userdir = users.getHomeDir(users.getUserFromRequest(req))

        for node in nodes:
            if not access.hasWriteAccess(node) or node.id == userdir.id:
                print "error 3"
                req.setStatus(httpstatus.HTTP_FORBIDDEN)
                return req.getTAL("web/edit/edit.html", {}, macro="access_error")

        logging.getLogger('usertracing').info(
            access.user.name + " change metadata " + idstr)
        logging.getLogger('editor').info(
            access.user.name + " change metadata " + idstr)
        logging.getLogger('editor').debug(pf(req.params))

        for node in nodes:
            node.set("updateuser", user.getName())
            if node.get('updatetime') < str(now()):
                node.set("updatetime", str(format_date()))

        if not hasattr(mask, "i_am_not_a_mask"):
            if (req.params.get('generate_new_version')):
                # Create new node version
                _ids = []
                _nodes = []
                for node in nodes:
                    n = node.createNewVersion(user)
                    n.set("system.version.comment", '(' + t(req, "document_new_version_comment") +
                          ')\n' + req.params.get('version_comment', ''))

                    # add all existing attributes to the new version node
                    for attr, value in node.items():
                        # do not overwrite existing attributes
                        # do not copy system attributes
                        if n.get(attr) != "" or attr.startswith("system."):
                            pass
                        else:
                            n.set(attr, value)

                    _nodes.append(n)
                    _ids.append(n.id)

                ids = _ids
                idstr = ",".join(ids)
                nodes = _nodes
                nodes = mask.updateNode(nodes, req)

                node_versions = nodes[0].getVersionList()
                update_date, creation_date = get_datelists(nodes)

                data = {
                    'url': '?id=' + nodes[0].id + '&tab=metadata',
                    'pid': None,
                }

                data["versions"] = node_versions
                data["creation_date"] = creation_date
                data["update_date"] = update_date

                _maskform, _fields = get_maskform_and_fields(
                    nodes, mask, req)
                data["maskform"] = _maskform
                data["fields"] = _fields

                data.update(ctx)

                ret += req.getTAL("web/edit/modules/metadata.html",
                                  data, macro="redirect")
            else:
                if nodes:
                    old_nodename = nodes[0].name
                nodes = mask.updateNode(nodes, req)
                if nodes:
                    new_nodename = nodes[0].name
                    if (old_nodename != new_nodename) and hasattr(nodes[0], 'isContainer') and nodes[0].isContainer():
                        # for updates of node label in editor tree
                        flag_nodename_changed = str(node.id)

        else:
            for field in mask.metaFields():
                msg = "in %s.%s: (hasattr(mask,'i_am_not_a_mask')) field: %r, field.id: %r, field.name: %r, mask: %r, maskname: %r" % (
                    __name__, funcname(), field, field.id, field.getName(), mask, maskname)
                logger.debug(msg)
                field_name = field.getName()
                if field_name == 'nodename' and maskname == 'settings':
                    if '__nodename' in req.params:
                        field_name = '__nodename'  # no multilang here !
                    elif getDefaultLanguage() + '__nodename' in req.params:
                        # no multilang here !
                        field_name = getDefaultLanguage() + '__nodename'
                    value = req.params.get(field_name, None)
                    if value:
                        if value != node.name:
                            flag_nodename_changed = str(node.id)
                        for node in nodes:
                            node.setName(value)
                value = req.params.get(field_name, None)
                if value is not None:
                    for node in nodes:
                        node.set(field.getName(), value)
                else:
                    node.set(field.getName(), "")

    if "edit_metadata" in req.params or node.get("faulty") == "true":
        if not hasattr(mask, "i_am_not_a_mask"):
            req.params["errorlist"] = mask.validate(nodes)

    node_versions = nodes[0].getVersionList()
    update_date, creation_date = get_datelists(nodes)

    data = {}
    data["versions"] = node_versions
    data["creation_date"] = creation_date
    data["update_date"] = update_date
    data["err"] = err

    _maskform, _fields = get_maskform_and_fields(nodes, mask, req)
    data["maskform"] = _maskform
    data["fields"] = _fields

    data.update(ctx)
    data["flag_nodename_changed"] = flag_nodename_changed

    ret += req.getTAL("web/edit/modules/metadata.html",
                      data, macro="edit_metadata")
    return ret