Exemplo n.º 1
0
   def entry(self, date="", repo=""):
      # Validate date
      try:
         entryTime = rdw_helpers.rdwTime()
         entryTime.initFromString(date)
      except ValueError:
         return self.writeErrorPage("Invalid date parameter.")

      if not repo:
         userRepos = self.userDB.getUserRepoPaths(self.getUsername())

         # 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 = entryTime.timeInSeconds
         startTime.tzOffset = entryTime.tzOffset
         endTime = rdw_helpers.rdwTime()
         endTime.timeInSeconds = entryTime.timeInSeconds
         endTime.tzOffset = entryTime.tzOffset
         startTime.setTime(0, 0, 0)
         endTime.setTime(23, 59, 59)

         userMessages = self._getUserMessages(userRepos, True, False, startTime, endTime)
      else:
         # Validate repo parameter
         if not repo: return self.writeErrorPage("Backup location not specified.")
         if not repo in self.userDB.getUserRepoPaths(self.getUsername()):
            return self.writeErrorPage("Access is denied.")
         try:
            rdw_helpers.ensurePathValid(repo)
         except rdw_helpers.accessDeniedError, error:
            return self.writeErrorPage(str(error))

         userMessages = self._getUserMessages([repo], False, True, entryTime, entryTime)
Exemplo n.º 2
0
   def testGetBackupHistory(self):
      entries = getBackupHistory(self.destDir)
      assert len(entries) == 3
      for entry in entries:
         assert entry.errors == ""
      assert entries[0].size == 15
      assert entries[1].size == 56
      assert entries[2].size == 23

      lastEntry = getLastBackupHistoryEntry(self.destDir)
      assert lastEntry.size == 23

      # Test that timezone differences are ignored
      historyAsOf = lastEntry.date.getUrlString()
      if "+" in historyAsOf:
         historyAsOf = historyAsOf.replace("+", "-")
      else:
         historyAsOf = historyAsOf[:19] + "+" + historyAsOf[20:]

      lastBackupTime = rdw_helpers.rdwTime()
      lastBackupTime.initFromString(historyAsOf)
      entries = getBackupHistorySinceDate(self.destDir, lastBackupTime)
      assert len(entries) == 1

      # Test that no backups are returned one second after the last backup
      historyAsOf = historyAsOf[:18] + "1" + historyAsOf[19:]
      postBackupTime = rdw_helpers.rdwTime()
      postBackupTime.initFromString(historyAsOf)
      assert lastBackupTime.getLocalSeconds() + 1 == postBackupTime.getLocalSeconds()
      entries = getBackupHistorySinceDate(self.destDir, postBackupTime)
      assert len(entries) == 0
Exemplo n.º 3
0
   def testGetBackupHistory(self):
      tests = self.getBackupTests()
      for testDir in tests:
         # Get a list of backup entries for the root folder
         origBackupDir = joinPaths(self.masterDirPath, testDir)
         backupStates = self.getBackupStates(origBackupDir)
         backupStates.sort(lambda x, y: cmp(x, y))

         rdiffDestDir = joinPaths(self.destRoot, testDir)
         entries = getBackupHistory(rdiffDestDir)
         assert len(entries) == len(backupStates)

         backupNum = 0
         for backup in backupStates:
            origBackupStateDir = joinPaths(origBackupDir, backup)
            totalBackupSize = 0
            for file in os.listdir(origBackupStateDir):
               totalBackupSize = totalBackupSize + os.lstat(joinPaths(origBackupStateDir, file))[6]

            #TODO: fix this to handle subdirs
            #assert totalBackupSize == entries[backupNum].size, "Calculated: "+str(totalBackupSize)+" Reported: "+str(entries[backupNum].size)+" State: "+str(backupNum)
            backupNum = backupNum + 1

         # Test that the last backup entry works correctly
         lastEntry = getLastBackupHistoryEntry(rdiffDestDir)

         lastBackupTime = rdw_helpers.rdwTime()
         lastBackupTime.initFromString(backupStates[-1])
         assert lastEntry.date == lastBackupTime

         # Test that timezone differences are ignored
         historyAsOf = lastEntry.date.getUrlString()
#          if "+" in historyAsOf:
#             historyAsOf = historyAsOf.replace("+", "-")
#          else:
#             historyAsOf = historyAsOf[:19] + "+" + historyAsOf[20:]

         lastBackupTime = rdw_helpers.rdwTime()
         lastBackupTime.initFromString(historyAsOf)
         entries = getBackupHistorySinceDate(rdiffDestDir, lastBackupTime)
         assert len(entries) == 1

         # Test that no backups are returned one second after the last backup
         historyAsOf = historyAsOf[:18] + "1" + historyAsOf[19:]
         postBackupTime = rdw_helpers.rdwTime()
         postBackupTime.initFromString(historyAsOf)
         assert lastBackupTime.getLocalSeconds() + 1 == postBackupTime.getLocalSeconds()
         entries = getBackupHistorySinceDate(rdiffDestDir, postBackupTime)
         assert len(entries) == 0
Exemplo n.º 4
0
   def _getUserMessagesForDay(self, date):
      userRepos = self.getUserDB().getUserRepoPaths(self.getUsername())

      # 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)
Exemplo n.º 5
0
   def _getUserMessagesForDay(self, date):
      userRepos = self.getUserDB().getUserRepoPaths(self.getUsername())

      # 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 _getOldRepoInfo(self, repoName, repoPath,
                     notifySettings, isAdminMonitoring):
      if isAdminMonitoring:
         maxAge = notifySettings['adminMaxAge']
      else:
         maxAge = notifySettings['anyRepoMaxAge']
         if not maxAge:
            maxAge = notifySettings['repos'][repoName]

      if maxAge == 0:
         return None

      try:
         lastBackup = librdiff.getLastBackupHistoryEntry(repoPath, False)
      except librdiff.FileError:
         return {
            "repo" : repoName,
            "lastBackupDate" : "never",
            "maxAge" : maxAge
         }
      except Exception:
         rdw_logging.log_exception()
         rdw_logging.log('(Previous exception occurred for repo %s.)' % repoPath)
      else:
         if lastBackup:
            oldestGoodBackupTime = rdw_helpers.rdwTime()
            oldestGoodBackupTime.initFromMidnightUTC(-maxAge)
            if lastBackup.date < oldestGoodBackupTime:
               return {
                  "repo" : repoName,
                  "lastBackupDate" : lastBackup.date.getDisplayString(),
                  "maxAge" : maxAge
               }
      return None
Exemplo n.º 7
0
    def _getRecentUserMessages(self, failuresOnly):
        userRepos = self.getUserDB().getUserRepoPaths(self.getUsername())
        asOfDate = rdw_helpers.rdwTime()
        asOfDate.initFromMidnightUTC(-5)

        return self._getUserMessages(userRepos, not failuresOnly, True,
                                     asOfDate, None)
Exemplo n.º 8
0
    def _get_recent_user_messages(self, failuresOnly):
        user_repos = self.app.userdb.get_repos(self.app.currentuser.username)
        asOfDate = rdw_helpers.rdwTime()
        asOfDate.initFromMidnightUTC(-5)

        return self._getUserMessages(user_repos, not failuresOnly, True,
                                     asOfDate, None)
Exemplo n.º 9
0
class rdiffRestorePage(page_main.rdiffPage):
   def index(self, repo, path, date):
      repo = rdw_helpers.decodeUrl(repo)
      path = rdw_helpers.decodeUrl(path)
      date = rdw_helpers.decodeUrl(date)
      try:
         rdw_helpers.ensurePathValid(repo)
         rdw_helpers.ensurePathValid(path)
      except rdw_helpers.accessDeniedError, error:
         return self.writeErrorPage(str(error))
      if not repo: return self.writeErrorPage("Backup location not specified.")
      if not repo in self.userDB.getUserRepoPaths(self.getUsername()):
         return self.writeErrorPage("Access is denied.")

      if librdiff.backupIsInProgress(rdw_helpers.joinPaths(self.userDB.getUserRoot(self.getUsername()), repo)):
         return self.writeErrorPage("A backup is currently in progress to this location.  Restores are disabled until this backup is complete.")

      try:
         restoreTime = rdw_helpers.rdwTime()
         restoreTime.initFromString(date)
         (path, file) = os.path.split(path)
         if not file:
            file = path
            path = "/"
         filePath = librdiff.restoreFileOrDir(rdw_helpers.joinPaths(self.userDB.getUserRoot(self.getUsername()), repo), path, file, restoreTime)
      except librdiff.FileError, error:
         return self.writeErrorPage(error.getErrorString())
Exemplo n.º 10
0
   def testGetDirEntries(self):
      tests = self.getBackupTests()
      for testDir in tests:
         # Get a list of backup entries for the root folder
         rdiffDestDir = joinPaths(self.destRoot, testDir)
         entries = getDirEntries(rdiffDestDir, "/")

         # Go back through all backup states and make sure that the backup entries match the files that exist
         origStateDir = joinPaths(self.masterDirPath, testDir)
         backupStates = self.getBackupStates(origStateDir)
         backupStates.sort(lambda x, y: cmp(x, y))
         for backupState in backupStates:
            backupTime = rdw_helpers.rdwTime()
            backupTime.initFromString(backupState)

            # Go through each file, and make sure we have a backup entry for this file and date
            origStateDir = joinPaths(self.masterDirPath, testDir, backupState)
            files = self.getBackupStates(origStateDir)
            for file in files:
               origFilePath = joinPaths(origStateDir, file)

               entry = getMatchingDirEntry(entries, file)
               assertionErrorMessage = "backupTime "+backupTime.getDisplayString()+" not found in backup entries for backup test \""+testDir+"\" for file \""+file+"\". Returned changeDates:"
               for changeDate in entry.changeDates:
                  assertionErrorMessage = assertionErrorMessage + "\n"+changeDate.getDisplayString()
               assertionErrorMessage = assertionErrorMessage + "\nIncrements dir: "+str(os.listdir(joinPaths(rdiffDestDir, "rdiff-backup-data", "increments")))
               for entryDate in entry.changeDates:
                  if backupTime.getSeconds() == entryDate.getSeconds():
                     if self.fileChangedBetweenBackups(testDir, entry.name, backupState, backupStates):
                        assert False, assertionErrorMessage
                     break
               else:
                  if not self.fileChangedBetweenBackups(testDir, entry.name, backupState, backupStates):
                     assert False or False, assertionErrorMessage
               assert os.path.isdir(origFilePath) == entry.isDir
Exemplo n.º 11
0
    def setUp(self):
        # The temp dir on Mac OS X is a symlink; expand it because of validation against symlinks in paths
        self.destRoot = joinPaths(os.path.realpath(tempfile.gettempdir()),
                                  "rdiffWeb")
        self.masterDirPath = joinPaths(
            "..", "tests"
        )  # TODO: do this right, including tying tests into "python setup.py test"
        self.tearDown()

        os.makedirs(self.destRoot)

        # Set up each scenario
        tests = self.getBackupTests()
        for testDir in tests:
            # Iterate through the backup states
            origStateDir = joinPaths(self.masterDirPath, testDir)
            backupStates = self.getBackupStates(origStateDir)
            backupStates.sort(lambda x, y: cmp(x, y))
            for backupState in backupStates:
                # Try to parse the folder name as a date.  If we can't, raise
                backupTime = rdw_helpers.rdwTime()
                backupTime.initFromString(backupState)

                # Backup the data as it should be at that state
                #print "   State", backupState
                runRdiff(joinPaths(origStateDir, backupState),
                         joinPaths(self.destRoot, testDir), backupTime)
Exemplo n.º 12
0
class rdiffRestorePage(page_main.rdiffPage):
    _cp_config = {"response.stream": True, "response.timeout": 3000}

    def index(self, repo, path, date):
        try:
            self.validateUserPath(rdw_helpers.joinPaths(repo, path))
        except rdw_helpers.accessDeniedError, error:
            return self.writeErrorPage(str(error))
        if not repo:
            return self.writeErrorPage("Backup location not specified.")
        if not repo in self.getUserDB().getUserRepoPaths(self.getUsername()):
            return self.writeErrorPage("Access is denied.")

        if librdiff.backupIsInProgressForRepo(
                rdw_helpers.joinPaths(
                    self.getUserDB().getUserRoot(self.getUsername()), repo)):
            return self.writeErrorPage(
                "A backup is currently in progress to this location.  Restores are disabled until this backup is complete."
            )

        try:
            restoreTime = rdw_helpers.rdwTime()
            restoreTime.initFromString(date)
            (path, file) = os.path.split(path)
            if not file:
                file = path
                path = "/"
            fullPath = rdw_helpers.joinPaths(
                self.getUserDB().getUserRoot(self.getUsername()), repo)
            useZipFormat = self.getUserDB().useZipFormat(self.getUsername())
            filePath = librdiff.restoreFileOrDir(fullPath, path, file,
                                                 restoreTime, useZipFormat)
        except librdiff.FileError, error:
            return self.writeErrorPage(error.getErrorString())
Exemplo n.º 13
0
    def testRestoreFile(self):
        tests = self.getBackupTests()
        for testDir in tests:
            # Get a list of backup entries for the root folder
            rdiffDestDir = joinPaths(self.destRoot, testDir)
            entries = getDirEntries(rdiffDestDir, "/")

            # Go back through all backup states and make sure that the backup entries match the files that exist
            origStateDir = joinPaths(self.masterDirPath, testDir)
            backupStates = self.getBackupStates(origStateDir)
            backupStates.sort(lambda x, y: cmp(x, y))
            for backupState in backupStates:
                backupTime = rdw_helpers.rdwTime()
                backupTime.initFromString(backupState)

                # Go through each file, and make sure that the restored file looks the same as the orig file
                origStateDir = joinPaths(self.masterDirPath, testDir,
                                         backupState)
                files = self.getBackupStates(origStateDir)
                for file in files:
                    origFilePath = joinPaths(origStateDir, file)
                    if not os.path.isdir(origFilePath):
                        restoredFilePath = restoreFileOrDir(
                            rdiffDestDir, "/", file, backupTime)
                        assert open(restoredFilePath,
                                    "r").read() == open(origFilePath,
                                                        "r").read()
                        os.remove(restoredFilePath)
 def sendEmails(self):
    for user in self.userDB.getUserList():
       userRepos = self.userDB.getUserRepoPaths(user)
       oldRepos = []
       for repo in userRepos:
          maxDaysOld = self.userDB.getRepoMaxAge(user, repo)
          if maxDaysOld != 0:
             # get the last backup date
             try:
                lastBackup = librdiff.getLastBackupHistoryEntry(rdw_helpers.joinPaths(self.userDB.getUserRoot(user), repo), False)
             except librdiff.FileError:
                pass # Skip repos that have never been successfully backed up
             else:
                if lastBackup:
                   oldestGoodBackupTime = rdw_helpers.rdwTime()
                   oldestGoodBackupTime.initFromMidnightUTC(-maxDaysOld)
                   if lastBackup.date < oldestGoodBackupTime:
                      oldRepos.append({"repo" : repo, "lastBackupDate" : lastBackup.date.getDisplayString(), "maxAge" : maxDaysOld })
                
       if oldRepos:
          userEmailAddress = self.userDB.getUserEmail(user)
          emailText = rdw_helpers.compileTemplate("email_notification.txt", repos=oldRepos, sender=self._getEmailSender(), user=user)
 
          session = smtplib.SMTP(self._getEmailHost())
          session.login(self._getEmailUsername(), self._getEmailPassword())
          smtpresult = session.sendmail(self._getEmailSender(), userEmailAddress.split(";"), emailText)
          session.quit()
Exemplo n.º 15
0
    def entry(self, path_b=b"", date=""):
        assert isinstance(path_b, str)
        assert isinstance(date, unicode)
        # Validate date
        try:
            entry_time = rdw_helpers.rdwTime()
            entry_time.initFromInt(int(date))
        except ValueError:
            logger.exception("invalid date")
            return self._compile_error_template(_("Invalid date."))

        if not path_b:
            userMessages = self._get_user_messages_for_day(entry_time)
        else:
            # Validate repo parameter
            try:
                repo_obj = self.validate_user_path(path_b)[0]
            except librdiff.FileError as e:
                logger.exception("invalid user path")
                return self._compile_error_template(unicode(e))

            userMessages = self._getUserMessages(
                [repo_obj.path], False, True, entry_time, entry_time)

        return self._compileStatusPageTemplate(False, userMessages, False)
