2
# Copyright (C) 2006 Robey Pointer <robey@lag.net>
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.
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.
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
20
collection of configuration and objects related to a bazaar branch.
29
from cherrypy import HTTPRedirect
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
43
with_history_lock = util.with_lock('_history_lock', 'History')
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
51
self._folder = subfolder
52
self._absfolder = absfolder
54
self._project_config = project_config
55
self._root_config = root_config
56
self.log = logging.getLogger('loggerhead.%s' % (name,))
59
self._history_lock = threading.RLock()
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)
70
# force history object to be loaded:
73
config = property(lambda self: self._config)
75
name = property(lambda self: self._name)
77
group_name = property(lambda self: self._group_name)
79
def _get_friendly_name(self):
80
name = self._config.get('branch_name', None)
83
# try branch-specific config?
84
name = self.get_history().get_config().get_nickname()
89
friendly_name = property(_get_friendly_name)
91
def _get_description(self):
92
description = self._config.get('description', None)
93
if description is not None:
95
# try branch-specific config?
96
description = self.get_history().get_config().get_user_option('description')
99
description = property(_get_description)
101
def _get_branch_url(self):
102
url = self._config.get('url', None)
105
# try to assemble one from the project, if an url_prefix was defined.
106
url = self._project_config.get('url_prefix', 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')
113
branch_url = property(_get_branch_url)
117
raise HTTPRedirect(self.url('/changes'))
119
def get_config_item(self, item, default=None):
120
for conf in self._config, self._project_config, self._root_config:
126
def get_history(self):
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.
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))
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)
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))
158
def last_updated(self):
159
h = self.get_history()
160
change = h.get_changes([ h.last_revid ])[0]