SF.net SVN: fclient: [97] trunk/sandbox/fcp/fcp_2_0_requests.py
Status: Pre-Alpha
Brought to you by:
jurner
From: <ju...@us...> - 2008-02-01 14:42:16
|
Revision: 97 http://fclient.svn.sourceforge.net/fclient/?rev=97&view=rev Author: jurner Date: 2008-02-01 06:42:18 -0800 (Fri, 01 Feb 2008) Log Message: ----------- experimental to tackle uploads Added Paths: ----------- trunk/sandbox/fcp/fcp_2_0_requests.py Added: trunk/sandbox/fcp/fcp_2_0_requests.py =================================================================== --- trunk/sandbox/fcp/fcp_2_0_requests.py (rev 0) +++ trunk/sandbox/fcp/fcp_2_0_requests.py 2008-02-01 14:42:18 UTC (rev 97) @@ -0,0 +1,231 @@ +"""fcp request objects""" + +import fcp2_0_consts as consts +#****************************************************************************************************************** +# +#****************************************************************************************************************** +class Upload(object): + """Wrapper class to represent a freenet upload + + @note: you can upload one or more items of any kind (data, files, redirects), except from directories + wich have to be the only item to upload + """ + + + ReservedParamPrefix = 'Fc' # params prefixed with this are skipped when generating the message + + ItemTypeData = 0 + ItemTypeDirectory = 1 + ItemTypeFile = 2 + ItemTypeRedirect = 3 + + def __init__(self, + keyType, + dontCompress=None, + earlyEncode=None, + maxRetries=None, + persistence=consts.Persistence.Connection, + priorityClass=consts.Priority.Medium, + + privateKey=None, + ): + """ + @param keyType: (L{consts.KeyType}) the desired key type to upload + @param dontCompress: + @param earlyEncode: + @param maxRetries: + @param persistence: + @param priorityClass: + + @param privateKey: (str) privateKey if keyType is SSK or USK + """ + + if keyType not in consts.KeyType.TypesAll: + raise ValueError('Invalid key type: %r' % keyType) + + self.items = [] + self.keyType = keyType + self.params = { + 'DontCompress': dontCompress, + 'EarlyEncode': earlyEncode, + 'MaxRetries': maxRetries, + 'Persistence': persistence, + 'PriorityClass': priorityClass, + } + self.privateKey = privateKey + self._directoryAdded = False + self._targetNames = [] # record to check if names are unique (assert order is arbitrary) + + + + + def _addItem(self, **params): + """Private method to add an upload item""" + if self._directoryAdded: + raise ValueError('A directory has already been added, no other items allowed') + + if itemType == self.ItemTypeDirectory: + if self._directoryAdded: + raise ValueError('An item has already been added, no additional directory allowed') + else: + self._directoryAdded = True + + name = params['Name'] + if name in self._targetNames: + raise ValueError('Target name already exists: %r' % name) + + self.targetNames.append(name) + self.iotems.append(params) + + + def addData(self, name, data, contentType=None): + """Adds data to be uploaded + @param name: target name + @param data: (str) data to upload + @param contentType: (str) content type of the data (if desired) + """ + return self._addItem( + FcItemType=self.ItemTypeData, + FcData=data, + ContentType=contentType, + DataLength=len(data), + Name=name, + UploadFrom=self.UploadFrom.Direct + ) + + def addDirectory(name, directory, allowUnreadableFiles=False): + """Adds a directory to be uploaded + @param name: target name + @param directory: (abspath) of the directory to be uploaded + @param contentType: (str) content type of the file (if desired) + + @note: if you add a directory, every attempt to add anything else will fail + """ + return self._addItem( + FcItemType=self.ItemTypeDirectory, + AllowUnreadableFiles=allowUnreadableFiles, + Filename=directory, + Name=name, + ) + + def addFile(self, name, filename, contentType=None): + """Adds a file to be uploaded + @param name: target name + @param filename: (abspath) of the file to be uploaded + @param contentType: (str) content type of the file (if desired) + """ + return self._addItem( + FcItemType=self.ItemTypeFile, + ContentType=contentType, + Filename=filename, + Name=name, + UploadFrom=self.UploadFrom.Disk, + ) + + def addRedirect(self, name, redirect): + """Adds a redirect to be uploaded + @param name: target name + @param redirect: (freenet-key) to redirect to + """ + return self._addItem( + FcItemType=self.ItemTypeRedirect, + ContentType=contentType, + DataLength=len(data), + Name=name, + TargetURI=redirect, + UploadFrom=self.UploadFrom.Redirect + ) + + def getMessage(self, messageClass): + """Returns the message for the request, ready to send the request to the node + @param messageClass: (L{Message}) class to fill in + @return: (L{Message}) instance + """ + if self.keyType in (consts.KeyType.SSK, consts.KeyType.USK) and self.privateKey is None: + raise ValueError('For %s a public key is required' % self.keyType) + elif self.keyType in (consts.KeyType.CHK, consts.KeyType.KSK) and self.privateKey is not None: + raise ValueError('For %s no public key is required' % self.keyType) + + + n = len(self.items) + if n == 0: + return None + + elif n == 1 and self.itemTypes[0] == self.ItemTypeDirectory: + msg = messageClass(messageClass.MessageClientPutDiskDir, **self.params) + params = self.items[0] + for param, value in params.items(): + if value is None: + continue + if param.startswith(self.ReservedParamPrefix): + continue + + if param == 'Name': + param = 'TargetFilename' + elif param == 'ContentType': + param = 'Metadata.ContentType' + msg[param] = value + + elif n == 1: + msg = messageClass(messageClass.MessageClientPut, **self.params) + params = self.items[0] + for param, value in params.items(): + if value is None: + continue + if param.startswith(self.ReservedParamPrefix): + continue + + if param == 'Name': + param = 'TargetFilename' + elif param == 'ContentType': + param = 'Metadata.ContentType' + msg[param] = value + + if params['FcItemType'] == self.ItemTypeData: + msg.data = params['FcData'] + + #TODO: USK@s allowed for complex dirs? + else: + + #NOTE: for simplicity we take the first item as default item and its name + # as TargetName if that causes any problems, pass it twice + msg = messageClass(messageClass.MessageClientPutComplexDir, **self.params) + msg.data = '' + defaultName = temParams[0]['Name'] + msg['DefaultName'] = defaultName + params = {'TargetFilename': defaultName} + for itemParams in self.items: + k = 0 + for param, value in itemParams.items(): + if value is None: + continue + if param.startswith(self.ReservedParamPrefix): + if param == 'FcData': + msg.data += data + continue + + if param == 'ContentType': + param = 'Metadata.ContentType' + param = 'Files.%s.%s' % (k, param) + msg[param] = value + k += 1 + + if not msg.data: + msg.data = None + + # set some defaults + msg['Global'] = consts.FcpFalse + msg['Verbosity'] = consts.Verbosity.ReportProgress | consts.Verbosity.ReportCompression + + # compose URI + if self.KeyType == consts.KeyType.CHK: + msg['URI'] == consts.KeyType.CHK + elif self.KeyType == consts.KeyType.KSK: + msg['URI'] == consts.KeyType.KSK + '/' + params.pop('TargetFilename') + elif self.KeyType == consts.KeyType.SSK: + msg['URI'] == consts.KeyType.SSK + self.privateKey + '/' + params.pop('TargetFilename') + elif self.KeyType == consts.KeyType.USK: + msg['URI'] == consts.KeyType.USH + self.privateKey + '/' + params.pop('TargetFilename') + + return msg + This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |