~jelmer/loggerhead/breezy-compat

« back to all changes in this revision

Viewing changes to loggerhead/apps/branch.py

  • Committer: Colin Watson
  • Date: 2019-09-19 08:10:36 UTC
  • mfrom: (491.2.62 breezy)
  • Revision ID: cjwatson@canonical.com-20190919081036-q1symc2h2iedtlh3
[r=cjwatson] Switch loggerhead over to using the Breezy rather than Bazaar APIs.

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
"""The WSGI application for serving a Bazaar branch."""
18
18
 
19
19
import logging
20
 
import urllib
21
20
import sys
 
21
import wsgiref.util
22
22
 
23
 
import bzrlib.branch
24
 
import bzrlib.errors
25
 
from bzrlib.hooks import Hooks
26
 
import bzrlib.lru_cache
 
23
import breezy.branch
 
24
import breezy.errors
 
25
from breezy.hooks import Hooks
 
26
import breezy.lru_cache
 
27
from breezy.sixish import viewitems
 
28
from breezy import urlutils
27
29
 
28
30
from paste import request
29
31
from paste import httpexceptions
30
32
 
31
 
from loggerhead.apps import static_app
32
 
from loggerhead.controllers.annotate_ui import AnnotateUI
33
 
from loggerhead.controllers.view_ui import ViewUI
34
 
from loggerhead.controllers.atom_ui import AtomUI
35
 
from loggerhead.controllers.changelog_ui import ChangeLogUI
36
 
from loggerhead.controllers.diff_ui import DiffUI
37
 
from loggerhead.controllers.download_ui import DownloadUI, DownloadTarballUI
38
 
from loggerhead.controllers.filediff_ui import FileDiffUI
39
 
from loggerhead.controllers.inventory_ui import InventoryUI
40
 
from loggerhead.controllers.revision_ui import RevisionUI
41
 
from loggerhead.controllers.revlog_ui import RevLogUI
42
 
from loggerhead.controllers.search_ui import SearchUI
43
 
from loggerhead.history import History
44
 
from loggerhead import util
 
33
from ..apps import static_app
 
34
from ..controllers.annotate_ui import AnnotateUI
 
35
from ..controllers.view_ui import ViewUI
 
36
from ..controllers.atom_ui import AtomUI
 
37
from ..controllers.changelog_ui import ChangeLogUI
 
38
from ..controllers.diff_ui import DiffUI
 
39
from ..controllers.download_ui import DownloadUI, DownloadTarballUI
 
40
from ..controllers.filediff_ui import FileDiffUI
 
41
from ..controllers.inventory_ui import InventoryUI
 
42
from ..controllers.revision_ui import RevisionUI
 
43
from ..controllers.revlog_ui import RevLogUI
 
44
from ..controllers.search_ui import SearchUI
 
45
from ..history import History
 
46
from .. import util
45
47
 
46
48
 
47
49
_DEFAULT = object()
63
65
        self.branch_link = branch_link  # Currently only used in Launchpad
64
66
        self.log = logging.getLogger('loggerhead.%s' % (friendly_name,))
65
67
        if graph_cache is None:
66
 
            graph_cache = bzrlib.lru_cache.LRUCache(10)
 
68
            graph_cache = breezy.lru_cache.LRUCache(10)
67
69
        self.graph_cache = graph_cache
68
70
        self.is_root = is_root
69
71
        self.served_url = served_url
84
86
            # Only import the cache if we're going to use it.
85
87
            # This makes sqlite optional
86
88
            try:
87
 
                from loggerhead.changecache import RevInfoDiskCache
 
89
                from ..changecache import RevInfoDiskCache
88
90
            except ImportError:
89
91
                self.log.debug("Couldn't load python-sqlite,"
90
92
                               " continuing without using a cache")
92
94
                revinfo_disk_cache = RevInfoDiskCache(cache_path)
93
95
        return History(
94
96
            self.branch, self.graph_cache,
95
 
            revinfo_disk_cache=revinfo_disk_cache, cache_key=self.friendly_name)
 
97
            revinfo_disk_cache=revinfo_disk_cache,
 
