~certify-web-dev/twisted/certify-trunk

« back to all changes in this revision

Viewing changes to twisted/vfs/adapters/ftp.py

  • Committer: Bazaar Package Importer
  • Author(s): Matthias Klose
  • Date: 2007-01-17 14:52:35 UTC
  • mfrom: (1.1.5 upstream) (2.1.2 etch)
  • Revision ID: james.westby@ubuntu.com-20070117145235-btmig6qfmqfen0om
Tags: 2.5.0-0ubuntu1
New upstream version, compatible with python2.5.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
import os, time
 
2
from cStringIO import StringIO
 
3
 
 
4
from twisted.protocols.ftp import IFTPShell, IReadFile, IWriteFile
 
5
from twisted.internet import defer
 
6
from twisted.internet.interfaces import IConsumer
 
7
from twisted.web2.stream import StreamProducer, IByteStream
 
8
 
 
9
from zope.interface import implements
 
10
 
 
11
from twisted.python import components
 
12
from twisted.vfs import ivfs, pathutils
 
13
 
 
14
# XXX: Import this to make sure the adapter registration has happened.
 
15
from twisted.vfs.adapters import stream
 
16
 
 
17
 
 
18
class FileSystemToIFTPShellAdaptor:
 
19
 
 
20
    implements(IFTPShell)
 
21
 
 
22
    def __init__(self, filesystem):
 
23
        self.filesystem = filesystem
 
24
 
 
25
    def _makePath(segments):
 
26
        return '/'.join(segments)
 
27
    _makePath = staticmethod(_makePath)
 
28
 
 
29
    def makeDirectory(self, path):
 
30
        dirname, basename = path[:-1], path[-1]
 
31
        parent = self.filesystem.fetch(self._makePath(dirname))
 
32
        try:
 
33
            parent.createDirectory(basename)
 
34
        except:
 
35
            return defer.fail()
 
36
        else:
 
37
            return defer.succeed(None)
 
38
 
 
39
    def removeDirectory(self, path):
 
40
        try:
 
41
            node = self.filesystem.fetch(self._makePath(path))
 
42
            if not ivfs.IFileSystemContainer.providedBy(node):
 
43
                raise IOError("removeDirectory can only remove directories.")
 
44
            node.remove()
 
45
        except:
 
46
            return defer.fail()
 
47
        else:
 
48
            return defer.succeed(None)
 
49
 
 
50
    def removeFile(self, path):
 
51
        try:
 
52
            node = self.filesystem.fetch(self._makePath(path))
 
53
            if ivfs.IFileSystemContainer.providedBy(node):
 
54
                raise IOError("removeFile cannot remove directories.")
 
55
            node.remove()
 
56
        except:
 
57
            return defer.fail()
 
58
        else:
 
59
            return defer.succeed(None)
 
60
 
 
61
    def list(self, path, keys=()):
 
62
        node = self.filesystem.fetch(self._makePath(path))
 
63
 
 
64
        result = []
 
65
        for childName, childNode in node.children():
 
66
            attrs = self._attrify(childNode)
 
67
            result.append((childName, [attrs[attrName] for attrName in keys]))
 
68
 
 
69
        return defer.succeed(result)
 
70
 
 
71
    # XXX - this should probably go in a helper somewhere
 
72
    def _attrify(self, node):
 
73
        meta = node.getMetadata()
 
74
        permissions = meta.get('permissions', None)
 
75
        directory = ivfs.IFileSystemContainer.providedBy(node)
 
76
        if permissions is None:
 
77
            # WTF
 
78
            if ivfs.IFileSystemContainer.providedBy(node):
 
79
                permissions = 16877
 
80
            else:
 
81
                permissions = 33188
 
82
 
 
83
        return {'permissions': permissions,
 
84
                'directory': directory,
 
85
                'size': meta.get('size', 0),
 
86
                'owner': str(meta.get('uid', 'user')),
 
87
                'group': str(meta.get('gid', 'user')),
 
88
                'modified': meta.get('mtime', time.time()),
 
89
                'hardlinks': meta.get('nlink', 1)
 
90
                }
 
91
 
 
92
    def access(self, path):
 
93
        # XXX: stubbed out to always succeed.
 
94
        return defer.succeed(None)
 
95
 
 
96
    def openForReading(self, segs):
 
97
        node = self.filesystem.fetch(self._makePath(segs))
 
98
        frvfs = FTPReadVFS(node)
 
99
        return defer.succeed(frvfs)
 
100
 
 
101
    def openForWriting(self, segs):
 
102
        # XXX: this method is way too ugly
 
103
        dirname, basename = segs[:-1], segs[-1]
 
104
        node = self.filesystem.fetch(
 
105
            self._makePath(dirname)).createFile(basename)
 
106
        fwvfs = FTPWriteVFS(node)
 
107
        return defer.succeed(fwvfs)
 
108
 
 
109
    def stat(self, path, keys=()):
 
110
        node = self.filesystem.fetch(self._makePath(path))
 
111
        attrs = self._attrify(node)
 
112
        return defer.succeed([attrs[attrName] for attrName in keys])
 
113
 
 
114
    def rename(self, from_, to):
 
115
        assert len(to) == 1, (
 
116
            "renaming into other directories isn't supported yet.")
 
117
        try:
 
118
            self.filesystem.fetch(self._makePath(from_)).rename(to[0])
 
119
        except:
 
120
            return defer.fail()
 
121
        else:
 
122
            return defer.succeed(None)
 
123
 
 
124
 
 
125
class FTPReadVFS(object):
 
126
    implements(IReadFile)
 
127
 
 
128
    def __init__(self, node):
 
129
        self.node = node
 
130
 
 
131
    def send(self, consumer):
 
132
        return StreamProducer(IByteStream(self.node)).beginProducing(consumer)
 
133
 
 
134
 
 
135
class FTPWriteVFS(object):
 
136
    implements(IWriteFile)
 
137
 
 
138
    def __init__(self, node):
 
139
        self.node = node
 
140
 
 
141
    def receive(self):
 
142
        return defer.succeed(IConsumer(self.node))
 
143
 
 
144
 
 
145
class _FileToConsumerAdapter:
 
146
    implements(IConsumer)
 
147
 
 
148
    def __init__(self, original):
 
149
        self.original = original
 
150
        self.offset = 0
 
151
 
 
152
    def write(self, bytes):
 
153
        self.original.writeChunk(self.offset, bytes)
 
154
        self.offset += len(bytes)
 
155
 
 
156
 
 
157
 
 
158
components.registerAdapter(FileSystemToIFTPShellAdaptor,
 
159
                           pathutils.IFileSystem, IFTPShell)
 
160
components.registerAdapter(_FileToConsumerAdapter,
 
161
                           ivfs.IFileSystemLeaf, IConsumer)
 
162
 
 
163