예제 #1
0
 def write(self, data):
     """
     FileTransfer.write(data) -> None
         Requests over 128KB will be buffered internally
     """
     if self.mode != 'w':
         raise MythFileError('attempting to write to a read-only socket')
     while len(data) > 0:
         size = len(data)
         # check size for buffering
         if size > self._tsize:
             size = self._tsize
             buff = data[:size]
             data = data[size:]
         else:
             buff = data
             data = ''
         # push data to server
         self._pos += int(self.ftsock.send(buff))
         if self._pos > self._size:
             self._size = self._pos
         # inform server of new data
         self.backendCommand('QUERY_FILETRANSFER '\
                 +BACKEND_SEP.join(\
                         [str(self._sockno),
                          'WRITE_BLOCK',
                          str(size)]))
     return
예제 #2
0
 def write(self, data):
     """
     FileTransfer.write(data) -> None
         Requests over 128KB will be buffered internally
     """
     if self.mode != 'w':
         raise MythFileError('attempting to write to a read-only socket')
     while len(data) > 0:
         size = len(data)
         # check size for buffering
         if size > self._tsize:
             size = self._tsize
             buff = data[:size]
             data = data[size:]
         else:
             buff = data
             data = ''
         # push data to server
         self._pos += int(self.ftsock.send(buff))
         if self._pos > self._size:
             self._size = self._pos
         # inform server of new data
         self.backendCommand('QUERY_FILETRANSFER '\
                 +BACKEND_SEP.join(\
                         [str(self._sockno),
                          'WRITE_BLOCK',
                          str(size)]))
     return
예제 #3
0
    def read(self, size):
        """
        FileTransfer.read(size) -> string of <size> characters
            Requests over 128KB will be buffered internally.
        """

        # some sanity checking
        if self.mode != 'r':
            raise MythFileError('attempting to read from a write-only socket')
        if size == 0:
            return ''
        if self._pos + size > self._size:
            size = self._size - self._pos

        buff = ''
        while len(buff) < size:
            ct = size - len(buff)
            if ct > self._tsize:
                # drop size and bump counter if over limit
                self._count += 1
                ct = self._tsize

            # request transfer
            res = self.backendCommand('QUERY_FILETRANSFER '\
                        +BACKEND_SEP.join(
                                [str(self._sockno),
                                 'REQUEST_BLOCK',
                                 str(ct)]))

            if res == '':
                # complete failure, hard reset position and retry
                self._count = 0
                self.seek(self._pos)
                continue

            if int(res) == ct:
                if (self._count >= 5) and (self._tsize < self._tmax):
                    # multiple successful transfers, bump transfer limit
                    self._count = 0
                    self._tsize += self._step

            else:
                if int(res) == -1:
                    # complete failure, hard reset position and retry
                    self._count = 0
                    self.seek(self._pos)
                    continue

                # partial failure, reset counter and drop transfer limit
                ct = int(res)
                self._count = 0
                self._tsize -= 2 * self._step
                if self._tsize < self._step:
                    self._tsize = self._step

            # append data and move position
            buff += self.ftsock.recv(ct)
            self._pos += ct
        return buff
예제 #4
0
    def read(self, size):
        """
        FileTransfer.read(size) -> string of <size> characters
            Requests over 128KB will be buffered internally.
        """

        # some sanity checking
        if self.mode != 'r':
            raise MythFileError('attempting to read from a write-only socket')
        if size == 0:
            return ''
        if self._pos + size > self._size:
            size = self._size - self._pos

        buff = ''
        while len(buff) < size:
            ct = size - len(buff)
            if ct > self._tsize:
                # drop size and bump counter if over limit
                self._count += 1
                ct = self._tsize

            # request transfer
            res = self.backendCommand('QUERY_FILETRANSFER '\
                        +BACKEND_SEP.join(
                                [str(self._sockno),
                                 'REQUEST_BLOCK',
                                 str(ct)]))

            if res == '':
                # complete failure, hard reset position and retry
                self._count = 0
                self.seek(self._pos)
                continue

            if int(res) == ct:
                if (self._count >= 5) and (self._tsize < self._tmax):
                    # multiple successful transfers, bump transfer limit
                    self._count = 0
                    self._tsize += self._step

            else:
                if int(res) == -1:
                    # complete failure, hard reset position and retry
                    self._count = 0
                    self.seek(self._pos)
                    continue

                # partial failure, reset counter and drop transfer limit
                ct = int(res)
                self._count = 0
                self._tsize -= 2*self._step
                if self._tsize < self._step:
                    self._tsize = self._step

            # append data and move position
            buff += self.ftsock.recv(ct)
            self._pos += ct
        return buff
예제 #5
0
 def fileExists(self, file, sgroup='Default'):
     """FileOps.fileExists() -> file path"""
     res = self.backendCommand(BACKEND_SEP.join((\
                 'QUERY_FILE_EXISTS',file,sgroup))).split(BACKEND_SEP)
     if int(res[0]) == 0:
         return None
     else:
         return res[1]
예제 #6
0
 def fileExists(self, file, sgroup='Default'):
     """FileOps.fileExists() -> file path"""
     res = self.backendCommand(BACKEND_SEP.join((\
                 'QUERY_FILE_EXISTS',file,sgroup))).split(BACKEND_SEP)
     if int(res[0]) == 0:
         return None
     else:
         return res[1]
예제 #7
0
 def deleteRecording(self, program, force=False):
     """
     FileOps.deleteRecording(program, force=False) -> retcode
         'force' will force a delete even if the file cannot be found
         retcode will be -1 on success, -2 on failure
     """
     command = 'DELETE_RECORDING'
     if force:
         command = 'FORCE_DELETE_RECORDING'
     return self.backendCommand(BACKEND_SEP.join(\
                 [command,program.toString()]))
예제 #8
0
 def deleteRecording(self, program, force=False):
     """
     FileOps.deleteRecording(program, force=False) -> retcode
         'force' will force a delete even if the file cannot be found
         retcode will be -1 on success, -2 on failure
     """
     command = 'DELETE_RECORDING'
     if force:
         command = 'FORCE_DELETE_RECORDING'
     return self.backendCommand(BACKEND_SEP.join(\
                 [command,program.toString()]))
예제 #9
0
def undelete_all(backend, recs):
    """Undeletes all recordings from the dict recs.

    Send an UNDELETE_RECORDING protocol message to the backend and test for
    failure.
    """
    for rec in recs.values():
        print('undelete ' + rec_to_string(rec))
        cmd = BACKEND_SEP.join(['UNDELETE_RECORDING', rec.to_string()])
        res = backend.backendCommand(cmd)
        if int(res) != 0:
            raise MythBEError("undelete failed")
예제 #10
0
def undelete_all(backend, recs):
    """Undeletes all recordings from the dict recs.

    Send an UNDELETE_RECORDING protocol message to the backend and test for
    failure.
    """
    for rec in recs.values():
        print('undelete ' + rec_to_string(rec))
        cmd = BACKEND_SEP.join(['UNDELETE_RECORDING', rec.to_string()])
        res = backend.backendCommand(cmd)
        if int(res) != 0:
            raise MythBEError("undelete failed")
예제 #11
0
 def reschedule(self, recordid=-1, wait=False):
     """FileOps.reschedule() -> None"""
     if wait:
         eventlock = self.allocateEventLock(\
                         re.escape(BACKEND_SEP).join(\
                                 ['BACKEND_MESSAGE',
                                  'SCHEDULE_CHANGE',
                                  'empty']))
     if recordid == 0:
         self.backendCommand(BACKEND_SEP.join(\
             ['RESCHEDULE_RECORDINGS',
              'CHECK 0 0 0 Python',
              '', '', '', '**any**']))
     else:
         if recordid == -1:
             recordid = 0
         self.backendCommand(BACKEND_SEP.join(\
             ['RESCHEDULE_RECORDINGS',
              'MATCH ' + str(recordid) + ' 0 0 - Python']))
     if wait:
         eventlock.wait()
