~loggerhead-team/loggerhead/trunk-rich

« back to all changes in this revision

Viewing changes to loggerhead/branchview.py

  • Committer: Martin Albisetti
  • Date: 2008-06-27 04:32:15 UTC
  • Revision ID: argentina@gmail.com-20080627043215-87bfzj5d2sm5ijqu
Don't add links to removed files, bug #243420

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