def test_add(self): """Check if addition with timedelta is working as expected.""" # Without timezone self.assertEqual(rdwTime('2014-11-08T21:04:30Z'), rdwTime('2014-11-05T21:04:30Z') + datetime.timedelta(days=3)) # With timezone self.assertEqual(rdwTime('2014-11-08T21:04:30-04:00'), rdwTime('2014-11-05T21:04:30-04:00') + datetime.timedelta(days=3))
def test_restore_dates(self): increments = [ IncrementEntry(self.root_path, b'my_dir.2014-11-05T16:04:30-05:00.dir'), IncrementEntry(self.root_path, b'my_dir.2014-11-05T16:04:55-05:00.dir')] entry = DirEntry(self.root_path, b'my_dir', False, increments) self.assertEqual( [rdwTime(1415221470), rdwTime(1415221495), ], entry.restore_dates)
def test_restore_dates(self): increments = [ IncrementEntry(self.root_path, b'my_dir.2014-11-05T16:04:30-05:00.dir'), IncrementEntry(self.root_path, b'my_dir.2014-11-05T16:04:55-05:00.dir') ] entry = DirEntry(self.root_path, b'my_dir', False, increments) self.assertEqual([ rdwTime(1415221470), rdwTime(1415221495), ], entry.restore_dates)
def test_init(self): """ Check various constructor. """ t0 = rdwTime() self.assertAlmostEqual(int(time.time()), t0.timeInSeconds, delta=5000) t1 = rdwTime(1415221470) self.assertEqual(1415221470, t1.timeInSeconds) t2 = rdwTime('2014-11-05T21:04:30Z') self.assertEqual(1415221470, t2.timeInSeconds)
def test_change_dates(self): """Check if dates are properly sorted.""" increments = [ IncrementEntry(self.root_path, b'my_filename.txt.2014-11-02T17:23:41-05:00.diff.gz'), IncrementEntry(self.root_path, b'my_filename.txt.2014-11-02T09:16:43-05:00.missing'), IncrementEntry(self.root_path, b'my_filename.txt.2014-11-03T19:04:57-05:00.diff.gz')] entry = DirEntry(self.root_path, b'my_filename.txt', False, increments) self.assertEqual( [rdwTime(1414939853), rdwTime(1414967021), rdwTime(1415059497)], entry.change_dates)
def test_init(self): increment = IncrementEntry( self.root_path, b'my_filename.txt.2014-11-02T17:23:41-05:00.diff.gz') self.assertEqual(rdwTime(1414967021), increment.date) self.assertEqual(b'my_filename.txt', increment.filename)
def send_notifications(self): """ Loop trough all the user repository and send notifications. """ now = rdwTime() def _user_repos(): """Return a generator trought user repos to be notified.""" for user in self.app.userdb.list(): # Check if user has email. if not user.email: continue # Identify old repo for current user. old_repos = [] for repo in user.repo_list: # Check if repo has age configured (in days) maxage = repo.maxage if not maxage or maxage <= 0: continue # Check repo age. r = librdiff.RdiffRepo(user.user_root, repo.name) if r.last_backup_date < (now - datetime.timedelta(days=maxage)): old_repos.append(r) # Return an item only if user had old repo if old_repos: yield user, old_repos # For each candidate, send mail. for user, repos in _user_repos(): parms = {'user': user, 'repos': repos} self.send_mail(user, _('Notification'), 'email_notification.html', **parms)
def _get_recent_user_messages(self, failuresOnly): user_repos = self.app.currentuser.repos asOfDate = rdw_helpers.rdwTime() asOfDate.initFromMidnightUTC(-5) return self._getUserMessages(user_repos, not failuresOnly, True, asOfDate, None)
def test_url_for_restore(self): self.assertEqual('/restore/testcases?date=1414967021', url_for_restore(b'testcases', path=b'', date=rdwTime(1414967021))) self.assertEqual('/restore/testcases/Revisions?date=1414967021', url_for_restore(b'testcases', path=b'Revisions', date=rdwTime(1414967021))) self.assertEqual('/restore/testcases/R%C3%A9pertoire%20%28%40vec%29%20%7Bc%C3%A0ra%C3%A7t%23%C3%A8r%C3%AB%7D%20%24%C3%A9p%C3%AAcial?date=1414967021', url_for_restore(b'testcases', path=b'R\xc3\xa9pertoire (@vec) {c\xc3\xa0ra\xc3\xa7t#\xc3\xa8r\xc3\xab} $\xc3\xa9p\xc3\xaacial', date=rdwTime(1414967021))) # Check if failing with unicode with self.assertRaises(AssertionError): url_for_restore('testcases', path='', date=rdwTime(1414967021))
def _get_user_messages_for_day(self, date): userRepos = self.app.currentuser.repos # Set the start and end time to be the start and end of the day, # respectively, to get all entries for that day startTime = rdw_helpers.rdwTime() startTime.timeInSeconds = date.timeInSeconds startTime.tzOffset = date.tzOffset startTime.setTime(0, 0, 0) endTime = rdw_helpers.rdwTime() endTime.timeInSeconds = date.timeInSeconds endTime.tzOffset = date.tzOffset endTime.setTime(23, 59, 59) return self._getUserMessages(userRepos, True, False, startTime, endTime)
def default(self, path=b"", date=None, kind=None, usetar=None): self.assertIsInstance(path, bytes) self.assertIsInstance(date, str) self.assertTrue(kind is None or kind in ARCHIVERS) self.assertTrue(usetar is None or isinstance(usetar, str)) logger.debug("restoring [%r][%s]", path, date) # The path wont have leading and trailing "/". (path, file_b) = os.path.split(path) if not path: path = file_b file_b = b"" # Check user access to repo / path. (repo_obj, path_obj) = self.validate_user_path(path) # Get the restore date try: rdw_helpers.rdwTime(int(date)) except: logger.warning("invalid date %s", date) raise cherrypy.HTTPError(400, _("Invalid date.")) # Get if backup in progress if repo_obj.in_progress: raise cherrypy.HTTPError( 500, _("""A backup is currently in progress to this repository. Restores are disabled until this backup is complete.""" )) # Determine the kind. kind = kind or 'zip' if usetar is not None: kind = 'tar.gz' # Restore file(s) filename, fileobj = path_obj.restore(file_b, int(date), kind=kind) # Define content-disposition. cherrypy.response.headers[ "Content-Disposition"] = self._content_disposition(filename) # Stream the data. return _serve_fileobj(fileobj, content_type=None, content_length=None)
def setUp(self): self.repo = MockRdiffRepo() backup_dates = [ 1414871387, 1414871426, 1414871448, 1414871475, 1414871489, 1414873822, 1414873850, 1414879639, 1414887165, 1414887491, 1414889478, 1414937803, 1414939853, 1414967021, 1415047607, 1415059497, 1415221262, 1415221470, 1415221495, 1415221507] self.repo._backup_dates = [rdwTime(x) for x in backup_dates] self.root_path = self.repo.root_path
def test_sub(self): """Check if addition with timedelta is working as expected.""" # Without timezone self.assertEqual(rdwTime('2014-11-02T21:04:30Z'), rdwTime('2014-11-05T21:04:30Z') - datetime.timedelta(days=3)) # With timezone self.assertEqual(rdwTime('2014-11-02T21:04:30-04:00'), rdwTime('2014-11-05T21:04:30-04:00') - datetime.timedelta(days=3)) # With datetime self.assertTrue((rdwTime('2014-11-02T21:04:30Z') - rdwTime()).days < 0) self.assertTrue((rdwTime() - rdwTime('2014-11-02T21:04:30Z')).days > 0)
def test_change_dates(self): """Check if dates are properly sorted.""" increments = [ IncrementEntry( self.root_path, b'my_filename.txt.2014-11-02T17:23:41-05:00.diff.gz'), IncrementEntry( self.root_path, b'my_filename.txt.2014-11-02T09:16:43-05:00.missing'), IncrementEntry( self.root_path, b'my_filename.txt.2014-11-03T19:04:57-05:00.diff.gz') ] entry = DirEntry(self.root_path, b'my_filename.txt', False, increments) self.assertEqual( [rdwTime(1414939853), rdwTime(1414967021), rdwTime(1415059497)], entry.change_dates)
def setUp(self): self.repo = MockRdiffRepo() backup_dates = [ 1414871387, 1414871426, 1414871448, 1414871475, 1414871489, 1414873822, 1414873850, 1414879639, 1414887165, 1414887491, 1414889478, 1414937803, 1414939853, 1414967021, 1415047607, 1415059497, 1415221262, 1415221470, 1415221495, 1415221507 ] self.repo._backup_dates = [rdwTime(x) for x in backup_dates] self.root_path = self.repo.root_path
def default(self, path=b"", date=None, kind=None, usetar=None): self.assertIsInstance(path, bytes) self.assertIsInstance(date, str) self.assertTrue(kind is None or kind in ARCHIVERS) self.assertTrue(usetar is None or isinstance(usetar, str)) logger.debug("restoring [%r][%s]", path, date) # The path wont have leading and trailing "/". (path, file_b) = os.path.split(path) if not path: path = file_b file_b = b"" # Check user access to repo / path. (repo_obj, path_obj) = self.validate_user_path(path) # Get the restore date try: rdw_helpers.rdwTime(int(date)) except: logger.warning("invalid date %s", date) raise cherrypy.HTTPError(400, _("Invalid date.")) # Get if backup in progress if repo_obj.in_progress: raise cherrypy.HTTPError(500, _("""A backup is currently in progress to this repository. Restores are disabled until this backup is complete.""")) # Determine the kind. kind = kind or 'zip' if usetar is not None: kind = 'tar.gz' # Restore file(s) filename, fileobj = path_obj.restore(file_b, int(date), kind=kind) # Define content-disposition. cherrypy.response.headers["Content-Disposition"] = self._content_disposition(filename) # Stream the data. return _serve_fileobj(fileobj, content_type=None, content_length=None)
def extract_date(filename): """ Extract date from rdiff-backup filenames. """ # Remove suffix from filename filename = IncrementEntry._remove_suffix(filename) # Remove prefix from filename date_string = filename.rsplit(b".", 1)[-1] try: return rdw_helpers.rdwTime(date_string.decode()) except: logger.warn('fail to parse date [%r]', date_string, exc_info=1) return None
def _remove_older(self, user, repo, keepdays): """ Take action to remove older. """ assert keepdays > 0 # Get instance of the repo. r = librdiff.RdiffRepo(user.user_root, repo.name) # Check history date. if not r.last_backup_date: _logger.info("no backup dates for [%r]", r.repo_root) return d = rdwTime() - r.last_backup_date d = d.days + keepdays _logger.info("execute rdiff-backup --force --remove-older-than=%sD %r", d, r.repo_root) r.execute(b'--force', b'--remove-older-than=' + str(d).encode(encoding='latin1') + b'D', r.repo_root)
def entry(self, path_b=b"", date=""): self.assertIsInstance(path_b, bytes) self.assertIsInstance(date, str) # Validate date try: entry_time = rdw_helpers.rdwTime(int(date)) except: logger.exception("invalid date") raise cherrypy.HTTPError(400, _("Invalid date.")) if not path_b: userMessages = self._get_user_messages_for_day(entry_time) else: # Validate repo parameter repo_obj = self.validate_user_path(path_b)[0] userMessages = self._getUserMessages( [repo_obj.path], False, True, entry_time, entry_time) return self._compileStatusPageTemplate(False, userMessages, False)
def _remove_older(self, user, repo, keepdays): """ Take action to remove older. """ assert keepdays > 0 # Get instance of the repo. r = librdiff.RdiffRepo(user.user_root, repo.name) # Check history date. if not r.last_backup_date: _logger.info("no backup dates for [%r]", r.repo_root) return d = rdwTime() - r.last_backup_date d = d.days + keepdays _logger.info("execute rdiff-backup --force --remove-older-than=%sD %r", d, r.repo_root) r.execute( b'--force', b'--remove-older-than=' + str(d).encode(encoding='latin1') + b'D', r.repo_root)
def entry(self, path_b=b"", date=""): self.assertIsInstance(path_b, bytes) self.assertIsInstance(date, str) # Validate date try: entry_time = rdw_helpers.rdwTime(int(date)) except: logger.exception("invalid date") raise cherrypy.HTTPError(400, _("Invalid date.")) if not path_b: userMessages = self._get_user_messages_for_day(entry_time) else: # Validate repo parameter repo_obj = self.validate_user_path(path_b)[0] userMessages = self._getUserMessages([repo_obj.path], False, True, entry_time, entry_time) return self._compileStatusPageTemplate(False, userMessages, False)
def test_init(self): increment = IncrementEntry(self.root_path, b'my_filename.txt.2014-11-02T17:23:41-05:00.diff.gz') self.assertEqual(rdwTime(1414967021), increment.date) self.assertEqual(b'my_filename.txt', increment.filename)
def test_extract_date(self): self.assertEqual(rdwTime(1414967021), IncrementEntry.extract_date(b'my_filename.txt.2014-11-02T17:23:41-05:00.diff.gz'))
def test_compare(self): """Check behaviour of comparison operator operator.""" self.assertTrue(rdwTime('2014-11-07T21:04:30-04:00') < rdwTime('2014-11-08T21:04:30Z')) self.assertTrue(rdwTime('2014-11-08T21:04:30Z') < rdwTime('2014-11-08T21:50:30Z')) self.assertFalse(rdwTime('2014-11-08T22:04:30Z') < rdwTime('2014-11-08T21:50:30Z')) self.assertFalse(rdwTime('2014-11-07T21:04:30-04:00') > rdwTime('2014-11-08T21:04:30Z')) self.assertFalse(rdwTime('2014-11-08T21:04:30Z') > rdwTime('2014-11-08T21:50:30Z')) self.assertTrue(rdwTime('2014-11-08T22:04:30Z') > rdwTime('2014-11-08T21:50:30Z'))
def test_int(self): """Check if int(rdwTime) return expected value.""" self.assertEqual(1415221470, int(rdwTime(1415221470)))
def test_extract_date(self): self.assertEqual( rdwTime(1414967021), IncrementEntry.extract_date( b'my_filename.txt.2014-11-02T17:23:41-05:00.diff.gz'))
def test_str(self): """Check if __str__ is working.""" self.assertEqual('2014-11-05 21:04:30', str(rdwTime(1415221470)))