1 # Copyright (c) 2005.-2006. Ivan Voras <ivoras@gmail.com>
2 # Released under the Artistic License
4 from member
import Member
5 from collection
import *
13 class FileMember(Member
):
15 def __init__(self
, name
, parent
):
19 self
.fsname
= parent
.fsname
+ name
# e.g. '/var/www/mysite/some.txt'
20 self
.virname
= parent
.virname
+ name
# e.g. '/mysite/some.txt'
21 self
.type = Member
.M_MEMBER
23 assert(type(self
.name
) == unicode)
24 assert(type(self
.fsname
) == unicode)
25 assert(type(self
.virname
) == unicode)
28 return "%s -> %s" % (self
.virname
, self
.fsname
)
30 def getProperties(self
):
31 """Return dictionary with WebDAV properties. Values shold be
32 formatted according to the WebDAV specs."""
33 st
= os
.stat(self
.fsname
)
35 p
['creationdate'] = unixdate2iso8601(st
.st_ctime
)
36 p
['getlastmodified'] = unixdate2httpdate(st
.st_mtime
)
37 if self
.type == Member
.M_COLLECTION
:
38 p
['displayname'] = self
.name
.strip(u
"/").split('/')[-1]
40 p
['displayname'] = self
.name
41 p
['getetag'] = md5
.new(self
.fsname
.encode("utf-8")).hexdigest()
42 #p['resourcetype'] = None
43 if self
.type == Member
.M_MEMBER
:
44 p
['getcontentlength'] = st
.st_size
45 p
['getcontenttype'], z
= mimetypes
.guess_type(self
.name
)
46 p
['getcontentlanguage'] = None
47 if self
.name
[0] == ".":
49 if not os
.access(self
.fsname
, os
.W_OK
):
56 def sendData(self
, wfile
):
57 """Send the file to the client. Literally."""
58 st
= os
.stat(self
.fsname
)
59 f
= file(self
.fsname
, 'rb')
61 while writ
< st
.st_size
:
64 if len(buf
) == 0: # eof?
73 class DirCollection(FileMember
, Collection
):
75 COLLECTION_MIME_TYPE
= 'httpd/unix-directory'
77 def __init__(self
, fsdir
, virdir
, parent
=None):
78 if not os
.path
.exists(fsdir
):
79 raise "Local directory (fsdir) not found: " + fsdir
80 assert( type(fsdir
) == unicode )
81 assert( type(virdir
) == unicode )
85 if self
.fsname
[-1] != os
.sep
:
86 if self
.fsname
[-1] == '/': # fixup win/dos/mac separators
87 self
.fsname
= self
.fsname
[:-1] + os
.sep
92 if self
.virname
[-1] != '/':
96 self
.type = Member
.M_COLLECTION
99 def getProperties(self
):
100 p
= FileMember
.getProperties(self
) # inherit file properties
101 p
['iscollection'] = 1
102 p
['getcontenttype'] = DirCollection
.COLLECTION_MIME_TYPE
106 def getMembers(self
):
107 """Get immediate members of this collection."""
108 dircache
.reset() # workaround to make sure we also get very recently created files
109 l
= dircache
.listdir(self
.fsname
)[:] # obtain a copy of dirlist
110 dircache
.annotate(self
.fsname
, l
)
114 m
= FileMember(f
, self
) # Member is a file
116 m
= DirCollection(self
.fsname
+ f
, self
.virname
+ f
, self
) # Member is a collection
121 def findMember(self
, name
):
122 """Search for a particular member."""
123 dircache
.reset() # workaround to make sure we also get very recently created files
124 l
= dircache
.listdir(self
.fsname
)[:] # obtain a copy of dirlist
125 dircache
.annotate(self
.fsname
, l
)
126 #print "%s - %s, find %s" % (self.fsname, repr(l), name)
130 return FileMember(name
, self
)
132 return DirCollection(self
.fsname
+ name
, self
.virname
+ name
, self
)
133 elif name
[-1] != '/':
136 return DirCollection(self
.fsname
+ name
, self
.virname
+ name
, self
)
139 def sendData(self
, wfile
):
140 """Send "file" to the client. Since this is a directory, build some arbitrary HTML."""
141 memb
= self
.getMembers()
142 data
= '<html><head><title>%s</title></head><body>' % self
.virname
143 data
+= '<table><tr><th>Name</th><th>Size</th><th>Timestamp</th></tr>'
145 p
= m
.getProperties()
146 if 'getcontentlength' in p
:
147 p
['size'] = int(p
['getcontentlength'])
148 p
['timestamp'] = p
['getlastmodified']
151 p
['timestamp'] = '-DIR-'
152 data
+= '<tr><td>%s</td><td>%d</td><td>%s</td></tr>' % (p
['displayname'], p
['size'], p
['timestamp'])
153 data
+= '</table></body></html>'
157 def recvMember(self
, rfile
, name
, size
, req
):
158 """Receive (save) a member file"""
159 fname
= os
.path
.join(self
.fsname
, name
)
160 f
= file(fname
, 'wb')
164 if size
!= -1 and (bs
> size
-writ
):
171 if size
!= -1 and writ
>= size
:
175 def createSubCollection (self
, name
):
176 dname
= os
.path
.join(self
.fsname
, name
)
178 if os
.path
.exists(dname
):
179 raise CollectionExistsError
181 print "creating new folder '%s'" % dname
185 raise CollectionError
, str(e
)