89
77
return posixpath.join(url, folder) + '/'
92
def _get_description(self, view, view_config, history):
80
def _get_description(self, view, view_config):
93
81
description = view_config.get('description', None)
94
82
if description is not None:
96
description = history._branch.get_config().get_user_option(
84
description = view.history._branch.get_config().get_user_option('description')
100
87
def _add_view(self, view_name, view_config, folder):
101
b = bzrlib.branch.Branch.open(folder)
102
view = BranchWSGIApp(b, view_name, view_config, self.graph_cache)
105
history = view.get_history()
106
friendly_name = view_config.get('branch_name', None)
88
view = BranchWSGIApp(folder, view_name, view_config)
89
friendly_name = view_config.get('branch_name', None)
90
if friendly_name is None:
91
friendly_name = view.history.get_config().get_nickname()
107
92
if friendly_name is None:
108
friendly_name = history.get_config().get_nickname()
109
if friendly_name is None:
110
friendly_name = view_name
111
branch_url = self._get_branch_url(view, view_config, view_name)
112
description = self._get_description(view, view_config, history)
113
self.view_data_by_name[view_name] = {
114
'branch_path': folder,
115
'config': view_config,
116
'description': description,
117
'friendly_name': friendly_name,
118
'graph_cache': self.graph_cache,
120
'served_url': branch_url,
122
self.view_names.append(view_name)
126
def view_named(self, name):
127
view_data = self.view_data_by_name.get(name)
128
if view_data is None:
130
view_data = view_data.copy()
131
branch_path = view_data.pop('branch_path')
132
description = view_data.pop('description')
133
name = view_data.pop('name')
134
b = bzrlib.branch.Branch.open(branch_path)
136
view = BranchWSGIApp(b, **view_data)
137
view.description = description
93
friendly_name = view_name
94
view.friendly_name = friendly_name
96
branch_url = self._get_branch_url(view, view_config, view_name)
97
if branch_url is not None:
98
view.branch_url = branch_url
99
view.description = self._get_description(view, view_config)
100
view._src_folder = folder
101
view._view_config = view_config
102
self.views.append(view)
103
self.views_by_name[view_name] = view
141
105
def call(self, environ, start_response):
142
106
segment = path_info_pop(environ)
144
108
raise httpexceptions.HTTPNotFound()
146
view = self.view_named(segment)
110
view = self.views_by_name.get(segment)
148
112
raise httpexceptions.HTTPNotFound()
150
return view.app(environ, start_response)
113
return view.app(environ, start_response)
155
116
class Root(object):
156
"""The root of the server -- renders as the browse view,
157
dispatches to Project above for each 'project'."""
159
118
def __init__(self, config):
160
119
self.projects = []
161
120
self.config = config
162
121
self.projects_by_name = {}
163
graph_cache = bzrlib.lru_cache.LRUCache()
164
122
for project_name in self.config.sections:
165
project = Project(project_name, self.config[project_name],
166
self.config, graph_cache)
124
project_name, self.config[project_name], self.config)
167
125
self.projects.append(project)
168
126
self.projects_by_name[project_name] = project
170
128
def browse(self, response):
171
# This is insanely complicated because we want to open and
172
# lock all the branches, render the view and then unlock the
174
129
for p in self.projects:
175
130
p._recheck_auto_folders()
177
class branch(object):
180
133
def static_url(path):
181
134
return self._static_url_base + path
182
views_by_project = {}
185
for p in self.projects:
186
views_by_project[p] = []
187
for vn in p.view_names:
190
views_by_project[p].append(v)
192
'projects': self.projects,
194
'title': self.config.get('title', None),
196
'views_by_project': views_by_project,
198
vals.update(templatefunctions)
199
response.headers['Content-Type'] = 'text/html'
200
template = load_template('loggerhead.templates.browse')
201
template.expand_into(response, **vals)
136
'projects': self.projects,
138
'title': self.config.get('title', None),
141
vals.update(templatefunctions)
142
response.headers['Content-Type'] = 'text/html'
143
template = load_template('loggerhead.templates.browse')
144
template.expand_into(response, **vals)
206
146
def __call__(self, environ, start_response):
207
self._static_url_base = environ['loggerhead.static.url'] = \
208
environ['SCRIPT_NAME']
147
self._static_url_base = environ['loggerhead.static.url'] = environ['SCRIPT_NAME']
209
148
segment = path_info_pop(environ)
210
149
if segment is None:
211
raise httpexceptions.HTTPMovedPermanently.relative_redirect(
212
environ['SCRIPT_NAME'] + '/', environ)
150
raise httpexceptions.HTTPMovedPermanently(
151
environ['SCRIPT_NAME'] + '/')
213
152
elif segment == '':
214
153
response = WSGIResponse()
215
154
self.browse(response)
216
155
return response(environ, start_response)
217
elif segment == 'robots.txt':
218
return robots_app(environ, start_response)
219
156
elif segment == 'static':
220
157
return static_app(environ, start_response)
221
158
elif segment == 'favicon.ico':