From 43044a0326b83190feaebadfd1eb9b5cadaac56e Mon Sep 17 00:00:00 2001 From: johannes Date: Tue, 16 Dec 2014 21:23:58 +0100 Subject: [PATCH 1/8] initial changes --- pyseq.py | 324 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 314 insertions(+), 10 deletions(-) diff --git a/pyseq.py b/pyseq.py index f02967c..5fc4e9e 100755 --- a/pyseq.py +++ b/pyseq.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # --------------------------------------------------------------------------------------------- -# Copyright (c) 2011-2014, Ryan Galloway (ryan@rsgalloway.com) +# Copyright (c) 2011-2012, Ryan Galloway (ryan@rsgalloway.com) # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: @@ -35,6 +35,57 @@ __author__ = "Ryan Galloway " __version__ = "0.3.0" +# --------------------------------------------------------------------------------------------- +# TODO +# --------------------------------------------------------------------------------------------- +""" + - add sequence operations that modify members, e.g. rename, reindex + - support additional syntax, e.g. x10 for every tenth frame + - keyboard interrupt (cntl+c) + - recurse subdirectories and display trees + - add optional explicit format parameter to diff function +""" + +# --------------------------------------------------------------------------------------------- +# CHANGELOG +# --------------------------------------------------------------------------------------------- +""" ++v0.3.0 - 2012 Aug 05 + + fixed %R in uncompress() + + fixed minor bug in getSequences() with glob + + fixed issue #1: same seqs with different extensions don't compress + + added some simple inline unit tests + ++v0.2.1b - 2011 Mar 23 + + supports sequences of any serializable, sortable items + + fixes bug in lss + ++v0.2.0b - 2011 Mar 14 + + Added support for wildcards in getSequence source input and in lss + + Added format method to Sequence class for formatted string stdout + + Sequence __str__ method now returns simplified compressed sequence string + + Added SequenceError exception + + Sequence qppend method raises SequenceError if file is non-sequence-member + + Export diff function to get numeric differences between two sequential files + + Alpha version of uncompress func for deserialization of compressed sequence strings + + Added additional attributes to Item class: path, frame, head, tail + + Item name attribute is now base name, fixes bug where contains method didn't work on file paths + + Moved function 'main' to lss permanently + + Added --format and --debug options to lss + + Ability to set log level with environment variable $PYSEQ_LOG_LEVEL + + Simplified format directives, e.g. from %(head)s to %h, with support for padding, e.g. %04l + + Fixed duplicate sequence index number bug + + Set logging level with PYSEQ_LOG_LEVEL environment variable + + Added 32 additional test cases + * Performance improvements + + Added html docs + ++v0.1.2 - 2011 Feb 15 + + getSequences now takes either a directory path or a python list of files + + added setup.py + + added lss script +""" + import os import re import logging @@ -47,6 +98,10 @@ # regex for matching numerical characters gDigitsRE = re.compile(r'\d+') +gStereoRE = re.compile(r'\_left\_|\_right\_|\_l\.|\_r\.') +#testPattern = re.compile(r'\_left\_|\_right\_|\_l\.|\_r\.') +gStereoREFilter = re.compile(r'.*\_left\_.*|.*\_right\_.*|.*\_l\..*|.*\_r\..*') + # regex for matching format directives gFormatRE = re.compile(r'%(?P\d+)?(?P\w+)') @@ -55,8 +110,6 @@ # logging handlers log = logging.getLogger('pyseq') -log.addHandler(logging.StreamHandler()) -log.setLevel(int(os.environ.get('PYSEQ_LOG_LEVEL', logging.INFO))) class SequenceError(Exception): """special exception for sequence errors""" @@ -82,6 +135,8 @@ def __init__(self, item): self.__filename = os.path.basename(str(item)) self.__digits = gDigitsRE.findall(self.name) self.__parts = gDigitsRE.split(self.name) + self.__size = os.path.getsize(self.__path) + self.__mtime = os.path.getmtime(self.__path) # modified by self.isSibling() self.frame = '' @@ -108,6 +163,12 @@ def _get_dirname(self): def _get_digits(self): return self.__digits + + def _get_size(self): + return self.__size + + def _get_mtime(self): + return self.__mtime def _get_parts(self): return self.__parts @@ -123,6 +184,7 @@ def _set_readonly(self, value): name = property(_get_filename, _set_readonly, doc="Item base name attribute.") dirname = property(_get_dirname, _set_readonly, doc="Item directory name, if a filesystem item.") digits = property(_get_digits, _set_readonly, doc="Numerical components of item name.") + size = property(_get_size, _set_readonly, doc="Item Size") parts = property(_get_parts, _set_readonly, doc="Non-numerical components of item name.") signature = property(_get_sig, _set_readonly, doc="Non-numerical unique item signature.") @@ -177,6 +239,7 @@ def __init__(self, items): :return: pyseq.Sequence class instance. """ super(Sequence, self).__init__([Item(items.pop(0))]) + self.isStereo = False while items: f = Item(items.pop(0)) try: @@ -205,7 +268,7 @@ def __attrs__(self): } def __str__(self): - return self.format('%h%r%t') + return self.format('%h%p%t') def __repr__(self): return '' % str(self) @@ -276,15 +339,23 @@ def start(self): try: return self.frames()[0] except IndexError: - return 0 + if self.length() == 1: + '''fishy workaround we tend to have the last digit pack as frame numbers''' + return int(self[0]._get_digits()[-1]) + else: + return 0 def end(self): """:return: Last index number in sequence.""" try: return self.frames()[-1] except IndexError: - return 0 - + if self.length() == 1: + '''fishy workaround we tend to have the last digit pack as frame numbers''' + return int(self[0]._get_digits()[-1]) + else: + return 0 + def missing(self): """:return: List of missing files.""" if not hasattr(self, '__missing') or not self.__missing: @@ -303,6 +374,9 @@ def path(self): """:return: Absolute path to sequence.""" _dirname = str(os.path.dirname(os.path.abspath(self[0].path))) return os.path.join(_dirname, str(self)) + + def dirname(self): + return str(os.path.dirname(os.path.abspath(self[0].path))) def contains(self, item): """ @@ -402,6 +476,173 @@ def _get_missing(self): frange = xrange(self.start(), self.end()) return filter(lambda x: x not in self.frames(), frange) return '' + + def _calc_average_size(self, low = None, high= None): + ''' + returns the average size of items if low and high are indicated + it calculates the average between those + ''' + self._sizes = list() + if not low and not high: + for i in self: + self._sizes.append(i._get_size()) + else: + for i in self[low:high]: + self._sizes.append(i._get_size()) + self._sizes.remove(min(self._sizes)) + self._sizes.remove(max(self._sizes)) + self._average_size = (sum(self._sizes)/len(self._sizes)) + return self._average_size + + def _get_fishy_sizes(self,threshold = 5): + ''' + returns items which differ from the average in percent + ''' + self._calc_average_size() + percent = self._average_size * (threshold/100.0) + minV = self._average_size - percent + maxV = self._average_size + percent + self._fishy_files = list() + for i in self: + if i._get_size() < minV or i._get_size() > maxV: + self._fishy_files.append(i) + + return self._fishy_files + + def _get_size_jumps(self, threshold = 5, frameRange = 10): + ''' + returns a list of dicts + per item a dict is created with the item under the key item and the average filesize + ''' + + self._fishy_jump = list() + + for e, i in enumerate(self): + tempDict = dict() + if e <= frameRange/2.0: + high = e + frameRange/2 + low = 0 + elif frameRange/2.0 < e < len(self)-frameRange/2.0: + high = e + frameRange/2 + low = e - frameRange/2 + elif e >= len(self)-frameRange/2.0: + high = len(self)-1 + low = e - frameRange/2 + tempAvg = self._calc_average_size(low=low,high=high) + percent = tempAvg * (threshold/100.0) + minV = tempAvg - percent + maxV = tempAvg + percent + if i._get_size() < minV or i._get_size() > maxV: + tempDict['item'] = i + tempDict['avgSize'] = tempAvg + self._fishy_jump.append(tempDict) + + if self._fishy_jump: + log.info('found %s items %s that vary in size by %s percent in an average range of %s frames' % (len(self._fishy_jump),self._fishy_jump,threshold,frameRange)) + return self._fishy_jump + + def _create_mov(self, resX = 1724, resY = 936, soundFile = None, **kwargs): + ''' + little wrapper to create an mov from a sequence object + ''' + oldExt = self.format("%t").split('.')[-1] + newDirname = self.dirname().replace(oldExt, 'mov') + mjpgName = os.path.join(newDirname, self.format("%h.mov")) + mjpgName =mjpgName.replace('..','.') + from helper import srConverter + convert = srConverter.srConverter() + convert.generateMjpgAFromImageSequence(self.path(),self.start(), self.end(),mjpgName, resX = resX, resY = resY, soundFile = soundFile, **kwargs) + return mjpgName + + def _create_mp4(self,resX = 1724, resY = 936, soundFile = None, **kwargs): + ''' + little wrapper to create an mov from a sequence object + ''' + oldExt = self.format("%t").split('.')[-1] + newDirname = self.dirname().replace(oldExt, 'mp4') + mp4Name = os.path.join(newDirname, self.format("%h.mp4")) + mp4Name =mp4Name.replace('..','.') + from helper import srConverter + convert = srConverter.srConverter() + convert.generateMp4FromImageSequence(self.path(),self.start(), self.end(),mp4Name, resX = resX, resY = resY, soundFile = soundFile, **kwargs) + return mp4Name + + def _get_max_mtime(self): + ''' + returns the latest mtime of all items + ''' + maxDate = list() + for i in self: + maxDate.append(i._get_mtime()) + log.info('returning max time from mono object') + return max(maxDate) + + def _get_size(self): + ''' + returns the size all items + divide the result by 1024/1024 to get megabytes + ''' + tempSize = list() + for i in self: + tempSize.append(i._get_size()) + return sum(tempSize) + +class stereoSequence(Sequence): + + + def __init__(self, items, left, right): + + super(Sequence, self).__init__([Item(items.pop(0))]) + self.isStereo = False + while items: + f = Item(items.pop(0)) + try: + self.append(f) + log.debug('+Item belongs to sequence.') + except SequenceError: + log.debug('-Item does not belong to sequence.') + continue + except KeyboardInterrupt: + log.info("Stopping.") + break + + self.left = left + self.right = right + self.isStereo = True + + def __str__(self): + lPattern = re.compile(r'\_l\.|\_r\.') + leftPattern = re.compile(r'\_left\_|\_right\_') + lFilter = re.compile(r'.*\_l\..*|.*\_r\..*') + leftFilter = re.compile(r'.*\_left\_.*|.*\_right\_.*') + if re.match(lFilter,self.left.format('%h%p%t')): + return re.sub(lPattern,'_%v.',self.left.format('%h%p%t')) + elif re.match(leftFilter,self.left.format('%h%p%t')): + return re.sub(leftPattern,'_%V_',self.left.format('%h%p%t')) + + def _get_max_mtime(self): + ''' + returns the latest mtime of all items left and right + ''' + maxDate = list() + for i in self.left: + maxDate.append(i._get_mtime()) + for i in self.right: + maxDate.append(i._get_mtime()) + log.info('returning max time from s3d object') + return max(maxDate) + + def _get_size(self): + ''' + returns the size all items left and right in bytes + divide the result by 1024/1024 to get megabytes + ''' + tempSize = list() + for i in self.left: + tempSize.append(i._get_size()) + for i in self.right: + tempSize.append(i._get_size()) + return sum(tempSize) def diff(f1, f2): """ @@ -604,7 +845,7 @@ def uncompress(seqstring, format=gFormat): return seqs[0] return seqs -def getSequences(source): +def getSequences(source,stereo=False,folders=True): """ Returns a list of Sequence objects given a directory or list that contain sequential members. @@ -658,8 +899,10 @@ def getSequences(source): # glob the source items and sort them if type(source) == list: items = sorted(source, key=lambda x: str(x)) - elif type(source) == str and os.path.isdir(source): + elif type(source) == str and os.path.isdir(source) and folders: items = sorted(glob(os.path.join(source, '*'))) + elif type(source) == str and os.path.isdir(source) and not folders: + items = sorted(glob(os.path.join(source, '*.*'))) elif type(source) == str: items = sorted(glob(source)) else: @@ -680,7 +923,68 @@ def getSequences(source): seqs.append(seq) log.debug("time: %s" %(datetime.now() - start)) - return seqs + if not stereo: + log.info("added sequences: %s" %(seqs)) + return seqs + else: + + listName = [] + left = [] + right = [] + newSeqs = [] + seqs.sort() + + ### this is super unsexy but a fair assumption but it needs to be extended... + ### checking for pairs somehow or rewrite the entire s3d thingy + if len(seqs) == 1: + newSeqs = seqs + else: + for i in seqs: + if re.match(gStereoREFilter,str(i)): + log.info("stereo detected for %s" % i) + listName.append((gStereoRE.finditer(str(i)),i)) + else: + newSeqs.append(i) + + for d in listName: + for x in d[0]: + eye = re.sub(r'[^A-Za-z]','', x.group()) + log.debug('found eye %s' % eye) + if eye == 'left' or eye == 'l' : + left.append({'index':x.span(),'file':d[1],'start':d[1].format('%h%p%t')[:x.start()],'end':d[1].format('%h%p%t')[x.end():]}) + elif eye == 'right' or eye == 'r' : + right.append({'index':x.span(),'file':d[1],'start':d[1].format('%h%p%t')[:x.start()],'end':d[1].format('%h%p%t')[x.end():]}) + + + for l,r in zip(left,right): + ## assuming that the order dictates that the stereo pairs reside at the same index.. + if l['start'] == r['start'] and l['end'] == r['end']: + newSeqs.append(stereoSequence(l['file'][:],l['file'],r['file'])) + + log.debug("time: %s" %(datetime.now() - start)) + log.info("added sequences: %s" %(newSeqs)) + return newSeqs + +def img2pyseq(path,stereo=True): + ''' + path string can be either an evaluated path + like prj_SQ0010_SH0010_matte_base_v001_l.1001.exr + or prj_SQ0010_SH0010_matte_base_v001_%v.%04d.exr + ''' + stereoRe = re.compile(r'\_left\.|\_right\.|\_l\.|\_r\.|\_\%v\.') + padding = re.compile(r'[0-9]{4}\.|\%04d\.|\%d\.|\%02d\.|\%03d\.|\%05d\.|\#\.|\#\#\.|\#\#\#\.|\#\#\#\#\.|[0-9]*\-[0-9]*\#\.') + path = re.sub(padding, '*.' , path) + path = re.sub(stereoRe, '_*.',path) + seq = getSequences(path,stereo=stereo,folders=False) + if not seq: + return None + else: + for i in seq: + if not str(i).__contains__('_c.'): + return i + + + if __name__ == '__main__': """ From 8afb59398fe91f9f5cc99684d7386df5502908ce Mon Sep 17 00:00:00 2001 From: johannes Date: Tue, 10 Mar 2015 10:13:24 +0100 Subject: [PATCH 2/8] major clean up now fully supports s3d sequences with left and l surrounded by dashes or colons --- pyseq.py | 215 +++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 136 insertions(+), 79 deletions(-) diff --git a/pyseq.py b/pyseq.py index 5fc4e9e..2421234 100755 --- a/pyseq.py +++ b/pyseq.py @@ -98,9 +98,7 @@ # regex for matching numerical characters gDigitsRE = re.compile(r'\d+') -gStereoRE = re.compile(r'\_left\_|\_right\_|\_l\.|\_r\.') -#testPattern = re.compile(r'\_left\_|\_right\_|\_l\.|\_r\.') -gStereoREFilter = re.compile(r'.*\_left\_.*|.*\_right\_.*|.*\_l\..*|.*\_r\..*') +gStereoRE = re.compile(r'(\_|\.)(left|right|l|r|%v|%V)(\_|\.)') # regex for matching format directives gFormatRE = re.compile(r'%(?P\d+)?(?P\w+)') @@ -239,7 +237,7 @@ def __init__(self, items): :return: pyseq.Sequence class instance. """ super(Sequence, self).__init__([Item(items.pop(0))]) - self.isStereo = False + self.__isStereo = False while items: f = Item(items.pop(0)) try: @@ -251,6 +249,11 @@ def __init__(self, items): except KeyboardInterrupt: log.info("Stopping.") break + self.foundS3d = re.search(gStereoRE,self[0]) + + @property + def isStereo(self): + return self.__isStereo def __attrs__(self): """Replaces format directives with values""" @@ -352,7 +355,10 @@ def end(self): except IndexError: if self.length() == 1: '''fishy workaround we tend to have the last digit pack as frame numbers''' - return int(self[0]._get_digits()[-1]) + try: + return int(self[0]._get_digits()[-1]) + except: + return 0 else: return 0 @@ -541,32 +547,6 @@ def _get_size_jumps(self, threshold = 5, frameRange = 10): log.info('found %s items %s that vary in size by %s percent in an average range of %s frames' % (len(self._fishy_jump),self._fishy_jump,threshold,frameRange)) return self._fishy_jump - def _create_mov(self, resX = 1724, resY = 936, soundFile = None, **kwargs): - ''' - little wrapper to create an mov from a sequence object - ''' - oldExt = self.format("%t").split('.')[-1] - newDirname = self.dirname().replace(oldExt, 'mov') - mjpgName = os.path.join(newDirname, self.format("%h.mov")) - mjpgName =mjpgName.replace('..','.') - from helper import srConverter - convert = srConverter.srConverter() - convert.generateMjpgAFromImageSequence(self.path(),self.start(), self.end(),mjpgName, resX = resX, resY = resY, soundFile = soundFile, **kwargs) - return mjpgName - - def _create_mp4(self,resX = 1724, resY = 936, soundFile = None, **kwargs): - ''' - little wrapper to create an mov from a sequence object - ''' - oldExt = self.format("%t").split('.')[-1] - newDirname = self.dirname().replace(oldExt, 'mp4') - mp4Name = os.path.join(newDirname, self.format("%h.mp4")) - mp4Name =mp4Name.replace('..','.') - from helper import srConverter - convert = srConverter.srConverter() - convert.generateMp4FromImageSequence(self.path(),self.start(), self.end(),mp4Name, resX = resX, resY = resY, soundFile = soundFile, **kwargs) - return mp4Name - def _get_max_mtime(self): ''' returns the latest mtime of all items @@ -592,8 +572,8 @@ class stereoSequence(Sequence): def __init__(self, items, left, right): - super(Sequence, self).__init__([Item(items.pop(0))]) - self.isStereo = False + super(stereoSequence, self).__init__([Item(items.pop(0))]) + while items: f = Item(items.pop(0)) try: @@ -608,18 +588,18 @@ def __init__(self, items, left, right): self.left = left self.right = right - self.isStereo = True - - def __str__(self): - lPattern = re.compile(r'\_l\.|\_r\.') - leftPattern = re.compile(r'\_left\_|\_right\_') - lFilter = re.compile(r'.*\_l\..*|.*\_r\..*') - leftFilter = re.compile(r'.*\_left\_.*|.*\_right\_.*') - if re.match(lFilter,self.left.format('%h%p%t')): - return re.sub(lPattern,'_%v.',self.left.format('%h%p%t')) - elif re.match(leftFilter,self.left.format('%h%p%t')): - return re.sub(leftPattern,'_%V_',self.left.format('%h%p%t')) - + self.__isStereo = True + if 'left' in self.left.foundS3d.groups(): + pattern = ''.join([ self.left.foundS3d.groups()[0], '%V' , self.left.foundS3d.groups()[-1] ]) + elif'l' in self.left.foundS3d.groups(): + pattern = ''.join([ self.left.foundS3d.groups()[0], '%v' , self.left.foundS3d.groups()[-1] ]) + searchPath = re.sub(gStereoRE,pattern, self[0]) + self.foundS3d = re.search( gStereoRE, searchPath) + + @property + def isStereo(self): + return self.__isStereo + def _get_max_mtime(self): ''' returns the latest mtime of all items left and right @@ -632,6 +612,30 @@ def _get_max_mtime(self): log.info('returning max time from s3d object') return max(maxDate) + def head(self): + """:return: String before the sequence index number.""" + s3d = re.search(gStereoRE, self[0].head) + if s3d: + if 'l' in s3d.groups(): + return re.sub(gStereoRE, '%s%s%s' %(s3d.groups()[0],'%v', s3d.groups()[-1]), self[0].head) + elif 'left' in s3d.groups(): + return re.sub(gStereoRE, '%s%s%s' %(s3d.groups()[0],'%V', s3d.groups()[-1]), self[0].head) + else: + return self[0].head + return self[0].head + + def tail(self): + """:return: String after the sequence index number.""" + s3d = re.search(gStereoRE, self[0].tail) + if s3d: + if 'l' in s3d.groups(): + return re.sub(gStereoRE, '%s%s%s' %(s3d.groups()[0],'%v', s3d.groups()[-1]), self[0].tail) + elif 'left' in s3d.groups(): + return re.sub(gStereoRE, '%s%s%s' %(s3d.groups()[0],'%V', s3d.groups()[-1]), self[0].tail) + else: + return self[0].tail + return self[0].tail + def _get_size(self): ''' returns the size all items left and right in bytes @@ -845,6 +849,14 @@ def uncompress(seqstring, format=gFormat): return seqs[0] return seqs +def stereoPairs(left,right): + if left == 'left' and right == 'right': + return True + elif left == 'l' and right == 'r': + return True + else: + return False + def getSequences(source,stereo=False,folders=True): """ Returns a list of Sequence objects given a directory or list that contain @@ -940,27 +952,46 @@ def getSequences(source,stereo=False,folders=True): newSeqs = seqs else: for i in seqs: - if re.match(gStereoREFilter,str(i)): + found = re.search(gStereoRE,str(i)) + if found: log.info("stereo detected for %s" % i) - listName.append((gStereoRE.finditer(str(i)),i)) + listName.append((found,i)) else: newSeqs.append(i) for d in listName: - for x in d[0]: - eye = re.sub(r'[^A-Za-z]','', x.group()) - log.debug('found eye %s' % eye) - if eye == 'left' or eye == 'l' : - left.append({'index':x.span(),'file':d[1],'start':d[1].format('%h%p%t')[:x.start()],'end':d[1].format('%h%p%t')[x.end():]}) - elif eye == 'right' or eye == 'r' : - right.append({'index':x.span(),'file':d[1],'start':d[1].format('%h%p%t')[:x.start()],'end':d[1].format('%h%p%t')[x.end():]}) - + x = d[0] + eye = x.groups()[1] + log.debug('found eye %s' % eye) + if eye == 'left' or eye == 'l' : + left.append({'index':x.span(), + 'file':d[1], + 'start':d[1].format('%h%p%t')[:x.start()], + 'end':d[1].format('%h%p%t')[x.end():], + 'eye': eye}) + elif eye == 'right' or eye == 'r': + right.append({'index':x.span(), + 'file':d[1], + 'start':d[1].format('%h%p%t')[:x.start()], + 'end':d[1].format('%h%p%t')[x.end():], + 'eye': eye}) + for l,r in zip(left,right): - ## assuming that the order dictates that the stereo pairs reside at the same index.. - if l['start'] == r['start'] and l['end'] == r['end']: + if l in left: + left.remove(l) + if r in right: + right.remove(r) + ## assuming that the order dictates that the stereo pairs reside at the same index.. from the lists + if l['start'] == r['start'] and l['end'] == r['end'] and stereoPairs(l['eye'] , r['eye']) : newSeqs.append(stereoSequence(l['file'][:],l['file'],r['file'])) - + else: + newSeqs += [l['file'],r['file']] + + if left: + newSeqs += [f.get('file') for f in left ] + if right: + newSeqs += [f.get('file') for f in right ] log.debug("time: %s" %(datetime.now() - start)) log.info("added sequences: %s" %(newSeqs)) return newSeqs @@ -971,17 +1002,24 @@ def img2pyseq(path,stereo=True): like prj_SQ0010_SH0010_matte_base_v001_l.1001.exr or prj_SQ0010_SH0010_matte_base_v001_%v.%04d.exr ''' - stereoRe = re.compile(r'\_left\.|\_right\.|\_l\.|\_r\.|\_\%v\.') - padding = re.compile(r'[0-9]{4}\.|\%04d\.|\%d\.|\%02d\.|\%03d\.|\%05d\.|\#\.|\#\#\.|\#\#\#\.|\#\#\#\#\.|[0-9]*\-[0-9]*\#\.') - path = re.sub(padding, '*.' , path) - path = re.sub(stereoRe, '_*.',path) + padding = re.compile(r'(\_|\.)([0-9]{4}|\%04d|\%d|\%02d|\%03d|\%05d|\#|\#\#|\#\#\#|\#\#\#\#|[0-9]*\-[0-9]*\#)(\_|\.)') + found = re.search(padding, path) + if found: + path = re.sub(padding, '%s*%s' % (path[found.start()],path[found.end()-1]), path) + found = re.search(gStereoRE, path) + if found: + path = re.sub(gStereoRE,'%s*%s' % (path[found.start()],path[found.end()-1]), path) seq = getSequences(path,stereo=stereo,folders=False) if not seq: return None else: for i in seq: if not str(i).__contains__('_c.'): - return i + if not found: + return i + else: + if i.foundS3d.groups() == found.groups() or i.left.foundS3d.groups() == found.groups() or i.right.foundS3d.groups() == found.groups(): + return i @@ -992,37 +1030,56 @@ def img2pyseq(path,stereo=True): dummy files that live in pyseq/tests. Changing or modifying these files may break the assertions in the tests below. """ - + logging.basicConfig(level=logging.INFO) +#=============================================================================== # test passing in a list of files - seqs = getSequences(['fileA.1.rgb', 'fileA.2.rgb', 'fileB.1.rgb']) + testRoot = os.path.join(os.path.dirname(__file__), 'tests') + s3dTestRoot = os.path.join(os.path.dirname(__file__), 's3dTests') + seqs = getSequences([os.path.join(testRoot,'fileA.0001.jpg'), + os.path.join(testRoot,'fileA.0002.jpg'), + os.path.join(testRoot,'fileB.0001.jpg')]) assert len(seqs) == 2 - + # get a diff of two files in the same seq - d = diff('fileA.0001.dpx', 'fileA.0002.dpx') + d = diff(os.path.join(testRoot,'fileA.0001.jpg'), os.path.join(testRoot, 'fileA.0002.jpg')) assert d[0]['frames'] == ('0001', '0002') - + # get a diff of two files in the same seq - d = diff('012_vb_110_v002.1.dpx', '012_vb_110_v002.2.dpx') - assert d[0]['frames'] == ('1', '2') - + d = diff(os.path.join(testRoot,'012_vb_110_v002.0001.png'), os.path.join(testRoot,'012_vb_110_v002.0002.png')) + assert d[0]['frames'] == ('0001', '0002') + # glob some files from the tests dir - seqs = getSequences('tests/fileA.*') + seqs = getSequences('./tests/fileA.*') assert len(seqs) == 2 - + # uncompress a few files, test the format matching seq = uncompress('./tests/012_vb_110_v001.%04d.png 1-10', format='%h%p%t %r') assert len(seq) == 10 assert seq.head() == '012_vb_110_v001.' and seq.tail() == '.png' assert seq.frames() == range(1, 11) - + # ... with slightly different format matching - seq = uncompress('./tests/012_vb_110_v001.1-10.png', format='%h%r%t') - assert len(seq) == 10 - assert seq.head() == '012_vb_110_v001.' and seq.tail() == '.png' - assert seq.frames() == range(1, 11) + #seq = uncompress('./tests/012_vb_110_v001.1-10.png', format='%h%r%t') + #assert len(seq) == 10 + #assert seq.head() == '012_vb_110_v001.' and seq.tail() == '.png' + #assert seq.frames() == range(1, 11) +#=============================================================================== # grab all the seqs in the tests dir - seqs = getSequences(os.path.join(os.path.dirname(__file__), 'tests')) + seqs = getSequences(testRoot, stereo = True) for s in seqs: print s.format('%h%p%t %r') + + seqs = getSequences(s3dTestRoot, stereo = True) + for s in seqs: + print s.format('%h%p%t %r') + if s.isStereo: + print s.left.format('%h%p%t %r') + print s.right.format('%h%p%t %r') + + seq = img2pyseq(os.path.join(s3dTestRoot,'012_vb_110_v001_%v.%04d.png')) + print seq + print seq.path() + #print s._get_size() + #print s._get_max_mtime() From 978b5adae82b4f39a0987d1e09eedeee846c9910 Mon Sep 17 00:00:00 2001 From: johannes Date: Tue, 10 Mar 2015 10:13:52 +0100 Subject: [PATCH 3/8] added s3d testFiles --- s3dTests/012_vb_110_v001_l.0001.png | 0 s3dTests/012_vb_110_v001_l.0002.png | 0 s3dTests/012_vb_110_v001_l.0003.png | 0 s3dTests/012_vb_110_v001_l.0004.png | 0 s3dTests/012_vb_110_v001_left.0001.png | 0 s3dTests/012_vb_110_v001_left.0002.png | 0 s3dTests/012_vb_110_v001_left.0003.png | 0 s3dTests/012_vb_110_v001_left.0004.png | 0 s3dTests/012_vb_110_v001_r.0001.png | 0 s3dTests/012_vb_110_v001_r.0002.png | 0 s3dTests/012_vb_110_v001_r.0003.png | 0 s3dTests/012_vb_110_v001_r.0004.png | 0 s3dTests/012_vb_110_v001_right.0001.png | 0 s3dTests/012_vb_110_v001_right.0002.png | 0 s3dTests/012_vb_110_v001_right.0003.png | 0 s3dTests/012_vb_110_v001_right.0004.png | 0 tests/fileB.0001.jpg | 0 tests/fileB.0002.jpg | 0 18 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 s3dTests/012_vb_110_v001_l.0001.png create mode 100644 s3dTests/012_vb_110_v001_l.0002.png create mode 100644 s3dTests/012_vb_110_v001_l.0003.png create mode 100644 s3dTests/012_vb_110_v001_l.0004.png create mode 100644 s3dTests/012_vb_110_v001_left.0001.png create mode 100644 s3dTests/012_vb_110_v001_left.0002.png create mode 100644 s3dTests/012_vb_110_v001_left.0003.png create mode 100644 s3dTests/012_vb_110_v001_left.0004.png create mode 100644 s3dTests/012_vb_110_v001_r.0001.png create mode 100644 s3dTests/012_vb_110_v001_r.0002.png create mode 100644 s3dTests/012_vb_110_v001_r.0003.png create mode 100644 s3dTests/012_vb_110_v001_r.0004.png create mode 100644 s3dTests/012_vb_110_v001_right.0001.png create mode 100644 s3dTests/012_vb_110_v001_right.0002.png create mode 100644 s3dTests/012_vb_110_v001_right.0003.png create mode 100644 s3dTests/012_vb_110_v001_right.0004.png create mode 100644 tests/fileB.0001.jpg create mode 100644 tests/fileB.0002.jpg diff --git a/s3dTests/012_vb_110_v001_l.0001.png b/s3dTests/012_vb_110_v001_l.0001.png new file mode 100644 index 0000000..e69de29 diff --git a/s3dTests/012_vb_110_v001_l.0002.png b/s3dTests/012_vb_110_v001_l.0002.png new file mode 100644 index 0000000..e69de29 diff --git a/s3dTests/012_vb_110_v001_l.0003.png b/s3dTests/012_vb_110_v001_l.0003.png new file mode 100644 index 0000000..e69de29 diff --git a/s3dTests/012_vb_110_v001_l.0004.png b/s3dTests/012_vb_110_v001_l.0004.png new file mode 100644 index 0000000..e69de29 diff --git a/s3dTests/012_vb_110_v001_left.0001.png b/s3dTests/012_vb_110_v001_left.0001.png new file mode 100644 index 0000000..e69de29 diff --git a/s3dTests/012_vb_110_v001_left.0002.png b/s3dTests/012_vb_110_v001_left.0002.png new file mode 100644 index 0000000..e69de29 diff --git a/s3dTests/012_vb_110_v001_left.0003.png b/s3dTests/012_vb_110_v001_left.0003.png new file mode 100644 index 0000000..e69de29 diff --git a/s3dTests/012_vb_110_v001_left.0004.png b/s3dTests/012_vb_110_v001_left.0004.png new file mode 100644 index 0000000..e69de29 diff --git a/s3dTests/012_vb_110_v001_r.0001.png b/s3dTests/012_vb_110_v001_r.0001.png new file mode 100644 index 0000000..e69de29 diff --git a/s3dTests/012_vb_110_v001_r.0002.png b/s3dTests/012_vb_110_v001_r.0002.png new file mode 100644 index 0000000..e69de29 diff --git a/s3dTests/012_vb_110_v001_r.0003.png b/s3dTests/012_vb_110_v001_r.0003.png new file mode 100644 index 0000000..e69de29 diff --git a/s3dTests/012_vb_110_v001_r.0004.png b/s3dTests/012_vb_110_v001_r.0004.png new file mode 100644 index 0000000..e69de29 diff --git a/s3dTests/012_vb_110_v001_right.0001.png b/s3dTests/012_vb_110_v001_right.0001.png new file mode 100644 index 0000000..e69de29 diff --git a/s3dTests/012_vb_110_v001_right.0002.png b/s3dTests/012_vb_110_v001_right.0002.png new file mode 100644 index 0000000..e69de29 diff --git a/s3dTests/012_vb_110_v001_right.0003.png b/s3dTests/012_vb_110_v001_right.0003.png new file mode 100644 index 0000000..e69de29 diff --git a/s3dTests/012_vb_110_v001_right.0004.png b/s3dTests/012_vb_110_v001_right.0004.png new file mode 100644 index 0000000..e69de29 diff --git a/tests/fileB.0001.jpg b/tests/fileB.0001.jpg new file mode 100644 index 0000000..e69de29 diff --git a/tests/fileB.0002.jpg b/tests/fileB.0002.jpg new file mode 100644 index 0000000..e69de29 From dcc7feb87169b55b8d93e6c3ea6da4cc57ea668c Mon Sep 17 00:00:00 2001 From: johannes Date: Tue, 10 Mar 2015 11:37:50 +0100 Subject: [PATCH 4/8] misse one method update --- lss | 2 +- pyseq.py | 10 +++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/lss b/lss index 8720834..a69b347 100755 --- a/lss +++ b/lss @@ -55,7 +55,7 @@ Formatting options: args = os.listdir(os.getcwd()) elif len(args) == 1 and os.path.isdir(args[0]): args = os.listdir(args[0]) - for seq in pyseq.getSequences(args): + for seq in pyseq.getSequences(args,stereo=True): print seq.format(options.format) return 0 diff --git a/pyseq.py b/pyseq.py index 2421234..d2bcba8 100755 --- a/pyseq.py +++ b/pyseq.py @@ -343,8 +343,11 @@ def start(self): return self.frames()[0] except IndexError: if self.length() == 1: - '''fishy workaround we tend to have the last digit pack as frame numbers''' - return int(self[0]._get_digits()[-1]) + try: + '''fishy workaround we tend to have the last digit pack as frame numbers''' + return int(self[0]._get_digits()[-1]) + except: + return 0 else: return 0 @@ -1073,12 +1076,13 @@ def img2pyseq(path,stereo=True): seqs = getSequences(s3dTestRoot, stereo = True) for s in seqs: print s.format('%h%p%t %r') + print s.path() if s.isStereo: print s.left.format('%h%p%t %r') print s.right.format('%h%p%t %r') seq = img2pyseq(os.path.join(s3dTestRoot,'012_vb_110_v001_%v.%04d.png')) - print seq + print seq.format('%h%p%t %r') print seq.path() #print s._get_size() #print s._get_max_mtime() From c5549d65605bdf1125ae88ffa01fe8f4f9c8f3cc Mon Sep 17 00:00:00 2001 From: johannes Date: Wed, 18 Mar 2015 19:43:52 +0100 Subject: [PATCH 5/8] added a method to reindex a sequence object --- pyseq.py | 104 ++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 95 insertions(+), 9 deletions(-) diff --git a/pyseq.py b/pyseq.py index d2bcba8..cd29e47 100755 --- a/pyseq.py +++ b/pyseq.py @@ -133,8 +133,12 @@ def __init__(self, item): self.__filename = os.path.basename(str(item)) self.__digits = gDigitsRE.findall(self.name) self.__parts = gDigitsRE.split(self.name) - self.__size = os.path.getsize(self.__path) - self.__mtime = os.path.getmtime(self.__path) + if os.path.isfile(self.__path): + self.__size = os.path.getsize(self.__path) + self.__mtime = os.path.getmtime(self.__path) + else: + self.__size = 0 + self.__mtime = 0 # modified by self.isSibling() self.frame = '' @@ -250,6 +254,7 @@ def __init__(self, items): log.info("Stopping.") break self.foundS3d = re.search(gStereoRE,self[0]) + self.NEEDREINDEX = False @property def isStereo(self): @@ -332,7 +337,7 @@ def length(self): def frames(self): """:return: List of files in sequence.""" - if not hasattr(self, '__frames') or not self.__frames: + if not hasattr(self, '__frames') or not self.__frames or self.NEEDREINDEX == True: self.__frames = map(int, self._get_frames()) self.__frames.sort() return self.__frames @@ -570,6 +575,36 @@ def _get_size(self): tempSize.append(i._get_size()) return sum(tempSize) + def reIndex(self, addSub, padding=None, run=False): + ''' + renames the files on disk + reIndex the items in the sequence object egg + 1001 + 100 = 1101 + can change the padding too + ''' + if not padding: + padding = self.format("%p") + + for image,frame in zip(self,self.frames()): + oldName = image._get_path() + newFrame = padding % (frame + addSub) + newFileName ="%s%s%s" % (self.format("%h"), newFrame , self.format("%t") ) + newName = os.path.join(self.dirname(), newFileName) + try: + import shutil + if run: + shutil.move(oldName,newName) + except Exception,e: + log.error(e) + else: + log.info('renaming %s -->' % oldName) + log.info(' %s' % newName) + self.NEEDREINDEX = True + image.frame = newFrame + else: + self.frames() + + class stereoSequence(Sequence): @@ -650,6 +685,48 @@ def _get_size(self): for i in self.right: tempSize.append(i._get_size()) return sum(tempSize) + + def reIndex(self, addSub, padding=None, run=False): + ''' + renames the files on disk + reIndex the items in the sequence object egg + 1001 + 100 = 1101 + can change the padding too + ''' + if not padding: + padding = self.format("%p") + + for image ,imageL, imageR ,frame in zip(self, self.left, self.right, self.frames()): + oldNameL = imageL._get_path() + oldNameR = imageR._get_path() + newFrame = padding % (frame + addSub) + newFileNameL ="%s%s%s" % (self.left.format("%h"), newFrame , self.left.format("%t") ) + newFileNameR = "%s%s%s" % (self.right.format("%h"), newFrame , self.right.format("%t") ) + newNameL = os.path.join(self.dirname(), newFileNameL) + newNameR = os.path.join(self.dirname(), newFileNameR) + try: + import shutil + if run: + shutil.move(oldNameL,newNameL) + shutil.move(oldNameR,newNameR) + except Exception,e: + log.error(e) + else: + log.info('renaming %s -->' % oldNameL) + log.info(' %s' % newNameL) + log.info('renaming %s -->' % oldNameR) + log.info(' %s' % newNameR) + self.NEEDREINDEX = True + self.left.NEEDREINDEX = True + self.right.NEEDREINDEX = True + image.frame = newFrame + imageL.frame = newFrame + imageR.frame = newFrame + else: + self.frames() + self.left.frames() + self.right.frames() + def diff(f1, f2): """ @@ -1033,7 +1110,7 @@ def img2pyseq(path,stereo=True): dummy files that live in pyseq/tests. Changing or modifying these files may break the assertions in the tests below. """ - logging.basicConfig(level=logging.INFO) + #logging.basicConfig(level=logging.INFO) #=============================================================================== # test passing in a list of files testRoot = os.path.join(os.path.dirname(__file__), 'tests') @@ -1062,24 +1139,33 @@ def img2pyseq(path,stereo=True): assert seq.frames() == range(1, 11) # ... with slightly different format matching - #seq = uncompress('./tests/012_vb_110_v001.1-10.png', format='%h%r%t') - #assert len(seq) == 10 - #assert seq.head() == '012_vb_110_v001.' and seq.tail() == '.png' - #assert seq.frames() == range(1, 11) + seq = uncompress('./tests/012_vb_110_v001.1-10.png', format='%h%r%t') + assert len(seq) == 10 + assert seq.head() == '012_vb_110_v001.' and seq.tail() == '.png' + assert seq.frames() == range(1, 11) #=============================================================================== # grab all the seqs in the tests dir seqs = getSequences(testRoot, stereo = True) for s in seqs: print s.format('%h%p%t %r') + s.reIndex(1000,padding= "%07d") seqs = getSequences(s3dTestRoot, stereo = True) for s in seqs: print s.format('%h%p%t %r') print s.path() if s.isStereo: - print s.left.format('%h%p%t %r') + #print s.left.format('%h%p%t %r') + print s.left.frames() + s.reIndex(150,padding = "%05d") + print s.frames() + print s.left.frames() + print s.right.frames() + #print s.left.format("%p") + print s.left.path() print s.right.format('%h%p%t %r') + print s.format('%h%p%t %r') seq = img2pyseq(os.path.join(s3dTestRoot,'012_vb_110_v001_%v.%04d.png')) print seq.format('%h%p%t %r') From a3fd980c165c13db4e83ce4199ca3e8c8de53c2c Mon Sep 17 00:00:00 2001 From: johannes Date: Tue, 24 Mar 2015 12:33:49 +0100 Subject: [PATCH 6/8] some changes : -- added mtime and size properties to item -- added methods to sequence to get max mtime and size for the sequence object -- added reindex function can change padding too --- pyseq.py | 78 +++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 75 insertions(+), 3 deletions(-) diff --git a/pyseq.py b/pyseq.py index ab28ea7..98bc8d8 100755 --- a/pyseq.py +++ b/pyseq.py @@ -90,7 +90,13 @@ def __init__(self, item): self.__filename = os.path.basename(str(item)) self.__digits = gDigitsRE.findall(self.name) self.__parts = gDigitsRE.split(self.name) - + + if os.path.isfile(self.__path): + self.__size = os.path.getsize(self.__path) + self.__mtime = os.path.getmtime(self.__path) + else: + self.__size = 0 + self.__mtime = 0 # modified by self.is_sibling() self.frame = '' self.head = self.name @@ -136,6 +142,18 @@ def parts(self): """ return self.__parts + @property + def size(self): + """Non-numerical components of item name + """ + return self.__size + + @property + def mtime(self): + """Non-numerical components of item name + """ + return self.__mtime + def isSibling(self, item): """Determines if this and item are part of the same sequence. @@ -194,6 +212,7 @@ def __init__(self, items): """ super(Sequence, self).__init__([Item(items.pop(0))]) self.__missing = [] + self.__NEEDREINDEX = False while items: f = Item(items.pop(0)) try: @@ -205,6 +224,8 @@ def __init__(self, items): except KeyboardInterrupt: log.info("Stopping.") break + + def __attrs__(self): """Replaces format directives with values""" @@ -296,7 +317,7 @@ def length(self): def frames(self): """:return: List of files in sequence.""" - if not hasattr(self, '__frames') or not self.__frames: + if not hasattr(self, '__frames') or not self.__frames or self.__NEEDREINDEX: self.__frames = list(map(int, self._get_frames())) self.__frames.sort() return self.__frames @@ -408,6 +429,57 @@ def append(self, item): else: raise SequenceError('Item is not a member of this sequence') + def get_max_mtime(self): + ''' + returns the latest mtime of all items + ''' + maxDate = list() + for i in self: + maxDate.append(i.mtime) + return max(maxDate) + + def get_size(self): + ''' + returns the size all items + divide the result by 1024/1024 to get megabytes + ''' + tempSize = list() + for i in self: + tempSize.append(i.size) + return sum(tempSize) + + def reIndex(self, addSub, padding=None, run=False): + ''' + renames the files on disk + reIndex the items in the sequence object egg + 1001 + 100 = 1101 + can change the padding too + @param addSub int + @param padding str + @param run boolean + ''' + if not padding: + padding = self.format("%p") + + for image,frame in zip(self,self.frames()): + oldName = image.path + newFrame = padding % (frame + addSub) + newFileName ="%s%s%s" % (self.format("%h"), newFrame , self.format("%t") ) + newName = os.path.join(self.dirname, newFileName) + try: + import shutil + if run: + shutil.move(oldName,newName) + except Exception,e: + log.error(e) + else: + log.info('renaming %s -->' % oldName) + log.info(' %s' % newName) + self.__NEEDREINDEX = True + image.frame = newFrame + else: + self.frames() + def _get_padding(self): """:return: padding string, e.g. %07d""" try: @@ -733,7 +805,7 @@ def getSequences(source): items = sorted(source, key=lambda x: str(x)) elif isinstance(source, str): if os.path.isdir(source): - items = sorted(glob(os.path.join(source, '*'))) + items = sorted(glob(os.path.join(source, '*.*'))) else: items = sorted(glob(source)) else: From f1110abf637a449999a690ef84db8717505964ac Mon Sep 17 00:00:00 2001 From: johannes Date: Tue, 24 Mar 2015 14:20:04 +0100 Subject: [PATCH 7/8] remove old clutter --- s3dTests/012_vb_110_v001_l.0001.png | 0 s3dTests/012_vb_110_v001_l.0002.png | 0 s3dTests/012_vb_110_v001_l.0003.png | 0 s3dTests/012_vb_110_v001_l.0004.png | 0 s3dTests/012_vb_110_v001_left.0001.png | 0 s3dTests/012_vb_110_v001_left.0002.png | 0 s3dTests/012_vb_110_v001_left.0003.png | 0 s3dTests/012_vb_110_v001_left.0004.png | 0 s3dTests/012_vb_110_v001_r.0001.png | 0 s3dTests/012_vb_110_v001_r.0002.png | 0 s3dTests/012_vb_110_v001_r.0003.png | 0 s3dTests/012_vb_110_v001_r.0004.png | 0 s3dTests/012_vb_110_v001_right.0001.png | 0 s3dTests/012_vb_110_v001_right.0002.png | 0 s3dTests/012_vb_110_v001_right.0003.png | 0 s3dTests/012_vb_110_v001_right.0004.png | 0 tests/fileB.0001.jpg | 0 tests/fileB.0002.jpg | 0 18 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 s3dTests/012_vb_110_v001_l.0001.png delete mode 100644 s3dTests/012_vb_110_v001_l.0002.png delete mode 100644 s3dTests/012_vb_110_v001_l.0003.png delete mode 100644 s3dTests/012_vb_110_v001_l.0004.png delete mode 100644 s3dTests/012_vb_110_v001_left.0001.png delete mode 100644 s3dTests/012_vb_110_v001_left.0002.png delete mode 100644 s3dTests/012_vb_110_v001_left.0003.png delete mode 100644 s3dTests/012_vb_110_v001_left.0004.png delete mode 100644 s3dTests/012_vb_110_v001_r.0001.png delete mode 100644 s3dTests/012_vb_110_v001_r.0002.png delete mode 100644 s3dTests/012_vb_110_v001_r.0003.png delete mode 100644 s3dTests/012_vb_110_v001_r.0004.png delete mode 100644 s3dTests/012_vb_110_v001_right.0001.png delete mode 100644 s3dTests/012_vb_110_v001_right.0002.png delete mode 100644 s3dTests/012_vb_110_v001_right.0003.png delete mode 100644 s3dTests/012_vb_110_v001_right.0004.png delete mode 100644 tests/fileB.0001.jpg delete mode 100644 tests/fileB.0002.jpg diff --git a/s3dTests/012_vb_110_v001_l.0001.png b/s3dTests/012_vb_110_v001_l.0001.png deleted file mode 100644 index e69de29..0000000 diff --git a/s3dTests/012_vb_110_v001_l.0002.png b/s3dTests/012_vb_110_v001_l.0002.png deleted file mode 100644 index e69de29..0000000 diff --git a/s3dTests/012_vb_110_v001_l.0003.png b/s3dTests/012_vb_110_v001_l.0003.png deleted file mode 100644 index e69de29..0000000 diff --git a/s3dTests/012_vb_110_v001_l.0004.png b/s3dTests/012_vb_110_v001_l.0004.png deleted file mode 100644 index e69de29..0000000 diff --git a/s3dTests/012_vb_110_v001_left.0001.png b/s3dTests/012_vb_110_v001_left.0001.png deleted file mode 100644 index e69de29..0000000 diff --git a/s3dTests/012_vb_110_v001_left.0002.png b/s3dTests/012_vb_110_v001_left.0002.png deleted file mode 100644 index e69de29..0000000 diff --git a/s3dTests/012_vb_110_v001_left.0003.png b/s3dTests/012_vb_110_v001_left.0003.png deleted file mode 100644 index e69de29..0000000 diff --git a/s3dTests/012_vb_110_v001_left.0004.png b/s3dTests/012_vb_110_v001_left.0004.png deleted file mode 100644 index e69de29..0000000 diff --git a/s3dTests/012_vb_110_v001_r.0001.png b/s3dTests/012_vb_110_v001_r.0001.png deleted file mode 100644 index e69de29..0000000 diff --git a/s3dTests/012_vb_110_v001_r.0002.png b/s3dTests/012_vb_110_v001_r.0002.png deleted file mode 100644 index e69de29..0000000 diff --git a/s3dTests/012_vb_110_v001_r.0003.png b/s3dTests/012_vb_110_v001_r.0003.png deleted file mode 100644 index e69de29..0000000 diff --git a/s3dTests/012_vb_110_v001_r.0004.png b/s3dTests/012_vb_110_v001_r.0004.png deleted file mode 100644 index e69de29..0000000 diff --git a/s3dTests/012_vb_110_v001_right.0001.png b/s3dTests/012_vb_110_v001_right.0001.png deleted file mode 100644 index e69de29..0000000 diff --git a/s3dTests/012_vb_110_v001_right.0002.png b/s3dTests/012_vb_110_v001_right.0002.png deleted file mode 100644 index e69de29..0000000 diff --git a/s3dTests/012_vb_110_v001_right.0003.png b/s3dTests/012_vb_110_v001_right.0003.png deleted file mode 100644 index e69de29..0000000 diff --git a/s3dTests/012_vb_110_v001_right.0004.png b/s3dTests/012_vb_110_v001_right.0004.png deleted file mode 100644 index e69de29..0000000 diff --git a/tests/fileB.0001.jpg b/tests/fileB.0001.jpg deleted file mode 100644 index e69de29..0000000 diff --git a/tests/fileB.0002.jpg b/tests/fileB.0002.jpg deleted file mode 100644 index e69de29..0000000 From b8f707d6beb8d1e3c7da2817cbda8b5613a0b855 Mon Sep 17 00:00:00 2001 From: johannes Date: Wed, 25 Mar 2015 14:31:56 +0100 Subject: [PATCH 8/8] =?UTF-8?q?--=20changed=20comments=20to=20double=20quo?= =?UTF-8?q?tes=20--=20method=20Names=20are=20camelCase=20for=20now=20--=20?= =?UTF-8?q?had=20to=20change=20item.=5F=5Fdirname=20to=20use=20self.=5F=5F?= =?UTF-8?q?path=20as=20it=20was=20missing=20on=20the=20first=20item,=20tho?= =?UTF-8?q?ugh=20I=20do=20not=20know=20why=E2=80=A6.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pyseq.py | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/pyseq.py b/pyseq.py index f463205..c5f63cb 100755 --- a/pyseq.py +++ b/pyseq.py @@ -86,7 +86,7 @@ def __init__(self, item): log.debug('adding %s' % item) self.item = item self.__path = getattr(item, 'path', os.path.abspath(str(item))) - self.__dirname = os.path.dirname(str(item)) + self.__dirname = os.path.dirname(self.__path) self.__filename = os.path.basename(str(item)) self.__digits = gDigitsRE.findall(self.name) self.__parts = gDigitsRE.split(self.name) @@ -429,27 +429,27 @@ def append(self, item): else: raise SequenceError('Item is not a member of this sequence') - def get_max_mtime(self): - ''' + def getMaxMTime(self): + """ returns the latest mtime of all items - ''' + """ maxDate = list() for i in self: maxDate.append(i.mtime) return max(maxDate) - def get_size(self): - ''' + def getSize(self): + """ returns the size all items divide the result by 1024/1024 to get megabytes - ''' + """ tempSize = list() for i in self: tempSize.append(i.size) return sum(tempSize) def reIndex(self, addSub, padding=None, run=False): - ''' + """ renames the files on disk reIndex the items in the sequence object egg 1001 + 100 = 1101 @@ -457,15 +457,20 @@ def reIndex(self, addSub, padding=None, run=False): @param addSub int @param padding str @param run boolean - ''' + """ if not padding: padding = self.format("%p") - - for image,frame in zip(self,self.frames()): + + if addSub > 0: + gen = ((image,frame) for (image,frame) in zip(reversed(self),reversed(self.frames()))) + else: + gen = ((image,frame) for (image,frame) in zip(self,self.frames())) + + for image,frame in gen: oldName = image.path newFrame = padding % (frame + addSub) newFileName ="%s%s%s" % (self.format("%h"), newFrame , self.format("%t") ) - newName = os.path.join(self.dirname, newFileName) + newName = os.path.join(image.dirname, newFileName) try: import shutil if run: @@ -805,7 +810,7 @@ def getSequences(source): items = sorted(source, key=lambda x: str(x)) elif isinstance(source, str): if os.path.isdir(source): - items = sorted(glob(os.path.join(source, '*.*'))) + items = sorted(glob(os.path.join(source, '*'))) else: items = sorted(glob(source)) else: