Example #1
0
 def _createHard(self, idRev, openedconn):
     self._logger.debug ( 'Doing a hard revision on %s', str(idRev) )
     deltaList = self._getDeltasSinceEvent ('hardexist', 1, idRev)
     self._logger.debug ( "received this deltaList: %s", repr(deltaList) )
     if type(deltaList) == int:
         self._seterrormsg( 'Could not create internal chain of deltas. '+
             'Internal error: ' + str(deltaList) )
         return ERR_INTERNAL
     
     # join everything
     # first throw away this, but save for later
     hardRev = deltaList.pop()
     self._logger.debug ( "Generating internal delta" )
     try:
         listoffiles = [os.path.join(self._deltasdir, str(i)) for i in deltaList]
         delta = Deltas.multiOpen(listoffiles)
     except:
         return ERR_FS
     # the last one, now will have hardcopy
     openedconn.execute ( '''update revisions set hardexist=1
         where idrev=?''' , (idRev,) )
     infile =  os.path.join(self._hardsdir,str(hardRev))
     outfile = os.path.join(self._hardsdir,str(idRev))
     delta.patch(infile, outfile)
     return 0
Example #2
0
 def GetDelta(self, idRev, idFromRev):
     '''
     Get a delta (see rsync algorithm) from the server to jump to a newer
     revision. The delta is known to the server or fabricated from some 
     deltas
     
     @param idRev: "Destination revision"
     @param irFromRev: "Origin revision"
     @return: Binary information of the petition (asked delta)
     '''
     
     with self._conn as c:
         # First, check permissions
         row = c.execute ("select idfile from revisions where idrev=?",
             (idFromRev,) ).fetchone()
         if not row:
             self._seterrormsg("Unknown origin revision")
             return ERR_NOTEXIST
         row = c.execute ("select path,isfolder from files where idfile=?",
             (row['idfile'],) )
         if not row:
             self._seterrormsg('Unconsistent files table (database error)')
             return ERR_INTERNAL
         if row['isfolder']:
             self._seterrormsg('Cannot get a delta for a folder')
             return ERR_CANNOT
         originpath = row['path']
         ret = self._checkPerms(originpath, auth.READ)
         if ret < 0:
             return ret
         
         # Until now everything seems fine, let's check "destination"
         revRow = c.execute( "select * from revisions where idrev=?" , 
             (idRev,) ).fetchone()
         if not revRow:
             self._seterrormsg('Unknown destination revision')
             return ERR_NOTEXIST
         row = c.execute ("select path,isfolder from files where idfile=?" ,
             (revRow['idfile']) ).fetchone()
         if not row:
             self._seterrormsg('Inconsistent files table (database error)')
             return ERR_INTERNAL
         if row['isfolder']:
             self._seterrormsg('Cannot get a delta for a folder')
             return ERR_CANNOT
         # only check permissions if there is a folder change
         if originpath != row['path']:
             ret = self._checkperms(row['path'], auth.READ)
             if ret < 0:
                 return ret
     #if it's the easy way, we do it the easy way (most likely to hapen)
     if (revRow['fromrev'] == idFromRev) and (revRow['fromtype'] == REV_MODIFIED):
         #yes, we are lucky!
         try:
             return Deltas.open(os.path.join(self._deltasdir,str(idRev))).getXMLRPCBinary()
         except:
             return ERR_FS
     else:
         # 1st: check that exists a chain of non-deletions between 
         # this two revisions (save the first hardcopy for later)
         deltaList = self._getDeltasSinceEvent ( 'fromrev' , idFromRev , idRev )
         if type(deltaList) == int:
             return deltaList
             
         # 2nd: try to join everything
         try:
             listoffiles = [os.path.join(self._deltasdir, str(i)) for i in deltaList]
             delta = Deltas.multiOpen(listoffiles)
         except:
             return ERR_FS
         
         # 3rd: Send delta
         return delta.getXMLRPCBinary()
Example #3
0
    def SendDelta(self, idRev, sentdelta, chksum = None, size = 'NULL'):
        '''
        Send a delta (see rsync algorithm) to server
        
        @param idRev: The identifier of the origin revision
        @param sentdelta: Binary of the delta
        @param chksum: Checksum of the file (not the delta)
        @param size: Size of the file (not the delta)
        @return: Pair of the identifier of the actual revision (once applied
        this delta) and the server timestamp of this file.
        '''        
        tsnow = datetime.fromtimestamp(int(time.time()))
        # get real checksum
        self._logger.debug("Receiving delta, now()=%s", repr(tsnow) )
        self._logger.debug("Chksum received: %s", repr(chksum) )

        #check if everything is ok
        with self._conn as c:
            self._logger.debug ( "Getting row of revisions . . ." )
            rowRev = c.execute ( "select * from revisions where idrev=?" ,
                (idRev,)).fetchone()
            if not rowRev:
                self._seterrormsg('Unknown revision')
                return ERR_NOTEXIST
            self._logger.debug ( "Getting row of file information . . ." )
            rowFile = c.execute ( "select * from files where idfile=?" ,
                (rowRev['idfile'],) ).fetchone()
            if not rowFile:
                self._seterrormsg('Data not found in the database, '+
                    'check revision existance')
                return ERR_NOTEXIST
            
            # Authentication check
            self._checkPerms(rowFile['path'], auth.WRITE)
            
            # Basic checks
            if rowFile['lastrev'] != idRev:
                self._seterrormsg("Outdated client: not the last revision")
                return ERR_OUTDATED
            if rowFile['deleted'] == 1:
                self._seterrormsg("File is deleted, cannot add revisions to it")
                return ERR_DELETED
            if rowFile['isfolder']:
                self._seterrormsg('The file is a folder, cannot add revisions to it')
                return ERR_CANNOT
            
            # Now do really something
            self._logger.debug ( "Inserting new revision into database . . ." )
            cur = c.execute ( '''insert into revisions 
                (idfile,uid,timestamp,fromrev,typefrom,chksum,size,hardexist) 
                values (?,?,?,?,?,?,?,0)''' , 
                (rowRev['idfile'], self._getUID(), tsnow, 
                idRev, REV_MODIFIED, chksum, size ) )
            nextRev = cur.lastrowid
            c.execute ( '''update files set lastrev=? where idfile=?''' ,
                (nextRev , rowRev['idfile'] ) )
            
        self._logger.debug ( "Going to write the delta file" )
        #save the delta
        delta = Deltas.load(sentdelta)
        delta.save(os.path.join(self._deltasdir,str(nextRev)))
        
        self._logger.debug ( "Latest revision: %s" , int(nextRev) )
        return nextRev, tsnow