Exemplo n.º 16
0
    def index(self, path_b=b"", date="", usetar=""):
        assert isinstance(path_b, str)
        assert isinstance(date, unicode)
        assert isinstance(usetar, unicode)

        logger.debug("restoring [%s][%s]" % (decode_s(path_b, "replace"), date))

        # The path_b wont have leading and trailing "/".
        (path_b, file_b) = os.path.split(path_b)
        if not path_b:
            path_b = file_b
            file_b = b""

        # Check user access to repo / path.
        try:
            (repo_obj, path_obj) = self.validate_user_path(path_b)
        except librdiff.FileError as e:
            logger.exception("invalid user path")
            return self._compile_error_template(unicode(e))

        # Get the restore date
        try:
            restore_date = rdw_helpers.rdwTime()
            restore_date.initFromInt(int(date))
        except:
            logger.warn("invalid date %s" % date)
            return self._compile_error_template(_("Invalid date."))

        try:
            # Get if backup in progress
            if repo_obj.in_progress:
                return self._compile_error_template(
                    _(
                        """A backup is currently in progress to this repository. Restores are disabled until this backup is complete."""
                    )
                )

            # Restore the file
            file_path_b = path_obj.restore(file_b, restore_date, usetar != "T")

        except librdiff.FileError as e:
            logger.exception("fail to restore")
            return self._compile_error_template(unicode(e))
        except ValueError:
            logger.exception("fail to restore")
            return self._compile_error_template(_("Fail to restore."))

        # The restored file path need to be deleted when the user is finish
        # downloading. The auto-delete tool, will do it if we give him a file
        # to delete.
        cherrypy.request._autodelete_dir = file_path_b

        # The file name return by rdiff-backup is in bytes. We do not process
        # it. Cherrypy seams to handle it any weird encoding from this point.
        logger.info("restored file [%s]" % decode_s(file_path_b, "replace"))
        filename = os.path.basename(file_path_b)
        # Escape quotes in filename
        filename = filename.replace(b'"', b'\\"')
        return serve_file(file_path_b, None, disposition=b"attachment", name=filename)
Exemplo n.º 17
0
    def _get_user_messages_for_day(self, date):
        userRepos = self.app.userdb.get_repos(self.app.currentuser.username)

        # 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)
Exemplo n.º 18
0
 def getDate(self):
     timeString = self.getDateString()
     returnTime = rdw_helpers.rdwTime()
     try:
         returnTime.loadFromString(timeString)
         return returnTime
     except ValueError:
         return None
Exemplo n.º 19
0
 def getDate(self):
    timeString = self.getDateString()
    returnTime = rdw_helpers.rdwTime()
    try:
       returnTime.initFromString(timeString)
       return returnTime
    except ValueError:
       return None
Exemplo n.º 20
0
    def _getFirstBackupAfterDate(self, date):
        """ Iterates the mirror_metadata files in the rdiff data dir """
        if not self.backupTimes:
            return rdw_helpers.rdwTime()
        if not date:
            return self.backupTimes[0]

        index = bisect.bisect_right(self.backupTimes, date)
        if index >= len(self.backupTimes):
            return self.backupTimes[-1]
        return self.backupTimes[index]
Exemplo n.º 21
0
   def _getFirstBackupAfterDate(self, date):
      """ Iterates the mirror_metadata files in the rdiff data dir """
      if not self.backupTimes:
         return rdw_helpers.rdwTime()
      if not date:
         return self.backupTimes[0]

      index = bisect.bisect_right(self.backupTimes, date)
      if index >= len(self.backupTimes):
         return self.backupTimes[-1]
      return self.backupTimes[index]
Exemplo n.º 22
0
 def _parseDate(self, filename):
     """Return a date object from a filename."""
     # Parse the date of the file
     filename = self._removeSuffix(filename)
     filename = rsplit(filename, ".", 1)[1]
     time = rdw_helpers.rdwTime()
     try:
         time.initFromString(filename)
         return time
     except ValueError:
         return None
Exemplo n.º 23
0
 def _getFirstBackupAfterDate(self, date):
    """ Iterates the mirror_metadata files in the rdiff data dir """
    backupFiles = filter(lambda x: x.startswith("mirror_metadata"), self.dataDirEntries)
    backupFiles.sort()
    for backup in backupFiles:
       backupTimeString = rsplit(backup, ".", 3)[1]
       backupTime = rdw_helpers.rdwTime()
       backupTime.initFromString(backupTimeString)
       if not date or backupTime > date:
          return backupTime
    return backupFiles[-1]
Exemplo n.º 24
0
 def date(self):
     # Remove suffix from filename
     filename = self._remove_suffix(self.name)
     # Remove prefix from filename
     date_string = filename.rsplit(b".", 1)[-1]
     return_time = rdw_helpers.rdwTime()
     try:
         return_time.initFromString(date_string)
         return return_time
     except ValueError:
         return None
