~ubuntu-branches/debian/sid/trac-bzr/sid

« back to all changes in this revision

Viewing changes to tracbzr/backend.py

  • Committer: Package Import Robot
  • Author(s): Jelmer Vernooij
  • Date: 2012-03-12 15:24:14 UTC
  • mfrom: (1.1.9)
  • Revision ID: package-import@ubuntu.com-20120312152414-yi6wngu8vgm266fp
Tags: 0.4.2+bzr125-1
* New upstream snapshot.
* Bump standards version to 3.9.3 (no changes).
* Use DEP-5 for copyright file.

Show diffs side-by-side

added added

removed removed

Lines of Context:
8
8
# Copyright (C) 2006 Marien Zwart <marienz@gentoo.org>
9
9
# Copyright (C) 2006,2007 Panoramic Feedback <abentley@panoramicfeedback.com>
10
10
# Copyright (C) 2006,2008,2009 Jelmer Vernooij <jelmer@samba.org>
11
 
# Copyright (C) 2009,2010 Martin von Gagern <Martin.vGagern@gmx.net>
 
11
# Copyright (C) 2009,2010,2011 Martin von Gagern <Martin.vGagern@gmx.net>
12
12
# All rights reserved.
13
13
#
14
14
# This program is free software; you can redistribute it and/or modify
38
38
import urllib
39
39
import re
40
40
import fnmatch
 
41
import pkg_resources
 
42
import sys
41
43
 
42
44
import trac
43
45
from trac import versioncontrol, core, config, mimeview, util, wiki
44
 
from trac.web.chrome import Chrome
 
46
from trac.web import chrome
 
47
from trac.web.chrome import Chrome, ITemplateProvider
45
48
from trac.util.html import html, Markup
 
49
from trac.util.text import exception_to_unicode
46
50
 
47
51
trac_version = (int(trac.__version__[0]), int(trac.__version__[2:4]))
48
52
 
64
68
    def trac_timestamp(timestamp):
65
69
        return datetime.datetime.fromtimestamp(timestamp, utc)
66
70
    from trac.versioncontrol.web_ui.browser import IPropertyRenderer
 
71
    from trac.admin import IAdminPanelProvider
67
72
else:
68
73
    def trac_timestamp(timestamp):
69
74
        return timestamp
70
 
    class IPropertyRenderer(core.Interface):
 
75
    class DummyInterface(core.Interface):
71
76
        pass
 
77
    IPropertyRenderer = DummyInterface
 
78
    IAdminPanelProvider = DummyInterface
72
79
 
73
80
 
74
81
from bzrlib import (
79
86
    osutils,
80
87
    revision,
81
88
    transport,
 
89
    urlutils,
82
90
)
83
91
import bzrlib.api
84
92
from bzrlib.revision import (
104
112
                self.log.warn(e)
105
113
                tracbzr_version = 'unknown'
106
114
            self.env.systeminfo.append(('TracBzr', tracbzr_version))
 
115
            self.env.systeminfo.append(('FSEncoding',
 
116
                                        sys.getfilesystemencoding()))
107
117
 
108
118
    def get_supported_types(self):
109
119
        """Support for `repository_type = bzr`"""
203
213
    core.implements(IPropertyRenderer)
204
214
 
205
215
    def match_property(self, name, mode):
206
 
        if name == 'parents' and mode == 'revprop':
 
216
        if name in ('parents', 'bugs') and mode == 'revprop':
207
217
            return 4
208
218
        return 0
209
219
 
231
241
                                       href=context.href.changeset(p, path))))
232
242
                    for p in props[name].split('\n')]))
233
243
            return content
 
244
        
 
245
        if name == 'bugs' and mode == 'revprop':
 
246
            url, action = props[name].split(' ', 1)
 
247
            reMyTicket = self.localTicketPattern(context.href)
 
248
            if reMyTicket:
 
249
                m = reMyTicket.match(url)
 
250
                if m:
 
251
                    number = m.group(1)
 
252
                    return html.a('#' + number, href=url) + ' ' + action
 
253
            return html.a(url, href=url) + ' ' + action
 
254
 
 
255
    def localTicketPattern(self, href):
 
256
        """Find a regular expression matching tickets URLs from the
 
257
        current Trac environment."""
 
258
 
 
259
        default_ports = { 'http': ':80', 'https': ':443' }
 
260
        pat = self.env.abs_href.ticket(1234)
 
261
        m = re.match(r'^(https?)://([^/:]*)(:[0-9]+)?(/.*)1234$', pat)
 
262
        if not m:
 
263
            return None
 
264
        scheme, host, port, path = m.groups('')
 
265
        if port == default_ports[scheme]:
 
266
            port = ''
 
267
        pat = (r'^https?://%s%s%s(\d+)$' %
 
268
               tuple(re.escape(x) for x in (host, port, path)))
 
269
        pat = re.compile(pat)
 
270
        return pat
234
271
 
235
272
 
236
273
class LockedBranches(object):
458
495
        return branch
459
496
 
460
497
    def get_containing_branch(self, location):
461
 
        branch, relpath = containing_branch(self.root_transport, location)
462
 
        real_location = location[:-len(relpath)].rstrip('/')
463
 
        if real_location not in self._branch_cache:
464
 
            self._branch_cache[real_location] = BranchCache(self, branch)
 
498
        locurl = urlutils.escape(location)
 
499
        url = urlutils.joinpath(self.root_transport.base, locurl)
 
500
        my_bzrdir, relpath = bzrdir.BzrDir.open_containing(
 
501
            url, possible_transports=[self.root_transport])
 
502
        if not location.endswith(relpath):
 
503
            raise core.TracError('%r does not end with %r'
 
504
                                 % (location, relpath))
 