98
            cache_key=(self.friendly_name.encode('utf-8') if self.friendly_name else None))
 
99
 
 
100
    # Before the addition of this method, clicking to sort by date from 
 
101
    # within a branch caused a jump up to the top of that branch.
 
102
    def sort_url(self, *args, **kw):
 
103
        if isinstance(args[0], list):
 
104
            args = args[0]
 
105
        qs = []
 
106
        for k, v in viewitems(kw):
 
107
            if v is not None:
 
108
                qs.append('%s=%s' % (k, urlutils.quote(v)))
 
109
        qs = '&'.join(qs)
 
110
        path_info = self._path_info.strip('/').split('?')[0]
 
111
        path_info += '?' + qs
 
112
        return self._url_base + '/' + path_info
96
113
 
97
114
    def url(self, *args, **kw):
98
115
        if isinstance(args[0], list):
99
116
            args = args[0]
100
117
        qs = []
101
 
        for k, v in kw.iteritems():
 
118
        for k, v in viewitems(kw):
102
119
            if v is not None:
103
 
                qs.append('%s=%s' % (k, urllib.quote(v)))
 
120
                qs.append('%s=%s' % (k, urlutils.quote(v)))
104
121
        qs = '&'.join(qs)
105
 
        path_info = urllib.quote(
106
 
            unicode('/'.join(args)).encode('utf-8'), safe='/~:')
 
122
        path_info = urlutils.quote('/'.join(args), safe='/~:')
107
123
        if qs:
108
124
            path_info += '?' + qs
109
125
        return self._url_base + path_info
147
163
        return change.date
148
164
 
149
165
    def public_branch_url(self):
150
 
        return self.branch.get_config().get_user_option('public_branch')
 
166
        return self.branch.get_public_branch()
151
167
 
152
168
    def lookup_app(self, environ):
153
169
        # Check again if the branch is blocked from being served, this is
154
170
        # mostly for tests. It's already checked in apps/transport.py
155
 
        if self.branch.get_config().get_user_option('http_serve') == 'False':
 
171
        if not self.branch.get_config().get_user_option_as_bool('http_serve', default=True):
156
172
            raise httpexceptions.HTTPNotFound()
157
173
        self._url_base = environ['SCRIPT_NAME']
 
174
        self._path_info = environ['PATH_INFO']
158
175
        self._static_url_base = environ.get('loggerhead.static.url')
159
176
        if self._static_url_base is None:
160
177
            self._static_url_base = self._url_base
164
181
            if public_branch is not None:
165
182
                self.served_url = public_branch
166
183
            else:
167
 
                # Loggerhead only supports serving .bzr/ on local branches, so
168
 
                # we shouldn't suggest something that won't work.
169
 
                try:
170
 
                    util.local_path_from_url(self.branch.base)
171
 
                    self.served_url = self.url([])
172
 
                except bzrlib.errors.InvalidURL:
173
 
                    self.served_url = None
 
184
                self.served_url = wsgiref.util.application_uri(environ)
174
185
        for hook in self.hooks['controller']:
175
186
            controller = hook(self, environ)
176
187
            if controller is not None:
190
201
        raise httpexceptions.HTTPNotFound()
191
202
 
192
203
    def app(self, environ, start_response):
193
 
        self.branch.lock_read()
194
 
        try:
 
204
        with self.branch.lock_read():
195
205
            try:
196
206
                c = self.lookup_app(environ)
197
207
                return c(environ, start_response)
199
209
                environ['exc_info'] = sys.exc_info()
200
210
                environ['branch'] = self
201
211
                raise
202
 
        finally:
203
 
            self.branch.unlock()
204
212
 
205
213
 
206
214
class BranchWSGIAppHooks(Hooks):
210
218
    def __init__(self):
211
219
        """Create the default hooks.
212
220
        """
213
 
        Hooks.__init__(self, "bzrlib.plugins.loggerhead.apps.branch",
 
221
        Hooks.__init__(self, "breezy.plugins.loggerhead.apps.branch",
214
222
            "BranchWSGIApp.hooks")
215
223
        self.add_hook('controller',
216
224
            "Invoked when looking for the controller to use for a "