def getStatFile(node, timestamp, type, period=period): f = None for file in node.getFiles(): if file.getType() == "statistic": try: if file.getName() == "stat_{}_{}_{}.xml".format(node.id, timestamp, type): if timestamp == str(format_date(now(), "yyyy-mm")) or timestamp == period: # update current month or given period if os.path.exists(file.retrieveFile()): print 'removing %s' % file.retrieveFile() os.remove(file.retrieveFile()) node.removeFile(file) # remove old file and create new f = None break else: # old month, do nothing print 'old file doing nothing' return None except: return None if not f: # create new file f_name = config.get("paths.tempdir") + "stat_{}_{}_{}.xml".format(node.id, timestamp, type) if os.path.exists(f_name): f = open(f_name, "a") else: # create new file and write header: print 'creating writing headers %s' % f_name f = open(f_name, "w") f.write('<?xml version="1.0" encoding="utf-8" ?>\n') f.write('<nodelist created="' + str(format_date(now(), "yyyy-mm-dd HH:MM:SS")) + '">\n') if f_name not in statfiles: statfiles.append(f_name) return f
def getStatFile(col_id, timestamp, type, period=period): f = None node = col_id.collection orig_file = None for file in node.getFiles(): if file.getType() == u"statistic": try: if file.getName() == u"stat_{}_{}_{}.xml".format(node.id, timestamp, type): if timestamp == format_date(now(), "yyyy-mm") or timestamp == period: # update current month or given period # orig_file = file.retrieveFile() if os.path.exists(file.retrieveFile()): print 'removing %s' % file.retrieveFile() os.remove(file.retrieveFile()) orig_file = file.retrieveFile() # node.files.remove(file) f = None break else: # old month, do nothing print 'old file doing nothing' return None except: return None if not f: # create new file f_name = config.get("paths.tempdir") + u"stat_{}_{}_{}.xml".format(node.id, timestamp, type) # create new file and write header:j print 'creating writing headers %s' % f_name f = codecs.open(f_name, "w", encoding='utf8') f.write('<?xml version="1.0" encoding="utf-8" ?>\n') f.write('<nodelist created="' + format_date(now(), "yyyy-mm-dd HH:MM:SS") + '">\n') if f_name not in col_id.statfiles: col_id.statfiles.append((f_name, orig_file)) return f
def runAction(self, node, op=""): # insert node into searchindex try: if node.get('updatetime') <= str(now()): # do only if date in the past node.set('updatetime', str(now())) node.setDirty() except: pass
def runAction(self, node, op=""): # insert node into searchindex try: if node.get('updatetime') <= str( now()): # do only if date in the past node.set('updatetime', str(now())) node.setDirty() except: pass
def runAction(self, node, op=""): if self.get("endsetupdatetime") != "": # insert node into searchindex try: if node.get('updatetime') <= unicode(now()): # do only if date in the past node.set('updatetime', unicode(now())) db.session.commit() except: logg.exception("exception in workflow step end, runAction failed")
def runAction(self, node, op=""): if self.get("endsetupdatetime") != "": # insert node into searchindex try: if node.get('updatetime') <= unicode( now()): # do only if date in the past node.set('updatetime', unicode(now())) db.session.commit() except: logg.exception( "exception in workflow step end, runAction failed")
def save_model(self, request, obj, form, change): user = get_user_from_request(request) obj.modified_by = user obj.modified_time = now() if not change: obj.owner = user obj.created_by = user obj.created_time = now() super().save_model(request, obj, form, change)
def archive_thread(self): if not time: return while True: time.sleep(int(config.get("archive.interval", 60))) archive_nodes_3 = db.getNodeIdByAttribute("archive_state", "3") archive_nodes_2 = [] date_now = format_date(now(), "yyymmddhhmmss") for manager in self.manager: # search for nodes to archive after access over period (state 2) for n in db.getNodeIdByAttribute("archive_state", "2"): try: node = tree.getNode(n) if node.get("archive_date"): date_archive = format_date(parse_date(node.get("archive_date"), "%Y-%m-%dT%H:%M:%S"), "yyymmddhhmmss") if date_now >= date_archive: archive_nodes_2.append(long(node.id)) except: pass # union to get all nodes with state 3 and 2 with over period archive_nodes = union((archive_nodes_3, archive_nodes_2)) nodes = intersection((db.getNodeIdByAttribute("archive_type", str(manager)), archive_nodes)) # run action defined in manager try: self.manager[manager].actionArchive(nodes) except: pass
def createNewVersion(self, user): if self.get('system.version.id') == '': self.set('system.version.id', '1') n = Node(name=self.name, type=self.type) n.set("creator", self.get('creator')) n.set("creationtime", self.get('creationtime')) n.set("updateuser", user.getName()) n.set("edit.lastmask", self.get('edit.lastmask')) if self.get('updatetime') < str(now()): n.set("updatetime", str(format_date())) else: n.set("updatetime", str(self.get('updatetime'))) for f in self.getFiles(): n.addFile(f) activeNode = self.getActiveVersion() for pid in db.getParents(activeNode.id): parentNode = getNode(pid) parentNode.addChild(n) parentNode.removeChild(activeNode) for cid in db.getChildren(activeNode.id): if cid != activeNode.prev_nid: n.addChild(getNode(cid)) n.set("system.version.id", self.getLastVersionID() + 1) n.setPrevID(activeNode.id) activeNode.setNextID(n.id) n.addChild(activeNode) return n
def runAction(self, node, op=""): ugid = q(UserGroup).filter_by(name=u'_workflow').one().id user = current_user # remove access rule with '_workflow' user group id # XXX the following debug messages are needed for analyzing the problem that # XXX some dissertations are not published which means that the special_access_ruleset # XXX is not removed logg.debug("publish node id = %d: get_special_access_ruleset", node.id) special_access_ruleset = node.get_special_access_ruleset( ruletype=u'read') workflow_rules = get_all_access_rules(group_ids=[ugid]) logg.debug( "publish node id = %d: loop over special_access_ruleset.rule_assocs", node.id) for rule_assoc in special_access_ruleset.rule_assocs: logg.debug( "publish node id = %d: rule_id = %d ruleset_name = '%s'", node.id, rule_assoc.rule_id, rule_assoc.ruleset_name) for workflow_rule in workflow_rules: if rule_assoc.rule == workflow_rule: logg.debug( "publish node id = %d: delete rule_id = %d ruleset_name = '%s'", node.id, rule_assoc.rule_id, rule_assoc.ruleset_name) db.session.delete(rule_assoc) break db.session.commit() # set updatetime (possibly publish tag), # but refrain from doing so if updatetime is # in the future (this indicates an embargo) if node.get('updatetime') <= unicode(now()): if self.get("publishsetpublishedversion") != "": # set publish tag with node.new_tagged_version(publish='published', user=user): node.set_legacy_update_attributes( user) # note: also updatetime is set elif self.get("publishsetupdatetime") != "": node.set('updatetime', unicode(now())) db.session.commit() logg.debug("publish node id = %d: db.session.commit()", node.id) self.forward(node, True)
def writeHead(req, attributes=""): request = mklink(req) d = ISO8601(date.now()) try: verb = req.params["verb"] except KeyError: verb = "" req.reply_headers['charset'] = 'utf-8' req.reply_headers['Content-Type'] = 'text/xml; charset=utf-8' req.write("""<?xml version="1.0" encoding="UTF-8"?> <OAI-PMH xmlns="http://www.openarchives.org/OAI/2.0/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/ http://www.openarchives.org/OAI/2.0/OAI-PMH.xsd"> <responseDate>%sZ</responseDate> <request""" % (ISO8601(date.now()))) if attributes != "noatt": for n in ["verb", "identifier", "metadataprefix", "from", "until", "set"]: if n in req.params: req.write(' %s="%s"' % (n, esc(req.params[n]))) req.write('>%s</request>' % (request)) if DEBUG: timetable_update(req, "leaving writeHead")
def save(self, force_insert=False, force_update=False, using=None, update_fields=None, force_update_deleted=False): if self.deleted and not force_update_deleted: raise UpdateDeletedError(_("Deleted record can not be update!")) self._soft_touch() self.modified_time = now() # set created_time and created_by in creating if self.pk is None: self.created_time = now() if not self.pyr_guid: self.pyr_guid = guid() if self.created_by is None: self.created_by = get_unknown_user() return super().save(force_insert, force_update, using, update_fields)
def getAccessRights(node): """ Get acccess rights for the public. The values returned descend from http://wiki.surffoundation.nl/display/standards/info-eu-repo/#info-eu-repo-AccessRights. This values are used by OpenAIRE portal. """ try: # if node.get('updatetime') is empty, the method parse_date would raise an exception l_date = parse_date(node.get('updatetime')) except: l_date = date.now() guest_user = get_guest_user() if date.now() < l_date: return "embargoedAccess" elif node.has_read_access(user=guest_user): if node.has_data_access(user=guest_user): return "openAccess" else: return "restrictedAccess" else: return "closedAccess"
def runAction(self, node, op=""): ugid = q(UserGroup).filter_by(name=u'_workflow').one().id user = current_user # remove access rule with '_workflow' user group id # XXX the following debug messages are needed for analyzing the problem that # XXX some dissertations are not published which means that the special_access_ruleset # XXX is not removed logg.debug("publish node id = %d: get_special_access_ruleset", node.id) special_access_ruleset = node.get_special_access_ruleset(ruletype=u'read') workflow_rules = get_all_access_rules(group_ids=[ugid]) logg.debug("publish node id = %d: loop over special_access_ruleset.rule_assocs", node.id) for rule_assoc in special_access_ruleset.rule_assocs: logg.debug("publish node id = %d: rule_id = %d ruleset_name = '%s'", node.id, rule_assoc.rule_id, rule_assoc.ruleset_name) for workflow_rule in workflow_rules: if rule_assoc.rule == workflow_rule: logg.debug("publish node id = %d: delete rule_id = %d ruleset_name = '%s'", node.id, rule_assoc.rule_id, rule_assoc.ruleset_name) db.session.delete(rule_assoc) break db.session.commit() # set updatetime (possibly publish tag), # but refrain from doing so if updatetime is # in the future (this indicates an embargo) if node.get('updatetime') <= unicode(now()): if self.get("publishsetpublishedversion") != "": # set publish tag with node.new_tagged_version(publish='published', user=user): node.set_legacy_update_attributes(user) # note: also updatetime is set elif self.get("publishsetupdatetime") != "": node.set('updatetime', unicode(now())) db.session.commit() logg.debug("publish node id = %d: db.session.commit()", node.id); self.forward(node, True)
def getStatFile(node, timestamp, type, period=period): f = None for file in node.getFiles(): if file.getType() == "statistic": try: if file.getName() == "stat_{}_{}_{}.xml".format( node.id, timestamp, type): if timestamp == str( format_date(now(), "yyyy-mm") ) or timestamp == period: # update current month or given period if os.path.exists(file.retrieveFile()): print 'removing %s' % file.retrieveFile() os.remove(file.retrieveFile()) node.removeFile( file) # remove old file and create new f = None break else: # old month, do nothing print 'old file doing nothing' return None except: return None if not f: # create new file f_name = config.get("paths.tempdir") + "stat_{}_{}_{}.xml".format( node.id, timestamp, type) if os.path.exists(f_name): f = open(f_name, "a") else: # create new file and write header: print 'creating writing headers %s' % f_name f = open(f_name, "w") f.write('<?xml version="1.0" encoding="utf-8" ?>\n') f.write('<nodelist created="' + str(format_date(now(), "yyyy-mm-dd HH:MM:SS")) + '">\n') if f_name not in statfiles: statfiles.append(f_name) return f
def getStatFile(col_id, timestamp, type, period=period): f = None node = col_id.collection orig_file = None for file in node.getFiles(): if file.getType() == u"statistic": try: if file.getName() == u"stat_{}_{}_{}.xml".format( node.id, timestamp, type): if timestamp == format_date( now(), "yyyy-mm" ) or timestamp == period: # update current month or given period # orig_file = file.retrieveFile() if os.path.exists(file.retrieveFile()): print 'removing %s' % file.retrieveFile() os.remove(file.retrieveFile()) orig_file = file.retrieveFile() # node.files.remove(file) f = None break else: # old month, do nothing print 'old file doing nothing' return None except: return None if not f: # create new file f_name = config.get("paths.tempdir") + u"stat_{}_{}_{}.xml".format( node.id, timestamp, type) # create new file and write header:j print 'creating writing headers %s' % f_name f = codecs.open(f_name, "w", encoding='utf8') f.write('<?xml version="1.0" encoding="utf-8" ?>\n') f.write('<nodelist created="' + format_date(now(), "yyyy-mm-dd HH:MM:SS") + '">\n') if f_name not in col_id.statfiles: col_id.statfiles.append((f_name, orig_file)) return f
def createUrn(node, namespace, urn_type): """ @param node for which the URN should be created @param namespace of the urn; list of the namespaces can be found here: http://www.iana.org/assignments/urn-namespaces/urn-namespaces.xml @param urn_type e.q. diss, epub, etc """ if node.get('urn') and (node.get('urn').strip() != ''): # keep the existing urn, if there is one logging.getLogger('everything').info('urn already exists for node %s' % node.id) else: try: d = date.parse_date(node.get('date-accepted')) except: d = date.now() niss = '%s-%s-%s-0' % (urn_type, date.format_date(d, '%Y%m%d'), node.id) node.set('urn', urn.buildNBN(namespace, config.get('urn.institutionid'), niss))
def send(self): self.send_time = now() try: result = self._backend.send(self.message) self.memo = result self.status = MESSAGE_STATUS_SUCCESS self.message.status = MESSAGE_STATUS_SUCCESS except MessageException as err: self.memo = err self.status = MESSAGE_STATUS_FAILED self.message.status = MESSAGE_STATUS_FAILED logger.warning(err) finally: pass self.message.save() self.save()
def getPopupWindow(req, ids): v = {} v["id"] = ids if "update" in req.params: v["action"] = "doupdate" elif req.params.get("action") == "do": # do action and refresh current month collection = tree.getNode(req.params.get("id")) collection.set("system.statsrun", "1") buildStat(collection, str(format_date(now(), "yyyy-mm"))) req.writeTAL("web/edit/modules/statsaccess.html", {}, macro="edit_stats_result") collection.removeAttribute("system.statsrun") return else: v["action"] = "showform" v["statsrun"] = tree.getNode(ids).get("system.statsrun") req.writeTAL("web/edit/modules/statsaccess.html", v, macro="edit_stats_popup")
def getEditorHTML(self, field, value="", width=400, lock=0, language=None, required=None): d = field.getSystemFormat(field.getValues()) if value == "?": value = date.format_date(date.now(), d.getValue()) with suppress(Exception, warn=False): value = date.format_date(date.parse_date(value), d.getValue()) return tal.getTAL("metadata/date.html", {"lock": lock, "value": value, "width": width, "name": field.getName(), "field": field, "pattern": self.get_input_pattern(field), "title": self.get_input_title(field), "placeholder": self.get_input_placeholder(field), "required": self.is_required(required)}, macro="editorfield", language=language)
def createUrn(node, namespace, urn_type): """ @param node for which the URN should be created @param namespace of the urn; list of the namespaces can be found here: http://www.iana.org/assignments/urn-namespaces/urn-namespaces.xml @param urn_type e.q. diss, epub, etc """ if node.get('urn') and (node.get('urn').strip() != ''): # keep the existing urn, if there is one logging.getLogger('everything').info('urn already exists for node %s' % node.id) else: try: d = date.parse_date(node.get('date-accepted')) except: d = date.now() niss = '%s-%s-%s-0' % (urn_type, date.format_date(d, '%Y%m%d'), node.id) node.set( 'urn', urn.buildNBN(namespace, config.get('urn.institutionid'), niss))
def getEditorHTML(self, field, value="", width=400, lock=0, language=None, required=None): d = field.getSystemFormat(str(field.getValues())) if value == "?": value = date.format_date(date.now(), d.getValue()) try: value = date.format_date(date.parse_date(value), d.getValue()) except: pass return tal.getTAL("metadata/date.html", {"lock": lock, "value": value, "width": width, "name": field.getName(), "field": field, "pattern": self.get_input_pattern(field), "title": self.get_input_title(field), "placeholder": self.get_input_placeholder(field), "required": self.is_required(required)}, macro="editorfield", language=language)
def getPopupWindow(req, ids): v = {} v["id"] = ids if "update" in req.params: v["action"] = "doupdate" elif req.params.get( "action") == "do": # do action and refresh current month collection = tree.getNode(req.params.get("id")) collection.set("system.statsrun", "1") buildStat(collection, str(format_date(now(), "yyyy-mm"))) req.writeTAL("web/edit/modules/statsaccess.html", {}, macro="edit_stats_result") collection.removeAttribute("system.statsrun") return else: v["action"] = "showform" v["statsrun"] = tree.getNode(ids).get("system.statsrun") req.writeTAL("web/edit/modules/statsaccess.html", v, macro="edit_stats_popup")
def update(self, force_update_deleted=False, **kwargs): if not force_update_deleted and 'deleted' in kwargs.keys( ) and kwargs['deleted']: raise UpdateDeletedError(_("Deleted record can not be update!")) kwargs['modified_time'] = now() return super().update(**kwargs)
def restore(self): self.update(deleted=False, modified_time=now())
def delete(self): self.update(deleted=True, force_update_deleted=True, modified_time=now())
def restore(self): # self._soft_touch() self.modified_time = now() self.deleted = False return self.save(update_fields=('modified_by', 'modified_time', 'deleted'))
def delete(self, using=None, keep_parents=False): self.modified_time = now() self.deleted = True self.save(update_fields=('modified_by', 'modified_time', 'deleted'), force_update_deleted=True)
def ISO8601(t=None): # MET summer time if not t: t = date.now() return "%0.4d-%0.2d-%0.2dT%0.2d:%0.2d:%0.2d" % (t.year, t.month, t.day, t.hour, t.minute, t.second)
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')
def guid(): ret = '%s-%s-%s-%s' % ( now().strftime('%Y%m%d%H%M%S%f'), PYRENEES_CLUSTER['GROUP_NAME'], PYRENEES_CLUSTER['NODE_NAME'], str(uuid.uuid1()).split('-')[0]) return str(ret)
def runAction(self, node, op=""): fnode = None for fnode in node.files: if fnode.filetype == "document": break def reformatAuthors(s): authors = s.strip().split(";") if len(authors) > 1: authors = ", ".join(authors[:-1]) + " and " + authors[-1] else: authors = authors[0] return authors # get pdf form appended to this workflow step through upload field 'upload_pdfform' current_workflow = getNodeWorkflow(node) current_workflow_step = getNodeWorkflowStep(node) formfilelist, formfilelist2 = getFilelist(current_workflow_step, 'upload_pdfform') pdf_fields_editable = current_workflow_step.get("pdf_fields_editable") pdf_form_separate = current_workflow_step.get("pdf_form_separate") pdf_form_overwrite = current_workflow_step.get("pdf_form_overwrite") if pdf_fields_editable.lower() in ["1", "true"]: pdf_fields_editable = True else: pdf_fields_editable = False if pdf_form_separate.lower() in ["1", "true"]: pdf_form_separate = True else: pdf_form_separate = False fields = [] f_retrieve_path = None schema = getMetaType(node.schema) if formfilelist: # take newest (mtime) f_mtime, f_name, f_mimetype, f_size, f_type, f_retrieve_path, f = formfilelist[ -1] for field_dict in parse_pdftk_fields_dump( get_pdftk_fields_dump(f_retrieve_path)): fieldname = field_dict.get('FieldName', None) if fieldname: value = '' if fieldname in dict(node.attrs.items()): schemafield = schema.children.filter_by( name=fieldname).first() value = schemafield.getFormattedValue(node)[1] if fieldname.find('author') >= 0: value = reformatAuthors(value) elif fieldname.lower() == 'node.schema': value = getMetaType(node.schema).getLongName() elif fieldname.lower() == 'node.id': value = unicode(node.id) elif fieldname.lower() == 'node.type': value = node.type elif fieldname.lower() == 'date()': value = format_date(now(), format='%d.%m.%Y') elif fieldname.lower() == 'time()': value = format_date(now(), format='%H:%M:%S') elif fieldname.find("+") > 0: for _fn in fieldname.split('+'): value = node.get(_fn) if value: break elif '[att:' in fieldname: value = fieldname while '[att:' in value: m = re.search('(?<=\[att:)([^&\]]+)', value) if m: if m.group(0) == 'id': v = unicode(node.id) elif m.group(0) == 'type': v = node.type elif m.group(0) == 'schema': v = getMetaType(node.schema).getLongName() else: schemafield = schema.children.filter_by( name=m.group(0)).first() v = schemafield.getFormattedValue(node)[0] value = value.replace( '[att:%s]' % (m.group(0)), v) else: logg.warning( "workflowstep %s (%s): could not find attribute for pdf form field '%s' - node: '%s' (%s)", current_workflow_step.name, current_workflow_step.id, fieldname, node.name, node.id) fields.append((fieldname, remove_tags(desc(value)))) if not pdf_form_separate and fnode and f_retrieve_path and os.path.isfile( f_retrieve_path): pages = fillPDFForm(f_retrieve_path, fields, input_is_fullpath=True, editable=pdf_fields_editable) if pages == "": # error in pdf creation -> forward to false operation logg.error( "workflowstep %s (%s): could not create pdf file - node: '%s' (%s)" % (current_workflow_step.name, current_workflow_step.id, node.name, node.id)) self.forward(node, False) return origname = fnode.abspath outfile = addPagesToPDF(pages, origname) for f in node.files: node.files.remove(f) fnode.path = outfile.replace(config.get("paths.datadir"), "") node.files.append(fnode) node.files.append( File(origname, 'upload', 'application/pdf')) # store original filename node.event_files_changed() db.session.commit() logg.info( "workflow '%s' (%s), workflowstep '%s' (%s): added pdf form to pdf (node '%s' (%s)) fields: %s", current_workflow.name, current_workflow.id, current_workflow_step.name, current_workflow_step.id, node.name, node.id, fields) elif pdf_form_separate and f_retrieve_path and os.path.isfile( f_retrieve_path): pages = fillPDFForm(f_retrieve_path, fields, input_is_fullpath=True, editable=pdf_fields_editable) if pages == "": # error in pdf creation -> forward to false operation logg.error( "workflowstep %s (%s): could not create pdf file - node: '%s' (%s)" % (current_workflow_step.name, current_workflow_step.id, node.name, node.id)) self.forward(node, False) return importdir = getImportDir() try: new_form_path = join_paths(importdir, "%s_%s" % (node.id, f_name)) counter = 0 if not pdf_form_overwrite: # build correct filename while os.path.isfile(new_form_path): counter += 1 new_form_path = join_paths( importdir, "%s_%s_%s" % (node.id, counter, f_name)) # copy new file and remove tmp shutil.copy(pages, new_form_path) if os.path.exists(pages): os.remove(pages) except Exception: logg.exception( "workflowstep %s (%s): could not copy pdf form to import directory - node: '%s' (%s), import directory: '%s'", current_workflow_step.name, current_workflow_step.id, node.name, node.id, importdir) found = 0 for fn in node.files: if fn.abspath == new_form_path: found = 1 break if found == 0 or (found == 1 and not pdf_form_overwrite): node.files.append( File(new_form_path, 'pdf_form', 'application/pdf')) db.session.commit() logg.info( "workflow '%s' (%s), workflowstep '%s' (%s): added separate pdf form to node (node '%s' (%s)) fields: %s, path: '%s'", current_workflow.name, current_workflow.id, current_workflow_step.name, current_workflow_step.id, node.name, node.id, fields, new_form_path) else: logg.warning( "workflowstep %s (%s): could not process pdf form - node: '%s' (%s)", current_workflow_step.name, current_workflow_step.id, node.name, node.id) self.forward(node, True)
def has_access(self, accessdata, node): from utils.date import now, parse_date return int(now().int() <= parse_date(self.date, "dd.mm.yyyy").int())
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')
def runAction(self, node, op=""): fnode = None for fnode in node.files: if fnode.filetype == "document": break def reformatAuthors(s): authors = s.strip().split(";") if len(authors) > 1: authors = ", ".join(authors[:-1]) + " and " + authors[-1] else: authors = authors[0] return authors # get pdf form appended to this workflow step through upload field 'upload_pdfform' current_workflow = getNodeWorkflow(node) current_workflow_step = getNodeWorkflowStep(node) formfilelist, formfilelist2 = getFilelist(current_workflow_step, 'upload_pdfform') pdf_fields_editable = current_workflow_step.get("pdf_fields_editable") pdf_form_separate = current_workflow_step.get("pdf_form_separate") pdf_form_overwrite = current_workflow_step.get("pdf_form_overwrite") if pdf_fields_editable.lower() in ["1", "true"]: pdf_fields_editable = True else: pdf_fields_editable = False if pdf_form_separate.lower() in ["1", "true"]: pdf_form_separate = True else: pdf_form_separate = False fields = [] f_retrieve_path = None schema = getMetaType(node.schema) if formfilelist: # take newest (mtime) f_mtime, f_name, f_mimetype, f_size, f_type, f_retrieve_path, f = formfilelist[-1] for field_dict in parse_pdftk_fields_dump(get_pdftk_fields_dump(f_retrieve_path)): fieldname = field_dict.get('FieldName', None) if fieldname: value = '' if fieldname in dict(node.attrs.items()): schemafield = schema.children.filter_by(name=fieldname).first() value = schemafield.getFormattedValue(node)[1] if fieldname.find('author') >= 0: value = reformatAuthors(value) elif fieldname.lower() == 'node.schema': value = getMetaType(node.schema).getLongName() elif fieldname.lower() == 'node.id': value = unicode(node.id) elif fieldname.lower() == 'node.type': value = node.type elif fieldname.lower() == 'date()': value = format_date(now(), format='%d.%m.%Y') elif fieldname.lower() == 'time()': value = format_date(now(), format='%H:%M:%S') elif fieldname.find("+") > 0: for _fn in fieldname.split('+'): value = node.get(_fn) if value: break elif '[att:' in fieldname: value = fieldname while '[att:' in value: m = re.search('(?<=\[att:)([^&\]]+)', value) if m: if m.group(0) == 'id': v = unicode(node.id) elif m.group(0) == 'type': v = node.type elif m.group(0) == 'schema': v = getMetaType(node.schema).getLongName() else: schemafield = schema.children.filter_by(name=m.group(0)).first() v = schemafield.getFormattedValue(node)[0] value = value.replace('[att:%s]' % (m.group(0)), v) else: logg.warning("workflowstep %s (%s): could not find attribute for pdf form field '%s' - node: '%s' (%s)", current_workflow_step.name, current_workflow_step.id, fieldname, node.name, node.id) fields.append((fieldname, remove_tags(desc(value)))) if not pdf_form_separate and fnode and f_retrieve_path and os.path.isfile(f_retrieve_path): pages = fillPDFForm(f_retrieve_path, fields, input_is_fullpath=True, editable=pdf_fields_editable) if pages == "": # error in pdf creation -> forward to false operation logg.error("workflowstep %s (%s): could not create pdf file - node: '%s' (%s)" % (current_workflow_step.name, current_workflow_step.id, node.name, node.id)) self.forward(node, False) return origname = fnode.abspath outfile = addPagesToPDF(pages, origname) for f in node.files: node.files.remove(f) fnode.path = outfile.replace(config.get("paths.datadir"), "") node.files.append(fnode) node.files.append(File(origname, 'upload', 'application/pdf')) # store original filename node.event_files_changed() db.session.commit() logg.info("workflow '%s' (%s), workflowstep '%s' (%s): added pdf form to pdf (node '%s' (%s)) fields: %s", current_workflow.name, current_workflow.id, current_workflow_step.name, current_workflow_step.id, node.name, node.id, fields) elif pdf_form_separate and f_retrieve_path and os.path.isfile(f_retrieve_path): pages = fillPDFForm(f_retrieve_path, fields, input_is_fullpath=True, editable=pdf_fields_editable) if pages == "": # error in pdf creation -> forward to false operation logg.error("workflowstep %s (%s): could not create pdf file - node: '%s' (%s)" % (current_workflow_step.name, current_workflow_step.id, node.name, node.id)) self.forward(node, False) return importdir = getImportDir() try: new_form_path = join_paths(importdir, "%s_%s" % (node.id, f_name)) counter = 0 if not pdf_form_overwrite: # build correct filename while os.path.isfile(new_form_path): counter += 1 new_form_path = join_paths(importdir, "%s_%s_%s" % (node.id, counter, f_name)) # copy new file and remove tmp shutil.copy(pages, new_form_path) if os.path.exists(pages): os.remove(pages) except Exception: logg.exception("workflowstep %s (%s): could not copy pdf form to import directory - node: '%s' (%s), import directory: '%s'", current_workflow_step.name, current_workflow_step.id, node.name, node.id, importdir) found = 0 for fn in node.files: if fn.abspath == new_form_path: found = 1 break if found == 0 or (found == 1 and not pdf_form_overwrite): node.files.append(File(new_form_path, 'pdf_form', 'application/pdf')) db.session.commit() logg.info( "workflow '%s' (%s), workflowstep '%s' (%s): added separate pdf form to node (node '%s' (%s)) fields: %s, path: '%s'", current_workflow.name, current_workflow.id, current_workflow_step.name, current_workflow_step.id, node.name, node.id, fields, new_form_path) else: logg.warning("workflowstep %s (%s): could not process pdf form - node: '%s' (%s)", current_workflow_step.name, current_workflow_step.id, node.name, node.id) self.forward(node, True)
def getNodes(req): global tokenpositions, CHUNKSIZE access = acl.AccessData(req) nodes = None if "resumptionToken" in req.params: token = req.params.get("resumptionToken") if token in tokenpositions: pos, nodes, metadataformat = tokenpositions[token] else: return None, "badResumptionToken", None if not checkParams(req, ["verb", "resumptionToken"]): OUT("OAI: getNodes: additional arguments (only verb and resumptionToken allowed)" ) return None, "badArgument", None else: token, metadataformat = new_token(req) if not checkMetaDataFormat(metadataformat): OUT('OAI: ListRecords: metadataPrefix missing', 'error') return None, "badArgument", None pos = 0 if not nodes: string_from, string_to = None, None try: string_from = req.params["from"] date_from = parseDate(string_from) if date_from.year < EARLIEST_YEAR: date_from = date.DateTime(0, 0, 0, 0, 0, 0) except: if "from" in req.params: return None, "badArgument", None date_from = None try: date_to = parseDate(req.params["until"]) string_to = req.params.get("until") if not date_to.has_time: date_to.hour = 23 date_to.minute = 59 date_to.second = 59 if date_to.year < EARLIEST_YEAR - 1: raise except: if "until" in req.params: return None, "badArgument", None date_to = None setspec = None if "set" in req.params: setspec = req.params.get("set") if string_from and string_to and (string_from > string_to or len(string_from) != len(string_to)): return None, "badArgument", None try: nodes = retrieveNodes(req, access, setspec, date_from, date_to, metadataformat) nodes = [n for n in nodes if not parentIsMedia(n)] # filter out nodes that are inactive or older versions of other nodes nodes = [n for n in nodes if n.isActiveVersion()] except tree.NoSuchNodeError: # collection doesn't exist return None, "badArgument", None with token_lock: tokenpositions[token] = pos + CHUNKSIZE, nodes, metadataformat tokenstring = '<resumptionToken expirationDate="' + ISO8601(date.now().add(3600 * 24)) + '" ' + \ 'completeListSize="' + str(len(nodes)) + '" cursor="' + str(pos) + '">' + token + '</resumptionToken>' if pos + CHUNKSIZE >= len(nodes): tokenstring = None with token_lock: del tokenpositions[token] OUT( req.params.get('verb') + ": set=" + str(req.params.get('set')) + ", " + str(len(nodes)) + " objects, format=" + metadataformat) res = tree.NodeList(nodes[pos:pos + CHUNKSIZE]) if DEBUG: timetable_update( req, "leaving getNodes: returning %d nodes, tokenstring='%s', metadataformat='%s'" % (len(res), tokenstring, metadataformat)) return res, tokenstring, metadataformat
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')
def _soft_touch(self, by_user=None): self.modified_time = now() if by_user is not None: self.modified_by = by_user
def getNodes(req): global tokenpositions, CHUNKSIZE access = acl.AccessData(req) nodes = None if "resumptionToken" in req.params: token = req.params.get("resumptionToken") if token in tokenpositions: pos, nodes, metadataformat = tokenpositions[token] else: return None, "badResumptionToken", None if not checkParams(req, ["verb", "resumptionToken"]): OUT("OAI: getNodes: additional arguments (only verb and resumptionToken allowed)") return None, "badArgument", None else: token, metadataformat = new_token(req) if not checkMetaDataFormat(metadataformat): OUT('OAI: ListRecords: metadataPrefix missing', 'error') return None, "badArgument", None pos = 0 if not nodes: string_from, string_to = None, None try: string_from = req.params["from"] date_from = parseDate(string_from) if date_from.year < EARLIEST_YEAR: date_from = date.DateTime(0, 0, 0, 0, 0, 0) except: if "from" in req.params: return None, "badArgument", None date_from = None try: date_to = parseDate(req.params["until"]) string_to = req.params.get("until") if not date_to.has_time: date_to.hour = 23 date_to.minute = 59 date_to.second = 59 if date_to.year < EARLIEST_YEAR - 1: raise except: if "until" in req.params: return None, "badArgument", None date_to = None setspec = None if "set" in req.params: setspec = req.params.get("set") if string_from and string_to and (string_from > string_to or len(string_from) != len(string_to)): return None, "badArgument", None try: nodes = retrieveNodes(req, access, setspec, date_from, date_to, metadataformat) nodes = [n for n in nodes if not parentIsMedia(n)] # filter out nodes that are inactive or older versions of other nodes nodes = [n for n in nodes if n.isActiveVersion()] except tree.NoSuchNodeError: # collection doesn't exist return None, "badArgument", None with token_lock: tokenpositions[token] = pos + CHUNKSIZE, nodes, metadataformat tokenstring = '<resumptionToken expirationDate="' + ISO8601(date.now().add(3600 * 24)) + '" ' + \ 'completeListSize="' + str(len(nodes)) + '" cursor="' + str(pos) + '">' + token + '</resumptionToken>' if pos + CHUNKSIZE >= len(nodes): tokenstring = None with token_lock: del tokenpositions[token] OUT(req.params.get('verb') + ": set=" + str(req.params.get('set')) + ", " + str(len(nodes)) + " objects, format=" + metadataformat) res = tree.NodeList(nodes[pos:pos + CHUNKSIZE]) if DEBUG: timetable_update(req, "leaving getNodes: returning %d nodes, tokenstring='%s', metadataformat='%s'" % (len(res), tokenstring, metadataformat)) return res, tokenstring, metadataformat
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')
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
def getNodes(req): global tokenpositions, CHUNKSIZE nodes = None nids = None if "resumptionToken" in req.params: token = req.params.get("resumptionToken") if token in tokenpositions: pos, nids, metadataformat = tokenpositions[token] else: return None, "badResumptionToken", None if not checkParams(req, ["verb", "resumptionToken"]): logg.info("OAI: getNodes: additional arguments (only verb and resumptionToken allowed)") return None, "badArgument", None else: token, metadataformat = new_token(req) if not checkMetaDataFormat(metadataformat): logg.info('OAI: ListRecords: metadataPrefix missing') return None, "badArgument", None pos = 0 if not nids: string_from, string_to = None, None try: string_from = req.params["from"] date_from = parseDate(string_from) if date_from.year < EARLIEST_YEAR: date_from = date.DateTime(0, 0, 0, 0, 0, 0) except: if "from" in req.params: return None, "badArgument", None date_from = None try: date_to = parseDate(req.params["until"]) string_to = req.params.get("until") if not date_to.has_time: date_to.hour = 23 date_to.minute = 59 date_to.second = 59 if date_to.year < EARLIEST_YEAR - 1: raise except: if "until" in req.params: return None, "badArgument", None date_to = None setspec = None if "set" in req.params: setspec = req.params.get("set") if not oaisets.existsSetSpec(setspec): return None, "noRecordsMatch", None if string_from and string_to and (string_from > string_to or len(string_from) != len(string_to)): return None, "badArgument", None try: nodequery = retrieveNodes(req, setspec, date_from, date_to, metadataformat) nodequery = nodequery.filter(Node.subnode == False) #[n for n in nodes if not parentIsMedia(n)] # filter out nodes that are inactive or older versions of other nodes #nodes = [n for n in nodes if n.isActiveVersion()] # not needed anymore except: logg.exception('error retrieving nodes for oai') # collection doesn't exist return None, "badArgument", None #if not nodes: # return None, "badArgument", None with token_lock: if not nids: import time from sqlalchemy.orm import load_only atime = time.time() nodes = nodequery.options(load_only('id')).all() etime = time.time() logg.info('querying %d nodes for tokenposition took %.3f sec.' % (len(nodes), etime - atime)) atime = time.time() nids = [n.id for n in nodes] etime = time.time() logg.info('retrieving %d nids for tokenposition took %.3f sec.' % (len(nids), etime - atime)) tokenpositions[token] = pos + CHUNKSIZE, nids, metadataformat tokenstring = '<resumptionToken expirationDate="' + ISO8601(date.now().add(3600 * 24)) + '" ' + \ 'completeListSize="' + ustr(len(nids)) + '" cursor="' + ustr(pos) + '">' + token + '</resumptionToken>' if pos + CHUNKSIZE >= len(nids): tokenstring = None with token_lock: del tokenpositions[token] logg.info("%s : set=%s, objects=%s, format=%s", req.params.get('verb'), req.params.get('set'), len(nids), metadataformat) res = nids[pos:pos + CHUNKSIZE] if DEBUG: timetable_update(req, "leaving getNodes: returning %d nodes, tokenstring='%s', metadataformat='%s'" % (len(res), tokenstring, metadataformat)) return res, tokenstring, metadataformat
def get_udate(node): try: return format_date(parse_date(node.get("updatetime")), "%Y-%m-%d") except: return format_date(date.now(), "%Y-%m-%d")