@@ -3,7 +3,7 @@ DjangoDav
3
3
4
4
Production ready WebDav extension for Django.
5
5
6
- .. image :: https://travis-ci.org/meteozond /djangodav.svg
6
+ .. image :: https://travis-ci.org/anx-ckreuzberger /djangodav.svg
7
7
8
8
Motivation
9
9
----------
@@ -13,13 +13,52 @@ machine access to it. Most popular production ready tools provide json based api
13
13
advantages and disadvantages.
14
14
15
15
WebDav today is a standard for cooperative document management. Its clients are built in the modern operation systems
16
- and supported by the world popular services. But it very important to remember that it's not only about file storage,
16
+ and supported by the world popular services. But it is very important to remember that it's not only about file storage,
17
17
WebDab provides a set of methods to deal with tree structured objects of any kind.
18
18
19
19
Providing WebDav access to Django resources opens new horizons for building Web2.0 apps, with inplace edition and
20
20
providing native operation system access to the stored objects.
21
21
22
22
23
+ Example App
24
+ -----------
25
+
26
+ An example app is provided `at another repository <https://github.com/anx-ckreuzberger/djangodav-example-app >`_.
27
+
28
+ For a quick example please look at the code at the bottom of this readme.
29
+
30
+
31
+ Development & Contributions
32
+ ---------------------------
33
+
34
+ - Create a virtual environment: ``virtualenv -p python3 env ``
35
+ - Activate virtual environment: ``source env/bin/activate ``
36
+ - Install dependencies: ``pip install requirements.txt ``
37
+ - Edit Source Code and make a Pull Request :)
38
+
39
+
40
+ Contributions within this repository
41
+ ------------------------------------
42
+
43
+ - Cleanup
44
+ - Django 1.11+ compatibility
45
+ - Python3 compatibility
46
+ - Replaced `vulnerable lxml.etree.parse function <https://blog.python.org/2013/02/announcing-defusedxml-fixes-for-xml.html >`_ with ``defusedxml.lxml.parse ``
47
+ - Documentation
48
+ - Pep8/Pycodestyle fixes
49
+
50
+
51
+ Original Source
52
+ ---------------
53
+
54
+ The original source code is from the following repositories
55
+
56
+ - `djangodav by TZanke <https://github.com/TZanke/djangodav >`_
57
+ - `djangodav by MnogoByte <https://github.com/MnogoByte/djangodav >`_
58
+ - `django-webdav by sirmmo <https://github.com/sirmmo/django-webdav >`_
59
+
60
+
61
+
23
62
Difference with SmartFile django-webdav
24
63
---------------------------------------
25
64
@@ -43,19 +82,29 @@ Added FSResource and DBResource to provide file system and data base access.
43
82
Xml library usage is replaced with lxml to achieve proper xml generation code readability.
44
83
45
84
46
- How to create simple filesystem webdav resource
47
- -----------------------------------------------
85
+ Basic Authentication on Windows
86
+ -------------------------------
48
87
49
- 1. Create resource.py
50
- ~~~~~~~~~~~~~~~~~~~~~
88
+ Be careful when using Basic Authentication on Windows, as it is not enabled by default (for non SSL sites). You can
89
+ either set ``BasicAuthLevel `` to ``2 `` in the `Windows Registry <http://www.windowspage.de/tipps/022703.html >`_ , or
90
+ just make sure your site uses SSL and has a valid SSL certificate.
91
+
92
+
93
+ Example 1: Create a simple filesystem webdav resource
94
+ -----------------------------------------------------
95
+
96
+ This will just host the provided directory ``/path/to/folder ``, without any permission handling.
97
+
98
+ 1. Create resources.py
99
+ ~~~~~~~~~~~~~~~~~~~~~~
51
100
52
101
.. code :: python
53
102
54
103
from django.conf import settings
55
104
from djangodav.base.resources import MetaEtagMixIn
56
105
from djangodav.fs.resources import DummyFSDAVResource
57
106
58
- class MyDavResource (MetaEtagMixIn , DummyFSDAVResource ):
107
+ class MyFSDavResource (MetaEtagMixIn , DummyFSDAVResource ):
59
108
root = ' /path/to/folder'
60
109
61
110
@@ -70,9 +119,143 @@ How to create simple filesystem webdav resource
70
119
71
120
from django.conf.urls import patterns
72
121
73
- from .resource import MyDavResource
122
+ from .resource import MyFSDavResource
74
123
124
+ # include fsdav/webdav without trailing slash (do not use a slash like in 'fsdav/(?P<path>.*)$')
75
125
urlpatterns = patterns(' ' ,
76
- (r ' ^ fsdav( ?P<path> . * ) $ ' , DavView.as_view(resource_class = MyDavResource , lock_class = DummyLock,
126
+ (r ' ^ fsdav( ?P<path> . * ) $ ' , DavView.as_view(resource_class = MyFSDavResource , lock_class = DummyLock,
77
127
acl_class = FullAcl)),
78
128
)
129
+
130
+
131
+ Example 2: Create a simple database webdav resource
132
+ ---------------------------------------------------
133
+
134
+ This example is a bit more complex, as it requires two Django models and some handling.
135
+
136
+ 1. Create the following models in models.py
137
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
138
+
139
+ .. code :: python
140
+
141
+ from django.db import models
142
+ from django.utils.timezone import now
143
+
144
+
145
+ class BaseWebDavModel (models .Model ):
146
+ name = models.CharField(max_length = 255 )
147
+ created = models.DateTimeField(default = now)
148
+ modified = models.DateTimeField(default = now)
149
+
150
+ class Meta :
151
+ abstract = True
152
+
153
+
154
+ class CollectionModel (BaseWebDavModel ):
155
+ parent = models.ForeignKey(' self' , blank = True , null = True )
156
+ size = 0
157
+
158
+ class Meta :
159
+ unique_together = ((' parent' , ' name' ),)
160
+
161
+ def __str__ (self ):
162
+ return " Collection {} " .format(self .name)
163
+
164
+
165
+ class ObjectModel (BaseWebDavModel ):
166
+ parent = models.ForeignKey(CollectionModel, blank = True , null = True )
167
+ path = models.FileField(max_length = 255 )
168
+ size = models.IntegerField(default = 0 )
169
+ md5 = models.CharField(max_length = 255 )
170
+
171
+ class Meta :
172
+ unique_together = ((' parent' , ' name' ),)
173
+
174
+ def __str__ (self ):
175
+ return " Object {} " .format(self .name)
176
+
177
+
178
+
179
+ 2. Create resources.py
180
+ ~~~~~~~~~~~~~~~~~~~~~~
181
+
182
+ .. code :: python
183
+
184
+ from hashlib import md5
185
+
186
+ from django.conf import settings
187
+ from djangodav.db.resources import NameLookupDBDavMixIn, BaseDBDavResource
188
+
189
+ from .models import CollectionModel, ObjectModel
190
+
191
+ class MyDBDavResource (NameLookupDBDavMixIn , BaseDBDavResource ):
192
+ collection_model = CollectionModel
193
+ object_model = ObjectModel
194
+
195
+ root = " /path/to/folder"
196
+
197
+ def write (self , request , temp_file = None ):
198
+ size = len (request.body)
199
+
200
+ # calculate a hashsum of the request (ToDo: probably need to replace this with SHA1 or such, and maybe add a salt)
201
+ hashsum = md5(request.body).hexdigest()
202
+
203
+ # save the file
204
+ new_path = os.path.join(settings.MEDIA_ROOT , self .displayname)
205
+
206
+ f = open (new_path, ' wb' )
207
+ f.write(request.body)
208
+ f.close()
209
+
210
+ if not self .exists:
211
+ obj = self .object_model(
212
+ name = self .displayname,
213
+ parent = self .get_parent().obj,
214
+ md5 = hashsum,
215
+ size = size
216
+ )
217
+
218
+ obj.path.name = new_path
219
+
220
+ obj.save()
221
+
222
+ return
223
+
224
+ self .obj.size = size
225
+ self .obj.modified = now()
226
+ self .obj.path.name = new_path
227
+ self .obj.md5 = hashsum
228
+
229
+ self .obj.save(update_fields = [' path' , ' size' , ' modified' , ' md5' ])
230
+
231
+ def read (self ):
232
+ return self .obj.path
233
+
234
+ @ property
235
+ def etag (self ):
236
+ return self .obj.md5
237
+
238
+ @ property
239
+ def getcontentlength (self ):
240
+ return self .obj.size
241
+
242
+
243
+
244
+ 3. Register WebDav view in urls.py
245
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
246
+
247
+ .. code :: python
248
+
249
+ from djangodav.acls import FullAcl
250
+ from djangodav.locks import DummyLock
251
+ from djangodav.views import DavView
252
+
253
+ from django.conf.urls import patterns
254
+
255
+ from .resource import MyDBDavResource
256
+
257
+ # include fsdav/webdav without trailing slash (do not use a slash like in 'dbdav/(?P<path>.*)$')
258
+ urlpatterns = patterns(' ' ,
259
+ (r ' ^ dbdav( ?P<path> . * ) $ ' , DavView.as_view(resource_class = MyFSDavResource, lock_class = DummyLock,
260
+ acl_class = FullAcl)),
261
+ )
0 commit comments