def transform(self, sens): assert sens in ["auto", "rotate90", "rotate180", "rotate270", "flipHorizontal", "flipVertical", "transpose", "transverse"] pc = PhotoCmd(self.file) pc.transform(sens) self.updateInfo(pc)
def redoIPTC(self): """ refresh IPTC in file and db """ ln = self.root.xpath(u"""//photo[t]""") for i in ln: p = PhotoNode(i) print p.name pc = PhotoCmd(p.file) pc.__maj() # rewrite iptc in file p.updateInfo(pc) # rewrite iptc in db.xml
def transform(self, sens): assert sens in [ "auto", "rotate90", "rotate180", "rotate270", "flipHorizontal", "flipVertical", "transpose", "transverse" ] pc = PhotoCmd(self.file) pc.transform(sens) self.updateInfo(pc)
def getInfoFrom(self, copy): """ rewrite info from a 'copy' to the file (exif, iptc, ...) and rebuild thumb (used to ensure everything is back after a run in another program see plugin 'touch') """ pc = PhotoCmd(copy) pc.copyInfoTo(self.file) #and update infos # generally, it's not necessary ... but if size had changed, jhead # correct automatically width/height exif, so we need to put back in db pc = PhotoCmd(self.file) self.updateInfo(pc)
def __addPhoto(self, nodeDir, file, tags, filesInBasket): assert type(file) == unicode newNode = Element("photo") nodeDir.append(newNode) node = PhotoNode(newNode) if file in filesInBasket: node.addToBasket() try: iii = PhotoCmd( file, needAutoRename=DBPhotos.normalizeName, needAutoRotation=DBPhotos.autorotAtImport, ) if iii.exifdate == "": # exif is not present, and photocmd can't reach # to recreate minimal exif tags (because it's readonly ?) # we can't continue to import this photo raise Exception( "Exif couldn't be set in this picture (readonly?)") except Exception, m: # remove the bad node nodeDir.remove(newNode) return m
def updateName(self): #photo has been redated #it should be renamed if in config ... if DBPhotos.normalizeName: pc = PhotoCmd(self.file, needAutoRename=True) self.updateInfo(pc) return True
def moveToFolder(self, nodeFolder): assert nodeFolder.__class__ == FolderNode name = self.name while os.path.isfile(os.path.join(nodeFolder.file, name)): name = PhotoCmd.giveMeANewName(name) try: shutil.move(self.file, os.path.join(nodeFolder.file, name)) moved = True except os.error, detail: raise Exception(detail) moved = False
def getInfo(self): """ get real infos from photocmd """ pc = PhotoCmd(self.file) info = {} info["tags"] = pc.tags info["comment"] = pc.comment info["exifdate"] = pc.exifdate info["rating"] = pc.rating # huh, did i use that? info["filedate"] = pc.filedate info["resolution"] = pc.resolution info["readonly"] = pc.readonly info["filesize"] = os.stat(self.file)[6] return info
def setRating(self, val): assert type(val) == int pc = PhotoCmd(self.file) if pc.addRating(val): # always true self.updateInfo(pc)
def setComment(self, txt): assert type(txt) == unicode pc = PhotoCmd(self.file) if pc.addComment(txt): self.updateInfo(pc)
def clearTags(self): pc = PhotoCmd(self.file) if pc.clear(): self.updateInfo(pc)
def setDate(self, date): pc = PhotoCmd(self.file) pc.setDate(date) self.updateInfo(pc) self.updateName()
def rotate(self, sens): assert sens in ["R", "L"] pc = PhotoCmd(self.file) pc.rotate(sens) self.updateInfo(pc)
def rebuildThumbnail(self): pc = PhotoCmd(self.file) pc.rebuildExifTB() self.updateInfo(pc)
def delTag(self, tag): assert type(tag) == unicode pc = PhotoCmd(self.file) if pc.sub(tag): self.updateInfo(pc)
def addTags(self, tags): assert type(tags) == list pc = PhotoCmd(self.file) if pc.addTags(tags): self.updateInfo(pc)
def redate(self, w, d, h, m, s): pc = PhotoCmd(self.file) pc.redate(w, d, h, m, s) self.updateInfo(pc) self.updateName()
def copyTo(self, path, resize=None, keepInfo=True, delTags=False, delCom=False): """ copy self to the path "path", and return its newfilename or none by default, it keeps IPTC/THUMB/EXIF, but it can be removed by setting keepInfo at False. In all case, new file keep its filedate system image can be resized/recompressed (preserving ratio) if resize (which is a tuple=(size, qual)) is provided: if size is a float : it's a percent of original if size is a int : it's the desired largest side qual : is the percent for the quality """ assert type(path) == unicode, "photonod.copyTo() : path is not unicode" dest = os.path.join(path, self.name) while os.path.isfile(dest): dest = os.path.join( path, PhotoCmd.giveMeANewName(os.path.basename(dest))) if resize: assert len(resize) == 2 size, qual = resize assert type(size) in [int, float] pb = self.getImage() # a gtk.PixBuf (wx, wy) = pb.get_width(), pb.get_height() # compute the new size -> wx/wy if type(size) == float: # size is a percent size = int(size * 100) wx = int(wx * size / 100) wy = int(wy * size / 100) else: # size is the largest side in pixels if wx > wy: # format landscape wx, wy = size, (size * wy) / wx else: # format portrait wx, wy = (size * wx) / wy, size # 3= best quality (gtk.gdk.INTERP_HYPER) pb = pb.scale_simple(wx, wy, 3) pb.save(dest, "jpeg", {"quality": str(int(qual))}) if keepInfo: pc = PhotoCmd(self.file) pc.copyInfoTo(dest) del (pb) gc.collect() # so it cleans pixbufs else: shutil.copy2(self.file, dest) if not keepInfo: # we must destroy info PhotoCmd(dest).destroyInfo() if keepInfo: if delCom: PhotoCmd(dest).addComment(u"") if delTags: PhotoCmd(dest).clear() return dest
def addTag(self, tag): assert type(tag) == unicode pc = PhotoCmd(self.file) if pc.add(tag): self.updateInfo(pc)
def setNormalizeNameFormat(self, v): assert isinstance(v, basestring) PhotoCmd.setNormalizeNameFormat(v)
def copyTo(self, path, resize=None, keepInfo=True, delTags=False, delCom=False): """ copy self to the path "path", and return its newfilename or none by default, it keeps IPTC/THUMB/EXIF, but it can be removed by setting keepInfo at False. In all case, new file keep its filedate system image can be resized/recompressed (preserving ratio) if resize (which is a tuple=(size, qual)) is provided: if size is a float : it's a percent of original if size is a int : it's the desired largest side qual : is the percent for the quality """ assert type(path) == unicode, "photonod.copyTo() : path is not unicode" dest = os.path.join(path, self.name) while os.path.isfile(dest): dest = os.path.join(path, PhotoCmd.giveMeANewName( os.path.basename(dest))) if resize: assert len(resize) == 2 size, qual = resize assert type(size) in [int, float] pb = self.getImage() # a gtk.PixBuf (wx, wy) = pb.get_width(), pb.get_height() # compute the new size -> wx/wy if type(size) == float: # size is a percent size = int(size * 100) wx = int(wx * size / 100) wy = int(wy * size / 100) else: # size is the largest side in pixels if wx > wy: # format landscape wx, wy = size, (size * wy) / wx else: # format portrait wx, wy = (size * wx) / wy, size # 3= best quality (gtk.gdk.INTERP_HYPER) pb = pb.scale_simple(wx, wy, 3) pb.save(dest, "jpeg", {"quality": str(int(qual))}) if keepInfo: pc = PhotoCmd(self.file) pc.copyInfoTo(dest) del(pb) gc.collect() # so it cleans pixbufs else: shutil.copy2(self.file, dest) if not keepInfo: # we must destroy info PhotoCmd(dest).destroyInfo() if keepInfo: if delCom: PhotoCmd(dest).addComment(u"") if delTags: PhotoCmd(dest).clear() return dest