~loggerhead-team/loggerhead/trunk-rich

« back to all changes in this revision

Viewing changes to loggerhead/branchview.py

  • Committer: Robey Pointer
  • Date: 2006-12-15 11:10:23 UTC
  • Revision ID: robey@lag.net-20061215111023-brrb46658dljz9x4
fix a couple of bugs:
- merged in/from lines should be broken up on multiple lines (some of mpool's
  bzr.dev revisions have dozens of merged-ins)
- navigation footer shouldn't be displayed if there's only 1 page
- changes list by file wasn't calculated correctly

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
 
 
27
 
import turbogears
28
 
from cherrypy import HTTPRedirect
29
 
 
30
 
from loggerhead import util
31
 
from loggerhead.changecache import ChangeCache
32
 
from loggerhead.history import History
33
 
from loggerhead.textindex import TextIndex
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, project_config):
48
 
        self._group_name = group_name
49
 
        self._name = name
50
 
        self._folder = subfolder
51
 
        self._absfolder = absfolder
52
 
        self._config = config
53
 
        self._project_config = project_config
54
 
        self.log = logging.getLogger('loggerhead.%s' % (name,))
55
 
        
56
 
        # branch history
57
 
        self._history_lock = threading.RLock()
58
 
        self._history = None
59
 
        self._closed = False
60
 
        
61
 
        self.changes = ChangeLogUI(self)
62
 
        self.revision = RevisionUI(self)
63
 
        self.files = InventoryUI(self)
64
 
        self.annotate = AnnotateUI(self)
65
 
        self.download = DownloadUI(self)
66
 
        self.atom = AtomUI(self)
67
 
        self.bundle = BundleUI(self)
68
 
        
69
 
        # force history object to be loaded:
70
 
        self.get_history()
71
 
        
72
 
        turbogears.startup.call_on_shutdown.append(self.close)
73
 
    
74
 
    @with_history_lock
75
 
    def close(self):
76
 
        # it's important that we cleanly detach the history, so the cache
77
 
        # files can be closed correctly and hopefully remain uncorrupted.
78
 
        # this should also stop any ongoing indexing.
79
 
        self._history.detach()
80
 
        self._history = None
81
 
        self._closed = True
82
 
            
83
 
    config = property(lambda self: self._config)
84
 
    
85
 
    name = property(lambda self: self._name)
86
 
 
87
 
    group_name = property(lambda self: self._group_name)
88
 
    
89
 
    def _get_friendly_name(self):
90
 
        name = self._config.get('branch_name', None)
91
 
        if name is not None:
92
 
            return name
93
 
        # try branch-specific config?
94
 
        name = self.get_history().get_config().get_nickname()
95
 
        if name is not None:
96
 
            return name
97
 
        return self._name
98
 
 
99
 
    friendly_name = property(_get_friendly_name)
100
 
 
101
 
    def _get_description(self):
102
 
        description = self._config.get('description', None)
103
 
        if description is not None:
104
 
            return description
105
 
        # try branch-specific config?
106
 
        description = self.get_history().get_config().get_user_option('description')
107
 
        return description
108
 
        
109
 
    description = property(_get_description)
110
 
    
111
 
    def _get_branch_url(self):
112
 
        url = self._config.get('url', None)
113
 
        if url is not None:
114
 
            return url
115
 
        # try to assemble one from the project, if an url_prefix was defined.
116
 
        url = self._project_config.get('url_prefix', None)
117
 
        if url is not None:
118
 
            return posixpath.join(url, self._folder) + '/'
119
 
        # try branch-specific config?
120
 
        url = self.get_history().get_config().get_user_option('public_branch')
121
 
        return url
122
 
        
123
 
    branch_url = property(_get_branch_url)
124
 
    
125
 
    @turbogears.expose()
126
 
    def index(self):
127
 
        raise HTTPRedirect(self.url('/changes'))
128
 
 
129
 
    @with_history_lock
130
 
    def get_history(self):
131
 
        """
132
 
        get an up-to-date History object, safely.  each page-view calls this
133
 
        method, and normally it will get the same History object as on previous
134
 
        calls.  but if the bazaar branch on-disk has been updated since this
135
 
        History was created, a new object will be created and returned.
136
 
        """
137
 
        if self._closed:
138
 
            return None
139
 
        if (self._history is None) or self._history.out_of_date():
140
 
            self.log.debug('Reload branch history...')
141
 
            if self._history is not None:
142
 
                self._history.detach()
143
 
            self._history = History.from_folder(self._absfolder, self._name)
144
 
            cache_path = self._config.get('cachepath', None)
145
 
            if cache_path is None:
146
 
                # try the project config
147
 
                cache_path = self._project_config.get('cachepath', None)
148
 
            if cache_path is not None:
149
 
                self._history.use_cache(ChangeCache(self._history, cache_path))
150
 
                self._history.use_search_index(TextIndex(self._history, cache_path))
151
 
        return self._history
152
 
    
153
 
    def check_rebuild(self):
154
 
        h = self.get_history()
155
 
        if h is not None:
156
 
            h.check_rebuild()
157
 
    
158
 
    def url(self, elements, **kw):
159
 
        if not isinstance(elements, list):
160
 
            elements = [elements]
161
 
        if elements[0].startswith('/'):
162
 
            elements[0] = elements[0][1:]
163
 
        return turbogears.url([ '/' + self.group_name, self.name ] + elements, **kw)
164
 
 
165
 
    def last_updated(self):
166
 
        h = self.get_history()
167
 
        change = h.get_changes([ h.last_revid ])[0]
168
 
        return change.date