mirror of
https://github.com/tahoe-lafs/tahoe-lafs.git
synced 2025-04-27 06:20:25 +00:00
move upload/download interfaces to allmydata.interfaces, let SubTreeMaker assert IDownloader-ness of its 'downloader' argument
This commit is contained in:
parent
a8ecaf45b6
commit
430b3a03fc
@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
import os, sha
|
import os, sha
|
||||||
from zope.interface import Interface, implements
|
from zope.interface import implements
|
||||||
from twisted.python import failure, log
|
from twisted.python import failure, log
|
||||||
from twisted.internet import defer
|
from twisted.internet import defer
|
||||||
from twisted.application import service
|
from twisted.application import service
|
||||||
@ -9,6 +9,7 @@ from allmydata.util import idlib, bencode
|
|||||||
from allmydata.util.deferredutil import DeferredListShouldSucceed
|
from allmydata.util.deferredutil import DeferredListShouldSucceed
|
||||||
from allmydata import codec
|
from allmydata import codec
|
||||||
from allmydata.uri import unpack_uri
|
from allmydata.uri import unpack_uri
|
||||||
|
from allmydata.interfaces import IDownloadTarget, IDownloader
|
||||||
|
|
||||||
class NotEnoughPeersError(Exception):
|
class NotEnoughPeersError(Exception):
|
||||||
pass
|
pass
|
||||||
@ -147,26 +148,6 @@ class FileDownloader:
|
|||||||
def netstring(s):
|
def netstring(s):
|
||||||
return "%d:%s," % (len(s), s)
|
return "%d:%s," % (len(s), s)
|
||||||
|
|
||||||
class IDownloadTarget(Interface):
|
|
||||||
def open():
|
|
||||||
"""Called before any calls to write() or close()."""
|
|
||||||
def write(data):
|
|
||||||
pass
|
|
||||||
def close():
|
|
||||||
pass
|
|
||||||
def fail():
|
|
||||||
"""fail() is called to indicate that the download has failed. No
|
|
||||||
further methods will be invoked on the IDownloadTarget after fail()."""
|
|
||||||
def register_canceller(cb):
|
|
||||||
"""The FileDownloader uses this to register a no-argument function
|
|
||||||
that the target can call to cancel the download. Once this canceller
|
|
||||||
is invoked, no further calls to write() or close() will be made."""
|
|
||||||
def finish(self):
|
|
||||||
"""When the FileDownloader is done, this finish() function will be
|
|
||||||
called. Whatever it returns will be returned to the invoker of
|
|
||||||
Downloader.download.
|
|
||||||
"""
|
|
||||||
|
|
||||||
class FileName:
|
class FileName:
|
||||||
implements(IDownloadTarget)
|
implements(IDownloadTarget)
|
||||||
def __init__(self, filename):
|
def __init__(self, filename):
|
||||||
@ -222,10 +203,6 @@ class FileHandle:
|
|||||||
def finish(self):
|
def finish(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
class IDownloader(Interface):
|
|
||||||
def download(uri, target):
|
|
||||||
pass
|
|
||||||
|
|
||||||
class Downloader(service.MultiService):
|
class Downloader(service.MultiService):
|
||||||
"""I am a service that allows file downloading.
|
"""I am a service that allows file downloading.
|
||||||
"""
|
"""
|
||||||
|
@ -9,6 +9,7 @@ from allmydata.filetree.interfaces import (
|
|||||||
PathDoesNotExistError,
|
PathDoesNotExistError,
|
||||||
)
|
)
|
||||||
from allmydata.upload import IUploadable
|
from allmydata.upload import IUploadable
|
||||||
|
from allmydata.interfaces import IDownloader
|
||||||
|
|
||||||
from allmydata.filetree.nodemaker import NodeMaker
|
from allmydata.filetree.nodemaker import NodeMaker
|
||||||
|
|
||||||
@ -30,6 +31,7 @@ class SubTreeMaker(object):
|
|||||||
# create subtrees. That means a Downloader and a reference to the
|
# create subtrees. That means a Downloader and a reference to the
|
||||||
# queen.
|
# queen.
|
||||||
self._queen = queen
|
self._queen = queen
|
||||||
|
assert IDownloader(downloader)
|
||||||
self._downloader = downloader
|
self._downloader = downloader
|
||||||
self._node_maker = NodeMaker()
|
self._node_maker = NodeMaker()
|
||||||
self._cache = {}
|
self._cache = {}
|
||||||
|
@ -180,3 +180,46 @@ class ICodecDecoder(Interface):
|
|||||||
of 'required_shares' passed into the original
|
of 'required_shares' passed into the original
|
||||||
ICodecEncode.set_params() call.
|
ICodecEncode.set_params() call.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
class IDownloadTarget(Interface):
|
||||||
|
def open():
|
||||||
|
"""Called before any calls to write() or close()."""
|
||||||
|
def write(data):
|
||||||
|
"""Output some data to the target."""
|
||||||
|
def close():
|
||||||
|
"""Inform the target that there is no more data to be written."""
|
||||||
|
def fail():
|
||||||
|
"""fail() is called to indicate that the download has failed. No
|
||||||
|
further methods will be invoked on the IDownloadTarget after fail()."""
|
||||||
|
def register_canceller(cb):
|
||||||
|
"""The FileDownloader uses this to register a no-argument function
|
||||||
|
that the target can call to cancel the download. Once this canceller
|
||||||
|
is invoked, no further calls to write() or close() will be made."""
|
||||||
|
def finish(self):
|
||||||
|
"""When the FileDownloader is done, this finish() function will be
|
||||||
|
called. Whatever it returns will be returned to the invoker of
|
||||||
|
Downloader.download.
|
||||||
|
"""
|
||||||
|
|
||||||
|
class IDownloader(Interface):
|
||||||
|
def download(uri, target):
|
||||||
|
"""Perform a CHK download, sending the data to the given target.
|
||||||
|
'target' must provide IDownloadTarget."""
|
||||||
|
|
||||||
|
class IUploadable(Interface):
|
||||||
|
def get_filehandle():
|
||||||
|
"""Return a filehandle from which the data to be uploaded can be
|
||||||
|
read. It must implement .read, .seek, and .tell (since the latter two
|
||||||
|
are used to determine the length of the data)."""
|
||||||
|
def close_filehandle(f):
|
||||||
|
"""The upload is finished. This provides the same filehandle as was
|
||||||
|
returned by get_filehandle. This is an appropriate place to close the
|
||||||
|
filehandle."""
|
||||||
|
|
||||||
|
class IUploader(Interface):
|
||||||
|
def upload(uploadable):
|
||||||
|
"""Upload the file. 'uploadable' must impement IUploadable. This
|
||||||
|
returns a Deferred which fires with the URI of the file."""
|
||||||
|
|
||||||
|
def upload_ssk(write_capability, new_version, uploadable):
|
||||||
|
pass # TODO
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
|
|
||||||
#from zope.interface import implements
|
from zope.interface import implements
|
||||||
from twisted.trial import unittest
|
from twisted.trial import unittest
|
||||||
from twisted.internet import defer
|
from twisted.internet import defer
|
||||||
#from allmydata.filetree.interfaces import IOpener, IDirectoryNode
|
from allmydata.interfaces import IDownloader, IUploader
|
||||||
#from allmydata.filetree.directory import (ImmutableDirectorySubTree,
|
#from allmydata.filetree.directory import (ImmutableDirectorySubTree,
|
||||||
# SubTreeNode,
|
# SubTreeNode,
|
||||||
# CHKDirectorySubTree)
|
# CHKDirectorySubTree)
|
||||||
@ -20,6 +20,7 @@ class FakeOpener(object):
|
|||||||
#print "open", subtree_specification, subtree_specification.serialize(), parent_is_mutable
|
#print "open", subtree_specification, subtree_specification.serialize(), parent_is_mutable
|
||||||
return defer.succeed(self.objects[subtree_specification.serialize()])
|
return defer.succeed(self.objects[subtree_specification.serialize()])
|
||||||
|
|
||||||
|
|
||||||
class FakeWorkQueue(object):
|
class FakeWorkQueue(object):
|
||||||
implements(workqueue.IWorkQueue)
|
implements(workqueue.IWorkQueue)
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
@ -319,6 +320,7 @@ from allmydata.filetree.interfaces import (ISubTree, INode, IDirectoryNode,
|
|||||||
IFileNode, NoSuchDirectoryError,
|
IFileNode, NoSuchDirectoryError,
|
||||||
NoSuchChildError)
|
NoSuchChildError)
|
||||||
from allmydata.filetree.file import CHKFileNode
|
from allmydata.filetree.file import CHKFileNode
|
||||||
|
from allmydata.interfaces import IDownloader
|
||||||
from allmydata.util import bencode
|
from allmydata.util import bencode
|
||||||
|
|
||||||
class InPairs(unittest.TestCase):
|
class InPairs(unittest.TestCase):
|
||||||
@ -327,11 +329,14 @@ class InPairs(unittest.TestCase):
|
|||||||
pairs = list(directory.in_pairs(l))
|
pairs = list(directory.in_pairs(l))
|
||||||
self.failUnlessEqual(pairs, [(0,1), (2,3), (4,5), (6,7)])
|
self.failUnlessEqual(pairs, [(0,1), (2,3), (4,5), (6,7)])
|
||||||
|
|
||||||
|
class StubDownloader(object):
|
||||||
|
implements(IDownloader)
|
||||||
|
|
||||||
class Stuff(unittest.TestCase):
|
class Stuff(unittest.TestCase):
|
||||||
|
|
||||||
def makeVirtualDrive(self, basedir, root_node=None):
|
def makeVirtualDrive(self, basedir, root_node=None):
|
||||||
wq = workqueue.WorkQueue(os.path.join(basedir, "1.workqueue"))
|
wq = workqueue.WorkQueue(os.path.join(basedir, "1.workqueue"))
|
||||||
dl = None
|
dl = StubDownloader()
|
||||||
if not root_node:
|
if not root_node:
|
||||||
root_node = directory.LocalFileSubTreeNode()
|
root_node = directory.LocalFileSubTreeNode()
|
||||||
root_node.new("rootdirtree.save")
|
root_node.new("rootdirtree.save")
|
||||||
@ -347,7 +352,7 @@ class Stuff(unittest.TestCase):
|
|||||||
self.failUnlessEqual(c1a, c2a)
|
self.failUnlessEqual(c1a, c2a)
|
||||||
|
|
||||||
def testDirectory(self):
|
def testDirectory(self):
|
||||||
stm = vdrive.SubTreeMaker(None, None)
|
stm = vdrive.SubTreeMaker(None, StubDownloader())
|
||||||
|
|
||||||
# create an empty directory (stored locally)
|
# create an empty directory (stored locally)
|
||||||
subtree = directory.LocalFileSubTree()
|
subtree = directory.LocalFileSubTree()
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
from zope.interface import Interface, implements
|
from zope.interface import implements
|
||||||
from twisted.python import failure, log
|
from twisted.python import failure, log
|
||||||
from twisted.internet import defer
|
from twisted.internet import defer
|
||||||
from twisted.application import service
|
from twisted.application import service
|
||||||
@ -10,6 +10,7 @@ from allmydata.util.idlib import peerid_to_short_string as shortid
|
|||||||
from allmydata.util.deferredutil import DeferredListShouldSucceed
|
from allmydata.util.deferredutil import DeferredListShouldSucceed
|
||||||
from allmydata import codec
|
from allmydata import codec
|
||||||
from allmydata.uri import pack_uri
|
from allmydata.uri import pack_uri
|
||||||
|
from allmydata.interfaces import IUploadable, IUploader
|
||||||
|
|
||||||
from cStringIO import StringIO
|
from cStringIO import StringIO
|
||||||
import sha
|
import sha
|
||||||
@ -245,12 +246,6 @@ class FileUploader:
|
|||||||
def netstring(s):
|
def netstring(s):
|
||||||
return "%d:%s," % (len(s), s)
|
return "%d:%s," % (len(s), s)
|
||||||
|
|
||||||
class IUploadable(Interface):
|
|
||||||
def get_filehandle():
|
|
||||||
pass
|
|
||||||
def close_filehandle(f):
|
|
||||||
pass
|
|
||||||
|
|
||||||
class FileName:
|
class FileName:
|
||||||
implements(IUploadable)
|
implements(IUploadable)
|
||||||
def __init__(self, filename):
|
def __init__(self, filename):
|
||||||
@ -279,17 +274,10 @@ class FileHandle:
|
|||||||
# the originator of the filehandle reserves the right to close it
|
# the originator of the filehandle reserves the right to close it
|
||||||
pass
|
pass
|
||||||
|
|
||||||
class IUploader(Interface):
|
|
||||||
def upload(uploadable):
|
|
||||||
"""Upload the file. 'uploadable' must impement IUploadable. This
|
|
||||||
returns a Deferred which fires with the URI of the file."""
|
|
||||||
|
|
||||||
def upload_ssk(write_capability, new_version, uploadable):
|
|
||||||
pass # TODO
|
|
||||||
|
|
||||||
class Uploader(service.MultiService):
|
class Uploader(service.MultiService):
|
||||||
"""I am a service that allows file uploading.
|
"""I am a service that allows file uploading.
|
||||||
"""
|
"""
|
||||||
|
implements(IUploader)
|
||||||
name = "uploader"
|
name = "uploader"
|
||||||
uploader_class = FileUploader
|
uploader_class = FileUploader
|
||||||
debug = False
|
debug = False
|
||||||
|
@ -4,7 +4,7 @@ from twisted.web import static, resource, server, html
|
|||||||
from twisted.python import util, log
|
from twisted.python import util, log
|
||||||
from nevow import inevow, rend, loaders, appserver, url, tags as T
|
from nevow import inevow, rend, loaders, appserver, url, tags as T
|
||||||
from allmydata.util import idlib
|
from allmydata.util import idlib
|
||||||
from allmydata.download import IDownloadTarget#, IDownloader
|
from allmydata.interfaces import IDownloadTarget#, IDownloader
|
||||||
from allmydata import upload
|
from allmydata import upload
|
||||||
from zope.interface import implements, Interface
|
from zope.interface import implements, Interface
|
||||||
import urllib
|
import urllib
|
||||||
|
Loading…
x
Reference in New Issue
Block a user