2
2
3
3
import errno
4
4
import os
5
+ import subprocess
5
6
import uuid
6
7
7
8
from atomicwrites import atomic_write
@@ -35,13 +36,15 @@ class FilesystemStorage(Storage):
35
36
storage_name = 'filesystem'
36
37
_repr_attributes = ('path' ,)
37
38
38
- def __init__ (self , path , fileext , encoding = 'utf-8' , ** kwargs ):
39
+ def __init__ (self , path , fileext , encoding = 'utf-8' , post_hook = None ,
40
+ ** kwargs ):
39
41
super (FilesystemStorage , self ).__init__ (** kwargs )
40
42
path = expand_path (path )
41
43
checkdir (path , create = False )
42
44
self .path = path
43
45
self .encoding = encoding
44
46
self .fileext = fileext
47
+ self .post_hook = post_hook
45
48
46
49
@classmethod
47
50
def discover (cls , path , ** kwargs ):
@@ -103,7 +106,7 @@ def upload(self, item):
103
106
104
107
try :
105
108
href = self ._deterministic_href (item )
106
- return self ._upload_impl (item , href )
109
+ fpath , etag = self ._upload_impl (item , href )
107
110
except OSError as e :
108
111
if e .errno in (
109
112
errno .ENAMETOOLONG , # Unix
@@ -112,16 +115,20 @@ def upload(self, item):
112
115
logger .debug ('UID as filename rejected, trying with random '
113
116
'one.' )
114
117
href = self ._random_href ()
115
- return self ._upload_impl (item , href )
118
+ fpath , etag = self ._upload_impl (item , href )
116
119
else :
117
120
raise
118
121
122
+ if self .post_hook :
123
+ self ._run_post_hook (fpath )
124
+ return href , etag
125
+
119
126
def _upload_impl (self , item , href ):
120
127
fpath = self ._get_filepath (href )
121
128
try :
122
129
with atomic_write (fpath , mode = 'wb' , overwrite = False ) as f :
123
130
f .write (item .raw .encode (self .encoding ))
124
- return href , get_etag_from_fileobject (f )
131
+ return fpath , get_etag_from_fileobject (f )
125
132
except OSError as e :
126
133
if e .errno == errno .EEXIST :
127
134
raise exceptions .AlreadyExistingError (item )
@@ -141,7 +148,11 @@ def update(self, href, item, etag):
141
148
142
149
with atomic_write (fpath , mode = 'wb' , overwrite = True ) as f :
143
150
f .write (item .raw .encode (self .encoding ))
144
- return get_etag_from_fileobject (f )
151
+ etag = get_etag_from_fileobject (f )
152
+
153
+ if self .post_hook :
154
+ self ._run_post_hook (fpath )
155
+ return etag
145
156
146
157
def delete (self , href , etag ):
147
158
fpath = self ._get_filepath (href )
@@ -151,3 +162,11 @@ def delete(self, href, etag):
151
162
if etag != actual_etag :
152
163
raise exceptions .WrongEtagError (etag , actual_etag )
153
164
os .remove (fpath )
165
+
166
+ def _run_post_hook (self , fpath ):
167
+ logger .info ('Calling post_hook={} with argument={}' .format (
168
+ self .post_hook , fpath ))
169
+ try :
170
+ subprocess .call ([self .post_hook , fpath ])
171
+ except OSError :
172
+ logger .exception ('Error executing external hook.' )
0 commit comments