Exemplo n.º 25
0
 def _parseDate(self, filename):
    """Return a date object from a filename."""
    # Parse the date of the file
    filename = self._removeSuffix(filename)
    filename = rsplit(filename, ".", 1)[1]
    time = rdw_helpers.rdwTime()
    try:
       time.initFromString(filename)
       return time
    except ValueError:
       return None
Exemplo n.º 26
0
 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]
     return_time = rdw_helpers.rdwTime()
     try:
         return_time.initFromString(date_string)
         return return_time
     except ValueError:
         return None
Exemplo n.º 27
0
    def entry(self, date="", repo=""):
        # Validate date
        try:
            entryTime = rdw_helpers.rdwTime()
            entryTime.initFromString(date)
        except ValueError:
            return self.writeErrorPage("Invalid date parameter.")

        if not repo:
            userRepos = self.userDB.getUserRepoPaths(self.getUsername())

            # 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 = entryTime.timeInSeconds
            startTime.tzOffset = entryTime.tzOffset
            endTime = rdw_helpers.rdwTime()
            endTime.timeInSeconds = entryTime.timeInSeconds
            endTime.tzOffset = entryTime.tzOffset
            startTime.setTime(0, 0, 0)
            endTime.setTime(23, 59, 59)

            userMessages = self._getUserMessages(userRepos, True, False,
                                                 startTime, endTime)
        else:
            # Validate repo parameter
            if not repo:
                return self.writeErrorPage("Backup location not specified.")
            if not repo in self.userDB.getUserRepoPaths(self.getUsername()):
                return self.writeErrorPage("Access is denied.")
            try:
                rdw_helpers.ensurePathValid(repo)
            except rdw_helpers.accessDeniedError, error:
                return self.writeErrorPage(str(error))

            userMessages = self._getUserMessages([repo], False, True,
                                                 entryTime, entryTime)
Exemplo n.º 28
0
   def _getUserMessages(self):
      userRoot = self.userDB.getUserRoot(self.getUsername())
      userRepos = self.userDB.getUserRepoPaths(self.getUsername())

      asOfDate = rdw_helpers.rdwTime()
      asOfDate.initFromMidnightUTC(-5)

      # build list of all backups
      allBackups = []
      repoErrors = []
      for repo in userRepos:
         try:
            backups = librdiff.getBackupHistorySinceDate(rdw_helpers.joinPaths(userRoot, repo), asOfDate)
            allBackups += [{"repo": repo, "date": backup.date, "displayDate": backup.date.getDisplayString(),
               "size": rdw_helpers.formatFileSizeStr(backup.size), "errors": backup.errors} for backup in backups]
         except librdiff.FileError, error:
            repoErrors.append({"repo": repo, "error": error.getErrorString()})
    def sendEmails(self):
        for user in self.userDB.getUserList():
            userRepos = self.userDB.getUserRepoPaths(user)
            oldRepos = []
            for repo in userRepos:
                maxDaysOld = self.userDB.getRepoMaxAge(user, repo)
                if maxDaysOld != 0:
                    # get the last backup date
                    try:
                        lastBackup = librdiff.getLastBackupHistoryEntry(
                            rdw_helpers.joinPaths(
                                self.userDB.getUserRoot(user), repo), False)
                    except librdiff.FileError:
                        pass  # Skip repos that have never been successfully backed up
                    else:
                        if lastBackup:
                            oldestGoodBackupTime = rdw_helpers.rdwTime()
                            oldestGoodBackupTime.initFromMidnightUTC(
                                -maxDaysOld)
                            if lastBackup.date < oldestGoodBackupTime:
                                oldRepos.append({
                                    "repo":
                                    repo,
                                    "lastBackupDate":
                                    lastBackup.date.getDisplayString(),
                                    "maxAge":
                                    maxDaysOld
                                })

            if oldRepos:
                userEmailAddress = self.userDB.getUserEmail(user)
                emailText = rdw_helpers.compileTemplate(
                    "email_notification.txt",
                    repos=oldRepos,
                    sender=self._getEmailSender(),
                    user=user)

                session = smtplib.SMTP(self._getEmailHost())
                session.login(self._getEmailUsername(),
                              self._getEmailPassword())
                smtpresult = session.sendmail(self._getEmailSender(),
                                              userEmailAddress.split(";"),
                                              emailText)
                session.quit()
