~loggerhead-team/loggerhead/trunk-rich

« back to all changes in this revision

Viewing changes to loggerhead/branchview.py

  • Committer: Michael Hudson
  • Date: 2008-06-16 23:39:52 UTC
  • mto: This revision was merged to the branch mainline in revision 164.
  • Revision ID: michael.hudson@canonical.com-20080616233952-lcvy0p3wpsl1ll03
need a better url quoting story than this...

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#
 
2
# Copyright (C) 2006  Robey Pointer <robey@lag.net>
 
3
#
 
4
# This program is free software; you can redistribute it and/or modify
 
5
# it under the terms of the GNU General Public License as published by
 
6
# the Free Software Foundation; either version 2 of the License, or
 
7
# (at your option) any later version.
 
8
#
 
9
# This program is distributed in the hope that it will be useful,
 
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
12
# GNU General Public License for more details.
 
13
#
 
14
# You should have received a copy of the GNU General Public License
 
15
# along with this program; if not, write to the Free Software
 
16
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
17
#
 
18
 
 
19
"""
 
20
collection of configuration and objects related to a bazaar branch.
 
21
"""
 
22
 
 
23
import logging
 
24
import posixpath
 
25
import threading
 
26
import urllib
 
27
 
 
28
import turbogears
 
29
from cherrypy import HTTPRedirect
 
30
 
 
31
from loggerhead import util
 
32
from loggerhead.changecache import FileChangeCache
 
33
from loggerhead.history import History
 
34
from loggerhead.controllers.changelog_ui import ChangeLogUI
 
35
from loggerhead.controllers.atom_ui import AtomUI
 
36
from loggerhead.controllers.revision_ui import RevisionUI
 
37
from loggerhead.controllers.inventory_ui import InventoryUI
 
38
from loggerhead.controllers.annotate_ui import AnnotateUI
 
39
from loggerhead.controllers.download_ui import DownloadUI
 
40
from loggerhead.controllers.bundle_ui import BundleUI
 
41
 
 
42
 
 
43
with_history_lock = util.with_lock('_history_lock', 'History')
 
44
 
 
45
 
 
46
class BranchView (object):
 
47
    def __init__(self, group_name, name, subfolder, absfolder, config,
 
48
                 project_config, root_config):
 
49
        self._group_name = group_name
 
50
        self._name = name
 
51
        self._folder = subfolder
 
52
        self._absfolder = absfolder
 
53
        self._config = config
 
54
        self._project_config = project_config
 
55
        self._root_config = root_config
 
56
        self.log = logging.getLogger('loggerhead.%s' % (name,))
 
57
 
 
58
        # branch history
 
59
        self._history_lock = threading.RLock()
 
60
        self._history = None
 
61
 
 
62
        self.changes = ChangeLogUI(self)
 
63
        self.revision = RevisionUI(self)
 
64
        self.files = InventoryUI(self)
 
65
        self.annotate = AnnotateUI(self)
 
66
        self.download = DownloadUI(self)
 
67
        self.atom = AtomUI(self)
 
68
        self.bundle = BundleUI(self)
 
69
 
 
70
        # force history object to be loaded:
 
71
        self.get_history()
 
72
 
 
73
    config = property(lambda self: self._config)
 
74
 
 
75
    name = property(lambda self: self._name)
 
76
 
 
77
    group_name = property(lambda self: self._group_name)
 
78
 
 
79
    def _get_friendly_name(self):
 
80
        name = self._config.get('branch_name', None)
 
81
        if name is not None:
 
82
            return name
 
83
        # try branch-specific config?
 
84
        name = self.get_history().get_config().get_nickname()
 
85
        if name is not None:
 
86
            return name
 
87
        return self._name
 
88
 
 
89
    friendly_name = property(_get_friendly_name)
 
90
 
 
91
    def _get_description(self):
 
92
        description = self._config.get('description', None)
 
93
        if description is not None:
 
94
            return description
 
95
        # try branch-specific config?
 
96
        description = self.get_history().get_config().get_user_option('description')
 
97
        return description
 
98
 
 
99
    description = property(_get_description)
 
100
 
 
101
    def _get_branch_url(self):
 
102
        url = self._config.get('url', None)
 
103
        if url is not None:
 
104
            return url
 
105
        # try to assemble one from the project, if an url_prefix was defined.
 
106
        url = self._project_config.get('url_prefix', None)
 
107
        if url is not None:
 
108
            return posixpath.join(url, self._folder) + '/'
 
109
        # try branch-specific config?
 
110
        url = self.get_history().get_config().get_user_option('public_branch')
 
111
        return url
 
112
 
 
113
    branch_url = property(_get_branch_url)
 
114
 
 
115
    @turbogears.expose()
 
116
    def index(self):
 
117
        raise HTTPRedirect(self.url('/changes'))
 
118
 
 
119
    def get_config_item(self, item, default=None):
 
120
        for conf in self._config, self._project_config, self._root_config:
 
121
            if item in conf:
 
122
                return conf[item]
 
123
        return default
 
124
 
 
125
    @with_history_lock
 
126
    def get_history(self):
 
127
        """
 
128
        get an up-to-date History object, safely.  each page-view calls this
 
129
        method, and normally it will get the same History object as on previous
 
130
        calls.  but if the bazaar branch on-disk has been updated since this
 
131
        History was created, a new object will be created and returned.
 
132
        """
 
133
        if (self._history is None) or self._history.out_of_date():
 
134
            self.log.debug('Reload branch history...')
 
135
            _history = self._history = History.from_folder(
 
136
                self._absfolder, self._name)
 
137
            cache_path = self._config.get('cachepath', None)
 
138
            if cache_path is None:
 
139
                # try the project config
 
140
                cache_path = self._project_config.get('cachepath', None)
 
141
            if cache_path is not None:
 
142
                _history.use_file_cache(FileChangeCache(_history, cache_path))
 
143
        return self._history
 
144
 
 
145
    def url(self, elements, **kw):
 
146
        "build an url relative to this branch"
 
147
        if not isinstance(elements, list):
 
148
            elements = [elements]
 
149
        if elements[0].startswith('/'):
 
150
            elements[0] = elements[0][1:]
 
151
        elements = [urllib.quote(x) for x in elements]
 
152
        return turbogears.url([ '/' + self.group_name, self.name ] + elements, **kw)
 
153
 
 
154
    def context_url(self, elements, **kw):
 
155
        "build an url relative to this branch, bringing along browsing context"
 
156
        return self.url(elements, **util.get_context(**kw))
 
157
 
 
158
    def last_updated(self):
 
159
        h = self.get_history()
 
160
        change = h.get_changes([ h.last_revid ])[0]
 
161
        return change.date