diff --git a/tren.py b/tren.py index b2c4085..cb78bee 100755 --- a/tren.py +++ b/tren.py @@ -8,7 +8,7 @@ PROGNAME = "tren.py" BASENAME = PROGNAME.split(".py")[0] PROGENV = BASENAME.upper() -RCSID = "$Id: tren.py,v 1.197 2010/03/17 15:16:48 tundra Exp $" +RCSID = "$Id: tren.py,v 1.198 2010/03/17 21:12:05 tundra Exp $" VERSION = RCSID.split()[2] # Copyright Information @@ -140,8 +140,10 @@ # Shared File Attribute And Sequence Renaming Tokens +TOKFILADATE = "ADATE" TOKFILATIME = "ATIME" TOKFILCMD = "CMDLINE" +TOKFILCDATE = "CDATE" TOKFILCTIME = "CTIME" TOKFILDEV = "DEV" TOKFILFNAME = "FNAME" @@ -149,6 +151,7 @@ TOKFILGROUP = "GROUP" TOKFILINODE = "INODE" TOKFILMODE = "MODE" +TOKFILMDATE = "MDATE" TOKFILMTIME = "MTIME" TOKFILNLINK = "NLINK" TOKFILSIZE = "SIZE" @@ -225,10 +228,12 @@ # These literals serve two purposes: # # 1) They are used as the type indicator in a Sequence Renaming Token -# 2) They are keys to the SortViews dictionary that stores the prestorted views +# 2) They are keys to the SortViews and DateViews dictionaries that stores the prestorted views +ORDERBYADATE = TOKFILADATE ORDERBYATIME = TOKFILATIME ORDERBYCMDLINE = TOKFILCMD +ORDERBYCDATE = TOKFILCDATE ORDERBYCTIME = TOKFILCTIME ORDERBYDEV = TOKFILDEV ORDERBYFNAME = TOKFILFNAME @@ -236,6 +241,7 @@ ORDERBYGROUP = TOKFILGROUP ORDERBYINODE = TOKFILINODE ORDERBYMODE = TOKFILMODE +ORDERBYMDATE = TOKFILMDATE ORDERBYMTIME = TOKFILMTIME ORDERBYNLINK = TOKFILNLINK ORDERBYSIZE = TOKFILSIZE @@ -261,6 +267,7 @@ dALPHABETS = "Alphabets" dCMDLINE = "Command Line" dCURSTATE = "Current State Of Program Options" +dDATEVIEW = "Date View:" dDEBUG = "DEBUG" dDUMPOBJ = "Dumping Object %s" dINCLFILES = "Included Files:" @@ -458,23 +465,28 @@ } self.SortViews = { - - ORDERBYATIME : [fullnames in atimes order], - ORDERBYCMDLINE : [fullnames in command line order], - ORDERBYCTIME : [fullnames in ctimes order], - ORDERBYDEV : [fullnames in devs order], - ORDERBYFNAME : [fullnames in alphabetic order], - ORDERBYGID : [fullnames in gids order], - ORDERBYGROUP ; [fullnames in group name order], - ORDERBYINODE : [fullnames in inode order], - ORDERBYMODE : [fullnames in mode order], - ORDERBYMTIME : [fullnames in mtimes order], - ORDERBYNLINK : [fullnames in nlinks order], - ORDERBYSIZE : [fullnames in size order], - ORDERBYUID : [fullnames in uids order], - ORDERBYUSER : [fullnames in user name order] + ORDERBYATIME : [fullnames in atimes order], + ORDERBYCMDLINE : [fullnames in command line order], + ORDERBYCTIME : [fullnames in ctimes order], + ORDERBYDEV : [fullnames in devs order], + ORDERBYFNAME : [fullnames in alphabetic order], + ORDERBYGID : [fullnames in gids order], + ORDERBYGROUP ; [fullnames in group name order], + ORDERBYINODE : [fullnames in inode order], + ORDERBYMODE : [fullnames in mode order], + ORDERBYMTIME : [fullnames in mtimes order], + ORDERBYNLINK : [fullnames in nlinks order], + ORDERBYSIZE : [fullnames in size order], + ORDERBYUID : [fullnames in uids order], + ORDERBYUSER : [fullnames in user name order] } + self.DateViews = { + ORDERBYADATE-date... : [fullnames in order by atime within same 'date'] ... (repeated for each date), + ORDERBYCDATE-date... : [fullnames in order by ctime within same 'date'] ... (repeated for each date), + ORDERBYMDATE-date... : [fullnames in order by mtime within same 'date'] ... (repeated for each date) + } + self.RenRequests = [ { ASK : interactive ask flag @@ -526,6 +538,11 @@ self.SortViews = {ORDERBYCMDLINE : targs, ORDERBYFNAME : alpha} del alpha + # Dictionary to hold all possible date views - files sorted + # by time *within* a common date. + + self.DateViews = {} + # Dictionary of all the renaming requests - will be filled in # by -r command line parsing. @@ -533,6 +550,8 @@ # This data structure is used to build various sort views + # A null first field means the view requires special handling, + # otherwise it's just a stat structure lookup. SeqTypes = [ [ST_ATIME, {}, ORDERBYATIME], @@ -591,6 +610,8 @@ elif order == ORDERBYUSER: sortkey = pwd.getpwuid(stats[ST_UID])[0] + # Save into storage + if sortkey in storage: storage[sortkey].append(fullname) else: @@ -625,6 +646,49 @@ del SeqTypes + # Now build the special cases of ordering by time within date + # for each of the timestamp types. + + for dateorder, timeorder, year, mon, day in ((ORDERBYADATE, ORDERBYATIME, + FILETIMETOKS[TOKAYEAR], + FILETIMETOKS[TOKAMON], + FILETIMETOKS[TOKADAY]), + + (ORDERBYCDATE, ORDERBYCTIME, + FILETIMETOKS[TOKCYEAR], + FILETIMETOKS[TOKCMON], + FILETIMETOKS[TOKCDAY]), + + (ORDERBYMDATE, ORDERBYMTIME, + FILETIMETOKS[TOKMYEAR], + FILETIMETOKS[TOKMMON], + FILETIMETOKS[TOKMDAY])): + + + lastdate = "" + for fullname in self.SortViews[timeorder]: + + newdate = year[0] % eval("time.localtime(self.RenNames[fullname][STATS][%s]).%s" % (year[1], year[2])) + \ + mon[0] % eval("time.localtime(self.RenNames[fullname][STATS][%s]).%s" % (mon[1], mon[2])) + \ + day[0] % eval("time.localtime(self.RenNames[fullname][STATS][%s]).%s" % (day[1], day[2])) + + + key = dateorder+newdate + + # New file date encountered + + if newdate != lastdate: + + self.DateViews[key] = [fullname] + lastdate = newdate + + # Add file to existing list of others sharing that date + + else: + self.DateViews[key].append(fullname) + + + # End of '__init__()' @@ -643,7 +707,7 @@ # Dump the RenNames and SortView dictionaries - for i, msg in ((self.RenNames, dRENTARGET), (self.SortViews, dSORTVIEW)): + for i, msg in ((self.RenNames, dRENTARGET), (self.SortViews, dSORTVIEW), (self.DateViews, dDATEVIEW)): for j in i: DumpList(msg, j, i[j]) @@ -1098,18 +1162,22 @@ # Parse the Sequence Renaming Token into the token itself # and its corresponding formatting field. - + + # Note that the a legal Sequence Renaming Token will either + # be one of the keys of the SortViews dictionary or one + # of the "ORDERBYnDATE" orderings. + token = r[2][1:] found = False - for seqtoken in self.SortViews: + for seqtoken in self.SortViews.keys() + [ORDERBYADATE, ORDERBYCDATE, ORDERBYMDATE]: if token.startswith(seqtoken): token, field = token[:len(seqtoken)], token[len(seqtoken):] found = True break - + if not found: ErrorMsg(eTOKBADSEQ % fullrentoken) @@ -1140,7 +1208,33 @@ # (which is just the index of that filename in the # list). - orderedlist = self.SortViews[token][:] + # One of the standard sorted views requested + + if token in self.SortViews: + orderedlist = self.SortViews[token][:] + + # One of the views sorted within dates requested + + else: + + + if token == ORDERBYADATE: + year, mon, day = FILETIMETOKS[TOKAYEAR], FILETIMETOKS[TOKAMON], FILETIMETOKS[TOKADAY] + + elif token == ORDERBYCDATE: + year, mon, day = FILETIMETOKS[TOKCYEAR], FILETIMETOKS[TOKCMON], FILETIMETOKS[TOKCDAY] + + elif token == ORDERBYMDATE: + year, mon, day = FILETIMETOKS[TOKMYEAR], FILETIMETOKS[TOKMMON], FILETIMETOKS[TOKMDAY] + + targettime = eval("time.localtime(self.RenNames[target][STATS][%s])" % year[1]) + + key = token + \ + year[0] % eval("targettime.%s" % year[2]) + \ + mon[0] % eval("targettime.%s" % mon[2]) + \ + day[0] % eval("targettime.%s" % day[2]) + + orderedlist = self.DateViews[key][:] if r[2][0] == TOKDESCEND: orderedlist.reverse()