def emailNotifications():
   emailHost = getEmailHost()
   emailSender = getEmailSender()
   emailUsername = getEmailUsername()
   emailPassword = getEmailPassword()
      
   dbBackend = db.userDB().getUserDBModule()
   for user in dbBackend.getUserList():
      userRepos = dbBackend.getUserRepoPaths(user)
      oldRepos = []
      for repo in userRepos:
         maxDaysOld = dbBackend.getRepoMaxAge(user, repo)
         if maxDaysOld != 0:
            # get the last backup date
            try:
               lastBackup = librdiff.getLastBackupHistoryEntry(rdw_helpers.joinPaths(dbBackend.getUserRoot(user), repo), False)
            except librdiff.FileError:
               pass # Skip repos that have never been successfully backed up
            else:
               if lastBackup:
                  oldestGoodBackupTime = rdw_helpers.rdwTime()
                  oldestGoodBackupTime.initFromMidnightUTC(-maxDaysOld)
                  if lastBackup.date < oldestGoodBackupTime:
                     oldRepos.append({"repo" : repo, "lastBackupDate" : lastBackup.date.getDisplayString(), "maxAge" : maxDaysOld })
               
      if oldRepos:
         userEmailAddress = dbBackend.getUserEmail(user)
         emailText = rdw_helpers.compileTemplate("email_notification.txt", repos=oldRepos, sender=emailSender, user=user)

         session = smtplib.SMTP(emailHost)
         session.login(emailUsername, emailPassword)
         smtpresult = session.sendmail(emailSender, userEmailAddress.split(";"), emailText)
         if smtpresult:
            error = ""
            for recipient in smtpresult.keys():
               error = """Could not delivery mail to: %s

Server said: %s
%s

%s""" % (recipient, smtpresult[recipient][0], smtpresult[recipient][1], error)
            raise smtplib.SMTPException, error
         session.quit()
Exemplo n.º 31
0
   def entry(self, date="", repo=""):
      # Validate date
      try:
         entryTime = rdw_helpers.rdwTime()
         entryTime.initFromString(date)
      except ValueError:
         return self.writeErrorPage("Invalid date parameter.")

      if not repo:
         userMessages = self._getUserMessagesForDay(entryTime)
      else:
         # Validate repo parameter
         if not repo in self.userDB.getUserRepoPaths(self.getUsername()):
            return self.writeErrorPage("Access is denied.")
         try:
            self.validateUserPath(repo)
         except rdw_helpers.accessDeniedError, error:
            return self.writeErrorPage(str(error))

         userMessages = self._getUserMessages([repo], False, True, entryTime, entryTime)
Exemplo n.º 32
0
   def entry(self, date="", repo=""):
      # Validate date
      try:
         entryTime = rdw_helpers.rdwTime()
         entryTime.initFromString(date)
      except ValueError:
         return self.writeErrorPage("Invalid date parameter.")

      if not repo:
         userMessages = self._getUserMessagesForDay(entryTime)
      else:
         # Validate repo parameter
         if not repo in self.getUserDB().getUserRepoPaths(self.getUsername()):
            return self.writeErrorPage("Access is denied.")
         try:
            self.validateUserPath(repo)
         except rdw_helpers.accessDeniedError, error:
            return self.writeErrorPage(str(error))

         userMessages = self._getUserMessages([repo], False, True, entryTime, entryTime)
Exemplo n.º 33
0
   def setUp(self):
      # The temp dir on Mac OS X is a symlink; expand it because of validation against symlinks in paths
      self.destRoot = joinPaths(os.path.realpath(tempfile.gettempdir()), "rdiffWeb")
      self.masterDirPath = joinPaths("..", "tests") # TODO: do this right, including tying tests into "python setup.py test"
      self.tearDown()

      os.makedirs(self.destRoot)

      # Set up each scenario
      tests = self.getBackupTests()
      for testDir in tests:
         # Iterate through the backup states
         origStateDir = joinPaths(self.masterDirPath, testDir)
         backupStates = self.getBackupStates(origStateDir)
         backupStates.sort(lambda x, y: cmp(x, y))
         for backupState in backupStates:
            # Try to parse the folder name as a date.  If we can't, raise
            backupTime = rdw_helpers.rdwTime()
            backupTime.initFromString(backupState)

            # Backup the data as it should be at that state
            #print "   State", backupState
            runRdiff(joinPaths(origStateDir, backupState), joinPaths(self.destRoot, testDir), backupTime)
