~loggerhead-team/loggerhead/trunk-rich

« back to all changes in this revision

Viewing changes to loggerhead/apps/branch.py

  • Committer: Ian Clatworthy
  • Date: 2010-04-22 08:52:59 UTC
  • mfrom: (405.1.8 small-cleanups)
  • Revision ID: ian.clatworthy@canonical.com-20100422085259-1nb59i53emu2ny5b
Merge John's minor cleanups

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2008-2011 Canonical Ltd.
 
1
# Copyright (C) 2008, 2009, 2010 Canonical Ltd.
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
22
22
 
23
23
import bzrlib.branch
24
24
import bzrlib.errors
25
 
from bzrlib.hooks import Hooks
26
25
import bzrlib.lru_cache
27
26
 
28
27
from paste import request
30
29
 
31
30
from loggerhead.apps import static_app
32
31
from loggerhead.controllers.annotate_ui import AnnotateUI
33
 
from loggerhead.controllers.view_ui import ViewUI
34
32
from loggerhead.controllers.atom_ui import AtomUI
35
33
from loggerhead.controllers.changelog_ui import ChangeLogUI
36
34
from loggerhead.controllers.diff_ui import DiffUI
50
48
 
51
49
    def __init__(self, branch, friendly_name=None, config={},
52
50
                 graph_cache=None, branch_link=None, is_root=False,
53
 
                 served_url=_DEFAULT, use_cdn=False, private=False):
 
51
                 served_url=_DEFAULT, use_cdn=False):
54
52
        self.branch = branch
55
53
        self._config = config
56
54
        self.friendly_name = friendly_name
62
60
        self.is_root = is_root
63
61
        self.served_url = served_url
64
62
        self.use_cdn = use_cdn
65
 
        self.private = private
66
 
 
67
 
    def public_private_css(self):
68
 
        if self.private:
69
 
            return "private"
70
 
        else:
71
 
            return "public"
72
63
 
73
64
    def get_history(self):
 
65
        file_cache = None
74
66
        revinfo_disk_cache = None
75
67
        cache_path = self._config.get('cachepath', None)
76
68
        if cache_path is not None:
77
69
            # Only import the cache if we're going to use it.
78
70
            # This makes sqlite optional
79
71
            try:
80
 
                from loggerhead.changecache import RevInfoDiskCache
 
72
                from loggerhead.changecache import (
 
73
                    FileChangeCache, RevInfoDiskCache)
81
74
            except ImportError:
82
75
                self.log.debug("Couldn't load python-sqlite,"
83
76
                               " continuing without using a cache")
84
77
            else:
 
78
                file_cache = FileChangeCache(cache_path)
85
79
                revinfo_disk_cache = RevInfoDiskCache(cache_path)
86
80
        return History(
87
 
            self.branch, self.graph_cache,
 
81
            self.branch, self.graph_cache, file_cache=file_cache,
88
82
            revinfo_disk_cache=revinfo_disk_cache, cache_key=self.friendly_name)
89
83
 
90
84
    def url(self, *args, **kw):
95
89
            if v is not None:
96
90
                qs.append('%s=%s' % (k, urllib.quote(v)))
97
91
        qs = '&'.join(qs)
98
 
        path_info = urllib.quote(
99
 
            unicode('/'.join(args)).encode('utf-8'), safe='/~:')
100
 
        if qs:
101
 
            path_info += '?' + qs
102
 
        return self._url_base + path_info
103
 
 
104
 
    def absolute_url(self, *args, **kw):
105
 
        rel_url = self.url(*args, **kw)
106
 
        return request.resolve_relative_url(rel_url, self._environ)
 
92
        return request.construct_url(
 
93
            self._environ, script_name=self._url_base,
 
94
            path_info=unicode('/'.join(args)).encode('utf-8'),
 
95
            querystring=qs)
107
96
 
108
97
    def context_url(self, *args, **kw):
109
98
        kw = util.get_context(**kw)
130
119
        'files': InventoryUI,
131
120
        'revision': RevisionUI,
132
121
        'search': SearchUI,
133
 
        'view': ViewUI,
134
122
        }
135
123
 
136
124
    def last_updated(self):
141
129
    def public_branch_url(self):
142
130
        return self.branch.get_config().get_user_option('public_branch')
143
131
 
144
 
    def lookup_app(self, environ):
 
132
    def app(self, environ, start_response):
145
133
        # Check again if the branch is blocked from being served, this is
146
134
        # mostly for tests. It's already checked in apps/transport.py
147
135
        if self.branch.get_config().get_user_option('http_serve') == 'False':
163
151
                    self.served_url = self.url([])
164
152
                except bzrlib.errors.InvalidURL:
165
153
                    self.served_url = None
166
 
        for hook in self.hooks['controller']:
167
 
            controller = hook(self, environ)
168
 
            if controller is not None:
169
 
                return controller
170
154
        path = request.path_info_pop(environ)
171
155
        if not path:
172
156
            raise httpexceptions.HTTPMovedPermanently(
173
 
                self.absolute_url('/changes'))
 
157
                self._url_base + '/changes')
174
158
        if path == 'static':
175
 
            return static_app
176
 
        elif path == '+json':
177
 
            environ['loggerhead.as_json'] = True
178
 
            path = request.path_info_pop(environ)
 
159
            return static_app(environ, start_response)
179
160
        cls = self.controllers_dict.get(path)
180
 
        if cls is not None:
181
 
            return cls(self, self.get_history)
182
 
        raise httpexceptions.HTTPNotFound()
183
 
 
184
 
    def app(self, environ, start_response):
 
161
        if cls is None:
 
162
            raise httpexceptions.HTTPNotFound()
185
163
        self.branch.lock_read()
186
164
        try:
187
165
            try:
188
 
                c = self.lookup_app(environ)
 
166
                c = cls(self, self.get_history)
189
167
                return c(environ, start_response)
190
168
            except:
191
169
                environ['exc_info'] = sys.exc_info()
193
171
                raise
194
172
        finally:
195
173
            self.branch.unlock()
196
 
 
197
 
 
198
 
class BranchWSGIAppHooks(Hooks):
199
 
    """A dictionary mapping hook name to a list of callables for WSGI app branch hooks.
200
 
    """
201
 
 
202
 
    def __init__(self):
203
 
        """Create the default hooks.
204
 
        """
205
 
        Hooks.__init__(self, "bzrlib.plugins.loggerhead.apps.branch",
206
 
            "BranchWSGIApp.hooks")
207
 
        self.add_hook('controller',
208
 
            "Invoked when looking for the controller to use for a "
209
 
            "branch subpage. The api signature is (branch_app, environ)."
210
 
            "If a hook can provide a controller, it should return one, "
211
 
            "as a standard WSGI app. If it can't provide a controller, "
212
 
            "it should return None", (1, 19))
213
 
 
214
 
 
215
 
BranchWSGIApp.hooks = BranchWSGIAppHooks()