1
2
3 __all__ = ['SubversionStorage']
4
5 import os, os.path
6
7 import locale
8
9
10 import pysvn
11
12 from amplee.storage import Storage, StorageResourceInfo
13 from amplee.error import UnknownResource
14 from amplee.utils import safe_path_join
15
17 - def __init__(self, repository_uri, working_copy_path, username=None, password=None):
18 """
19 Subversion storage for amplee.
20
21 If the working copy does not exist, the storage will automatically check the
22 repository out.
23
24 Keyword arguments
25 repository_uri -- URI of the subversion repository. It can be a local or remote URL.
26 working_copy_path -- absoulte path to the local working copy
27 username -- if needed by the repository
28 password -- if needed by the repository
29 """
30 self.repository_uri = repository_uri
31 self.working_copy_path = working_copy_path
32
33 self.username = username
34 self.password = password
35
36 locale.setlocale(locale.LC_ALL, '')
37
38 try:
39 client = pysvn.Client()
40 self._set_credentials(client)
41 client.info(self.working_copy_path)
42 except pysvn.ClientError, ce:
43 try:
44 client.checkout(self.repository_uri,
45 self.working_copy_path)
46 except pysvn.ClientError, e:
47 raise OSError("Could not create working copy at %s: %s" % (self.working_copy_path, e))
48
50 if self.username:
51 client.set_default_username(self.username)
52 if self.password:
53 client.set_default_password(self.password)
54
56 """
57 Shutdown the subversion storage.
58 Does nothing effectively.
59 """
60 pass
61
63 """
64 Creates a subdirectory within the the svn working copy
65 If it already exists does nothing. The newly created
66 directory is immediatly checked in.
67
68 Keyword argument
69 collection_name -- name of the directory to create
70 """
71 client = pysvn.Client()
72 self._set_credentials(client)
73 info = self.info(collection_name)
74 resource = client.info(info.key)
75 if not resource:
76 client.mkdir(info.key, "Create %s" % info.key)
77 client.checkin(info.key, "Create %s" % info.key)
78
79 - def info(self, collection_name, resource_name=None):
80 """
81 Returns a StorageResourceInfo which ``key``
82 attribute is set to the absolute path to the
83 given resource or, if not provided, to the
84 collection directory.
85 """
86 p = safe_path_join(self.working_copy_path, collection_name,
87 resource_name)
88
89 return StorageResourceInfo(resource_name, p, collection_name)
90
91 - def get_content(self, info):
92 """
93 Returns the content as a string of the resource found at 'info'.
94 If no resource could be found, amplee.error.UnknownResourcean
95 is raised.
96
97 Keyword arguments
98 info -- as returned by info()
99 """
100 client = pysvn.Client()
101 self._set_credentials(client)
102 path = info.key
103 if isinstance(path, str):
104 path = path.decode('utf-8')
105 resource = client.info(path)
106 if resource:
107 content = client.cat(path)
108 return content
109
110 raise UnknownResource(info.name)
111
122
123 - def put_content(self, info, content, media_type=None, *args, **kwargs):
124 """
125 Set the content at 'info' of the resource.
126
127 Keyword arguments
128 info -- as returned by info()
129
130 content -- data as a string object or file object. In that case
131 content MUST return the full content as a byte string on the read() call
132
133 media_type -- if provided, mime type of the resource as a string object
134 It uses the svn:mime_type property
135 """
136 target = file(info.key, 'wb')
137 if hasattr(content, 'read'):
138 content = content.read()
139 target.write(content)
140 target.close()
141 client = pysvn.Client()
142 self._set_credentials(client)
143 path = info.key
144 if isinstance(path, str):
145 path = path.decode('utf-8')
146 resource = client.info(path)
147 if not resource:
148 client.add(path)
149 else:
150 client.update(path)
151
152 if media_type:
153 client.propset('svn:mime-type', media_type, path)
154
169
170 - def remove_content(self, info):
171 """
172 Remove the resource at 'info'
173
174 Keyword arguments
175 info -- as returned by info()
176 """
177 client = pysvn.Client()
178 self._set_credentials(client)
179 path = info.key
180 if isinstance(path, str):
181 path = path.decode('utf-8')
182 resource = client.info(path)
183 if resource:
184 client.remove(path)
185
194
195 - def persist(self, path_list, msg=None):
196 """
197 Finalize the svn checkin
198
199 Keyword arguments
200 path_list -- list of infos as returned by info() to
201 checkin
202 msg -- string message to provide for the checking
203 It defaults to a simple 'Persist'
204 """
205 if not msg:
206 msg = "Persist"
207
208 if isinstance(msg, str):
209 msg = msg.decode('utf-8')
210
211 client = pysvn.Client()
212 self._set_credentials(client)
213
214 for info in path_list:
215 path = info.key
216 if isinstance(path, str):
217 path = path.decode('utf-8')
218 client.checkin(path, msg)
219
221 """
222 Returns True if the resource at 'info.key' exists. False otherwise.
223
224 Keyword arguments
225 info -- as returned by info()
226 """
227 client = pysvn.Client()
228 self._set_credentials(client)
229 path = info.key
230 if isinstance(path, str):
231 path = path.decode('utf-8')
232 entry = client.info(path)
233 if entry:
234 return True
235 return False
236
237 - def ls(self, collection_name, ext=None):
238 """
239 List all the resources in a collection
240
241 Keyword arguments
242 collection_name -- name of the directory in the working copy
243 """
244 self.create_container(collection_name)
245 info = self.info(collection_name)
246 client = pysvn.Client()
247 self._set_credentials(client)
248 path = info.key
249 if isinstance(path, str):
250 path = path.decode('utf-8')
251 results = client.ls(path)
252
253 members = {}
254 for result in results:
255 name = os.path.basename(result['name'])
256 if ext:
257 if name.endswith(ext):
258 members[name] = StorageResourceInfo(name, result,
259 collection_name)
260
261 else:
262 members[name] = StorageResourceInfo(name, result, collection_name)
263
264 return members
265
266 - def ils(self, collection_name, ext=None):
267 """
268 List all the resources in a collection
269
270 Keyword arguments
271 collection_name -- name of the directory in the working copy
272 """
273 info = self.info(collection_name)
274 client = pysvn.Client()
275 self._set_credentials(client)
276 path = info.key
277 if isinstance(path, str):
278 path = path.decode('utf-8')
279 results = client.ls(path)
280
281 for result in results:
282 name = os.path.basename(result['name'])
283 if ext:
284 if name.endswith(ext):
285 yield name, StorageResourceInfo(name, result, collection_name)
286
287 else:
288 yield name, StorageResourceInfo(name, result, collection_name)
289
290 raise StopIteration()
291