Exemplo n.º 34
0
class rdiffHistoryPage(page_main.rdiffPage):
    def index(self, repo, date=''):
        try:
            self.validateUserPath(repo)
        except rdw_helpers.accessDeniedError, error:
            return self.writeErrorPage(str(error))

        if not repo:
            return self.writeErrorPage("Backup location not specified.")
        if not repo in self.getUserDB().getUserRepoPaths(self.getUsername()):
            return self.writeErrorPage("Access is denied.")

        if cherrypy.request.method == 'POST':
            if not date:
                return self.writeErrorPage("No deletion date was specified.")
            deleteTime = rdw_helpers.rdwTime()
            deleteTime.initFromString(date)
            repoPath = joinPaths(
                self.getUserDB().getUserRoot(self.getUsername()), repo)
            try:
                librdiff.removeRepoHistory(repoPath, deleteTime)
            except librdiff.FileError, error:
                return self.writeErrorPage(error.getErrorString())
Exemplo n.º 35
0
class rdiffRestorePage(page_main.rdiffPage):
   def index(self, repo, path, date):
      repo = rdw_helpers.decodeUrl(repo)
      path = rdw_helpers.decodeUrl(path)
      date = rdw_helpers.decodeUrl(date)
      try:
         rdw_helpers.ensurePathValid(repo)
         rdw_helpers.ensurePathValid(path)
      except rdw_helpers.accessDeniedError, error:
         return self.writeErrorPage(str(error))
      if not repo: return self.writeErrorPage("Backup location not specified.")
      if not repo in self.userDB.getUserRepoPaths(self.getUsername()):
         return self.writeErrorPage("Access is denied.")

      try:
         restoreTime = rdw_helpers.rdwTime()
         restoreTime.loadFromString(date)
         (path, file) = os.path.split(path)
         if not file:
            file = path
            path = "/"
         filePath = librdiff.restoreFile(rdw_helpers.joinPaths(self.userDB.getUserRoot(self.getUsername()), repo), path, file, restoreTime)
      except librdiff.FileError, error:
         return self.writeErrorPage(error.getErrorString())
Exemplo n.º 36
0
   def testRestoreFile(self):
      tests = self.getBackupTests()
      for testDir in tests:
         # Get a list of backup entries for the root folder
         rdiffDestDir = joinPaths(self.destRoot, testDir)
         entries = getDirEntries(rdiffDestDir, "/")

         # Go back through all backup states and make sure that the backup entries match the files that exist
         origStateDir = joinPaths(self.masterDirPath, testDir)
         backupStates = self.getBackupStates(origStateDir)
         backupStates.sort(lambda x, y: cmp(x, y))
         for backupState in backupStates:
            backupTime = rdw_helpers.rdwTime()
            backupTime.initFromString(backupState)

            # Go through each file, and make sure that the restored file looks the same as the orig file
            origStateDir = joinPaths(self.masterDirPath, testDir, backupState)
            files = self.getBackupStates(origStateDir)
            for file in files:
               origFilePath = joinPaths(origStateDir, file)
               if not os.path.isdir(origFilePath):
                  restoredFilePath = restoreFileOrDir(rdiffDestDir, "/", file, backupTime)
                  assert open(restoredFilePath, "r").read() == open(origFilePath, "r").read()
                  os.remove(restoredFilePath)
Exemplo n.º 37
0
    def _getRecentUserMessages(self):
        userRepos = self.userDB.getUserRepoPaths(self.getUsername())
        asOfDate = rdw_helpers.rdwTime()
        asOfDate.initFromMidnightUTC(-5)

        return self._getUserMessages(userRepos, True, True, asOfDate, None)
Exemplo n.º 38
0
   def _getRecentUserMessages(self, failuresOnly):
      userRepos = self.getUserDB().getUserRepoPaths(self.getUsername())
      asOfDate = rdw_helpers.rdwTime()
      asOfDate.initFromMidnightUTC(-5)

      return self._getUserMessages(userRepos, not failuresOnly, True, asOfDate, None)
Exemplo n.º 39
0
   def _getRecentUserMessages(self):
      userRepos = self.userDB.getUserRepoPaths(self.getUsername())
      asOfDate = rdw_helpers.rdwTime()
      asOfDate.initFromMidnightUTC(-5)

      return self._getUserMessages(userRepos, True, True, asOfDate, None)