Example #1
0
def retrieveNodes(req, access, setspec, date_from=None, date_to=None, metadataformat=None):
    schemata = []

    if metadataformat == 'mediatum':
        metadatatypes = tree.getRoot('metadatatypes').getChildren()
        schemata = [m.name for m in metadatatypes if m.type == 'metadatatype' and m.name not in ['directory', 'collection']]
    elif metadataformat:
        mdt_masks_list = getExportMasks("oai_" + metadataformat.lower() + "$")  # check exact name
        schemata = [x[0][1] for x in mdt_masks_list if x[1]]

    if DEBUG:
        timetable_update(req, "in retrieveNodes: find schemata with export mask for metadata type %s (%d found: '%s')" %
                         (metadataformat.lower(), len(schemata), str([x for x in schemata])))

    if setspec:
        res = oaisets.getNodes(setspec, schemata)
    else:
        osp = OAISearchParser()
        query = " or ".join(["schema=%s" % schema for schema in schemata])
        res = osp.parse(query).execute()

    res = tree.NodeList(res)
    if DEBUG:
        timetable_update(req, "in retrieveNodes: after building NodeList for %d nodes" % (len(res)))

    if date_from:
        res = [n for n in res if n.get(DATEFIELD) >= str(date_from)]
        if DEBUG:
            timetable_update(req, "in retrieveNodes: after filtering date_from --> %d nodes" % (len(res)))
    if date_to:
        res = [n for n in res if n.get(DATEFIELD) <= str(date_to)]
        if DEBUG:
            timetable_update(req, "in retrieveNodes: after filtering date_to --> %d nodes" % (len(res)))

    if access:
        res = access.filter(res)
        if DEBUG:
            timetable_update(req, "in retrieveNodes: after access filter --> %d nodes" % (len(res)))

    collections = tree.getRoot('collections')
    res = [n for n in res if isDescendantOf(n, collections)]
    if DEBUG:
        timetable_update(req, "in retrieveNodes: after checking descendance from basenode --> %d nodes" % (len(res)))

    if schemata:
        res = [n for n in res if n.getSchema() in schemata]
        if DEBUG:
            timetable_update(req, "in retrieveNodes: after schemata (%s) filter --> %d nodes" % (str(schemata), len(res)))

    if metadataformat and metadataformat.lower() in FORMAT_FILTERS.keys():
        format_string = metadataformat.lower()
        res = [n for n in res if filterFormat(n, format_string)]
        if DEBUG:
            timetable_update(req, "in retrieveNodes: after format (%s) filter --> %d nodes" % (format_string, len(res)))

    return res
Example #2
0
def getMaskitemForField(field, language=None, mask=None):
    if mask:
        masks = [mask]
    else:
        mdt = [p for p in field.getParents() if p.type == 'metadatatype'][0]
        masks = [m for m in mdt.getChildren() if m.get('masktype') in ['shortview', 'fullview', 'editmask']]
        if masks and language:
            masks = [m for m in masks if m.get('language') in [language]]

    maskitems = [p for p in field.getParents() if p.type == 'maskitem']
    maskitems = [mi for mi in maskitems if 1 in [isDescendantOf(mi, m) for m in masks]]

    if maskitems:
        return maskitems[0]
    else:
        return None
Example #3
0
def getMaskitemForField(field, language=None, mask=None):
    if mask:
        masks = [mask]
    else:
        mdt = [p for p in field.getParents() if p.type == 'metadatatype'][0]
        masks = [
            m for m in mdt.getChildren()
            if m.get('masktype') in ['shortview', 'fullview', 'editmask']
        ]
        if masks and language:
            masks = [m for m in masks if m.get('language') in [language]]

    maskitems = [p for p in field.getParents() if p.type == 'maskitem']
    maskitems = [
        mi for mi in maskitems if 1 in [isDescendantOf(mi, m) for m in masks]
    ]

    if maskitems:
        return maskitems[0]
    else:
        return None
Example #4
0
def load_shoppingbagByKey(req):
    bagkey = req.params.get("bagkey", "")
    if bagkey == "":
        return 1
    for user in users.loadUsersFromDB():
        for c in user.getShoppingBag():
            if c.getSharedKey() == bagkey:
                req.session["shoppingbag"] = c.getItems()
                return 1

    candidates = db.getNodeIdByAttribute("key", bagkey)
    home_root = tree.getRoot("home")
    for cand in candidates:
        n = tree.getNode(cand)
        if not n.getContentType() == "shoppingbag":
            continue
        if isDescendantOf(n, home_root):
            req.session["shoppingbag"] = n.getItems()
            return 1

    return 0
Example #5
0
def getContent(req, ids):
    """
    The standard method,  which has to be implemented by every module.
    It's called in edit.py, where all the modules will be identified.
    """
    raise Exception("ACL must be fixed!")
    user = current_user
    node = q(Node).get(ids[0])

    # first prove if the user has the required rights to call this module
    if 'sortfiles' in user.hidden_edit_functions or not node.has_write_access(
    ):
        req.setStatus(httpstatus.HTTP_FORBIDDEN)
        return req.getTAL('web/edit/edit.html', {}, macro='access_error')

    if node.isContainer():
        nodes = u', '.join(node.children.getIDs())
    else:
        nodes = unicode(node.id)

    v = {
        'msg': '',
        'urn_institutionid': config.get('urn.institutionid'),
        'urn_pubtypes': config.get('urn.pubtypes').split(';'),
        'namespaces': config.get('urn.namespace').split(';'),
        'user': user,
        'nodes': nodes.split(', '),
        'type': req.params.get('id_type'),
        'show_form': True,
        'namespace': req.params.get('namespace'),
        'urn_type': req.params.get('urn_type'),
        'host': config.get('host.name'),
        'creator': user
    }

    if user.is_admin:
        if 'id_type' in req.params:
            if req.params.get('id_type') == 'urn':
                createUrn(node, req.params.get('namespace'),
                          req.params.get('urn_type'))
            elif req.params.get('id_type') == 'doi':
                try:
                    createDOI(node)
                except:
                    return _error(req, 500,
                                  "doi was not successfully registered")

            db.session.commit()

            if any(identifier in node.attributes
                   for identifier in ('urn', 'doi')):
                if not node.get('system.identifierdate'):
                    node.set('system.identifierdate', unicode(date.now()))
                    db.session.commit()
                if node.get('system.identifierstate') != '2':
                    node.set('system.identifierstate', u'2')
                    db.session.commit()

                    # add nobody ruleset if not set
                    if node.access_rule_assocs.filter_by(
                            ruletype=u'write', invert=True,
                            blocking=True).scalar() is None:
                        everybody_rule = AccessRule()
                        db.session.add(everybody_rule)
                        node.access_rule_assocs.append(
                            NodeToAccessRule(rule=everybody_rule,
                                             ruletype=u"write",
                                             invert=True,
                                             blocking=True))
                        db.session.commit()

                try:
                    mailtext = req.getTAL(
                        'web/edit/modules/identifier.html',
                        v,
                        macro='generate_identifier_usr_mail_2')
                    mail.sendmail(
                        config.get('email.admin'),  # email from
                        "%s;%s" % (config.get('email.admin'),
                                   user.getEmail()),  # email to
                        u'Vergabe eines Identifikators / Generation of an Identifier',
                        mailtext)

                except mail.SocketError:
                    logg.exception(
                        'failed to send Autorenvertrag mail to user %r (%s): %r'
                        % (user.login_name, user.getName(), user.getEmail()))
                    v['msg'] = t(lang(req), 'edit_identifier_mail_fail')

        if node.get('system.identifierstate') != '2':
            v['msg'] = t(lang(req), 'edit_identifier_state_0_1_admin')
        else:
            v['msg'] = t(lang(req), 'edit_identifier_state_2_admin')

    else:
        if pathutils.isDescendantOf(node, q(Collections).one()):
            if not node.get('system.identifierstate'):
                if 'id_type' in req.params:
                    try:
                        # fetch autorenvertrag
                        attachment = []
                        autorenvertrag_name = 'formular_autorenvertrag.pdf'
                        autorenvertrag_path = os.path.join(
                            config.get('paths.tempdir'), autorenvertrag_name)

                        if not os.path.isfile(autorenvertrag_path):
                            logg.error(
                                "Unable to attach Autorenvertrag. Attachment file not found: '%s'",
                                autorenvertrag_path)
                            raise IOError(
                                'Autorenvertrag was not located on disk at %s. Please send this error message to %s'
                                % (autorenvertrag_path,
                                   config.get('email.admin')))
                        else:
                            attachment.append(
                                (autorenvertrag_path, 'Autorenvertrag.pdf'))

                        # notify user
                        mailtext_user = req.getTAL(
                            'web/edit/modules/identifier.html',
                            v,
                            macro='generate_identifier_usr_mail_1_' +
                            lang(req))
                        mail.sendmail(
                            config.get('email.admin'),
                            ("%s;%s" %
                             (config.get('email.admin'), user.getEmail())),
                            unicode(
                                t(lang(req),
                                  'edit_identifier_mail_title_usr_1')),
                            mailtext_user,
                            attachments_paths_and_filenames=attachment)

                        # notify admin
                        mailtext_admin = req.getTAL(
                            'web/edit/modules/identifier.html',
                            v,
                            macro='generate_identifier_admin_mail')
                        mail.sendmail(
                            config.get('email.admin'),
                            config.get('email.admin'),
                            u'Antrag auf Vergabe eines Identifikators',
                            mailtext_admin)

                        node.set('system.identifierstate', u'1')
                        db.session.commit()

                        # add nobody rule if not set
                        if node.access_rule_assocs.filter_by(
                                ruletype=u'write', invert=True,
                                blocking=True).scalar() is None:
                            everybody_rule = AccessRule()
                            db.session.add(everybody_rule)
                            node.access_rule_assocs.append(
                                NodeToAccessRule(rule=everybody_rule,
                                                 ruletype=u"write",
                                                 invert=True,
                                                 blocking=True))
                            db.session.commit()

                    except mail.SocketError:
                        logg.exception(
                            'failed to send identifier request mail')
                        v['msg'] = t(lang(req), 'edit_identifier_mail_fail')
                else:
                    v['msg'] = t(lang(req), 'edit_identifier_state_0_usr')

            if node.get('system.identifierstate') == '1':
                v['show_form'] = False
                v['msg'] = t(lang(req), 'edit_identifier_state_1_usr')
        else:
            v['show_form'] = False
            v['msg'] = t(lang(req), 'edit_identifier_state_published')

    v['urn_val'] = node.get('urn')
    v['doi_val'] = node.get('doi')

    # hides form if all identifier types are already set
    if all(idents != '' for idents in (v['urn_val'], v['doi_val'])):
        v['show_form'] = False
        v['msg'] = t(lang(req), 'edit_identifier_all_types_set')

    v["csrf"] = req.csrf_token.current_token
    return req.getTAL('web/edit/modules/identifier.html',
                      v,
                      macro='set_identifier')
Example #6
0
def func_getSetSpecsForNode(self, node, schemata):
    res = []
    for setspec in self.d_names.keys():
        if isDescendantOf(node, q(Node).get(setspec)):
            res.append(setspec)
    return res
Example #7
0
def getContent(req, ids):

    reload(su)

    language = lang(req)
    user = users.getUserFromRequest(req)
    username = user.getName()
    #access = acl.AccessData(user=user)
    access = acl.AccessData(req=req)

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

    errors = []
    error = ''

    if "action" in req.params.keys():
        action = req.params.get("action")
        if action.startswith("get_fields_for_"):
            schedule_func = req.params.get(
                "action").replace("get_fields_for_", "")
            fields = su.fc_dict[schedule_func].getMetafields(lang(req))
            fieldDicts = su.fc_dict[schedule_func].getMetafieldDicts(lang(req))

            field_errors = []
            for i, field in enumerate(fields):
                field_errors.append(False)

            d = {
                'fields': fields,
                'fieldDicts': fieldDicts,
                'currentField': fields[0],
                'field_errors': field_errors,
                'currentFunction': schedule_func,
                'explain_func': su.fc_dict[schedule_func].getExplanation(language)
            }

            req.writeTAL("web/edit/modules/schedule.html", d,
                         macro="schedule_func_show_fields_and_explanation")
            return ""

        elif action.startswith("load_schedule_"):
            schedule_id = action.replace("load_schedule_", "")
            try:
                schedule = tree.getNode(schedule_id)
            except:
                errors.append("edit_schedule_no_such_node_error")
                return "no such schedule error"

            if not schedule.type == "schedule" and access and access.hasWriteAccess(schedule):
                return "schedule access error"

            schedule_func = schedule.get("function")
            if schedule_func:
                fields = su.fc_dict[schedule_func].getMetafields(lang(req))
                fieldDicts = su.fc_dict[
                    schedule_func].getMetafieldDicts(lang(req))
                d['explain_func'] = su.fc_dict[
                    schedule_func].getExplanation(language)
            else:
                fields = []
                fieldDicts = []
                d['explain_func'] = ""

            field_errors = []
            for i, field in enumerate(fields):
                field_errors.append(False)

            has_evaluation_errors = False
            for i, dfield in enumerate(fieldDicts):
                field_name = dfield['field_name']
                field_value = schedule.get(field_name)
                dfield['value'] = field_value
                field_validator_func = dfield['field_validator_func']
                if field_validator_func and not field_validator_func(field_value):
                    dfield['evaluation_error'] = True
                    has_evaluation_errors = True
                else:
                    dfield['evaluation_error'] = False

            if has_evaluation_errors:
                error = "\n<br/>\n".join([error, t(language,
                                                   'edit_schedule_field_validation_error')])

            d = {
                'fields': fields,
                'fieldDicts': fieldDicts,
                'currentField': fields[0],
                'field_errors': field_errors,
                'currentFunction': schedule_func,
            }

            req.writeTAL("web/edit/modules/schedule.html", d,
                         macro="schedule_func_show_fields_and_explanation")
            return ""

        elif action == "delete_node_from_schedule":

            node_id = req.params.get('node_id', None)

            if node_id:
                pass
            else:
                errors.append("edit_schedule_unexpected_no_such_node")

            schedule_id = req.params.get('schedule_id', None)
            if schedule_id:
                try:
                    schedule = tree.getNode(schedule_id)
                except:
                    errors.append(
                        "edit_schedule_unexpected_no_such_schedule_node")
            else:
                errors.append("edit_schedule_unexpected_no_such_schedule_node")

            delete_errors = su.deleteNodeIDsFromSchedule(
                [node_id], schedule_id, access=access)

            if not delete_errors:
                msg = "user '%s' removed node %s from schedule '%s' (%s)" % (
                    username, node_id, schedule.name, schedule_id)
                logging.getLogger("backend").info(msg)
            else:
                error_msg = ", ".join([t(language, e) for e in delete_errors])
                msg = "user '%s' tried to remove node %s from schedule '%s' (%s): %s" % (
                    username, node_id, schedule.name, schedule_id, error_msg)
                logging.getLogger("backend").error(msg)

            errors += delete_errors

            s = {}
            s['errors'] = errors
            s['delete_errors'] = delete_errors

            s['delete_table_rows'] = ['sid_%s' % schedule_id]

            res_msg = req.params.get(
                "jsoncallback") + "(%s)" % json.dumps(s, indent=4)
            req.write(res_msg)
            return ""

        elif action == "delete_schedule":
            schedule_id = req.params.get('schedule_id', None)
            if schedule_id:
                try:
                    schedule = tree.getNode(schedule_id)
                except:
                    errors.append(
                        "edit_schedule_unexpected_no_such_schedule_node")
            else:
                errors.append("edit_schedule_unexpected_no_such_schedule_node")

            delete_errors = su.deleteSchedule(schedule_id, access=access)

            if not delete_errors:
                msg = "user '%s' removed schedule %s (%s)" % (
                    username, schedule.name, schedule_id)
                logging.getLogger("backend").info(msg)
            else:
                error_msg = ", ".join([t(language, e) for e in delete_errors])
                msg = "user '%s' tried to remove schedule '%s' (%s): %s" % (
                    username, schedule.name, schedule_id, error_msg)
                logging.getLogger("backend").error(msg)

            errors += delete_errors

            s = {}
            s['errors'] = errors
            s['delete_errors'] = delete_errors
            s['delete_table_rows'] = ['sid_%s' % schedule_id]

            res_msg = req.params.get(
                "jsoncallback") + "(%s)" % json.dumps(s, indent=4)
            req.write(res_msg)
            return ""

        elif action == "load_table_nid2schedules":

            nid2schedules, schedule2nids, nid2active_schedules = su.getSchedulesForIds(
                ids, access=access, language=language)

            nid2schedules_attrs = {}
            for nid in nid2schedules:
                nid2schedules_attrs[nid] = [
                    [s.id, s.name, s.get("single_trigger")] for s in nid2schedules[nid]['schedule_list']]

            d = {}
            d['nid2schedules'] = nid2schedules
            d['nid2active_schedules'] = nid2active_schedules
            d['errors'] = ['testerror1', 'testerror1']
            d['date'] = datetime.now().isoformat()
            d['isActive'] = su.isActive

            req.writeTAL(
                "web/edit/modules/schedule.html", d, macro="table_nid2schedules")
            return ""

        elif action == "load_table_schedule2nids":

            nid2schedules, schedule2nids, nid2active_schedules = su.getSchedulesForIds(
                ids, access=access, language=language)

            nid2schedules_attrs = {}
            for nid in nid2schedules:
                nid2schedules_attrs[nid] = [
                    [s.id, s.name, s.get("single_trigger")] for s in nid2schedules[nid]['schedule_list']]

            d = {}
            d['nid2schedules'] = nid2schedules
            d['schedule2nids'] = schedule2nids
            d['nid2active_schedules'] = nid2active_schedules
            d['errors'] = ['testerror1', 'testerror1']
            d['date'] = datetime.now().isoformat()
            d['isActive'] = su.isActive

            req.writeTAL(
                "web/edit/modules/schedule.html", d, macro="table_schedule2nids")
            return ""

    nid2schedules, schedule2nids, nid2active_schedules = su.getSchedulesForIds(
        ids, access=access, language=language)

    datetime_str = req.params.get("datetime", "").strip()
    datetime_error = False
    has_evaluation_errors = False

    if datetime_str:
        patter = "^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}$"
        if not re.match(patter, datetime_str):
            error = t(
                language, "edit_schedule_input_datetime_format_error") % datetime_str
            datetime_error = True
        else:
            try:
                parser_test_result = datetime.strptime(
                    datetime_str, "%Y-%m-%dT%H:%M")  # "%Y-%m-%dT%H:%M:%S.%f"
            except:
                parser_test_result = None
                error = t(
                    language, "edit_schedule_input_datetime_format_error") % datetime_str
                datetime_error = True
            if parser_test_result and datetime_str <= datetime.now().isoformat():
                error = t(
                    language, "edit_schedule_input_datetime_already_past_error") % datetime_str
                datetime_error = True
    elif "submit" in req.params:
        error = t(
            language, "edit_schedule_input_datetime_format_error") % datetime_str
        datetime_error = True

    schedule_id = req.params.get("schedule_id", "")
    if schedule_id:
        schedule = tree.getNode(schedule_id)
        if access and not access.hasWriteAccess(schedule):
            errors.append("edit_schedule_no_access_error")
            schedule = None
            current_function = req.params.get('schedule_function', '')
        else:
            current_function = schedule.get("function")
    else:
        schedule = None
        current_function = req.params.get('schedule_function', '')

    if "submit" in req.params or "submit_run_now" in req.params:
        current_function = req.params.get('schedule_function', '')
        if current_function in su.fc_dict:
            field_descriptors = su.fc_dict[
                current_function].getFieldDescriptors()
            field_errors = []
        else:
            # should not happen
            msg = "-> unexpected error: 'non-existant schedule function' requested in module %s: :s" % (
                str(__file__), str(inspect.currentframe().f_lineno))
            print msg
            logging.getLogger("backend").error(msg)

    d = {
        "id": req.params.get("id")
    }

    # nodes list is used to display icons in upper part of page
    # additional nodes should not / will not be shown there
    nodes = []
    for nid in ids:
        node = tree.getNode(nid)
        nodes.append(node)

    d['nodes'] = nodes

    if current_function in su.fc_dict:
        fields = su.fc_dict[current_function].getMetafields(lang(req))
        fieldDicts = su.fc_dict[current_function].getMetafieldDicts(lang(req))
        d['explain_func'] = su.fc_dict[
            current_function].getExplanation(language)
    else:
        fields = []
        fieldDicts = []
        d['explain_func'] = ""

    if not "submit_run_now" in req.params:
        has_evaluation_errors = datetime_error

    if schedule and not "submit" in req.params and not "submit_run_now" in req.params:
        for i, dfield in enumerate(fieldDicts):
            field_name = dfield['field_name']
            field_value = schedule.get(field_name)
            dfield['value'] = field_value
            field_validator_func = dfield['field_validator_func']
            if field_validator_func and not field_validator_func(field_value):
                dfield['evaluation_error'] = True
                has_evaluation_errors = True
            else:
                dfield['evaluation_error'] = False
    else:
        for i, dfield in enumerate(fieldDicts):
            field_name = dfield['field_name']
            # m_* classes from metadata/ are not multilingual for schedules
            # their getEditorHTML methods are used to display schedule node
            # attributes
            field_value = req.params.get(
                getDefaultLanguage() + '__' + field_name, '')
            dfield['value'] = field_value
            field_validator_func = dfield['field_validator_func']
            if field_validator_func and not field_validator_func(field_value):
                dfield['evaluation_error'] = True
                has_evaluation_errors = True
            else:
                dfield['evaluation_error'] = False

    additional_nodes_str = req.params.get("additional_nodes", "")
    additional_nodes_error = False
    additional_nodes_bad_ids = []

    try:
        additional_nodes_id_list = [
            str(int(nid.strip())) for nid in additional_nodes_str.strip().split(";") if nid.strip()]
    except:
        has_evaluation_errors = True
        additional_nodes_error = True
        additional_nodes_id_list = []
        errors.append(
            "edit_schedule_additional_nodes_list_not_semikolon_separated_list_of_integers")

    if not additional_nodes_error:
        collections_root = tree.getRoot("collections")
        for nid in additional_nodes_id_list:
            n = None
            try:
                n = tree.getNode(nid)
            except tree.NoSuchNodeError as e:
                has_evaluation_errors = True
                additional_nodes_error = True
                if nid not in additional_nodes_bad_ids:
                    additional_nodes_bad_ids.append(nid)
            if n and (not isDescendantOf(n, collections_root) or not access.hasWriteAccess(n)):
                # to do? discussion: override collections rectriction for
                # admins ?
                has_evaluation_errors = True
                additional_nodes_error = True
                if nid not in additional_nodes_bad_ids:
                    additional_nodes_bad_ids.append(nid)

    if additional_nodes_bad_ids:
        has_evaluation_errors = True
        additional_nodes_error = True
        errors.append(t(language, "edit_schedule_additional_nodes_bad_ids") +
                      (";".join(additional_nodes_bad_ids)))

    if has_evaluation_errors:
        errors.append('edit_schedule_field_validation_error')
        error = "\n<br/>\n".join(map(lambda x:
                                     t(language, x), [error] + errors))

    d['fields'] = fields
    d['fieldDicts'] = fieldDicts
    d['field_errors'] = [False] * len(fields)
    d['currentField'] = None
    d['currentFunction'] = current_function

    d['error'] = error

    d['fc_dict'] = su.filter_access(su.fc_dict, access)

    d['input_datetime'] = datetime_str
    d['input_datetime_error'] = datetime_error

    d['nid2schedules'] = nid2schedules
    d['schedule2nids'] = schedule2nids
    d['nid2active_schedules'] = nid2active_schedules

    d['loaded_schedule'] = schedule

    if schedule:
        d['loaded_schedule_id'] = str(schedule.id)
    else:
        d['loaded_schedule_id'] = None

    d['mklink'] = su.mklink

    d['language'] = language
    d['t'] = t
    d['isActive'] = su.isActive

    d['result'] = ''

    d['created_new_schedule'] = False

    d['additional_nodes'] = additional_nodes_str
    d['additional_nodes_error'] = additional_nodes_error

    d['submitbutton_run_now_label'] = t(
        language, 'edit_schedule_submit_run_now_button')
    d['edit_schedule_submit_run_now_button_confirm'] = t(
        language, 'edit_schedule_submit_run_now_button_confirm')
    d['edit_schedule_delete_schedule_confirm'] = t(
        language, 'edit_schedule_delete_schedule_confirm')

    if has_evaluation_errors and not ('submit_run_now' in req.params):
        return req.getTAL("web/edit/modules/schedule.html", d, macro="schedule_popup")

    new_schedule = None
    if (not schedule and "submit" in req.params) or "submit_run_now" in req.params:

        new_schedule_name = user.name + \
            "_created_at_" + datetime.now().isoformat()
        new_schedule = tree.Node(new_schedule_name, 'schedule')

        username = user.getName()
        new_schedule.setAccess("write", "{user %s}" % username)

        if not "submit_run_now" in req.params:
            schedules = tree.getRoot("schedules")
            schedules.addChild(new_schedule)

            msg = "user '%s' created new schedule '%s' (%s), trigger='%s', function='%s', nodelist='%s'" % (
                username, new_schedule.name, str(new_schedule.id), datetime_str, d['currentFunction'], new_schedule.get('nodelist'))
            logging.getLogger("backend").info(msg)

            d['result'] = t(
                language, 'edit_schedule_result_new_schedule_created')
            d['created_new_schedule'] = True
        else:
            msg = "user '%s' created temporary schedule '%s' (%s), trigger='%s', function='%s', nodelist='%s'" % (
                username, new_schedule.name, str(new_schedule.id), datetime_str, d['currentFunction'], new_schedule.get('nodelist'))
            logging.getLogger("backend").info(msg)

            d['result'] = t(
                language, 'edit_schedule_result_temporary_schedule_created')
            d['created_temporary_schedule'] = True

    elif (schedule) and ("submit" in req.params):
        new_schedule = schedule
        msg = "user '%s' is editing schedule '%s' (%s), trigger='%s', function='%s', nodelist='%s'" % (
            username, new_schedule.name, str(new_schedule.id), datetime_str, d['currentFunction'], new_schedule.get('nodelist'))
        logging.getLogger("backend").info(msg)
        new_schedule.set("system.edited", datetime.now().isoformat())

        d['result'] = t(
            language, 'edit_schedule_result_existing_schedule_edited')

    if new_schedule:
        for i, dfield in enumerate(fieldDicts):
            field_name = dfield['field_name']
            field_value = dfield['value']
            new_schedule.set(field_name, field_value)

        ids_plus_additional_nodes = ids
        for nid in additional_nodes_id_list:
            if nid not in ids_plus_additional_nodes:
                ids_plus_additional_nodes.append(nid)

        new_schedule.set('function', d['currentFunction'])
        new_schedule.set('nodelist', ",".join(ids_plus_additional_nodes))
        new_schedule.set('single_trigger', datetime_str)

        if datetime.now().isoformat() < datetime_str:
            new_schedule.set('single_trigger_status', '')

        if "submit_run_now" in req.params:
            new_schedule.set("single_trigger", datetime.now().isoformat())
            has_fired, has_error, TT = su.handle_single_trigger(
                new_schedule, datetime.now().isoformat(), su.OUT)
            if has_error:
                _error1 = d['error']
                _error2 = "<br/>\n".join(map(lambda x:
                                             (t(language, str(x))), TT))
                _error = "<br/>\n".join([_error1, _error2])
                d['error'] = _error

    return req.getTAL("web/edit/modules/schedule.html", d, macro="schedule_popup")
Example #8
0
def getContent(req, ids):
    """
    The standard method,  which has to be implemented by every module.
    It's called in edit.py, where all the modules will be identified.
    """
    user = users.getUserFromRequest(req)
    access = acl.AccessData(req)
    node = tree.getNode(ids[0])
    access_nobody = 'nicht Jeder'

    # first prove if the user has the required rights to call this module
    if 'sortfiles' in users.getHideMenusForUser(
            user) or not access.hasWriteAccess(node):
        req.setStatus(httpstatus.HTTP_FORBIDDEN)
        return req.getTAL('web/edit/edit.html', {}, macro='access_error')

    if node.isContainer():
        nodes = ', '.join(node.getChildren().getIDs())
    else:
        nodes = node.get('node.id')

    v = {
        'msg': '',
        'urn_institutionid': config.get('urn.institutionid'),
        'urn_pubtypes': config.get('urn.pubtypes').split(';'),
        'namespaces': config.get('urn.namespace').split(';'),
        'user': user,
        'nodes': nodes,
        'type': req.params.get('id_type'),
        'show_form': True,
        'namespace': req.params.get('namespace'),
        'urn_type': req.params.get('urn_type'),
        'host': config.get('host.name'),
        'creator': users.getUser(node.get('creator'))
    }

    if user.isAdmin():
        if 'id_type' in req.params:
            if req.params.get('id_type') == 'hash':
                createHash(node)
            if req.params.get('id_type') == 'urn':
                createUrn(node, req.params.get('namespace'),
                          req.params.get('urn_type'))
            if req.params.get('id_type') == 'doi':
                try:
                    createDOI(node)
                except:
                    return req.error(500,
                                     "doi was not successfully registered")

            if any(identifier in node.attributes
                   for identifier in ('hash', 'urn', 'doi')):
                if not node.get('system.identifierdate'):
                    node.set('system.identifierdate', date.now())
                if node.get('system.identifierstate') != '2':
                    node.set('system.identifierstate', '2')

                    # add nobody rule if not set
                    if node.getAccess('write') is None:
                        node.setAccess('write', access_nobody)
                    else:
                        if access_nobody not in node.getAccess('write'):
                            node.setAccess(
                                'write', ','.join(
                                    [node.getAccess('write'), access_nobody]))

                try:
                    mailtext = req.getTAL(
                        'web/edit/modules/identifier.html',
                        v,
                        macro='generate_identifier_usr_mail_2')
                    mail.sendmail(
                        config.get('email.admin'),
                        users.getUser(node.get('creator')).get('email'),
                        'Vergabe eines Idektifikators / Generation of an Identifier',
                        mailtext)

                except mail.SocketError:
                    logging.getLogger('backend').error(
                        'failed to send Autorenvertrag mail to user %s' %
                        node.get('creator'))
                    v['msg'] = t(lang(req), 'edit_identifier_mail_fail')

        if node.get('system.identifierstate') != '2':
            v['msg'] = t(lang(req), 'edit_identifier_state_0_1_admin')
        else:
            v['msg'] = t(lang(req), 'edit_identifier_state_2_admin')

    else:
        if pathutils.isDescendantOf(node, tree.getRoot('collections')):
            if not node.get('system.identifierstate'):
                if 'id_type' in req.params:
                    try:
                        # fetch autorenvertrag
                        attachment = []
                        autorenvertrag_name = 'formular_autorenvertrag.pdf'
                        autorenvertrag_path = os.path.join(
                            config.get('paths.tempdir'), autorenvertrag_name)

                        if not os.path.isfile(autorenvertrag_path):
                            logging.getLogger('backend').error(
                                "Unable to attach Autorenvergrag. Attachment file not found: '%s'"
                                % autorenvertrag_path)
                            raise IOError(
                                'Autorenvertrag was not located on disk at %s. Please send this error message to %s'
                                % (autorenvertrag_path,
                                   config.get('email.admin')))
                        else:
                            attachment.append(
                                (autorenvertrag_path, 'Autorenvertrag.pdf'))

                        # notify user
                        mailtext_user = req.getTAL(
                            'web/edit/modules/identifier.html',
                            v,
                            macro='generate_identifier_usr_mail_1_' +
                            lang(req))
                        mail.sendmail(
                            config.get('email.admin'),
                            user.get('email'),
                            t(lang(req), 'edit_identifier_mail_title_usr_1'),
                            mailtext_user,
                            attachments_paths_and_filenames=attachment)

                        # notify admin
                        mailtext_admin = req.getTAL(
                            'web/edit/modules/identifier.html',
                            v,
                            macro='generate_identifier_admin_mail')
                        mail.sendmail(
                            config.get('email.admin'),
                            config.get('email.admin'),
                            'Antrag auf Vergabe eines Identifikators',
                            mailtext_admin)

                        node.set('system.identifierstate', '1')

                        # add nobody rule
                        print node.getAccess('write')
                        if node.getAccess('write') is None:
                            node.setAccess('write', access_nobody)
                        else:
                            if access_nobody not in node.getAccess('write'):
                                node.setAccess(
                                    'write', ','.join([
                                        node.getAccess('write'), access_nobody
                                    ]))

                    except mail.SocketError:
                        logging.getLogger('backend').error(
                            'failed to send identifier request mail')
                        v['msg'] = t(lang(req), 'edit_identifier_mail_fail')
                else:
                    v['msg'] = t(lang(req), 'edit_identifier_state_0_usr')

            if node.get('system.identifierstate') == '1':
                v['show_form'] = False
                v['msg'] = t(lang(req), 'edit_identifier_state_1_usr')
        else:
            v['show_form'] = False
            v['msg'] = t(lang(req), 'edit_identifier_state_published')

    v['hash_val'] = node.get('hash')
    v['urn_val'] = node.get('urn')
    v['doi_val'] = node.get('doi')

    # hides form if all identifier types are already set
    if all(idents != ''
           for idents in (v['hash_val'], v['urn_val'], v['doi_val'])):
        v['show_form'] = False
        v['msg'] = t(lang(req), 'edit_identifier_all_types_set')

    return req.getTAL('web/edit/modules/identifier.html',
                      v,
                      macro='set_identifier')
