def sendFile(writer, safe, profileId, mask, checksum, expiry, blockSize=4098): """ Send file to from server to client destination @param writer: StreamWriter object to client @param safe: crypto box @param profileId: logged in user's profile ID @param mask: local friend mask for given friend's user ID @param checksum: sha1 sum value of file to be sent @param expiry: expire days for file transfer requests (config set value) @param blockSize: total number of bytes to read at once @return: True when file if completely sent, otherwise False """ try: # obtain current requests for provided mask and clear expired requests filename, size, rowid = getFileRequests(safe, profileId, outgoing=True, mask=mask, expire=expiry)[mask][checksum] except KeyError: logging.warning("\t".join(("File Transfer Failed", "File transfer request does not exist for mask {} and checksum {}".format(mask, checksum)))) writer.write(NONEXISTANT) yield from writer.drain() return False if not path.isfile(filename): delFileRequests(rowid) logging.warning("\t".join(("File Transfer Failed", "File no longer exists: {}".format(filename)))) writer.write(NONEXISTANT) yield from writer.drain() return False # match file checksum to ensure the same file which was to be sent # has not been modified since the original transfer request cursum = sha1sum(filename) if checksum != cursum: # remove invalid transfer request delFileRequests(rowid) logging.warning("\t".join(("File Transfer Failed", "File has been modified", "Filename: {}".format(filename), "Original checksum: {}".format(checksum), "Current checksum: {}".format(cursum)))) writer.write(MODIFIED_FILE) yield from writer.drain() return False blockSize = int(blockSize) with open(filename, 'rb') as fd: for buf in iter(partial(fd.read, blockSize), b''): writer.write(buf) yield from writer.drain() # remove file transfer request from storage delFileRequests(rowid) return True
def __init__(self, safe, profileId, outgoing=False): """ File requests contructor @param safe: crypto box @param profileId: logged in profile ID @param outgoing: True to contain requests this user sent, False to contain received file transfer requests """ self.safe = safe self.profileId = profileId self.outgoing = outgoing self.__requests = getFileRequests(safe, profileId, outgoing)
def reload(self): self.__requests = getFileRequests(self.safe, self.profileId, self.outgoing)