예제 #12
0
 def reschedule(self, recordid=-1, wait=False):
     """FileOps.reschedule() -> None"""
     if wait:
         eventlock = self.allocateEventLock(\
                         re.escape(BACKEND_SEP).join(\
                                 ['BACKEND_MESSAGE',
                                  'SCHEDULE_CHANGE',
                                  'empty']))
     if recordid == 0:
         self.backendCommand(BACKEND_SEP.join(\
             ['RESCHEDULE_RECORDINGS',
              'CHECK 0 0 0 Python',
              '', '', '', '**any**']))
     else:
         if recordid == -1:
             recordid = 0
         self.backendCommand(BACKEND_SEP.join(\
             ['RESCHEDULE_RECORDINGS',
              'MATCH ' + str(recordid) + ' 0 0 - Python']))
     if wait:
         eventlock.wait()
예제 #13
0
        def announce(self):
            if self.mode == 'r':
                cmd = 'ANN FileTransfer %s 0 0 2000'
            elif self.mode == 'w':
                cmd = 'ANN FileTransfer %s 1'

            res = self.backendCommand(
                BACKEND_SEP.join(
                    [cmd % self.localname, self.filename, self.sgroup]))
            if res.split(BACKEND_SEP)[0] != 'OK':
                raise MythBEError(MythError.PROTO_ANNOUNCE, self.host,
                                  self.port, res)
            else:
                sp = res.split(BACKEND_SEP)
                self._sockno = int(sp[1])
                self._size = int(sp[2])
예제 #14
0
        def announce(self):
            if self.mode == 'r':
                cmd = 'ANN FileTransfer %s 0 0 2000'
            elif self.mode == 'w':
                cmd = 'ANN FileTransfer %s 1'

            res = self.backendCommand(
                    BACKEND_SEP.join([cmd % self.localname,
                                      self.filename,
                                      self.sgroup]))
            if res.split(BACKEND_SEP)[0] != 'OK':
                raise MythBEError(MythError.PROTO_ANNOUNCE,
                                  self.host, self.port, res)
            else:
                sp = res.split(BACKEND_SEP)
                self._sockno = int(sp[1])
                self._size = int(sp[2])
예제 #15
0
 def downloadTo(self, url, storagegroup, filename, \
                      forceremote=False, openfile=False):
     if openfile:
         eventlock = self.allocateEventLock(\
                 re.escape(BACKEND_SEP).\
                         join(['BACKEND_MESSAGE',
                               'DOWNLOAD_FILE UPDATE',
                               re.escape(url)]))
     if filename[0] != '/':
         filename = '/'+filename
     res = self.backendCommand(BACKEND_SEP.join((\
                 'DOWNLOAD_FILE', url, storagegroup, filename))).\
                 split(BACKEND_SEP)
     if res[0] != 'OK':
         raise MythBEError('Download failed')
     if openfile:
         eventlock.wait()
         return ftopen(res[1], 'r', forceremote, db=self.db, download=True)
예제 #16
0
 def downloadTo(self, url, storagegroup, filename, \
                      forceremote=False, openfile=False):
     if openfile:
         eventlock = self.allocateEventLock(\
                 re.escape(BACKEND_SEP).\
                         join(['BACKEND_MESSAGE',
                               'DOWNLOAD_FILE UPDATE',
                               re.escape(url)]))
     if filename[0] != '/':
         filename = '/' + filename
     res = self.backendCommand(BACKEND_SEP.join((\
                 'DOWNLOAD_FILE', url, storagegroup, filename))).\
                 split(BACKEND_SEP)
     if res[0] != 'OK':
         raise MythBEError('Download failed')
     if openfile:
         eventlock.wait()
         return ftopen(res[1], 'r', forceremote, db=self.db, download=True)
예제 #17
0
    def seek(self, offset, whence=0):
        """
        FileTransfer.seek(offset, whence=0) -> None
            Seek 'offset' number of bytes
            whence == 0 - from start of file
                      1 - from current position
                      2 - from end of file
        """
        if whence == 0:
            if offset < 0:
                offset = 0
            elif offset > self._size:
                offset = self._size
        elif whence == 1:
            if offset + self._pos < 0:
                offset = -self._pos
            elif offset + self._pos > self._size:
                offset = self._size - self._pos
        elif whence == 2:
            if offset > 0:
                offset = 0
            elif offset < -self._size:
                offset = -self._size
            whence = 0
            offset = self._size+offset

        res = self.backendCommand('QUERY_FILETRANSFER '\
                +BACKEND_SEP.join(
                        [str(self._sockno),'SEEK',
                         str(offset),
                         str(whence),
                         str(self._pos)])\
                 ).split(BACKEND_SEP)
        if res[0] == '-1':
            raise MythFileError(MythError.FILE_FAILED_SEEK, \
                                    str(self), offset, whence)
        self._pos = int(res[0])