Example #9
0
def retrieveNodes(req,
                  access,
                  setspec,
                  date_from=None,
                  date_to=None,
                  metadataformat=None):
    schemata = []

    if metadataformat == 'mediatum':
        metadatatypes = tree.getRoot('metadatatypes').getChildren()
        schemata = [
            m.name for m in metadatatypes if m.type == 'metadatatype'
            and m.name not in ['directory', 'collection']
        ]
    elif metadataformat:
        mdt_masks_list = getExportMasks("oai_" + metadataformat.lower() +
                                        "$")  # check exact name
        schemata = [x[0][1] for x in mdt_masks_list if x[1]]

    if DEBUG:
        timetable_update(
            req,
            "in retrieveNodes: find schemata with export mask for metadata type %s (%d found: '%s')"
            %
            (metadataformat.lower(), len(schemata), str([x
                                                         for x in schemata])))

    if setspec:
        res = oaisets.getNodes(setspec, schemata)
    else:
        osp = OAISearchParser()
        query = " or ".join(["schema=%s" % schema for schema in schemata])
        res = osp.parse(query).execute()

    res = tree.NodeList(res)
    if DEBUG:
        timetable_update(
            req, "in retrieveNodes: after building NodeList for %d nodes" %
            (len(res)))

    if date_from:
        res = [n for n in res if n.get(DATEFIELD) >= str(date_from)]
        if DEBUG:
            timetable_update(
                req,
                "in retrieveNodes: after filtering date_from --> %d nodes" %
                (len(res)))
    if date_to:
        res = [n for n in res if n.get(DATEFIELD) <= str(date_to)]
        if DEBUG:
            timetable_update(
                req, "in retrieveNodes: after filtering date_to --> %d nodes" %
                (len(res)))

    if access:
        res = access.filter(res)
        if DEBUG:
            timetable_update(
                req, "in retrieveNodes: after access filter --> %d nodes" %
                (len(res)))

    collections = tree.getRoot('collections')
    res = [n for n in res if isDescendantOf(n, collections)]
    if DEBUG:
        timetable_update(
            req,
            "in retrieveNodes: after checking descendance from basenode --> %d nodes"
            % (len(res)))

    if schemata:
        res = [n for n in res if n.getSchema() in schemata]
        if DEBUG:
            timetable_update(
                req,
                "in retrieveNodes: after schemata (%s) filter --> %d nodes" %
                (str(schemata), len(res)))

    if metadataformat and metadataformat.lower() in FORMAT_FILTERS.keys():
        format_string = metadataformat.lower()
        res = [n for n in res if filterFormat(n, format_string)]
        if DEBUG:
            timetable_update(
                req,
                "in retrieveNodes: after format (%s) filter --> %d nodes" %
                (format_string, len(res)))

    return res
Example #10
0
def retrieveNodes(req, setspec, date_from=None, date_to=None, metadataformat=None):
    schemata = []

    nodequery = None
    res = []

    if metadataformat == 'mediatum':
        metadatatypes = q(Metadatatypes).one().children
        schemata = [m.name for m in metadatatypes if m.type == 'metadatatype' and m.name not in ['directory', 'collection']]
    elif metadataformat:
        schemata = get_schemata_for_metadataformat(metadataformat)

    if DEBUG:
        timetable_update(req, "in retrieveNodes: find schemata with export mask for metadata type %s (%d found: '%s')" %
                         (metadataformat.lower(), len(schemata), ustr([x for x in schemata])))

    if setspec:
        nodequery = oaisets.getNodesQueryForSetSpec(setspec, schemata)
        # if for this oai group set no function is defined that retrieve the nodes query, use the filters
        if not nodequery:
            collections_root = q(Collections).one()
            nodequery = collections_root.all_children
            setspecFilter = oaisets.getNodesFilterForSetSpec(setspec, schemata)
            if schemata:
                nodequery = nodequery.filter(Node.schema.in_(schemata))
            if type(setspecFilter) == list:
                for sFilter in setspecFilter:
                    nodequery = nodequery.filter(sFilter)
            else:
                nodequery = nodequery.filter(setspecFilter)
    else:
        collections_root = q(Collections).one()
        nodequery = collections_root.all_children
        nodequery = nodequery.filter(Node.schema.in_(schemata))

    if DEBUG:
        timetable_update(req, "in retrieveNodes: after building NodeList for %d nodes" % (len(res)))

    if date_from:
        nodequery = nodequery.filter(Node.attrs[DATEFIELD].astext >= str(date_from))
        if DEBUG:
            timetable_update(req, "in retrieveNodes: after filtering date_from --> %d nodes" % (len(res)))
    if date_to:
        nodequery = nodequery.filter(Node.attrs[DATEFIELD].astext <= str(date_to))
        if DEBUG:
            timetable_update(req, "in retrieveNodes: after filtering date_to --> %d nodes" % (len(res)))

    if nodequery:
        guest_user = get_guest_user()
        nodequery = nodequery.filter_read_access(user=guest_user)
    else:
        res = [n for n in res if n.has_read_access(user=get_guest_user())]
    if DEBUG:
        timetable_update(req, "in retrieveNodes: after read access filter --> %d nodes" % (len(res)))

    if not nodequery:
        collections = q(Collections).one()
        res = [n for n in res if isDescendantOf(n, collections)]
    if DEBUG:
        timetable_update(req, "in retrieveNodes: after checking descendance from basenode --> %d nodes" % (len(res)))

    # superflous ?!
    #if schemata:
    #    res = [n for n in res if n.getSchema() in schemata]
    #    if DEBUG:
    #        timetable_update(req, "in retrieveNodes: after schemata (%s) filter --> %d nodes" % (ustr(schemata), len(res)))

    if metadataformat and metadataformat.lower() in FORMAT_FILTERS.keys():
        format_string = metadataformat.lower()
        format_filter = FORMAT_FILTERS[format_string]['filterQuery']
        nodequery = nodequery.filter(format_filter)
        #res = [n for n in res if filterFormat(n, format_string)]
        if DEBUG:
            timetable_update(req, "in retrieveNodes: after format (%s) filter --> %d nodes" % (format_string, len(res)))

    if nodequery:
        res = nodequery

    return res
Example #11
0
def func_getSetSpecsForNode(self, node, schemata):
    res = []
    for setspec in self.d_names.keys():
        if isDescendantOf(node, tree.getNode(setspec)):
            res.append(setspec)
    return res
Example #12
0
def getContent(req, ids):
    """
    The standard method,  which has to be implemented by every module.
    It's called in edit.py, where all the modules will be identified.
    """
    user = users.getUserFromRequest(req)
    access = acl.AccessData(req)
    node = tree.getNode(ids[0])
    access_nobody = 'nicht Jeder'

    # first prove if the user has the required rights to call this module
    if 'sortfiles' in users.getHideMenusForUser(user) or not access.hasWriteAccess(node):
        req.setStatus(httpstatus.HTTP_FORBIDDEN)
        return req.getTAL('web/edit/edit.html', {}, macro='access_error')

    if node.isContainer():
        nodes = ', '.join(node.getChildren().getIDs())
    else:
        nodes = node.get('node.id')

    v = {'msg': '',
         'urn_institutionid': config.get('urn.institutionid'),
         'urn_pubtypes': config.get('urn.pubtypes').split(';'),
         'namespaces': config.get('urn.namespace').split(';'),
         'user': user,
         'nodes': nodes,
         'type': req.params.get('id_type'),
         'show_form': True,
         'namespace': req.params.get('namespace'),
         'urn_type': req.params.get('urn_type'),
         'host': config.get('host.name'),
         'creator': users.getUser(node.get('creator'))
         }

    if user.isAdmin():
        if 'id_type' in req.params:
            if req.params.get('id_type') == 'hash':
                createHash(node)
            if req.params.get('id_type') == 'urn':
                createUrn(node, req.params.get('namespace'), req.params.get('urn_type'))
            if req.params.get('id_type') == 'doi':
                try:
                    createDOI(node)
                except:
                    return req.error(500, "doi was not successfully registered")

            if any(identifier in node.attributes for identifier in ('hash', 'urn', 'doi')):
                if not node.get('system.identifierdate'):
                    node.set('system.identifierdate', date.now())
                if node.get('system.identifierstate') != '2':
                    node.set('system.identifierstate', '2')

                    # add nobody rule if not set
                    if node.getAccess('write') is None:
                        node.setAccess('write', access_nobody)
                    else:
                        if access_nobody not in node.getAccess('write'):
                            node.setAccess('write', ','.join([node.getAccess('write'), access_nobody]))

                try:
                    mailtext = req.getTAL('web/edit/modules/identifier.html', v, macro='generate_identifier_usr_mail_2')
                    mail.sendmail(config.get('email.admin'),
                                  users.getUser(node.get('creator')).get('email'),
                                  'Vergabe eines Idektifikators / Generation of an Identifier',
                                  mailtext)

                except mail.SocketError:
                    logging.getLogger('backend').error('failed to send Autorenvertrag mail to user %s' % node.get('creator'))
                    v['msg'] = t(lang(req), 'edit_identifier_mail_fail')

        if node.get('system.identifierstate') != '2':
            v['msg'] = t(lang(req), 'edit_identifier_state_0_1_admin')
        else:
            v['msg'] = t(lang(req), 'edit_identifier_state_2_admin')

    else:
        if pathutils.isDescendantOf(node, tree.getRoot('collections')):
            if not node.get('system.identifierstate'):
                if 'id_type' in req.params:
                    try:
                        # fetch autorenvertrag
                        attachment = []
                        autorenvertrag_name = 'formular_autorenvertrag.pdf'
                        autorenvertrag_path = os.path.join(config.get('paths.tempdir'),
                                                           autorenvertrag_name)

                        if not os.path.isfile(autorenvertrag_path):
                            logging.getLogger('backend').error(
                                "Unable to attach Autorenvergrag. Attachment file not found: '%s'" % autorenvertrag_path)
                            raise IOError('Autorenvertrag was not located on disk at %s. Please send this error message to %s' %
                                          (autorenvertrag_path, config.get('email.admin')))
                        else:
                            attachment.append((autorenvertrag_path, 'Autorenvertrag.pdf'))

                        # notify user
                        mailtext_user = req.getTAL(
                            'web/edit/modules/identifier.html', v, macro='generate_identifier_usr_mail_1_' + lang(req))
                        mail.sendmail(config.get('email.admin'),
                                      user.get('email'),
                                      t(lang(req), 'edit_identifier_mail_title_usr_1'),
                                      mailtext_user,
                                      attachments_paths_and_filenames=attachment)

                        # notify admin
                        mailtext_admin = req.getTAL('web/edit/modules/identifier.html', v, macro='generate_identifier_admin_mail')
                        mail.sendmail(config.get('email.admin'),
                                      config.get('email.admin'),
                                      'Antrag auf Vergabe eines Identifikators',
                                      mailtext_admin)

                        node.set('system.identifierstate', '1')

                        # add nobody rule
                        print node.getAccess('write')
                        if node.getAccess('write') is None:
                            node.setAccess('write', access_nobody)
                        else:
                            if access_nobody not in node.getAccess('write'):
                                node.setAccess('write', ','.join([node.getAccess('write'), access_nobody]))

                    except mail.SocketError:
                        logging.getLogger('backend').error('failed to send identifier request mail')
                        v['msg'] = t(lang(req), 'edit_identifier_mail_fail')
                else:
                    v['msg'] = t(lang(req), 'edit_identifier_state_0_usr')

            if node.get('system.identifierstate') == '1':
                v['show_form'] = False
                v['msg'] = t(lang(req), 'edit_identifier_state_1_usr')
        else:
            v['show_form'] = False
            v['msg'] = t(lang(req), 'edit_identifier_state_published')

    v['hash_val'] = node.get('hash')
    v['urn_val'] = node.get('urn')
    v['doi_val'] = node.get('doi')

    # hides form if all identifier types are already set
    if all(idents != '' for idents in (v['hash_val'], v['urn_val'], v['doi_val'])):
        v['show_form'] = False
        v['msg'] = t(lang(req), 'edit_identifier_all_types_set')

    return req.getTAL('web/edit/modules/identifier.html', v, macro='set_identifier')
