def _finish_change(node, change_file, user, uploadfile, req): if change_file in ["yes", "no"]: # check that the correct filetype is uploaded # note: only the suffix of the filename is checked not the file content uploadfile_type = getMimeType(uploadfile.filename)[1] if uploadfile_type != node.type and uploadfile_type != node.get_upload_filetype( ): req.setStatus(httpstatus.HTTP_NOT_ACCEPTABLE) return # sys files are always cleared to delete remaining thumbnails, presentation images etc. for f in node.files: if f.filetype in node.get_sys_filetypes(): node.files.remove(f) file = importFile(uploadfile.filename, uploadfile.tempname) # add new file file.filetype = node.get_upload_filetype() node.files.append(file) # this should re-create all dependent files node.event_files_changed() logg.info(u"%s changed file of node %s to %s (%s)", user.login_name, node.id, uploadfile.filename, uploadfile.tempname) return attpath = "" for f in node.files: if f.mimetype == "inode/directory": attpath = f.base_name break if change_file == "attdir": # add attachmentdir if attpath == "": # add attachment directory attpath = req.params.get("inputname") if not os.path.exists(getImportDir() + "/" + attpath): os.mkdir(getImportDir() + "/" + attpath) node.files.append( File(getImportDir() + "/" + attpath, "attachment", "inode/directory")) importFileIntoDir(getImportDir() + "/" + attpath, uploadfile.tempname) # add new file if change_file == "attfile": # add file as attachment if attpath == "": # no attachment directory existing file = importFile(uploadfile.filename, uploadfile.tempname) # add new file file.mimetype = "inode/file" file.filetype = "attachment" node.files.append(file) else: # import attachment file into existing attachment directory importFileIntoDir(getImportDir() + "/" + attpath, uploadfile.tempname) # add new file
def _finish_change(node, change_file, user, uploadfile, req): if change_file in ["yes", "no"]: # check that the correct filetype is uploaded # note: only the suffix of the filename is checked not the file content uploadfile_type = getMimeType(uploadfile.filename)[1] if uploadfile_type != node.type and uploadfile_type != node.get_upload_filetype(): req.setStatus(httpstatus.HTTP_NOT_ACCEPTABLE) return # sys files are always cleared to delete remaining thumbnails, presentation images etc. for f in node.files: if f.filetype in node.get_sys_filetypes(): node.files.remove(f) file = importFile(uploadfile.filename, uploadfile.tempname) # add new file file.filetype = node.get_upload_filetype() node.files.append(file) # this should re-create all dependent files node.event_files_changed() logg.info(u"%s changed file of node %s to %s (%s)", user.login_name, node.id, uploadfile.filename, uploadfile.tempname) return attpath = "" for f in node.files: if f.mimetype == "inode/directory": attpath = f.base_name break if change_file == "attdir": # add attachmentdir if attpath == "": # add attachment directory attpath = req.params.get("inputname") if not os.path.exists(getImportDir() + "/" + attpath): os.mkdir(getImportDir() + "/" + attpath) node.files.append(File(getImportDir() + "/" + attpath, "attachment", "inode/directory")) importFileIntoDir(getImportDir() + "/" + attpath, uploadfile.tempname) # add new file if change_file == "attfile": # add file as attachment if attpath == "": # no attachment directory existing file = importFileToRealname(uploadfile.filename, uploadfile.tempname) # add new file file.mimetype = "inode/file" file.filetype = "attachment" node.files.append(file) else: # import attachment file into existing attachment directory importFileIntoDir(getImportDir() + "/" + attpath, uploadfile.tempname) # add new file
def test_find_unique_destname_conflict(): import_dir = getImportDir() realname = "test.jpg" prefix = "my" path = os.path.join(import_dir, prefix + realname) with open(path, "w") as wf: wf.write("w") # _find_unique_destname should notice that the path already exists and count up to 1 alternative_path = path.replace(prefix, prefix + "1_") assert _find_unique_destname(realname, prefix) == alternative_path os.unlink(path)
def event_files_changed(self): print "Postprocessing node", self.id if "image" in self.type: for f in self.getFiles(): if f.getName().lower().endswith('svg'): self.svg_to_png(f.retrieveFile(), f.retrieveFile()[:-4] + ".png") self.removeFile(f) self.addFile(FileNode(name=f.retrieveFile(), type="original", mimetype=f.mimetype)) self.addFile(FileNode(name=f.retrieveFile(), type="image", mimetype=f.mimetype)) self.addFile(FileNode(name=f.retrieveFile()[:-4] + ".png", type="tmppng", mimetype="image/png")) break orig = 0 thumb = 0 for f in self.getFiles(): if f.type == "original": orig = 1 if f.type == "thumb": thumb = 1 if orig == 0: for f in self.getFiles(): if f.type == "image": if f.mimetype == "image/tiff" or ((f.mimetype is None or f.mimetype == "application/x-download") and (f.getName().lower().endswith("tif") or f.getName().lower().endswith("tiff"))): # move old file to "original", create a new png to be used as "image" self.removeFile(f) path, ext = splitfilename(f.retrieveFile()) pngname = path + ".png" if not os.path.isfile(pngname): makeOriginalFormat(f.retrieveFile(), pngname) width, height = getImageDimensions(pngname) self.set("width", width) self.set("height", height) else: width, height = getImageDimensions(pngname) self.set("width", width) self.set("height", height) print 'png name/path: ', pngname self.addFile(FileNode(name=pngname, type="image", mimetype="image/png")) self.addFile(FileNode(name=f.retrieveFile(), type="original", mimetype="image/tiff")) break else: self.addFile(FileNode(name=f.retrieveFile(), type="original", mimetype=f.mimetype)) # retrieve technical metadata. for f in self.getFiles(): if (f.type == "image" and not f.getName().lower().endswith("svg")) or f.type == "tmppng": width, height = getImageDimensions(f.retrieveFile()) self.set("origwidth", width) self.set("origheight", height) self.set("origsize", f.getSize()) if f.mimetype == "image/jpeg": self.set("jpg_comment", iso2utf8(getJpegSection(f.retrieveFile(), 0xFE).strip())) if thumb == 0: for f in self.getFiles(): if (f.type == "image" and not f.getName().lower().endswith("svg")) or f.type == "tmppng": path, ext = splitfilename(f.retrieveFile()) basename = hashlib.md5(str(random.random())).hexdigest()[0:8] # path = os.path.join(getImportDir(),os.path.basename(path)) path = os.path.join(getImportDir(), basename) thumbname = path + ".thumb" thumbname2 = path + ".thumb2" print 'tumb: ', thumbname print 'presentation: ', thumbname2 assert not os.path.isfile(thumbname) assert not os.path.isfile(thumbname2) width, height = getImageDimensions(f.retrieveFile()) makeThumbNail(f.retrieveFile(), thumbname) makePresentationFormat(f.retrieveFile(), thumbname2) if f.mimetype is None: if f.getName().lower().endswith("jpg"): f.mimetype = "image/jpeg" else: f.mimetype = "image/tiff" self.addFile(FileNode(name=thumbname, type="thumb", mimetype="image/jpeg")) self.addFile(FileNode(name=thumbname2, type="presentation", mimetype="image/jpeg")) self.set("width", width) self.set("height", height) #fetch unwanted tags to be omitted unwanted_attrs = self.unwanted_attributes() # Exif try: from lib.Exif import EXIF files = self.getFiles() for file in files: if file.type == "original": f = open(file.retrieveFile(), 'rb') tags = EXIF.process_file(f) tags.keys().sort() for k in tags.keys(): # don't set unwanted exif attributes if any(tag in k for tag in unwanted_attrs): continue if tags[k] != "" and k != "JPEGThumbnail": self.set("exif_" + k.replace(" ", "_"), utf8_decode_escape(str(tags[k]))) elif k == "JPEGThumbnail": if tags[k] != "": self.set("Thumbnail", "True") else: self.set("Thumbnail", "False") except: None if dozoom(self) == 1: tileok = 0 for f in self.getFiles(): if f.type.startswith("tile"): tileok = 1 if not tileok and self.get("width") and self.get("height"): zoom.getImage(self.id, 1) # iptc try: from lib.iptc import IPTC files = self.getFiles() for file in files: if file.type == "original": tags = IPTC.getIPTCValues(file.retrieveFile()) tags.keys().sort() for k in tags.keys(): # skip unknown iptc tags if 'IPTC_' in k: continue if any(tag in k for tag in unwanted_attrs): continue if isinstance(tags[k], list): tags[k] = ', '.join(tags[k]) if tags[k] != "": self.set("iptc_" + k.replace(" ", "_"), utf8_decode_escape(str(tags[k]))) except: None for f in self.getFiles(): if f.getName().lower().endswith("png") and f.type == "tmppng": self.removeFile(f) break
def getContent(req, ids): ret = "" user = users.getUserFromRequest(req) node = tree.getNode(ids[0]) update_error = False access = acl.AccessData(req) msg = "%s|web.edit.modules.files.getContend|req.fullpath=%r|req.path=%r|req.params=%r|ids=%r" % (get_user_id(req), req.fullpath, req.path, req.params, ids) log.debug(msg) if not access.hasWriteAccess(node) or "files" in users.getHideMenusForUser(user): req.setStatus(httpstatus.HTTP_FORBIDDEN) return req.getTAL("web/edit/edit.html", {}, macro="access_error") if 'data' in req.params: if req.params.get('data') == 'children': # get formated list of childnodes of selected directory excludeid = req.params.get('excludeid', None) if excludeid: grandchildren = [] for child in node.getChildren(): for grandchild in child.getChildren(): if not grandchild.isContainer(): grandchildren.append(grandchild) req.writeTAL("web/edit/modules/files.html", {'children': [c for c in node.getChildren() if str(c.id) != excludeid], 'grandchildren': grandchildren}, macro="edit_files_popup_children") else: grandchildren = [] for child in node.getChildren(): for grandchild in child.getChildren(): if not grandchild.isContainer(): grandchildren.append(grandchild) req.writeTAL("web/edit/modules/files.html", {'children': [c for c in node.getChildren() if str(c.id) != excludeid], 'grandchildren': grandchildren}, macro="edit_files_popup_children") elif req.params.get('data') =='grandchildren': grandchildren = [] for child in node.getChildren(): if not child.isContainer(): for grandchild in child.getChildren(): if not grandchild.isContainer(): if not grandchild.isContainer(): grandchildren.append(grandchild) if len(node.getChildren())==0: req.writeTAL("web/edit/modules/files.html", {'grandchildren': []}, macro="edit_files_popup_grandchildren") else: req.writeTAL("web/edit/modules/files.html", {'grandchildren': grandchildren}, macro="edit_files_popup_grandchildren") if req.params.get('data') == 'additems': # add selected node as children for childid in req.params.get('items').split(";"): if childid.strip() != "": childnode = tree.getNode(childid.strip()) for p in childnode.getParents(): if p.isContainer(): logging.getLogger('editor').info("Removed childnode: {} from node: {}. - caused by adding".format(childnode.id, node.id)) p.removeChild(childnode) node.addChild(childnode) req.writeTAL("web/edit/modules/files.html", {'children': node.getChildren(), 'node': node}, macro="edit_files_children_list") if req.params.get('data') == 'removeitem': # remove selected childnode node try: remnode = tree.getNode(req.params.get('remove')) if len(remnode.getParents()) == 1: users.getUploadDir(user).addChild(remnode) node.removeChild(remnode) except: # node not found pass req.writeTAL("web/edit/modules/files.html", {'children': node.getChildren(), 'node': node}, macro="edit_files_children_list") if req.params.get('data') == 'reorder': i = 0 for id in req.params.get('order').split(","): if id != "": n = tree.getNode(id) n.setOrderPos(i) i += 1 if req.params.get('data') == 'translate': req.writeTALstr('<tal:block i18n:translate="" tal:content="msgstr"/>', {'msgstr': req.params.get('msgstr')}) return "" if req.params.get("style") == "popup": v = {"basedirs": [tree.getRoot('home'), tree.getRoot('collections')]} id = req.params.get("id", tree.getRoot().id) v["script"] = "var currentitem = '%s';\nvar currentfolder = '%s';\nvar node = %s;" %(id, req.params.get('parent'), id) v["idstr"] = ",".join(ids) v["node"] = node if node.type != 'directory': try: if v['current_id'] == None: v['current_id'] = node.id except KeyError: pass req.writeTAL("web/edit/modules/files.html", v, macro="edit_files_popup_selection") return "" if "operation" in req.params: op = req.params.get("operation") if op == "delete": for key in req.params.keys(): # delete file if key.startswith("del|"): filename = key[4:-2].split("|") for file in node.getFiles(): if file.getName() == filename[1] and file.type == filename[0]: # remove all files in directory if file.getMimeType() == "inode/directory": for root, dirs, files in os.walk(file.retrieveFile()): for name in files: try: os.remove(root + "/" + name) except: pass os.removedirs(file.retrieveFile()+"/") if len([f for f in node.getFiles() if f.getName()==filename[1] and f.type==filename[0]]) > 1: # remove single file from database if there are duplicates node.removeFile(file, single=True) else: # remove single file node.removeFile(file) try: os.remove(file.retrieveFile()) except: pass break break elif key.startswith("delatt|"): for file in node.getFiles(): if file.getMimeType() == "inode/directory": try: os.remove(file.retrieveFile() + "/" + key.split("|")[2][:-2]) except: pass break break elif op=="change": uploadfile = req.params.get("updatefile") if uploadfile: create_version_error = False # Create new version when change file if (req.params.get('generate_new_version') and not hasattr(node, "metaFields")): if (req.params.get('version_comment', '').strip()=='' or req.params.get('version_comment', '').strip()==' '): create_version_error = True req.setStatus(httpstatus.HTTP_INTERNAL_SERVER_ERROR) ret += req.getTAL("web/edit/modules/files.html", {}, macro="version_error") else: current = node node = node.createNewVersion(user) for attr, value in current.items(): if node.get(attr)!="": # do not overwrite attributes pass else: node.set(attr, value) req.setStatus(httpstatus.HTTP_MOVED_TEMPORARILY) ret += req.getTAL("web/edit/modules/metadata.html", {'url':'?id='+node.id+'&tab=files', 'pid':None}, macro="redirect") if req.params.get("change_file")=="yes" and not create_version_error: # remove old files if uploadfile.filename: if getMimeType(uploadfile.filename)[0] == 'other': return '<h2 style="width:100%; text-align:center ;color:red">file-format is not supported (upload canceled / use attachment)</h2>' for f in node.getFiles(): if f.getType() in node.getSysFiles(): node.removeFile(f) node.set("system.version.comment", '('+t(req, "edit_files_new_version_exchanging_comment")+')\n'+req.params.get('version_comment', '')) if req.params.get("change_file")=="no" and not create_version_error: node.set("system.version.comment", '('+t(req, "edit_files_new_version_adding_comment")+')\n'+req.params.get('version_comment', '')) if req.params.get("change_file") in ["yes", "no"] and not create_version_error: if uploadfile.filename: if getMimeType(uploadfile.filename)[0] == 'other': return '<h2 style="width:100%; text-align:center ;color:red">file-format is not supported (upload canceled / use attachment)</h2>' file = importFile(uploadfile.filename, uploadfile.tempname) # add new file node.addFile(file) logging.getLogger('usertracing').info(user.name+" changed file of node "+node.id+" to "+uploadfile.filename+" ("+uploadfile.tempname+")") attpath = "" for f in node.getFiles(): if f.getMimeType()=="inode/directory": attpath = f.getName() break if req.params.get("change_file")=="attdir" and not create_version_error: # add attachmentdir dirname = req.params.get("inputname") if attpath=="": # add attachment directory attpath = req.params.get("inputname") if not os.path.exists(getImportDir() + "/" + attpath): os.mkdir(getImportDir() + "/" + attpath) node.addFile(tree.FileNode(name=getImportDir() + "/" + attpath, mimetype="inode/directory", type="attachment")) file = importFileIntoDir(getImportDir() + "/" + attpath, uploadfile.tempname) # add new file node.set("system.version.comment", '('+t(req, "edit_files_new_version_attachment_directory_comment")+')\n'+req.params.get('version_comment', '')) pass if req.params.get("change_file")=="attfile" and not create_version_error: # add file as attachment if attpath=="": # no attachment directory existing file = importFile(uploadfile.filename, uploadfile.tempname) # add new file file.mimetype = "inode/file" file.type = "attachment" node.addFile(file) else: # import attachment file into existing attachment directory file = importFileIntoDir(getImportDir() + "/" + attpath, uploadfile.tempname) # add new file node.set("system.version.comment", '('+t(req, "edit_files_new_version_attachment_comment")+')\n'+req.params.get('version_comment', '')) pass elif op == "addthumb": # create new thumbanil from uploaded file uploadfile = req.params.get("updatefile") if uploadfile: thumbname = os.path.join(getImportDir(), hashlib.md5(str(random.random())).hexdigest()[0:8]) + ".thumb" file = importFile(thumbname, uploadfile.tempname) # add new file makeThumbNail(file.retrieveFile(), thumbname) makePresentationFormat(file.retrieveFile(), thumbname + "2") if os.path.exists(file.retrieveFile()): # remove uploaded original os.remove(file.retrieveFile()) for f in node.getFiles(): if f.type in ["thumb", "presentation", "presentati"]: if os.path.exists(f.retrieveFile()): os.remove(f.retrieveFile()) node.removeFile(f) node.addFile(tree.FileNode(name=thumbname, type="thumb", mimetype="image/jpeg")) node.addFile(tree.FileNode(name=thumbname + "2", type="presentation", mimetype="image/jpeg")) logging.getLogger('usertracing').info(user.name + " changed thumbnail of node " + node.id) elif op == "postprocess": if hasattr(node, "event_files_changed"): try: node.event_files_changed() logging.getLogger('usertracing').info(user.name + " postprocesses node " + node.id) except: update_error = True v = {"id": req.params.get("id", "0"), "tab": req.params.get("tab", ""), "node": node, "update_error": update_error, "user": user, "files": filter(lambda x: x.type != 'statistic', node.getFiles()), "statfiles": filter(lambda x: x.type == 'statistic', node.getFiles()), "attfiles": filter(lambda x: x.type == 'attachment', node.getFiles()), "att": [], "nodes": [node], "access": access} for f in v["attfiles"]: # collect all files in attachment directory if f.getMimeType() == "inode/directory": for root, dirs, files in os.walk(f.retrieveFile()): for name in files: af = tree.FileNode(root + "/" + name, "attachmentfile", getMimeType(name)[0]) v["att"].append(af) return req.getTAL("web/edit/modules/files.html", v, macro="edit_files_file")
def test_find_unique_destname_not_conflict(): assert _find_unique_destname("test.jpg", "prefix") == os.path.join(getImportDir(), "prefixtest.jpg")
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 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 getContent(req, ids): ret = "" user = current_user node = q(Node).get(ids[0]) update_error = False update_error_extension = False logg.debug("%s|web.edit.modules.files.getContend|req.fullpath=%s|req.path=%s|req.params=%s|ids=%s", get_user_id(req), req.fullpath, req.path, req.params, ids) if not node.has_write_access() or "files" in current_user.hidden_edit_functions: req.setStatus(httpstatus.HTTP_FORBIDDEN) return req.getTAL("web/edit/edit.html", {}, macro="access_error") if 'data' in req.params: if 'data' in req.params: from contenttypes.container import Container if req.params.get('data') == 'children': # get formated list of childnodes of selected directory excludeid = str(req.params.get('excludeid', None)) if excludeid: grandchildren = [] for child in node.getChildren(): for grandchild in child.children.all(): if not isinstance(grandchild, Container): grandchildren.append(grandchild) req.writeTAL("web/edit/modules/files.html", {'children': [c for c in node.children.all() if str(c.id) != excludeid], 'grandchildren': grandchildren, "csrf": req.csrf_token.current_token}, macro="edit_files_popup_children") else: grandchildren = [] for child in node.children.all(): for grandchild in child.children.all(): if not isinstance(grandchild, Container): grandchildren.append(grandchild) req.writeTAL("web/edit/modules/files.html", {'children': [c for c in node.getChildren() if str(c.id) != excludeid], 'grandchildren': grandchildren, "csrf": req.csrf_token.current_token}, macro="edit_files_popup_children") elif req.params.get('data') =='grandchildren': grandchildren = [] for child in node.children.all(): if not isinstance(child, Container): for grandchild in child.children.all(): if not isinstance(grandchild, Container): grandchildren.append(grandchild) if len(node.getChildren())==0: req.writeTAL("web/edit/modules/files.html", {'grandchildren': [], "csrf": req.csrf_token.current_token}, macro="edit_files_popup_grandchildren") else: req.writeTAL("web/edit/modules/files.html", {'grandchildren': grandchildren, "csrf": req.csrf_token.current_token}, macro="edit_files_popup_grandchildren") if req.params.get('data') == 'additems': # add selected node as children for childid in req.params.get('items').split(";"): if childid.strip() != "": childnode = q(Node).get(childid.strip()) # don't try to add node as child to itself ! if childnode != node: for p in childnode.parents: if isinstance(p, Container): p.children.remove(childnode) node.children.append(childnode) req.writeTAL("web/edit/modules/files.html", {'children': node.children, 'node': node, "csrf": req.csrf_token.current_token}, macro="edit_files_children_list") if req.params.get('data') == 'removeitem': # remove selected childnode node with suppress(Exception): remnode = q(Node).get(req.params.get('remove')) if len(remnode.parents) == 1: users.getUploadDir(user).children.append(remnode) node.children.remove(remnode) req.writeTAL("web/edit/modules/files.html", {'children': node.children, 'node': node, "csrf": req.csrf_token.current_token}, macro="edit_files_children_list") if req.params.get('data') == 'reorder': i = 0 for id in req.params.get('order').split(","): if id != "": n = q(Node).get(id) n.setOrderPos(i) i += 1 if req.params.get('data') == 'translate': req.writeTALstr('<tal:block i18n:translate="" tal:content="msgstr"/>', {'msgstr': req.params.get('msgstr'), "csrf": req.csrf_token.current_token}) db.session.commit() return "" if req.params.get("style") == "popup": v = {"basedirs": [q(Home).one(), q(Collections).one()]} id = req.params.get("id", q(Root).one().id) v["script"] = "var currentitem = '%s';\nvar currentfolder = '%s';\nvar node = %s;" % (id, req.params.get('parent'), id) v["idstr"] = ",".join(ids) v["node"] = node v["csrf"] = req.csrf_token.current_token req.writeTAL("web/edit/modules/files.html", v, macro="edit_files_popup_selection") return "" if "operation" in req.params: op = req.params.get("operation") if op == "delete": for key in req.params.keys(): # delete file if key.startswith("del|"): filename = key[4:-2].split("|") for file in node.files: if file.base_name == filename[1] and file.filetype == filename[0]: # remove all files in directory if file.mimetype == "inode/directory": for root, dirs, files in os.walk(file.abspath): for name in files: try: os.remove(root + "/" + name) except: logg.exception("exception while removing file, ignore") os.removedirs(file.abspath + "/") node.files.remove(file) with suppress(Exception, warn=False): os.remove(file.abspath) break break elif key.startswith("delatt|"): for file in node.files: if file.mimetype == "inode/directory": try: os.remove(file.abspath + "/" + key.split("|")[2][:-2]) except: logg.exception("exception while removing file, ignore") break break elif op == "change": _handle_change(node, req) if req.reply_code != httpstatus.HTTP_OK and req.reply_code != httpstatus.HTTP_MOVED_TEMPORARILY: if req.reply_code is httpstatus.HTTP_NOT_ACCEPTABLE: update_error_extension = True else: update_error = True elif op == "addthumb": # create new thumbanil from uploaded file uploadfile = req.params.get("updatefile") if uploadfile: thumbname = os.path.join(getImportDir(), hashlib.md5(ustr(random.random())).hexdigest()[0:8]) + ".thumb" file = importFile(thumbname, uploadfile.tempname) # add new file make_thumbnail_image(file.abspath, thumbname) make_presentation_image(file.abspath, thumbname + "2") if os.path.exists(file.abspath): # remove uploaded original os.remove(file.abspath) for f in node.files: if f.type in ["thumb", "presentation"]: if os.path.exists(f.abspath): os.remove(f.abspath) node.files.remove(f) node.files.append(File(thumbname, "thumb", "image/jpeg")) node.files.append(File(thumbname + "2", "presentation", "image/jpeg")) logg.info("%s changed thumbnail of node %s", user.login_name, node.id) elif op == "postprocess": try: node.event_files_changed() logg.info("%s postprocesses node %s", user.login_name, node.id) except: update_error = True db.session.commit() v = {"id": req.params.get("id", "0"), "tab": req.params.get("tab", ""), "node": node, "update_error": update_error, "update_error_extension": update_error_extension, "user": user, "files": filter(lambda x: x.type != 'statistic', node.files), "statfiles": filter(lambda x: x.type == 'statistic', node.files), "attfiles": filter(lambda x: x.type == 'attachment', node.files), "att": [], "nodes": [node], "csrf": req.csrf_token.current_token } for f in v["attfiles"]: # collect all files in attachment directory if f.mimetype == "inode/directory": for root, dirs, files in os.walk(f.abspath): for name in files: af = File(root + "/" + name, "attachmentfile", getMimeType(name)[0]) v["att"].append(af) return req.getTAL("web/edit/modules/files.html", v, macro="edit_files_file")
def event_files_changed(self): print "Postprocessing node", self.id if "image" in self.type: for f in self.getFiles(): if f.getName().lower().endswith('svg'): self.svg_to_png(f.retrieveFile(), f.retrieveFile()[:-4] + ".png") self.removeFile(f) self.addFile(FileNode(name=f.retrieveFile(), type="original", mimetype=f.mimetype)) self.addFile(FileNode(name=f.retrieveFile(), type="image", mimetype=f.mimetype)) self.addFile(FileNode(name=f.retrieveFile()[:-4] + ".png", type="tmppng", mimetype="image/png")) break orig = 0 thumb = 0 for f in self.getFiles(): if f.type == "original": orig = 1 if f.type == "thumb": thumb = 1 if orig == 0: for f in self.getFiles(): if f.type == "image": if f.mimetype == "image/tiff" or ((f.mimetype is None or f.mimetype == "application/x-download") and (f.getName().lower().endswith("tif") or f.getName().lower().endswith("tiff"))): # move old file to "original", create a new png to be used as "image" self.removeFile(f) path, ext = splitfilename(f.retrieveFile()) pngname = path + ".png" if not os.path.isfile(pngname): makeOriginalFormat(f.retrieveFile(), pngname) width, height = getImageDimensions(pngname) self.set("width", width) self.set("height", height) else: width, height = getImageDimensions(pngname) self.set("width", width) self.set("height", height) print 'png: ', pngname self.addFile(FileNode(name=pngname, type="image", mimetype="image/png")) self.addFile(FileNode(name=f.retrieveFile(), type="original", mimetype="image/tiff")) break else: self.addFile(FileNode(name=f.retrieveFile(), type="original", mimetype=f.mimetype)) # retrieve technical metadata. for f in self.getFiles(): if (f.type == "image" and not f.getName().lower().endswith("svg")) or f.type == "tmppng": width, height = getImageDimensions(f.retrieveFile()) self.set("origwidth", width) self.set("origheight", height) self.set("origsize", f.getSize()) if f.mimetype == "image/jpeg": self.set("jpg_comment", iso2utf8(getJpegSection(f.retrieveFile(), 0xFE).strip())) if thumb == 0: for f in self.getFiles(): if (f.type == "image" and not f.getName().lower().endswith("svg")) or f.type == "tmppng": basename = hashlib.md5(str(random.random())).hexdigest()[0:8] path = os.path.join(getImportDir(), basename) thumbname = path + ".thumb" thumbname2 = path + ".thumb2" print 'tumb: ', thumbname print 'presentation: ', thumbname2 assert not os.path.isfile(thumbname) assert not os.path.isfile(thumbname2) width, height = getImageDimensions(f.retrieveFile()) makeThumbNail(f.retrieveFile(), thumbname) makePresentationFormat(f.retrieveFile(), thumbname2) if f.mimetype is None: if f.getName().lower().endswith("jpg"): f.mimetype = "image/jpeg" else: f.mimetype = "image/tiff" self.addFile(FileNode(name=thumbname, type="thumb", mimetype="image/jpeg")) self.addFile(FileNode(name=thumbname2, type="presentation", mimetype="image/jpeg")) self.set("width", width) self.set("height", height) # fetch unwanted tags to be omitted unwanted_attrs = self.unwanted_attributes() # Exif try: files = self.getFiles() for file in files: if file.type == "original": f = open(file.retrieveFile(), 'rb') tags = EXIF.process_file(f) tags.keys().sort() for k in tags.keys(): # don't set unwanted exif attributes if any(tag in k for tag in unwanted_attrs): continue if tags[k] != "" and k != "JPEGThumbnail": self.set("exif_" + k.replace(" ", "_"), utf8_decode_escape(str(tags[k]))) elif k == "JPEGThumbnail": if tags[k] != "": self.set("Thumbnail", "True") else: self.set("Thumbnail", "False") except: None if dozoom(self) == 1: tileok = 0 for f in self.getFiles(): if f.type.startswith("tile"): tileok = 1 if not tileok and self.get("width") and self.get("height"): zoom.getImage(self.id, 1) for f in self.getFiles(): if f.getType() == 'original': wanted_tags = lib.iptc.IPTC.get_wanted_iptc_tags() tags_in_upload = lib.iptc.IPTC.get_iptc_values(f.retrieveFile(), wanted_tags) with_value = [] for field in getMetaType(self.getSchema()).getMetaFields(): if field.get('type') == "meta" and len(field.getValueList()) > 1: value = self.get('iptc_{}'.format(field.getName())) if len(value) > 0: with_value.append(field.getName()) if tags_in_upload: for key in tags_in_upload.keys(): if tags_in_upload[key] != '': if key not in with_value: self.set('iptc_{}'.format(key.replace(' ', '_')), tags_in_upload[key]) for f in self.getFiles(): if f.getName().lower().endswith("png") and f.type == "tmppng": self.removeFile(f) break
def getContent(req, ids): ret = "" user = current_user node = q(Node).get(ids[0]) update_error = False update_error_extension = False logg.debug( "%s|web.edit.modules.files.getContend|req.fullpath=%s|req.path=%s|req.params=%s|ids=%s", get_user_id(req), req.fullpath, req.path, req.params, ids) if not node.has_write_access( ) or "files" in current_user.hidden_edit_functions: req.setStatus(httpstatus.HTTP_FORBIDDEN) return req.getTAL("web/edit/edit.html", {}, macro="access_error") if 'data' in req.params: if 'data' in req.params: from contenttypes.container import Container if req.params.get( 'data' ) == 'children': # get formated list of childnodes of selected directory excludeid = str(req.params.get('excludeid', None)) if excludeid: grandchildren = [] for child in node.getChildren(): for grandchild in child.children.all(): if not isinstance(grandchild, Container): grandchildren.append(grandchild) req.writeTAL("web/edit/modules/files.html", { 'children': [ c for c in node.children.all() if str(c.id) != excludeid ], 'grandchildren': grandchildren }, macro="edit_files_popup_children") else: grandchildren = [] for child in node.children.all(): for grandchild in child.children.all(): if not isinstance(grandchild, Container): grandchildren.append(grandchild) req.writeTAL("web/edit/modules/files.html", { 'children': [ c for c in node.getChildren() if str(c.id) != excludeid ], 'grandchildren': grandchildren }, macro="edit_files_popup_children") elif req.params.get('data') == 'grandchildren': grandchildren = [] for child in node.children.all(): if not isinstance(child, Container): for grandchild in child.children.all(): if not isinstance(grandchild, Container): grandchildren.append(grandchild) if len(node.getChildren()) == 0: req.writeTAL("web/edit/modules/files.html", {'grandchildren': []}, macro="edit_files_popup_grandchildren") else: req.writeTAL("web/edit/modules/files.html", {'grandchildren': grandchildren}, macro="edit_files_popup_grandchildren") if req.params.get( 'data') == 'additems': # add selected node as children for childid in req.params.get('items').split(";"): if childid.strip() != "": childnode = q(Node).get(childid.strip()) # don't try to add node as child to itself ! if childnode != node: for p in childnode.parents: if isinstance(p, Container): p.children.remove(childnode) node.children.append(childnode) req.writeTAL("web/edit/modules/files.html", { 'children': node.children, 'node': node }, macro="edit_files_children_list") if req.params.get( 'data') == 'removeitem': # remove selected childnode node try: remnode = q(Node).get(req.params.get('remove')) if len(remnode.parents) == 1: users.getUploadDir(user).children.append(remnode) node.children.remove(remnode) except: # node not found logg.exception( "exception in getContent, node not found? ignore") pass req.writeTAL("web/edit/modules/files.html", { 'children': node.children, 'node': node }, macro="edit_files_children_list") if req.params.get('data') == 'reorder': i = 0 for id in req.params.get('order').split(","): if id != "": n = q(Node).get(id) n.setOrderPos(i) i += 1 if req.params.get('data') == 'translate': req.writeTALstr( '<tal:block i18n:translate="" tal:content="msgstr"/>', {'msgstr': req.params.get('msgstr')}) db.session.commit() return "" if req.params.get("style") == "popup": v = {"basedirs": [q(Home).one(), q(Collections).one()]} id = req.params.get("id", q(Root).one().id) v["script"] = "var currentitem = '%s';\nvar currentfolder = '%s';\nvar node = %s;" % ( id, req.params.get('parent'), id) v["idstr"] = ",".join(ids) v["node"] = node req.writeTAL("web/edit/modules/files.html", v, macro="edit_files_popup_selection") return "" if "operation" in req.params: op = req.params.get("operation") if op == "delete": for key in req.params.keys(): # delete file if key.startswith("del|"): filename = key[4:-2].split("|") for file in node.files: if file.base_name == filename[ 1] and file.filetype == filename[0]: # remove all files in directory if file.mimetype == "inode/directory": for root, dirs, files in os.walk(file.abspath): for name in files: try: os.remove(root + "/" + name) except: logg.exception( "exception while removing file, ignore" ) os.removedirs(file.abspath + "/") node.files.remove(file) try: os.remove(file.abspath) except: pass break break elif key.startswith("delatt|"): for file in node.files: if file.mimetype == "inode/directory": try: os.remove(file.abspath + "/" + key.split("|")[2][:-2]) except: logg.exception( "exception while removing file, ignore") break break elif op == "change": _handle_change(node, req) if req.reply_code != httpstatus.HTTP_OK and req.reply_code != httpstatus.HTTP_MOVED_TEMPORARILY: if req.reply_code is httpstatus.HTTP_NOT_ACCEPTABLE: update_error_extension = True else: update_error = True elif op == "addthumb": # create new thumbanil from uploaded file uploadfile = req.params.get("updatefile") if uploadfile: thumbname = os.path.join( getImportDir(), hashlib.md5(ustr( random.random())).hexdigest()[0:8]) + ".thumb" file = importFile(thumbname, uploadfile.tempname) # add new file make_thumbnail_image(file.abspath, thumbname) make_presentation_image(file.abspath, thumbname + "2") if os.path.exists(file.abspath): # remove uploaded original os.remove(file.abspath) for f in node.files: if f.type in ["thumb", "presentation"]: if os.path.exists(f.abspath): os.remove(f.abspath) node.files.remove(f) node.files.append(File(thumbname, "thumb", "image/jpeg")) node.files.append( File(thumbname + "2", "presentation", "image/jpeg")) logg.info("%s changed thumbnail of node %s", user.login_name, node.id) elif op == "postprocess": try: node.event_files_changed() logg.info("%s postprocesses node %s", user.login_name, node.id) except: update_error = True db.session.commit() v = { "id": req.params.get("id", "0"), "tab": req.params.get("tab", ""), "node": node, "update_error": update_error, "update_error_extension": update_error_extension, "user": user, "files": filter(lambda x: x.type != 'statistic', node.files), "statfiles": filter(lambda x: x.type == 'statistic', node.files), "attfiles": filter(lambda x: x.type == 'attachment', node.files), "att": [], "nodes": [node], } for f in v["attfiles"]: # collect all files in attachment directory if f.mimetype == "inode/directory": for root, dirs, files in os.walk(f.abspath): for name in files: af = File(root + "/" + name, "attachmentfile", getMimeType(name)[0]) v["att"].append(af) return req.getTAL("web/edit/modules/files.html", v, macro="edit_files_file")
def test_find_unique_destname_not_conflict(): assert _find_unique_destname("test.jpg", "prefix") == os.path.join( getImportDir(), "prefixtest.jpg")
def getContent(req, ids): ret = "" user = users.getUserFromRequest(req) node = tree.getNode(ids[0]) update_error = False access = acl.AccessData(req) msg = "%s|web.edit.modules.files.getContend|req.fullpath=%r|req.path=%r|req.params=%r|ids=%r" % ( get_user_id(req), req.fullpath, req.path, req.params, ids) log.debug(msg) if not access.hasWriteAccess(node) or "files" in users.getHideMenusForUser( user): req.setStatus(httpstatus.HTTP_FORBIDDEN) return req.getTAL("web/edit/edit.html", {}, macro="access_error") if 'data' in req.params: if req.params.get( 'data' ) == 'children': # get formated list of childnodes of selected directory req.writeTAL("web/edit/modules/files.html", {'children': node.getChildren()}, macro="edit_files_popup_children") if req.params.get( 'data') == 'additems': # add selected node as children for childid in req.params.get('items').split(";"): if childid.strip() != "": childnode = tree.getNode(childid.strip()) for p in childnode.getParents(): p.removeChild(childnode) node.addChild(childnode) req.writeTAL("web/edit/modules/files.html", { 'children': node.getChildren(), 'node': node }, macro="edit_files_children_list") if req.params.get( 'data') == 'removeitem': # remove selected childnode node try: remnode = tree.getNode(req.params.get('remove')) if len(remnode.getParents()) == 1: users.getUploadDir(user).addChild(remnode) node.removeChild(remnode) except: # node not found pass req.writeTAL("web/edit/modules/files.html", { 'children': node.getChildren(), 'node': node }, macro="edit_files_children_list") if req.params.get('data') == 'reorder': i = 0 for id in req.params.get('order').split(","): if id != "": n = tree.getNode(id) n.setOrderPos(i) i += 1 if req.params.get('data') == 'translate': req.writeTALstr( '<tal:block i18n:translate="" tal:content="msgstr"/>', {'msgstr': req.params.get('msgstr')}) return "" if req.params.get("style") == "popup": v = {"basedirs": [tree.getRoot('home'), tree.getRoot('collections')]} id = req.params.get("id", tree.getRoot().id) v["script"] = "var currentitem = '%s';\nvar currentfolder = '%s';\nvar node = %s;" % ( id, req.params.get('parent'), id) v["idstr"] = ",".join(ids) v["node"] = node req.writeTAL("web/edit/modules/files.html", v, macro="edit_files_popup_selection") return "" if "operation" in req.params: op = req.params.get("operation") if op == "delete": for key in req.params.keys(): # delete file if key.startswith("del|"): filename = key[4:-2].split("|") for file in node.getFiles(): if file.getName( ) == filename[1] and file.type == filename[0]: # remove all files in directory if file.getMimeType() == "inode/directory": for root, dirs, files in os.walk( file.retrieveFile()): for name in files: try: os.remove(root + "/" + name) except: pass os.removedirs(file.retrieveFile() + "/") if len([ f for f in node.getFiles() if f.getName() == filename[1] and f.type == filename[0] ]) > 1: # remove single file from database if there are duplicates node.removeFile(file, single=True) else: # remove single file node.removeFile(file) try: os.remove(file.retrieveFile()) except: pass break break elif key.startswith("delatt|"): for file in node.getFiles(): if file.getMimeType() == "inode/directory": try: os.remove(file.retrieveFile() + "/" + key.split("|")[2][:-2]) except: pass break break elif op == "change": uploadfile = req.params.get("updatefile") if uploadfile: create_version_error = False # Create new version when change file if (req.params.get('generate_new_version') and not hasattr(node, "metaFields")): if (req.params.get('version_comment', '').strip() == '' or req.params.get('version_comment', '').strip() == ' '): create_version_error = True req.setStatus(httpstatus.HTTP_INTERNAL_SERVER_ERROR) ret += req.getTAL("web/edit/modules/files.html", {}, macro="version_error") else: current = node node = node.createNewVersion(user) for attr, value in current.items(): if node.get( attr) != "": # do not overwrite attributes pass else: node.set(attr, value) req.setStatus(httpstatus.HTTP_MOVED_TEMPORARILY) ret += req.getTAL("web/edit/modules/metadata.html", { 'url': '?id=' + node.id + '&tab=files', 'pid': None }, macro="redirect") if req.params.get( "change_file" ) == "yes" and not create_version_error: # remove old files for f in node.getFiles(): if f.getType() in node.getSysFiles(): node.removeFile(f) node.set( "system.version.comment", '(' + t(req, "edit_files_new_version_exchanging_comment") + ')\n' + req.params.get('version_comment', '')) if req.params.get( "change_file") == "no" and not create_version_error: node.set( "system.version.comment", '(' + t(req, "edit_files_new_version_adding_comment") + ')\n' + req.params.get('version_comment', '')) if req.params.get("change_file") in [ "yes", "no" ] and not create_version_error: file = importFile(uploadfile.filename, uploadfile.tempname) # add new file node.addFile(file) logging.getLogger('usertracing').info( user.name + " changed file of node " + node.id + " to " + uploadfile.filename + " (" + uploadfile.tempname + ")") attpath = "" for f in node.getFiles(): if f.getMimeType() == "inode/directory": attpath = f.getName() break if req.params.get( "change_file" ) == "attdir" and not create_version_error: # add attachmentdir dirname = req.params.get("inputname") if attpath == "": # add attachment directory attpath = req.params.get("inputname") if not os.path.exists(getImportDir() + "/" + attpath): os.mkdir(getImportDir() + "/" + attpath) node.addFile( tree.FileNode(name=getImportDir() + "/" + attpath, mimetype="inode/directory", type="attachment")) file = importFileIntoDir( getImportDir() + "/" + attpath, uploadfile.tempname) # add new file node.set( "system.version.comment", '(' + t( req, "edit_files_new_version_attachment_directory_comment" ) + ')\n' + req.params.get('version_comment', '')) pass if req.params.get( "change_file" ) == "attfile" and not create_version_error: # add file as attachment if attpath == "": # no attachment directory existing file = importFile(uploadfile.filename, uploadfile.tempname) # add new file file.mimetype = "inode/file" file.type = "attachment" node.addFile(file) else: # import attachment file into existing attachment directory file = importFileIntoDir( getImportDir() + "/" + attpath, uploadfile.tempname) # add new file node.set( "system.version.comment", '(' + t(req, "edit_files_new_version_attachment_comment") + ')\n' + req.params.get('version_comment', '')) pass elif op == "addthumb": # create new thumbanil from uploaded file uploadfile = req.params.get("updatefile") if uploadfile: thumbname = os.path.join( getImportDir(), hashlib.md5(str( random.random())).hexdigest()[0:8]) + ".thumb" file = importFile(thumbname, uploadfile.tempname) # add new file makeThumbNail(file.retrieveFile(), thumbname) makePresentationFormat(file.retrieveFile(), thumbname + "2") if os.path.exists( file.retrieveFile()): # remove uploaded original os.remove(file.retrieveFile()) for f in node.getFiles(): if f.type in ["thumb", "presentation", "presentati"]: if os.path.exists(f.retrieveFile()): os.remove(f.retrieveFile()) node.removeFile(f) node.addFile( tree.FileNode(name=thumbname, type="thumb", mimetype="image/jpeg")) node.addFile( tree.FileNode(name=thumbname + "2", type="presentation", mimetype="image/jpeg")) logging.getLogger('usertracing').info( user.name + " changed thumbnail of node " + node.id) elif op == "postprocess": if hasattr(node, "event_files_changed"): try: node.event_files_changed() logging.getLogger('usertracing').info( user.name + " postprocesses node " + node.id) except: update_error = True v = { "id": req.params.get("id", "0"), "tab": req.params.get("tab", ""), "node": node, "update_error": update_error, "user": user, "files": filter(lambda x: x.type != 'statistic', node.getFiles()), "statfiles": filter(lambda x: x.type == 'statistic', node.getFiles()), "attfiles": filter(lambda x: x.type == 'attachment', node.getFiles()), "att": [], "nodes": [node], "access": access } for f in v["attfiles"]: # collect all files in attachment directory if f.getMimeType() == "inode/directory": for root, dirs, files in os.walk(f.retrieveFile()): for name in files: af = tree.FileNode(root + "/" + name, "attachmentfile", getMimeType(name)[0]) v["att"].append(af) return req.getTAL("web/edit/modules/files.html", v, macro="edit_files_file")
def _finish_change(node, change_file, user, uploadfile, req): if change_file in ["yes", "no"]: # check that the correct filetype is uploaded # note: only the suffix of the filename is checked not the file content uploadfile_type = getMimeType(uploadfile.filename)[1] if uploadfile_type != node.type and uploadfile_type != node.get_upload_filetype( ): req.setStatus(httpstatus.HTTP_NOT_ACCEPTABLE) return # sys files are always cleared to delete remaining thumbnails, presentation images etc. for f in node.files: if f.filetype in node.get_sys_filetypes(): node.files.remove(f) file = importFile(uploadfile.filename, uploadfile.tempname) # add new file file.filetype = node.get_upload_filetype() node.files.append(file) # this should re-create all dependent files node.event_files_changed() logg.info(u"%s changed file of node %s to %s (%s)", user.login_name, node.id, uploadfile.filename, uploadfile.tempname) return attpath = "" for f in node.files: if f.mimetype == "inode/directory": attpath = f.base_name break if change_file == "attfile": # add file as attachment if attpath == "": # no attachment directory existing file = importFileToRealname(uploadfile.filename, uploadfile.tempname) # add new file file.mimetype = "inode/file" file.filetype = "attachment" node.files.append(file) else: # import attachment file into existing attachment directory importFileIntoDir(getImportDir() + "/" + attpath, uploadfile.tempname) # add new file # this should re-create all dependent files node.event_files_changed() logg.info(u"%s changed file of node %s to %s (%s)", user.login_name, node.id, uploadfile.filename, uploadfile.tempname) if change_file == "addthumb": # create new thumbanil from uploaded file thumbname = os.path.join( getImportDir(), hashlib.md5(ustr(random.random())).hexdigest()[0:8]) + ".thumb" file = importFile(thumbname, uploadfile.tempname) # add new file make_thumbnail_image(file.abspath, thumbname) make_presentation_image(file.abspath, thumbname + "2") if os.path.exists(file.abspath): # remove uploaded original os.remove(file.abspath) for f in node.files: if f.type in ["thumb", "presentation"]: if os.path.exists(f.abspath): os.remove(f.abspath) node.files.remove(f) node.files.append(File(thumbname, "thumb", "image/jpeg")) node.files.append(File(thumbname + "2", "presentation", "image/jpeg")) logg.info("%s changed thumbnail of node %s", user.login_name, node.id) # this should re-create all dependent files node.event_files_changed() logg.info(u"%s changed file of node %s to %s (%s)", user.login_name, node.id, uploadfile.filename, uploadfile.tempname)
def event_files_changed(self): print "Postprocessing node", self.id if "image" in self.type: for f in self.getFiles(): if f.getName().lower().endswith('svg'): self.svg_to_png(f.retrieveFile(), f.retrieveFile()[:-4] + ".png") self.removeFile(f) self.addFile( FileNode(name=f.retrieveFile(), type="original", mimetype=f.mimetype)) self.addFile( FileNode(name=f.retrieveFile(), type="image", mimetype=f.mimetype)) self.addFile( FileNode(name=f.retrieveFile()[:-4] + ".png", type="tmppng", mimetype="image/png")) break orig = 0 thumb = 0 for f in self.getFiles(): if f.type == "original": orig = 1 if f.type == "thumb": thumb = 1 if orig == 0: for f in self.getFiles(): if f.type == "image": if f.mimetype == "image/tiff" or ( (f.mimetype is None or f.mimetype == "application/x-download") and (f.getName().lower().endswith("tif") or f.getName().lower().endswith("tiff"))): # move old file to "original", create a new png to be used as "image" self.removeFile(f) path, ext = splitfilename(f.retrieveFile()) pngname = path + ".png" if not os.path.isfile(pngname): makeOriginalFormat(f.retrieveFile(), pngname) width, height = getImageDimensions(pngname) self.set("width", width) self.set("height", height) else: width, height = getImageDimensions(pngname) self.set("width", width) self.set("height", height) self.addFile( FileNode(name=pngname, type="image", mimetype="image/png")) self.addFile( FileNode(name=f.retrieveFile(), type="original", mimetype="image/tiff")) break else: self.addFile( FileNode(name=f.retrieveFile(), type="original", mimetype=f.mimetype)) # retrieve technical metadata. for f in self.getFiles(): if (f.type == "image" and not f.getName().lower().endswith("svg") ) or f.type == "tmppng": width, height = getImageDimensions(f.retrieveFile()) self.set("origwidth", width) self.set("origheight", height) self.set("origsize", f.getSize()) if f.mimetype == "image/jpeg": self.set( "jpg_comment", iso2utf8( getJpegSection(f.retrieveFile(), 0xFE).strip())) if thumb == 0: for f in self.getFiles(): if (f.type == "image" and not f.getName().lower().endswith("svg") ) or f.type == "tmppng": path, ext = splitfilename(f.retrieveFile()) basename = hashlib.md5(str( random.random())).hexdigest()[0:8] #path = os.path.join(getImportDir(),os.path.basename(path)) path = os.path.join(getImportDir(), basename) thumbname = path + ".thumb" thumbname2 = path + ".thumb2" assert not os.path.isfile(thumbname) assert not os.path.isfile(thumbname2) width, height = getImageDimensions(f.retrieveFile()) makeThumbNail(f.retrieveFile(), thumbname) makePresentationFormat(f.retrieveFile(), thumbname2) if f.mimetype is None: if f.getName().lower().endswith("jpg"): f.mimetype = "image/jpeg" else: f.mimetype = "image/tiff" self.addFile( FileNode(name=thumbname, type="thumb", mimetype="image/jpeg")) self.addFile( FileNode(name=thumbname2, type="presentation", mimetype="image/jpeg")) self.set("width", width) self.set("height", height) #fetch unwanted tags to be omitted unwanted_attrs = self.unwanted_attributes() # Exif try: from lib.Exif import EXIF files = self.getFiles() for file in files: if file.type == "original": f = open(file.retrieveFile(), 'rb') tags = EXIF.process_file(f) tags.keys().sort() for k in tags.keys(): # don't set unwanted exif attributes if any(tag in k for tag in unwanted_attrs): continue if tags[k] != "" and k != "JPEGThumbnail": self.set("exif_" + k.replace(" ", "_"), utf8_decode_escape(str(tags[k]))) elif k == "JPEGThumbnail": if tags[k] != "": self.set("Thumbnail", "True") else: self.set("Thumbnail", "False") except: None if dozoom(self) == 1: tileok = 0 for f in self.getFiles(): if f.type.startswith("tile"): tileok = 1 if not tileok and self.get("width") and self.get("height"): zoom.getImage(self.id, 1) # iptc try: from lib.iptc import IPTC files = self.getFiles() for file in files: if file.type == "original": tags = IPTC.getIPTCValues(file.retrieveFile()) tags.keys().sort() for k in tags.keys(): # skip unknown iptc tags if 'IPTC_' in k: continue if any(tag in k for tag in unwanted_attrs): continue if isinstance(tags[k], list): tags[k] = ', '.join(tags[k]) if tags[k] != "": self.set("iptc_" + k.replace(" ", "_"), utf8_decode_escape(str(tags[k]))) except: None for f in self.getFiles(): if f.getName().lower().endswith("png") and f.type == "tmppng": self.removeFile(f) break