예제 #18
0
    def seek(self, offset, whence=0):
        """
        FileTransfer.seek(offset, whence=0) -> None
            Seek 'offset' number of bytes
            whence == 0 - from start of file
                      1 - from current position
                      2 - from end of file
        """
        if whence == 0:
            if offset < 0:
                offset = 0
            elif offset > self._size:
                offset = self._size
        elif whence == 1:
            if offset + self._pos < 0:
                offset = -self._pos
            elif offset + self._pos > self._size:
                offset = self._size - self._pos
        elif whence == 2:
            if offset > 0:
                offset = 0
            elif offset < -self._size:
                offset = -self._size
            whence = 0
            offset = self._size + offset

        res = self.backendCommand('QUERY_FILETRANSFER '\
                +BACKEND_SEP.join(
                        [str(self._sockno),'SEEK',
                         str(offset),
                         str(whence),
                         str(self._pos)])\
                 ).split(BACKEND_SEP)
        if res[0] == '-1':
            raise MythFileError(MythError.FILE_FAILED_SEEK, \
                                    str(self), offset, whence)
        self._pos = int(res[0])
예제 #19
0
 def stopRecording(self, program):
     """FileOps.stopRecording(program) -> None"""
     self.backendCommand(BACKEND_SEP.join(['STOP_RECORDING',
                 program.toString()]))
예제 #20
0
 def getHash(self, file, sgroup, host=None):
     """FileOps.getHash(file, storagegroup, host) -> hash string"""
     m = ['QUERY_FILE_HASH', file, sgroup]
     if host:
         m.append(host)
     return self.backendCommand(BACKEND_SEP.join(m))
예제 #21
0
 def stopRecording(self, program):
     """FileOps.stopRecording(program) -> None"""
     self.backendCommand(
         BACKEND_SEP.join(['STOP_RECORDING',
                           program.toString()]))
예제 #22
0
 def forgetRecording(self, program):
     """FileOps.forgetRecording(program) -> None"""
     self.backendCommand(
         BACKEND_SEP.join(['FORGET_RECORDING',
                           program.toString()]))
예제 #23
0
 def deleteFile(self, file, sgroup):
     """FileOps.deleteFile(file, storagegroup) -> retcode"""
     return self.backendCommand(BACKEND_SEP.join(\
                 ['DELETE_FILE',file,sgroup]))
예제 #24
0
 def __del__(self):
     self.backendCommand('QUERY_FILETRANSFER '+BACKEND_SEP.join(
                                     [str(self._sockno), 'DONE']))
     del self.ftsock
     self.open = False
예제 #25
0
 def getHash(self, file, sgroup, host=None):
     """FileOps.getHash(file, storagegroup, host) -> hash string"""
     m = ['QUERY_FILE_HASH', file, sgroup]
     if host:
         m.append(host)
     return self.backendCommand(BACKEND_SEP.join(m))
예제 #26
0
 def toString(self):
     """
     Program.toString() -> string representation
                 for use with backend protocol commands
     """
     return BACKEND_SEP.join(self._deprocess())
예제 #27
0
 def forgetRecording(self, program):
     """FileOps.forgetRecording(program) -> None"""
     self.backendCommand(BACKEND_SEP.join(['FORGET_RECORDING',
                 program.toString()]))
예제 #28
0
 def __del__(self):
     self.backendCommand('QUERY_FILETRANSFER ' +
                         BACKEND_SEP.join([str(self._sockno), 'DONE']))
     del self.ftsock
     self.open = False
예제 #29
0
 def toString(self):
     """
     Program.toString() -> string representation
                 for use with backend protocol commands
     """
     return BACKEND_SEP.join(self._deprocess())
예제 #30
0
 def deleteFile(self, file, sgroup):
     """FileOps.deleteFile(file, storagegroup) -> retcode"""
     return self.backendCommand(BACKEND_SEP.join(\
                 ['DELETE_FILE',file,sgroup]))