Example #13
0
def getContent(req, ids):

    reload(su)

    language = lang(req)
    user = users.getUserFromRequest(req)
    username = user.getName()
    #access = acl.AccessData(user=user)
    access = acl.AccessData(req=req)

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

    errors = []
    error = ''

    if "action" in req.params.keys():
        action = req.params.get("action")
        if action.startswith("get_fields_for_"):
            schedule_func = req.params.get("action").replace(
                "get_fields_for_", "")
            fields = su.fc_dict[schedule_func].getMetafields(lang(req))
            fieldDicts = su.fc_dict[schedule_func].getMetafieldDicts(lang(req))

            field_errors = []
            for i, field in enumerate(fields):
                field_errors.append(False)

            d = {
                'fields': fields,
                'fieldDicts': fieldDicts,
                'currentField': fields[0],
                'field_errors': field_errors,
                'currentFunction': schedule_func,
                'explain_func':
                su.fc_dict[schedule_func].getExplanation(language)
            }

            req.writeTAL("web/edit/modules/schedule.html",
                         d,
                         macro="schedule_func_show_fields_and_explanation")
            return ""

        elif action.startswith("load_schedule_"):
            schedule_id = action.replace("load_schedule_", "")
            try:
                schedule = tree.getNode(schedule_id)
            except:
                errors.append("edit_schedule_no_such_node_error")
                return "no such schedule error"

            if not schedule.type == "schedule" and access and access.hasWriteAccess(
                    schedule):
                return "schedule access error"

            schedule_func = schedule.get("function")
            if schedule_func:
                fields = su.fc_dict[schedule_func].getMetafields(lang(req))
                fieldDicts = su.fc_dict[schedule_func].getMetafieldDicts(
                    lang(req))
                d['explain_func'] = su.fc_dict[schedule_func].getExplanation(
                    language)
            else:
                fields = []
                fieldDicts = []
                d['explain_func'] = ""

            field_errors = []
            for i, field in enumerate(fields):
                field_errors.append(False)

            has_evaluation_errors = False
            for i, dfield in enumerate(fieldDicts):
                field_name = dfield['field_name']
                field_value = schedule.get(field_name)
                dfield['value'] = field_value
                field_validator_func = dfield['field_validator_func']
                if field_validator_func and not field_validator_func(
                        field_value):
                    dfield['evaluation_error'] = True
                    has_evaluation_errors = True
                else:
                    dfield['evaluation_error'] = False

            if has_evaluation_errors:
                error = "\n<br/>\n".join([
                    error,
                    t(language, 'edit_schedule_field_validation_error')
                ])

            d = {
                'fields': fields,
                'fieldDicts': fieldDicts,
                'currentField': fields[0],
                'field_errors': field_errors,
                'currentFunction': schedule_func,
            }

            req.writeTAL("web/edit/modules/schedule.html",
                         d,
                         macro="schedule_func_show_fields_and_explanation")
            return ""

        elif action == "delete_node_from_schedule":

            node_id = req.params.get('node_id', None)

            if node_id:
                pass
            else:
                errors.append("edit_schedule_unexpected_no_such_node")

            schedule_id = req.params.get('schedule_id', None)
            if schedule_id:
                try:
                    schedule = tree.getNode(schedule_id)
                except:
                    errors.append(
                        "edit_schedule_unexpected_no_such_schedule_node")
            else:
                errors.append("edit_schedule_unexpected_no_such_schedule_node")

            delete_errors = su.deleteNodeIDsFromSchedule([node_id],
                                                         schedule_id,
                                                         access=access)

            if not delete_errors:
                msg = "user '%s' removed node %s from schedule '%s' (%s)" % (
                    username, node_id, schedule.name, schedule_id)
                logging.getLogger("backend").info(msg)
            else:
                error_msg = ", ".join([t(language, e) for e in delete_errors])
                msg = "user '%s' tried to remove node %s from schedule '%s' (%s): %s" % (
                    username, node_id, schedule.name, schedule_id, error_msg)
                logging.getLogger("backend").error(msg)

            errors += delete_errors

            s = {}
            s['errors'] = errors
            s['delete_errors'] = delete_errors

            s['delete_table_rows'] = ['sid_%s' % schedule_id]

            res_msg = req.params.get("jsoncallback") + "(%s)" % json.dumps(
                s, indent=4)
            req.write(res_msg)
            return ""

        elif action == "delete_schedule":
            schedule_id = req.params.get('schedule_id', None)
            if schedule_id:
                try:
                    schedule = tree.getNode(schedule_id)
                except:
                    errors.append(
                        "edit_schedule_unexpected_no_such_schedule_node")
            else:
                errors.append("edit_schedule_unexpected_no_such_schedule_node")

            delete_errors = su.deleteSchedule(schedule_id, access=access)

            if not delete_errors:
                msg = "user '%s' removed schedule %s (%s)" % (
                    username, schedule.name, schedule_id)
                logging.getLogger("backend").info(msg)
            else:
                error_msg = ", ".join([t(language, e) for e in delete_errors])
                msg = "user '%s' tried to remove schedule '%s' (%s): %s" % (
                    username, schedule.name, schedule_id, error_msg)
                logging.getLogger("backend").error(msg)

            errors += delete_errors

            s = {}
            s['errors'] = errors
            s['delete_errors'] = delete_errors
            s['delete_table_rows'] = ['sid_%s' % schedule_id]

            res_msg = req.params.get("jsoncallback") + "(%s)" % json.dumps(
                s, indent=4)
            req.write(res_msg)
            return ""

        elif action == "load_table_nid2schedules":

            nid2schedules, schedule2nids, nid2active_schedules = su.getSchedulesForIds(
                ids, access=access, language=language)

            nid2schedules_attrs = {}
            for nid in nid2schedules:
                nid2schedules_attrs[nid] = [[
                    s.id, s.name, s.get("single_trigger")
                ] for s in nid2schedules[nid]['schedule_list']]

            d = {}
            d['nid2schedules'] = nid2schedules
            d['nid2active_schedules'] = nid2active_schedules
            d['errors'] = ['testerror1', 'testerror1']
            d['date'] = datetime.now().isoformat()
            d['isActive'] = su.isActive

            req.writeTAL("web/edit/modules/schedule.html",
                         d,
                         macro="table_nid2schedules")
            return ""

        elif action == "load_table_schedule2nids":

            nid2schedules, schedule2nids, nid2active_schedules = su.getSchedulesForIds(
                ids, access=access, language=language)

            nid2schedules_attrs = {}
            for nid in nid2schedules:
                nid2schedules_attrs[nid] = [[
                    s.id, s.name, s.get("single_trigger")
                ] for s in nid2schedules[nid]['schedule_list']]

            d = {}
            d['nid2schedules'] = nid2schedules
            d['schedule2nids'] = schedule2nids
            d['nid2active_schedules'] = nid2active_schedules
            d['errors'] = ['testerror1', 'testerror1']
            d['date'] = datetime.now().isoformat()
            d['isActive'] = su.isActive

            req.writeTAL("web/edit/modules/schedule.html",
                         d,
                         macro="table_schedule2nids")
            return ""

    nid2schedules, schedule2nids, nid2active_schedules = su.getSchedulesForIds(
        ids, access=access, language=language)

    datetime_str = req.params.get("datetime", "").strip()
    datetime_error = False
    has_evaluation_errors = False

    if datetime_str:
        patter = "^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}$"
        if not re.match(patter, datetime_str):
            error = t(
                language,
                "edit_schedule_input_datetime_format_error") % datetime_str
            datetime_error = True
        else:
            try:
                parser_test_result = datetime.strptime(
                    datetime_str, "%Y-%m-%dT%H:%M")  # "%Y-%m-%dT%H:%M:%S.%f"
            except:
                parser_test_result = None
                error = t(
                    language,
                    "edit_schedule_input_datetime_format_error") % datetime_str
                datetime_error = True
            if parser_test_result and datetime_str <= datetime.now().isoformat(
            ):
                error = t(language,
                          "edit_schedule_input_datetime_already_past_error"
                          ) % datetime_str
                datetime_error = True
    elif "submit" in req.params:
        error = t(language,
                  "edit_schedule_input_datetime_format_error") % datetime_str
        datetime_error = True

    schedule_id = req.params.get("schedule_id", "")
    if schedule_id:
        schedule = tree.getNode(schedule_id)
        if access and not access.hasWriteAccess(schedule):
            errors.append("edit_schedule_no_access_error")
            schedule = None
            current_function = req.params.get('schedule_function', '')
        else:
            current_function = schedule.get("function")
    else:
        schedule = None
        current_function = req.params.get('schedule_function', '')

    if "submit" in req.params or "submit_run_now" in req.params:
        current_function = req.params.get('schedule_function', '')
        if current_function in su.fc_dict:
            field_descriptors = su.fc_dict[
                current_function].getFieldDescriptors()
            field_errors = []
        else:
            # should not happen
            msg = "-> unexpected error: 'non-existant schedule function' requested in module %s: :s" % (
                str(__file__), str(inspect.currentframe().f_lineno))
            print msg
            logging.getLogger("backend").error(msg)

    d = {"id": req.params.get("id")}

    # nodes list is used to display icons in upper part of page
    # additional nodes should not / will not be shown there
    nodes = []
    for nid in ids:
        node = tree.getNode(nid)
        nodes.append(node)

    d['nodes'] = nodes

    if current_function in su.fc_dict:
        fields = su.fc_dict[current_function].getMetafields(lang(req))
        fieldDicts = su.fc_dict[current_function].getMetafieldDicts(lang(req))
        d['explain_func'] = su.fc_dict[current_function].getExplanation(
            language)
    else:
        fields = []
        fieldDicts = []
        d['explain_func'] = ""

    if not "submit_run_now" in req.params:
        has_evaluation_errors = datetime_error

    if schedule and not "submit" in req.params and not "submit_run_now" in req.params:
        for i, dfield in enumerate(fieldDicts):
            field_name = dfield['field_name']
            field_value = schedule.get(field_name)
            dfield['value'] = field_value
            field_validator_func = dfield['field_validator_func']
            if field_validator_func and not field_validator_func(field_value):
                dfield['evaluation_error'] = True
                has_evaluation_errors = True
            else:
                dfield['evaluation_error'] = False
    else:
        for i, dfield in enumerate(fieldDicts):
            field_name = dfield['field_name']
            # m_* classes from metadata/ are not multilingual for schedules
            # their getEditorHTML methods are used to display schedule node
            # attributes
            field_value = req.params.get(
                getDefaultLanguage() + '__' + field_name, '')
            dfield['value'] = field_value
            field_validator_func = dfield['field_validator_func']
            if field_validator_func and not field_validator_func(field_value):
                dfield['evaluation_error'] = True
                has_evaluation_errors = True
            else:
                dfield['evaluation_error'] = False

    additional_nodes_str = req.params.get("additional_nodes", "")
    additional_nodes_error = False
    additional_nodes_bad_ids = []

    try:
        additional_nodes_id_list = [
            str(int(nid.strip()))
            for nid in additional_nodes_str.strip().split(";") if nid.strip()
        ]
    except:
        has_evaluation_errors = True
        additional_nodes_error = True
        additional_nodes_id_list = []
        errors.append(
            "edit_schedule_additional_nodes_list_not_semikolon_separated_list_of_integers"
        )

    if not additional_nodes_error:
        collections_root = tree.getRoot("collections")
        for nid in additional_nodes_id_list:
            n = None
            try:
                n = tree.getNode(nid)
            except tree.NoSuchNodeError as e:
                has_evaluation_errors = True
                additional_nodes_error = True
                if nid not in additional_nodes_bad_ids:
                    additional_nodes_bad_ids.append(nid)
            if n and (not isDescendantOf(n, collections_root)
                      or not access.hasWriteAccess(n)):
                # to do? discussion: override collections rectriction for
                # admins ?
                has_evaluation_errors = True
                additional_nodes_error = True
                if nid not in additional_nodes_bad_ids:
                    additional_nodes_bad_ids.append(nid)

    if additional_nodes_bad_ids:
        has_evaluation_errors = True
        additional_nodes_error = True
        errors.append(
            t(language, "edit_schedule_additional_nodes_bad_ids") +
            (";".join(additional_nodes_bad_ids)))

    if has_evaluation_errors:
        errors.append('edit_schedule_field_validation_error')
        error = "\n<br/>\n".join(
            map(lambda x: t(language, x), [error] + errors))

    d['fields'] = fields
    d['fieldDicts'] = fieldDicts
    d['field_errors'] = [False] * len(fields)
    d['currentField'] = None
    d['currentFunction'] = current_function

    d['error'] = error

    d['fc_dict'] = su.filter_access(su.fc_dict, access)

    d['input_datetime'] = datetime_str
    d['input_datetime_error'] = datetime_error

    d['nid2schedules'] = nid2schedules
    d['schedule2nids'] = schedule2nids
    d['nid2active_schedules'] = nid2active_schedules

    d['loaded_schedule'] = schedule

    if schedule:
        d['loaded_schedule_id'] = str(schedule.id)
    else:
        d['loaded_schedule_id'] = None

    d['mklink'] = su.mklink

    d['language'] = language
    d['t'] = t
    d['isActive'] = su.isActive

    d['result'] = ''

    d['created_new_schedule'] = False

    d['additional_nodes'] = additional_nodes_str
    d['additional_nodes_error'] = additional_nodes_error

    d['submitbutton_run_now_label'] = t(language,
                                        'edit_schedule_submit_run_now_button')
    d['edit_schedule_submit_run_now_button_confirm'] = t(
        language, 'edit_schedule_submit_run_now_button_confirm')
    d['edit_schedule_delete_schedule_confirm'] = t(
        language, 'edit_schedule_delete_schedule_confirm')

    if has_evaluation_errors and not ('submit_run_now' in req.params):
        return req.getTAL("web/edit/modules/schedule.html",
                          d,
                          macro="schedule_popup")

    new_schedule = None
    if (not schedule
            and "submit" in req.params) or "submit_run_now" in req.params:

        new_schedule_name = user.name + \
            "_created_at_" + datetime.now().isoformat()
        new_schedule = tree.Node(new_schedule_name, 'schedule')

        username = user.getName()
        new_schedule.setAccess("write", "{user %s}" % username)

        if not "submit_run_now" in req.params:
            schedules = tree.getRoot("schedules")
            schedules.addChild(new_schedule)

            msg = "user '%s' created new schedule '%s' (%s), trigger='%s', function='%s', nodelist='%s'" % (
                username, new_schedule.name, str(
                    new_schedule.id), datetime_str, d['currentFunction'],
                new_schedule.get('nodelist'))
            logging.getLogger("backend").info(msg)

            d['result'] = t(language,
                            'edit_schedule_result_new_schedule_created')
            d['created_new_schedule'] = True
        else:
            msg = "user '%s' created temporary schedule '%s' (%s), trigger='%s', function='%s', nodelist='%s'" % (
                username, new_schedule.name, str(
                    new_schedule.id), datetime_str, d['currentFunction'],
                new_schedule.get('nodelist'))
            logging.getLogger("backend").info(msg)

            d['result'] = t(language,
                            'edit_schedule_result_temporary_schedule_created')
            d['created_temporary_schedule'] = True

    elif (schedule) and ("submit" in req.params):
        new_schedule = schedule
        msg = "user '%s' is editing schedule '%s' (%s), trigger='%s', function='%s', nodelist='%s'" % (
            username, new_schedule.name, str(new_schedule.id), datetime_str,
            d['currentFunction'], new_schedule.get('nodelist'))
        logging.getLogger("backend").info(msg)
        new_schedule.set("system.edited", datetime.now().isoformat())

        d['result'] = t(language,
                        'edit_schedule_result_existing_schedule_edited')

    if new_schedule:
        for i, dfield in enumerate(fieldDicts):
            field_name = dfield['field_name']
            field_value = dfield['value']
            new_schedule.set(field_name, field_value)

        ids_plus_additional_nodes = ids
        for nid in additional_nodes_id_list:
            if nid not in ids_plus_additional_nodes:
                ids_plus_additional_nodes.append(nid)

        new_schedule.set('function', d['currentFunction'])
        new_schedule.set('nodelist', ",".join(ids_plus_additional_nodes))
        new_schedule.set('single_trigger', datetime_str)

        if datetime.now().isoformat() < datetime_str:
            new_schedule.set('single_trigger_status', '')

        if "submit_run_now" in req.params:
            new_schedule.set("single_trigger", datetime.now().isoformat())
            has_fired, has_error, TT = su.handle_single_trigger(
                new_schedule,
                datetime.now().isoformat(), su.OUT)
            if has_error:
                _error1 = d['error']
                _error2 = "<br/>\n".join(
                    map(lambda x: (t(language, str(x))), TT))
                _error = "<br/>\n".join([_error1, _error2])
                d['error'] = _error

    return req.getTAL("web/edit/modules/schedule.html",
                      d,
                      macro="schedule_popup")
