rdiff-backup-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Rdiff-backup-commits] rdiff-backup ./CHANGELOG rdiff_backup/Time.py [r1


From: dean gaudet
Subject: [Rdiff-backup-commits] rdiff-backup ./CHANGELOG rdiff_backup/Time.py [r1-0]
Date: Fri, 20 Jan 2006 16:30:19 +0000

CVSROOT:        /cvsroot/rdiff-backup
Module name:    rdiff-backup
Branch:         r1-0
Changes by:     dean gaudet <address@hidden>    06/01/20 16:30:19

Modified files:
        .              : CHANGELOG 
        rdiff_backup   : Time.py 

Log message:
        fix off-by-1 traceback in "--remove-older-than nB"

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/rdiff-backup/rdiff-backup/CHANGELOG.diff?only_with_tag=r1-0&tr1=1.147.2.15&tr2=1.147.2.16&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/rdiff-backup/rdiff-backup/rdiff_backup/Time.py.diff?only_with_tag=r1-0&tr1=1.11&tr2=1.11.2.1&r1=text&r2=text

Patches:
Index: rdiff-backup/CHANGELOG
diff -u rdiff-backup/CHANGELOG:1.147.2.15 rdiff-backup/CHANGELOG:1.147.2.16
--- rdiff-backup/CHANGELOG:1.147.2.15   Mon Jan 16 04:09:50 2006
+++ rdiff-backup/CHANGELOG      Fri Jan 20 16:30:19 2006
@@ -1,3 +1,9 @@
+New in v1.0.5 (????/??/??)
+--------------------------
+
+Fix a traceback due to an off-by-1 error in "--remove-older-than nB".
+
+
 New in v1.0.4 (2006/01/15)
 --------------------------
 
Index: rdiff-backup/rdiff_backup/Time.py
diff -u /dev/null rdiff-backup/rdiff_backup/Time.py:1.11.2.1
--- /dev/null   Fri Jan 20 16:30:19 2006
+++ rdiff-backup/rdiff_backup/Time.py   Fri Jan 20 16:30:19 2006
@@ -0,0 +1,238 @@
+# Copyright 2002 Ben Escoto
+#
+# This file is part of rdiff-backup.
+#
+# rdiff-backup is free software; you can redistribute it and/or modify
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 2 of the License, or (at your
+# option) any later version.
+#
+# rdiff-backup is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with rdiff-backup; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+# USA
+
+"""Provide time related exceptions and functions"""
+
+import time, types, re, sys, calendar
+import Globals
+
+
+class TimeException(Exception): pass
+
+_interval_conv_dict = {"s": 1, "m": 60, "h": 3600, "D": 86400,
+                                          "W": 7*86400, "M": 30*86400, "Y": 
365*86400}
+_integer_regexp = re.compile("^[0-9]+$")
+_session_regexp = re.compile("^[0-9]+B$")
+_interval_regexp = re.compile("^([0-9]+)([smhDWMY])")
+_genstr_date_regexp1 = re.compile("^(?P<year>[0-9]{4})[-/]"
+                                          
"(?P<month>[0-9]{1,2})[-/](?P<day>[0-9]{1,2})$")
+_genstr_date_regexp2 = re.compile("^(?P<month>[0-9]{1,2})[-/]"
+                                          
"(?P<day>[0-9]{1,2})[-/](?P<year>[0-9]{4})$")
+curtime = curtimestr = None
+
+def setcurtime(curtime = None):
+       """Sets the current time in curtime and curtimestr on all systems"""
+       t = curtime or time.time()
+       for conn in Globals.connections:
+               conn.Time.setcurtime_local(long(t))
+
+def setcurtime_local(timeinseconds):
+       """Only set the current time locally"""
+       global curtime, curtimestr
+       curtime, curtimestr = timeinseconds, timetostring(timeinseconds)
+
+def setprevtime(timeinseconds):
+       """Sets the previous inc time in prevtime and prevtimestr"""
+       assert 0 < timeinseconds < curtime, \
+                  "Time %s is out of bounds" % (timeinseconds,)
+       timestr = timetostring(timeinseconds)
+       for conn in Globals.connections:
+               conn.Time.setprevtime_local(timeinseconds, timestr)
+
+def setprevtime_local(timeinseconds, timestr):
+       """Like setprevtime but only set the local version"""
+       global prevtime, prevtimestr
+       prevtime, prevtimestr = timeinseconds, timestr
+
+def timetostring(timeinseconds):
+       """Return w3 datetime compliant listing of timeinseconds"""
+       s = time.strftime("%Y-%m-%dT%H:%M:%S", time.localtime(timeinseconds))
+       return s + gettzd(timeinseconds)
+
+def stringtotime(timestring):
+       """Return time in seconds from w3 timestring
+
+       If there is an error parsing the string, or it doesn't look
+       like a w3 datetime string, return None.
+
+       """
+       try:
+               date, daytime = timestring[:19].split("T")
+               year, month, day = map(int, date.split("-"))
+               hour, minute, second = map(int, daytime.split(":"))
+               assert 1900 < year < 2100, year
+               assert 1 <= month <= 12
+               assert 1 <= day <= 31
+               assert 0 <= hour <= 23
+               assert 0 <= minute <= 59
+               assert 0 <= second <= 61  # leap seconds
+               timetuple = (year, month, day, hour, minute, second, -1, -1, 0)
+               utc_in_secs = calendar.timegm(timetuple)
+
+               return long(utc_in_secs) + tzdtoseconds(timestring[19:])
+       except (TypeError, ValueError, AssertionError): return None
+
+def timetopretty(timeinseconds):
+       """Return pretty version of time"""
+       return time.asctime(time.localtime(timeinseconds))
+
+def stringtopretty(timestring):
+       """Return pretty version of time given w3 time string"""
+       return timetopretty(stringtotime(timestring))
+
+def inttopretty(seconds):
+       """Convert num of seconds to readable string like "2 hours"."""
+       partlist = []
+       hours, seconds = divmod(seconds, 3600)
+       if hours > 1: partlist.append("%d hours" % hours)
+       elif hours == 1: partlist.append("1 hour")
+
+       minutes, seconds = divmod(seconds, 60)
+       if minutes > 1: partlist.append("%d minutes" % minutes)
+       elif minutes == 1: partlist.append("1 minute")
+
+       if seconds == 1: partlist.append("1 second")
+       elif not partlist or seconds > 1:
+               if isinstance(seconds, int) or isinstance(seconds, long):
+                       partlist.append("%s seconds" % seconds)
+               else: partlist.append("%.2f seconds" % seconds)
+       return " ".join(partlist)
+
+def intstringtoseconds(interval_string):
+       """Convert a string expressing an interval (e.g. "4D2s") to seconds"""
+       def error():
+               raise TimeException("""Bad interval string "%s"
+
+Intervals are specified like 2Y (2 years) or 2h30m (2.5 hours).  The
+allowed special characters are s, m, h, D, W, M, and Y.  See the man
+page for more information.
+""" % interval_string)
+       if len(interval_string) < 2: error()
+
+       total = 0
+       while interval_string:
+               match = _interval_regexp.match(interval_string)
+               if not match: error()
+               num, ext = int(match.group(1)), match.group(2)
+               if not ext in _interval_conv_dict or num < 0: error()
+               total += num*_interval_conv_dict[ext]
+               interval_string = interval_string[match.end(0):]
+       return total
+
+def gettzd(timeinseconds = None):
+       """Return w3's timezone identification string.
+
+       Expresed as [+/-]hh:mm.  For instance, PDT is -07:00 during
+       dayling savings and -08:00 otherwise.  Zone is coincides with what
+       localtime(), etc., use.  If no argument given, use the current
+       time.
+
+       """
+       if timeinseconds is None: timeinseconds = time.time()
+       dst_in_effect = time.daylight and time.localtime(timeinseconds)[8]
+       if dst_in_effect: offset = -time.altzone/60
+       else: offset = -time.timezone/60
+       if offset > 0: prefix = "+"
+       elif offset < 0: prefix = "-"
+       else: return "Z" # time is already in UTC
+
+       hours, minutes = map(abs, divmod(offset, 60))
+       assert 0 <= hours <= 23
+       assert 0 <= minutes <= 59
+       return "%s%02d:%02d" % (prefix, hours, minutes)
+
+def tzdtoseconds(tzd):
+       """Given w3 compliant TZD, return how far ahead UTC is"""
+       if tzd == "Z": return 0
+       assert len(tzd) == 6 # only accept forms like +08:00 for now
+       assert (tzd[0] == "-" or tzd[0] == "+") and tzd[3] == ":"
+       return -60 * (60 * int(tzd[:3]) + int(tzd[4:]))
+
+def cmp(time1, time2):
+       """Compare time1 and time2 and return -1, 0, or 1"""
+       if type(time1) is types.StringType:
+               time1 = stringtotime(time1)
+               assert time1 is not None
+       if type(time2) is types.StringType:
+               time2 = stringtotime(time2)
+               assert time2 is not None
+
+       if time1 < time2: return -1
+       elif time1 == time2: return 0
+       else: return 1
+
+def time_from_session(session_num, rp = None):
+       """Return time in seconds of given backup
+
+       The current mirror is session_num 0, the next oldest increment has
+       number 1, etc.  Requires that the Globals.rbdir directory be set.
+
+       """
+       session_times = Globals.rbdir.conn.restore.MirrorStruct \
+                                       .get_increment_times()
+       session_times.sort()
+       if len(session_times) <= session_num:
+               return session_times[0] # Use oldest if two few backups
+       return session_times[-session_num-1]
+       
+def genstrtotime(timestr, curtime = None, rp = None):
+       """Convert a generic time string to a time in seconds
+
+       rp is used when the time is of the form "4B" or similar.  Then the
+       times of the increments of that particular file are used.
+
+       """
+       if curtime is None: curtime = globals()['curtime']
+       if timestr == "now": return curtime
+
+       def error():
+               raise TimeException("""Bad time string "%s"
+
+The acceptible time strings are intervals (like "3D64s"), w3-datetime
+strings, like "2002-04-26T04:22:01-07:00" (strings like
+"2002-04-26T04:22:01" are also acceptable - rdiff-backup will use the
+current time zone), or ordinary dates like 2/4/1997 or 2001-04-23
+(various combinations are acceptable, but the month always precedes
+the day).""" % timestr)
+
+       # Test for straight integer
+       if _integer_regexp.search(timestr): return int(timestr)
+
+       # Test for w3-datetime format, possibly missing tzd
+       t = stringtotime(timestr) or stringtotime(timestr+gettzd())
+       if t: return t
+
+       # Test for time given as number of backups, like 3B
+       if _session_regexp.search(timestr):
+               return time_from_session(int(timestr[:-1]), rp)
+
+       try: # test for an interval, like "2 days ago"
+               return curtime - intstringtoseconds(timestr)
+       except TimeException: pass
+
+       # Now check for dates like 2001/3/23
+       match = _genstr_date_regexp1.search(timestr) or \
+                       _genstr_date_regexp2.search(timestr)
+       if not match: error()
+       timestr = "%s-%02d-%02dT00:00:00%s" % (match.group('year'),
+                            int(match.group('month')), 
int(match.group('day')), gettzd())
+       t = stringtotime(timestr)
+       if t: return t
+       else: error()
+




reply via email to

[Prev in Thread] Current Thread [Next in Thread]