|
a/Allura/allura/model/repo.py |
|
b/Allura/allura/model/repo.py |
|
... |
|
... |
15 |
from ming.utils import LazyProperty
|
15 |
from ming.utils import LazyProperty
|
16 |
from ming.orm import mapper, session
|
16 |
from ming.orm import mapper, session
|
17 |
|
17 |
|
18 |
from allura.lib import utils
|
18 |
from allura.lib import utils
|
19 |
from allura.lib import helpers as h
|
19 |
from allura.lib import helpers as h
|
|
|
20 |
from allura.lib.patience import SequenceMatcher
|
20 |
|
21 |
|
21 |
from .auth import User
|
22 |
from .auth import User
|
22 |
from .session import main_doc_session, project_doc_session
|
23 |
from .session import main_doc_session, project_doc_session
|
23 |
from .session import repository_orm_session
|
24 |
from .session import repository_orm_session
|
24 |
|
25 |
|
|
... |
|
... |
229 |
return result
|
230 |
return result
|
230 |
|
231 |
|
231 |
def context(self):
|
232 |
def context(self):
|
232 |
result = dict(prev=None, next=None)
|
233 |
result = dict(prev=None, next=None)
|
233 |
if self.parent_ids:
|
234 |
if self.parent_ids:
|
234 |
result['prev'] = self.query.get(_id=self.parent_ids[0])
|
235 |
result['prev'] = self.query.find(dict(_id={'$in': self.parent_ids })).all()
|
235 |
if self.child_ids:
|
236 |
if self.child_ids:
|
236 |
result['next'] = self.query.get(_id=self.child_ids[0])
|
237 |
result['next'] = self.query.find(dict(_id={'$in': self.child_ids })).all()
|
237 |
return result
|
238 |
return result
|
|
|
239 |
|
|
|
240 |
@LazyProperty
|
|
|
241 |
def diffs(self):
|
|
|
242 |
di = DiffInfoDoc.m.get(_id=self._id)
|
|
|
243 |
if di is None:
|
|
|
244 |
return dict(added=[], removed=[], changed=[], copied=[])
|
|
|
245 |
added = []
|
|
|
246 |
removed = []
|
|
|
247 |
changed = []
|
|
|
248 |
copied = []
|
|
|
249 |
for change in di.differences:
|
|
|
250 |
print change.name
|
|
|
251 |
if change.rhs_id is None:
|
|
|
252 |
removed.append(change.name)
|
|
|
253 |
elif change.lhs_id is None:
|
|
|
254 |
added.append(change.name)
|
|
|
255 |
else:
|
|
|
256 |
changed.append(change.name)
|
|
|
257 |
return dict(
|
|
|
258 |
added=added, removed=removed,
|
|
|
259 |
changed=changed, copied=copied)
|
|
|
260 |
|
|
|
261 |
def get_path(self, path):
|
|
|
262 |
parts = path.split('/')[1:]
|
|
|
263 |
cur = self.tree
|
|
|
264 |
for part in parts:
|
|
|
265 |
cur = cur[part]
|
|
|
266 |
return cur
|
238 |
|
267 |
|
239 |
class Tree(RepoObject):
|
268 |
class Tree(RepoObject):
|
240 |
# Ephemeral attrs
|
269 |
# Ephemeral attrs
|
241 |
repo=None
|
270 |
repo=None
|
242 |
commit=None
|
271 |
commit=None
|
|
... |
|
... |
256 |
sha_obj.update(line)
|
285 |
sha_obj.update(line)
|
257 |
return sha_obj.hexdigest()
|
286 |
return sha_obj.hexdigest()
|
258 |
|
287 |
|
259 |
def __getitem__(self, name):
|
288 |
def __getitem__(self, name):
|
260 |
obj = self.by_name[name]
|
289 |
obj = self.by_name[name]
|
261 |
if obj['type'] == 'blob': return obj
|
290 |
if obj['type'] == 'blob':
|
|
|
291 |
return Blob(self, name, obj['id'])
|
262 |
obj = self.query.get(_id=obj['id'])
|
292 |
obj = self.query.get(_id=obj['id'])
|
263 |
if obj is None:
|
293 |
if obj is None:
|
264 |
oid = self.repo.compute_tree_new(self.commit, self.path() + name + '/')
|
294 |
oid = self.repo.compute_tree_new(self.commit, self.path() + name + '/')
|
265 |
obj = self.query.get(_id=oid)
|
295 |
obj = self.query.get(_id=oid)
|
266 |
if obj is None: raise KeyError, name
|
296 |
if obj is None: raise KeyError, name
|
|
... |
|
... |
280 |
def readme(self):
|
310 |
def readme(self):
|
281 |
'returns (filename, unicode text) if a readme file is found'
|
311 |
'returns (filename, unicode text) if a readme file is found'
|
282 |
for x in self.blob_ids:
|
312 |
for x in self.blob_ids:
|
283 |
if README_RE.match(x.name):
|
313 |
if README_RE.match(x.name):
|
284 |
name = x.name
|
314 |
name = x.name
|
285 |
obj = Object(
|
315 |
blob = self[name]
|
286 |
object_id=x.id,
|
|
|
287 |
path=lambda:self.path() + x['name'],
|
|
|
288 |
commit=Object(
|
|
|
289 |
object_id=self.commit._id))
|
|
|
290 |
text = self.repo.open_blob(obj).read()
|
|
|
291 |
return (x.name, h.really_unicode(text))
|
316 |
return (x.name, h.really_unicode(blob.text))
|
|
|
317 |
return None, None
|
292 |
|
318 |
|
293 |
def ls(self):
|
319 |
def ls(self):
|
294 |
# Load last commit info
|
320 |
# Load last commit info
|
295 |
oids = [ x.id for x in chain(self.tree_ids, self.blob_ids, self.other_ids) ]
|
321 |
oids = [ x.id for x in chain(self.tree_ids, self.blob_ids, self.other_ids) ]
|
296 |
lc_index = dict(
|
322 |
lc_index = dict(
|
|
... |
|
... |
300 |
object_id={'$in': oids})))
|
326 |
object_id={'$in': oids})))
|
301 |
results = []
|
327 |
results = []
|
302 |
def _get_last_commit(oid):
|
328 |
def _get_last_commit(oid):
|
303 |
lc = lc_index.get(oid)
|
329 |
lc = lc_index.get(oid)
|
304 |
if lc is None:
|
330 |
if lc is None:
|
|
|
331 |
import pdb; pdb.set_trace()
|
305 |
lc = dict(
|
332 |
lc = dict(
|
306 |
author=None,
|
333 |
author=None,
|
307 |
author_email=None,
|
334 |
author_email=None,
|
308 |
author_url=None,
|
335 |
author_url=None,
|
309 |
date=None,
|
336 |
date=None,
|
|
... |
|
... |
342 |
def url(self):
|
369 |
def url(self):
|
343 |
return self.commit.url() + 'tree' + self.path()
|
370 |
return self.commit.url() + 'tree' + self.path()
|
344 |
|
371 |
|
345 |
@LazyProperty
|
372 |
@LazyProperty
|
346 |
def by_name(self):
|
373 |
def by_name(self):
|
347 |
d = dict((x.name, x) for x in self.other_ids)
|
374 |
d = Object((x.name, x) for x in self.other_ids)
|
348 |
d.update(
|
375 |
d.update(
|
349 |
(x.name, dict(x, type='tree'))
|
376 |
(x.name, Object(x, type='tree'))
|
350 |
for x in self.tree_ids)
|
377 |
for x in self.tree_ids)
|
351 |
d.update(
|
378 |
d.update(
|
352 |
(x.name, dict(x, type='blob'))
|
379 |
(x.name, Object(x, type='blob'))
|
353 |
for x in self.blob_ids)
|
380 |
for x in self.blob_ids)
|
354 |
return d
|
381 |
return d
|
355 |
|
382 |
|
356 |
def is_blob(self, name):
|
383 |
def is_blob(self, name):
|
357 |
return self.by_name[name]['type'] == 'blob'
|
384 |
return self.by_name[name]['type'] == 'blob'
|
|
|
385 |
|
|
|
386 |
def get_blob(self, name):
|
|
|
387 |
x = self.by_name[name]
|
|
|
388 |
return Blob(self, name, x.id)
|
|
|
389 |
|
|
|
390 |
class Blob(object):
|
|
|
391 |
'''Lightweight object representing a file in the repo'''
|
|
|
392 |
|
|
|
393 |
def __init__(self, tree, name, _id):
|
|
|
394 |
self._id = _id
|
|
|
395 |
self.tree = tree
|
|
|
396 |
self.name = name
|
|
|
397 |
self.repo = tree.repo
|
|
|
398 |
self.commit = tree.commit
|
|
|
399 |
|
|
|
400 |
def path(self):
|
|
|
401 |
return self.tree.path() + h.really_unicode(self.name)
|
|
|
402 |
|
|
|
403 |
def url(self):
|
|
|
404 |
return self.tree.url() + h.really_unicode(self.name)
|
|
|
405 |
|
|
|
406 |
@LazyProperty
|
|
|
407 |
def prev_commit(self):
|
|
|
408 |
lc = self.repo.get_last_commit(self)
|
|
|
409 |
if lc['id']:
|
|
|
410 |
last_commit = self.repo.commit(lc.id)
|
|
|
411 |
if last_commit.parent_ids:
|
|
|
412 |
return self.repo.commit(last_commit.parent_ids[0])
|
|
|
413 |
return None
|
|
|
414 |
|
|
|
415 |
@LazyProperty
|
|
|
416 |
def next_commit(self):
|
|
|
417 |
try:
|
|
|
418 |
path = self.path()
|
|
|
419 |
cur = self.commit
|
|
|
420 |
next = cur.context()['next']
|
|
|
421 |
while next:
|
|
|
422 |
cur = next[0]
|
|
|
423 |
next = cur.context()['next']
|
|
|
424 |
other_blob = cur.get_path(path)
|
|
|
425 |
if other_blob is None or other_blob._id != self._id:
|
|
|
426 |
return cur
|
|
|
427 |
except:
|
|
|
428 |
log.exception('Lookup prev_commit')
|
|
|
429 |
return None
|
|
|
430 |
|
|
|
431 |
@LazyProperty
|
|
|
432 |
def _content_type_encoding(self):
|
|
|
433 |
return self.repo.guess_type(self.name)
|
|
|
434 |
|
|
|
435 |
@LazyProperty
|
|
|
436 |
def content_type(self):
|
|
|
437 |
return self._content_type_encoding[0]
|
|
|
438 |
|
|
|
439 |
@LazyProperty
|
|
|
440 |
def content_encoding(self):
|
|
|
441 |
return self._content_type_encoding[1]
|
|
|
442 |
|
|
|
443 |
@property
|
|
|
444 |
def has_html_view(self):
|
|
|
445 |
return self.content_type.startswith('text/')
|
|
|
446 |
|
|
|
447 |
@property
|
|
|
448 |
def has_image_view(self):
|
|
|
449 |
return self.content_type.startswith('image/')
|
|
|
450 |
|
|
|
451 |
def context(self):
|
|
|
452 |
path = self.path()
|
|
|
453 |
prev = self.prev_commit
|
|
|
454 |
next = self.next_commit
|
|
|
455 |
if prev is not None: prev = prev.get_path(path)
|
|
|
456 |
if next is not None: next = next.get_path(path)
|
|
|
457 |
return dict(
|
|
|
458 |
prev=prev,
|
|
|
459 |
next=next)
|
|
|
460 |
|
|
|
461 |
def open(self):
|
|
|
462 |
return self.repo.open_blob(self)
|
|
|
463 |
|
|
|
464 |
def __iter__(self):
|
|
|
465 |
return iter(self.open())
|
|
|
466 |
|
|
|
467 |
@LazyProperty
|
|
|
468 |
def text(self):
|
|
|
469 |
return self.open().read()
|
|
|
470 |
|
|
|
471 |
@classmethod
|
|
|
472 |
def diff(cls, v0, v1):
|
|
|
473 |
differ = SequenceMatcher(v0, v1)
|
|
|
474 |
return differ.get_opcodes()
|
358 |
|
475 |
|
359 |
mapper(Commit, CommitDoc, repository_orm_session)
|
476 |
mapper(Commit, CommitDoc, repository_orm_session)
|
360 |
mapper(Tree, TreeDoc, repository_orm_session)
|
477 |
mapper(Tree, TreeDoc, repository_orm_session)
|
361 |
|
478 |
|
362 |
def commitlog(commit_ids, skip=0, limit=sys.maxint):
|
479 |
def commitlog(commit_ids, skip=0, limit=sys.maxint):
|