2
# Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
4
# Permission is hereby granted, free of charge, to any person obtaining a copy
5
# of this software and associated documentation files (the "Software"), to deal
6
# in the Software without restriction, including without limitation the rights
7
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
# copies of the Software, and to permit persons to whom the Software is
9
# furnished to do so, subject to the following conditions:
11
# The above copyright notice and this permission notice shall be included in all
12
# copies or substantial portions of the Software.
14
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
# DRI: Wilfredo Sanchez, wsanchez@apple.com
26
WebDAV-aware static resources.
31
from twisted.python import log
32
from twisted.web2.static import File
33
from twisted.web2.dav import davxml
34
from twisted.web2.dav.idav import IDAVResource
35
from twisted.web2.dav.resource import DAVResource
36
from twisted.web2.dav.util import bindMethods
39
from twisted.web2.dav.xattrprops import xattrPropertyStore as DeadPropertyStore
41
log.msg("No dead property store available; using nonePropertyStore.")
42
log.msg("Setting of dead properties will not be allowed.")
43
from twisted.web2.dav.noneprops import NonePropertyStore as DeadPropertyStore
45
class DAVFile (DAVResource, File):
47
WebDAV-accessible File resource.
49
Extends twisted.web2.static.File to handle WebDAV methods.
51
def __init__(self, path,
52
defaultType="text/plain",
55
@param path: the path of the file backing this resource.
56
@param defaultType: the default mime type (as a string) for this
57
resource and (eg. child) resources derived from it.
58
@param indexNames: a sequence of index file names.
59
@param acl: an L{IDAVAccessControlList} with the .
61
super(DAVFile, self).__init__(path,
62
defaultType = defaultType,
65
indexNames = indexNames)
68
return "<%s: %s>" % (self.__class__.__name__, self.fp.path)
74
def davComplianceClasses(self):
75
return ("1",) # Add "2" when we have locking
77
def deadProperties(self):
78
if not hasattr(self, "_dead_properties"):
79
self._dead_properties = DeadPropertyStore(self)
80
return self._dead_properties
82
def isCollection(self):
84
See L{IDAVResource.isCollection}.
86
for child in self.listChildren(): return True
87
return self.fp.isdir()
89
def findChildren(self, depth):
91
See L{IDAVResource.findChildren}.
93
assert depth in ("0", "1", "infinity"), "Invalid depth: %s" % (depth,)
94
if depth != "0" and self.isCollection():
95
for name in self.listChildren():
97
child = IDAVResource(self.getChild(name))
101
if child is not None:
102
if child.isCollection():
103
yield (child, name + "/")
104
if depth == "infinity":
105
for grandchild in child.findChildren(depth):
106
yield (grandchild[0], name + "/" + grandchild[1])
114
def supportedPrivileges(self):
115
if not hasattr(DAVFile, "_supportedPrivilegeSet"):
116
DAVFile._supportedPrivilegeSet = davxml.SupportedPrivilegeSet(
117
davxml.SupportedPrivilege(
118
davxml.Privilege(davxml.All()),
119
davxml.Description("all privileges", **{"xml:lang": "en"}),
120
davxml.SupportedPrivilege(
121
davxml.Privilege(davxml.Read()),
122
davxml.Description("read resource", **{"xml:lang": "en"}),
124
davxml.SupportedPrivilege(
125
davxml.Privilege(davxml.Write()),
126
davxml.Description("write resource", **{"xml:lang": "en"}),
127
davxml.SupportedPrivilege(
128
davxml.Privilege(davxml.WriteProperties()),
129
davxml.Description("write resource properties", **{"xml:lang": "en"}),
131
davxml.SupportedPrivilege(
132
davxml.Privilege(davxml.WriteContent()),
133
davxml.Description("write resource content", **{"xml:lang": "en"}),
135
davxml.SupportedPrivilege(
136
davxml.Privilege(davxml.Bind()),
137
davxml.Description("add child resource", **{"xml:lang": "en"}),
139
davxml.SupportedPrivilege(
140
davxml.Privilege(davxml.Unbind()),
141
davxml.Description("remove child resource", **{"xml:lang": "en"}),
144
davxml.SupportedPrivilege(
145
davxml.Privilege(davxml.Unlock()),
146
davxml.Description("unlock resource without ownership", **{"xml:lang": "en"}),
148
davxml.SupportedPrivilege(
149
davxml.Privilege(davxml.ReadACL()),
150
davxml.Description("read resource access control list", **{"xml:lang": "en"}),
152
davxml.SupportedPrivilege(
153
davxml.Privilege(davxml.WriteACL()),
154
davxml.Description("write resource access control list", **{"xml:lang": "en"}),
156
davxml.SupportedPrivilege(
157
davxml.Privilege(davxml.ReadCurrentUserPrivilegeSet()),
158
davxml.Description("read privileges for current principal", **{"xml:lang": "en"}),
162
return DAVFile._supportedPrivilegeSet
165
# Workarounds for issues with File
168
def ignoreExt(self, ext):
170
Does nothing; doesn't apply to this subclass.
174
def createSimilarFile(self, path):
175
return self.__class__(path, defaultType=self.defaultType, indexNames=self.indexNames[:])
178
# Attach method handlers to DAVFile
181
import twisted.web2.dav.method
183
bindMethods(twisted.web2.dav.method, DAVFile)