1
"""The WSGI application for serving a Bazaar branch."""
8
import bzrlib.lru_cache
10
from paste import request
11
from paste import httpexceptions
13
from loggerhead.apps import static_app
14
from loggerhead.controllers.changelog_ui import ChangeLogUI
15
from loggerhead.controllers.inventory_ui import InventoryUI
16
from loggerhead.controllers.annotate_ui import AnnotateUI
17
from loggerhead.controllers.revision_ui import RevisionUI
18
from loggerhead.controllers.atom_ui import AtomUI
19
from loggerhead.controllers.download_ui import DownloadUI
20
from loggerhead.controllers.search_ui import SearchUI
21
from loggerhead.controllers.diff_ui import DiffUI
22
from loggerhead.history import History
23
from loggerhead import util
28
class BranchWSGIApp(object):
30
def __init__(self, branch, friendly_name=None, config={},
31
graph_cache=None, branch_link=None, is_root=False,
35
self.friendly_name = friendly_name
36
self.branch_link = branch_link # Currently only used in Launchpad
37
self.log = logging.getLogger('loggerhead.%s' % friendly_name)
38
if graph_cache is None:
39
graph_cache = bzrlib.lru_cache.LRUCache()
40
self.graph_cache = graph_cache
41
self.is_root = is_root
42
self.served_url = served_url
44
def get_history(self):
45
_history = History(self.branch, self.graph_cache)
46
cache_path = self._config.get('cachepath', None)
47
if cache_path is not None:
48
# Only import the cache if we're going to use it.
49
# This makes sqlite optional
51
from loggerhead.changecache import FileChangeCache
53
self.log.debug("Couldn't load python-sqlite,"
54
" continuing without using a cache")
56
_history.use_file_cache(
57
FileChangeCache(_history, cache_path))
60
def url(self, *args, **kw):
61
if isinstance(args[0], list):
64
for k, v in kw.iteritems():
66
qs.append('%s=%s'%(k, urllib.quote(v)))
68
return request.construct_url(
69
self._environ, script_name=self._url_base,
70
path_info=unicode('/'.join(args)).encode('utf-8'),
73
def context_url(self, *args, **kw):
74
kw = util.get_context(**kw)
75
return self.url(*args, **kw)
77
def static_url(self, path):
78
return self._static_url_base + path
81
'annotate': AnnotateUI,
82
'changes': ChangeLogUI,
84
'revision': RevisionUI,
85
'download': DownloadUI,
91
def last_updated(self):
92
h = self.get_history()
93
change = h.get_changes([h.last_revid])[0]
97
return self.branch.get_config().get_user_option('public_branch')
99
def app(self, environ, start_response):
100
self._url_base = environ['SCRIPT_NAME']
101
self._static_url_base = environ.get('loggerhead.static.url')
102
if self._static_url_base is None:
103
self._static_url_base = self._url_base
104
self._environ = environ
105
if self.served_url is _DEFAULT:
106
self.served_url = self.url([])
107
path = request.path_info_pop(environ)
109
raise httpexceptions.HTTPMovedPermanently(
110
self._url_base + '/changes')
112
return static_app(environ, start_response)
113
cls = self.controllers_dict.get(path)
115
raise httpexceptions.HTTPNotFound()
116
self.branch.lock_read()
119
c = cls(self, self.get_history)
120
return c(environ, start_response)
122
environ['exc_info'] = sys.exc_info()
123
environ['branch'] = self