Switch to unified view

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):