1
"""The WSGI application for serving a Bazaar branch."""
8
import bzrlib.lru_cache
10
4
from paste import request
11
5
from paste import httpexceptions
13
7
from loggerhead.apps import static_app
9
from loggerhead.controllers.changelog_ui import ChangeLogUI
10
from loggerhead.controllers.inventory_ui import InventoryUI
14
11
from loggerhead.controllers.annotate_ui import AnnotateUI
12
from loggerhead.controllers.revision_ui import RevisionUI
15
13
from loggerhead.controllers.atom_ui import AtomUI
16
from loggerhead.controllers.changelog_ui import ChangeLogUI
17
from loggerhead.controllers.diff_ui import DiffUI
18
14
from loggerhead.controllers.download_ui import DownloadUI
19
from loggerhead.controllers.filediff_ui import FileDiffUI
20
from loggerhead.controllers.inventory_ui import InventoryUI
21
from loggerhead.controllers.revision_ui import RevisionUI
22
from loggerhead.controllers.revlog_ui import RevLogUI
23
from loggerhead.controllers.search_ui import SearchUI
24
15
from loggerhead.history import History
25
16
from loggerhead import util
30
19
class BranchWSGIApp(object):
32
def __init__(self, branch, friendly_name=None, config={},
33
graph_cache=None, branch_link=None, is_root=False,
34
served_url=_DEFAULT, use_cdn=False):
21
def __init__(self, branch_url, friendly_name=None, config={}):
22
self.branch_url = branch_url
36
24
self._config = config
37
25
self.friendly_name = friendly_name
38
self.branch_link = branch_link # Currently only used in Launchpad
39
self.log = logging.getLogger('loggerhead.%s' % friendly_name)
40
if graph_cache is None:
41
graph_cache = bzrlib.lru_cache.LRUCache(10)
42
self.graph_cache = graph_cache
43
self.is_root = is_root
44
self.served_url = served_url
45
self.use_cdn = use_cdn
26
self.log = logging.getLogger('loggerhead.%s' % (friendly_name,))
47
def get_history(self):
49
revinfo_disk_cache = None
50
cache_path = self._config.get('cachepath', None)
51
if cache_path is not None:
52
# Only import the cache if we're going to use it.
53
# This makes sqlite optional
55
from loggerhead.changecache import (
56
FileChangeCache, RevInfoDiskCache)
58
self.log.debug("Couldn't load python-sqlite,"
59
" continuing without using a cache")
61
file_cache = FileChangeCache(cache_path)
62
revinfo_disk_cache = RevInfoDiskCache(cache_path)
64
self.branch, self.graph_cache, file_cache=file_cache,
65
revinfo_disk_cache=revinfo_disk_cache, cache_key=self.friendly_name)
30
if (self._history is None) or self._history.out_of_date():
31
self.log.debug('Reload branch history...')
32
_history = self._history = History.from_folder(self.branch_url)
33
cache_path = self._config.get('cachepath', None)
34
if cache_path is not None:
35
# Only import the cache if we're going to use it.
36
# This makes sqlite optional
38
from loggerhead.changecache import FileChangeCache
40
self.log.debug("Couldn't load python-sqlite,"
41
" continuing without using a cache")
43
_history.use_file_cache(FileChangeCache(_history,
67
47
def url(self, *args, **kw):
68
48
if isinstance(args[0], list):
84
64
def static_url(self, path):
85
65
return self._static_url_base + path
87
def yui_url(self, path):
89
base = 'http://yui.yahooapis.com/3.0.0pr2/build/'
91
base = self.static_url('/static/javascript/yui/build/')
94
67
controllers_dict = {
95
'+filediff': FileDiffUI,
97
68
'annotate': AnnotateUI,
99
69
'changes': ChangeLogUI,
101
'download': DownloadUI,
102
70
'files': InventoryUI,
103
71
'revision': RevisionUI,
72
'download': DownloadUI,
107
76
def last_updated(self):
108
h = self.get_history()
109
change = h.get_changes([h.last_revid])[0]
78
change = h.get_changes([ h.last_revid ])[0]
110
79
return change.date
112
def public_branch_url(self):
113
return self.branch.get_config().get_user_option('public_branch')
82
return self.history.get_config().get_user_option('public_branch')
115
84
def app(self, environ, start_response):
116
85
self._url_base = environ['SCRIPT_NAME']
118
87
if self._static_url_base is None:
119
88
self._static_url_base = self._url_base
120
89
self._environ = environ
121
if self.served_url is _DEFAULT:
122
public_branch = self.public_branch_url()
123
if public_branch is not None:
124
self.served_url = public_branch
126
# Loggerhead only supports serving .bzr/ on local branches, so
127
# we shouldn't suggest something that won't work.
128
if self.branch.base.startswith('file://'):
129
self.served_url = self.url([])
131
self.served_url = None
132
90
path = request.path_info_pop(environ)
134
92
raise httpexceptions.HTTPMovedPermanently(