Example #14
0
def getContent(req, ids):
    """
    The standard method,  which has to be implemented by every module.
    It's called in edit.py, where all the modules will be identified.
    """
    raise Exception("ACL must be fixed!")
    user = current_user
    node = q(Node).get(ids[0])

    # first prove if the user has the required rights to call this module
    if 'sortfiles' in user.hidden_edit_functions or not node.has_write_access():
        req.setStatus(httpstatus.HTTP_FORBIDDEN)
        return req.getTAL('web/edit/edit.html', {}, macro='access_error')

    if node.isContainer():
        nodes = u', '.join(node.children.getIDs())
    else:
        nodes = unicode(node.id)

    v = {'msg': '',
         'urn_institutionid': config.get('urn.institutionid'),
         'urn_pubtypes': config.get('urn.pubtypes').split(';'),
         'namespaces': config.get('urn.namespace').split(';'),
         'user': user,
         'nodes': nodes.split(', '),
         'type': req.params.get('id_type'),
         'show_form': True,
         'namespace': req.params.get('namespace'),
         'urn_type': req.params.get('urn_type'),
         'host': config.get('host.name'),
         'creator': user
         }

    if user.is_admin:
        if 'id_type' in req.params:
            if req.params.get('id_type') == 'urn':
                createUrn(node, req.params.get('namespace'), req.params.get('urn_type'))
            elif req.params.get('id_type') == 'doi':
                try:
                    createDOI(node)
                except:
                    return req.error(500, "doi was not successfully registered")

            db.session.commit()

            if any(identifier in node.attributes for identifier in ('urn', 'doi')):
                if not node.get('system.identifierdate'):
                    node.set('system.identifierdate', unicode(date.now()))
                    db.session.commit()
                if node.get('system.identifierstate') != '2':
                    node.set('system.identifierstate', u'2')
                    db.session.commit()

                    # add nobody ruleset if not set
                    if node.access_rule_assocs.filter_by(ruletype=u'write', invert=True, blocking=True).scalar() is None:
                        everybody_rule = AccessRule()
                        db.session.add(everybody_rule)
                        node.access_rule_assocs.append(NodeToAccessRule(rule=everybody_rule, ruletype=u"write", invert=True, blocking=True))
                        db.session.commit()

                try:
                    mailtext = req.getTAL('web/edit/modules/identifier.html', v, macro='generate_identifier_usr_mail_2')
                    mail.sendmail(config.get('email.admin'),  # email from
                                  "%s;%s" % (config.get('email.admin'), user.getEmail()), # email to
                                  u'Vergabe eines Identifikators / Generation of an Identifier',
                                  mailtext)

                except mail.SocketError:
                    logg.exception('failed to send Autorenvertrag mail to user %r (%s): %r' % (user.login_name, user.getName(), user.getEmail()))
                    v['msg'] = t(lang(req), 'edit_identifier_mail_fail')

        if node.get('system.identifierstate') != '2':
            v['msg'] = t(lang(req), 'edit_identifier_state_0_1_admin')
        else:
            v['msg'] = t(lang(req), 'edit_identifier_state_2_admin')

    else:
        if pathutils.isDescendantOf(node, q(Collections).one()):
            if not node.get('system.identifierstate'):
                if 'id_type' in req.params:
                    try:
                        # fetch autorenvertrag
                        attachment = []
                        autorenvertrag_name = 'formular_autorenvertrag.pdf'
                        autorenvertrag_path = os.path.join(config.get('paths.tempdir'),
                                                           autorenvertrag_name)

                        if not os.path.isfile(autorenvertrag_path):
                            logg.error("Unable to attach Autorenvertrag. Attachment file not found: '%s'", autorenvertrag_path)
                            raise IOError('Autorenvertrag was not located on disk at %s. Please send this error message to %s' %
                                          (autorenvertrag_path, config.get('email.admin')))
                        else:
                            attachment.append((autorenvertrag_path, 'Autorenvertrag.pdf'))

                        # notify user
                        mailtext_user = req.getTAL(
                            'web/edit/modules/identifier.html', v, macro='generate_identifier_usr_mail_1_' + lang(req))
                        mail.sendmail(config.get('email.admin'),
                                      ("%s;%s" % (config.get('email.admin'), user.getEmail())),
                                      unicode(t(lang(req), 'edit_identifier_mail_title_usr_1')),
                                      mailtext_user,
                                      attachments_paths_and_filenames=attachment)

                        # notify admin
                        mailtext_admin = req.getTAL('web/edit/modules/identifier.html', v, macro='generate_identifier_admin_mail')
                        mail.sendmail(config.get('email.admin'),
                                      config.get('email.admin'),
                                      u'Antrag auf Vergabe eines Identifikators',
                                      mailtext_admin)

                        node.set('system.identifierstate', u'1')
                        db.session.commit()

                        # add nobody rule if not set
                        if node.access_rule_assocs.filter_by(ruletype=u'write', invert=True, blocking=True).scalar() is None:
                            everybody_rule = AccessRule()
                            db.session.add(everybody_rule)
                            node.access_rule_assocs.append(NodeToAccessRule(rule=everybody_rule, ruletype=u"write", invert=True, blocking=True))
                            db.session.commit()

                    except mail.SocketError:
                        logg.exception('failed to send identifier request mail')
                        v['msg'] = t(lang(req), 'edit_identifier_mail_fail')
                else:
                    v['msg'] = t(lang(req), 'edit_identifier_state_0_usr')

            if node.get('system.identifierstate') == '1':
                v['show_form'] = False
                v['msg'] = t(lang(req), 'edit_identifier_state_1_usr')
        else:
            v['show_form'] = False
            v['msg'] = t(lang(req), 'edit_identifier_state_published')

    v['urn_val'] = node.get('urn')
    v['doi_val'] = node.get('doi')

    # hides form if all identifier types are already set
    if all(idents != '' for idents in (v['urn_val'], v['doi_val'])):
        v['show_form'] = False
        v['msg'] = t(lang(req), 'edit_identifier_all_types_set')

    v["csrf"] = req.csrf_token.current_token
    return req.getTAL('web/edit/modules/identifier.html', v, macro='set_identifier')