505
        branch_location = location[:-len(relpath)].rstrip('/')
 
506
        if branch_location not in self._branch_cache:
 
507
            branch = my_bzrdir.open_branch()
 
508
            self._branch_cache[branch_location] = BranchCache(self, branch)
465
509
            self._locked_branches.append(branch)
466
510
        # return the cached version, possibly throwing away the one we just
467
511
        # retrieved.
468
 
        return self._branch_cache[real_location].branch, relpath
 
512
        return self._branch_cache[branch_location].branch, relpath
469
513
 
470
514
    def get_branches(self):
471
515
        """Get an ordered list of all branches in the repository.
669
713
            heads = branch2.repository.get_graph().heads(both)
670
714
        else:
671
715
            heads = both
672
 
        if len(s) == 1:
 
716
        if len(heads) == 1:
673
717
            return rrev2 in heads
674
718
        # Bah, unrelated revisions. Fall back to comparing timestamps.
675
719
        return (branch1.repository.get_revision(rrev1).timestamp <
820
864
    def get_properties(self):
821
865
        return {}
822
866
 
 
867
    MAX_SYMLINK_STEPS = 10
 
868
 
823
869
    def get_entries(self):
824
870
        result = []
825
871
        for name in self.transport.list_dir(''):
826
872
            if name == '.bzr':
827
873
                continue
828
 
            stat_mode = self.transport.stat(name).st_mode
829
 
            kind = osutils.file_kind_from_stat_mode(stat_mode)
 
874
            child_path = name
 
875
            try:
 
876
                for step in xrange(self.MAX_SYMLINK_STEPS + 1):
 
877
                    stat_mode = self.transport.stat(child_path).st_mode
 
878
                    kind = osutils.file_kind_from_stat_mode(stat_mode)
 
879
                    if kind != 'symlink':
 
880
                        break
 
881
                    child_path = osutils.pathjoin(osutils.dirname(child_path),
 
882
                                                  self.transport.readlink(name))
 
883
            except errors.NoSuchFile:
 
884
                continue
830
885
            if not kind == 'directory':
831
886
                continue
832
887
            child_path = osutils.pathjoin(self.path, name)
1339
1394
                   self.bzr_repo.string_rev(self.branch, parent_revid))
1340
1395
 
1341
1396
 
1342
 
def containing_branch(transport, path):
1343
 
    child_transport = transport.clone(path)
1344
 
    my_bzrdir, relpath = \
1345
 
        bzrdir.BzrDir.open_containing_from_transport(child_transport)
1346
 
    return my_bzrdir.open_branch(), relpath
1347
 
 
1348
 
 
1349
1397
class BranchCache(object):
1350
1398
    
1351
1399
    def __init__(self, bzr_repo, branch):
1459
1507
        self.revcache[entry.file_id] = ancestry[best]
1460
1508
        return best
1461
1509
 
 
1510
 
 
1511
class BzrAdmin(core.Component):
 
1512
    """Adds bzr-related panels to the admin web interface."""
 
1513
 
 
1514
    core.implements(IAdminPanelProvider, ITemplateProvider)
 
1515
 
 
1516
    primary_branches = BzrRepository.primary_branches
 
1517
 
 
1518
    # IAdminPanelProvider
 
1519
 
 
1520
    def get_admin_panels(self, req):
 
1521
        """Return a list of available admin panels.
 
1522
        
 
1523
        The items returned by this function must be tuples of the form
 
1524
        `(category, category_label, page, page_label)`.
 
1525
        """
 
1526
        if 'TRAC_ADMIN' in req.perm:
 
1527
            yield ('tracbzr', 'Bazaar', 'basics', 'Basic bzr settings')
 
1528
 
 
1529
    def render_admin_panel(self, req, category, page, path_info):
 
1530
        """Process a request for an admin panel.
 
1531
        
 
1532
        This function should return a tuple of the form `(template, data)`,
 
1533
        where `template` is the name of the template to use and `data` is the
 
1534
        data to be passed to the template.
 
1535
        """
 
1536
 
 
1537
        if category == 'tracbzr':
 
1538
            if page == 'basics':
 
1539
                req.perm.require('TRAC_ADMIN')
 
1540
 
 
1541
                if req.method == 'POST':
 
1542
                    self.env.config.set(config_section, 'primary_branches',
 
1543
                                        req.args.get('primary_branches'))
 
1544
                    self._save_config(req)
 
1545
                    req.redirect(req.href.admin(category, page))
 
1546
                branches = {
 
1547
                    'primary': ','.join(self.primary_branches)
 
1548
                    }
 
1549
                data = { 'branches': branches }
 
1550
                return 'tracbzr_admin_basics.html', data
 
1551
 
 
1552
    def _save_config(self, req):
 
1553
        """Try to save the config, and display either a success notice or a
 
1554
        failure warning.
 
1555
        """
 
1556
        try:
 
1557
            self.config.save()
 
1558
        except Exception, e:
 
1559
            self.log.error('Error writing to trac.ini: %s',
 
1560
                           exception_to_unicode(e))
 
1561
            chrome.add_warning(req, 'Error writing to trac.ini, make sure it is '
 
1562
                               'writable by the web server. Your changes have not '
 
1563
                               'been saved.')
 
1564
        else:
 
1565
            chrome.add_notice(req, 'Your changes have been saved.')
 
1566
 
 
1567
    # ITemplateProvider
 
1568
 
 
1569
    def get_htdocs_dirs(self):
 
1570
        return []
 
1571
 
 
1572
    def get_templates_dirs(self):
 
1573
        return [pkg_resources.resource_filename('tracbzr.backend', 'templates')]