##// END OF EJS Templates
changelog: fix and optimize loading of chunks for file history....
marcink -
r2130:69819530 default
parent child Browse files
Show More
@@ -199,6 +199,9 b' def includeme(config):'
199 config.add_route(
199 config.add_route(
200 name='repo_changelog_elements',
200 name='repo_changelog_elements',
201 pattern='/{repo_name:.*?[^/]}/changelog_elements', repo_route=True)
201 pattern='/{repo_name:.*?[^/]}/changelog_elements', repo_route=True)
202 config.add_route(
203 name='repo_changelog_elements_file',
204 pattern='/{repo_name:.*?[^/]}/changelog_elements/{commit_id}/{f_path:.*}', repo_route=True)
202
205
203 # Compare
206 # Compare
204 config.add_route(
207 config.add_route(
@@ -162,6 +162,11 b' class RepoChangelogView(RepoAppView):'
162 self._register_global_c(c)
162 self._register_global_c(c)
163 return c
163 return c
164
164
165 def _get_preload_attrs(self):
166 pre_load = ['author', 'branch', 'date', 'message', 'parents',
167 'obsolete', 'phase', 'hidden']
168 return pre_load
169
165 @LoginRequired()
170 @LoginRequired()
166 @HasRepoPermissionAnyDecorator(
171 @HasRepoPermissionAnyDecorator(
167 'repository.read', 'repository.write', 'repository.admin')
172 'repository.read', 'repository.write', 'repository.admin')
@@ -181,6 +186,8 b' class RepoChangelogView(RepoAppView):'
181
186
182 c.branch_name = branch_name = self.request.GET.get('branch') or ''
187 c.branch_name = branch_name = self.request.GET.get('branch') or ''
183 c.book_name = book_name = self.request.GET.get('bookmark') or ''
188 c.book_name = book_name = self.request.GET.get('bookmark') or ''
189 c.f_path = f_path
190 c.commit_id = commit_id
184 hist_limit = safe_int(self.request.GET.get('limit')) or None
191 hist_limit = safe_int(self.request.GET.get('limit')) or None
185
192
186 p = safe_int(self.request.GET.get('page', 1), 1)
193 p = safe_int(self.request.GET.get('page', 1), 1)
@@ -190,7 +197,7 b' class RepoChangelogView(RepoAppView):'
190 self._check_if_valid_branch(branch_name, self.db_repo_name, f_path)
197 self._check_if_valid_branch(branch_name, self.db_repo_name, f_path)
191
198
192 c.changelog_for_path = f_path
199 c.changelog_for_path = f_path
193 pre_load = ['author', 'branch', 'date', 'message', 'parents']
200 pre_load = self._get_preload_attrs()
194 commit_ids = []
201 commit_ids = []
195
202
196 partial_xhr = self.request.environ.get('HTTP_X_PARTIAL_XHR')
203 partial_xhr = self.request.environ.get('HTTP_X_PARTIAL_XHR')
@@ -200,6 +207,7 b' class RepoChangelogView(RepoAppView):'
200 log.debug('generating changelog for path %s', f_path)
207 log.debug('generating changelog for path %s', f_path)
201 # get the history for the file !
208 # get the history for the file !
202 base_commit = self.rhodecode_vcs_repo.get_commit(commit_id)
209 base_commit = self.rhodecode_vcs_repo.get_commit(commit_id)
210
203 try:
211 try:
204 collection = base_commit.get_file_history(
212 collection = base_commit.get_file_history(
205 f_path, limit=hist_limit, pre_load=pre_load)
213 f_path, limit=hist_limit, pre_load=pre_load)
@@ -239,6 +247,7 b' class RepoChangelogView(RepoAppView):'
239 h.route_path('repo_changelog', repo_name=self.db_repo_name))
247 h.route_path('repo_changelog', repo_name=self.db_repo_name))
240
248
241 if partial_xhr or self.request.environ.get('HTTP_X_PJAX'):
249 if partial_xhr or self.request.environ.get('HTTP_X_PJAX'):
250 # case when loading dynamic file history in file view
242 # loading from ajax, we don't want the first result, it's popped
251 # loading from ajax, we don't want the first result, it's popped
243 # in the code above
252 # in the code above
244 html = render(
253 html = render(
@@ -261,9 +270,16 b' class RepoChangelogView(RepoAppView):'
261 route_name='repo_changelog_elements', request_method=('GET', 'POST'),
270 route_name='repo_changelog_elements', request_method=('GET', 'POST'),
262 renderer='rhodecode:templates/changelog/changelog_elements.mako',
271 renderer='rhodecode:templates/changelog/changelog_elements.mako',
263 xhr=True)
272 xhr=True)
273 @view_config(
274 route_name='repo_changelog_elements_file', request_method=('GET', 'POST'),
275 renderer='rhodecode:templates/changelog/changelog_elements.mako',
276 xhr=True)
264 def repo_changelog_elements(self):
277 def repo_changelog_elements(self):
265 c = self.load_default_context()
278 c = self.load_default_context()
279 commit_id = self.request.matchdict.get('commit_id')
280 f_path = self._get_f_path(self.request.matchdict)
266 chunk_size = 20
281 chunk_size = 20
282 hist_limit = safe_int(self.request.GET.get('limit')) or None
267
283
268 def wrap_for_error(err):
284 def wrap_for_error(err):
269 html = '<tr>' \
285 html = '<tr>' \
@@ -273,20 +289,30 b' class RepoChangelogView(RepoAppView):'
273
289
274 c.branch_name = branch_name = self.request.GET.get('branch') or ''
290 c.branch_name = branch_name = self.request.GET.get('branch') or ''
275 c.book_name = book_name = self.request.GET.get('bookmark') or ''
291 c.book_name = book_name = self.request.GET.get('bookmark') or ''
292 c.f_path = f_path
293 c.commit_id = commit_id
276
294
277 c.selected_name = branch_name or book_name
295 c.selected_name = branch_name or book_name
278 if branch_name and branch_name not in self.rhodecode_vcs_repo.branches_all:
296 if branch_name and branch_name not in self.rhodecode_vcs_repo.branches_all:
279 return wrap_for_error(
297 return wrap_for_error(
280 safe_str('Branch: {} is not valid'.format(branch_name)))
298 safe_str('Branch: {} is not valid'.format(branch_name)))
281
299
282 pre_load = ['author', 'branch', 'date', 'message', 'parents']
300 pre_load = self._get_preload_attrs()
283 collection = self.rhodecode_vcs_repo.get_commits(
301
284 branch_name=branch_name, pre_load=pre_load)
302 if f_path:
303 base_commit = self.rhodecode_vcs_repo.get_commit(commit_id)
304 collection = base_commit.get_file_history(
305 f_path, limit=hist_limit, pre_load=pre_load)
306 collection = list(reversed(collection))
307 else:
308 collection = self.rhodecode_vcs_repo.get_commits(
309 branch_name=branch_name, pre_load=pre_load)
285
310
286 p = safe_int(self.request.GET.get('page', 1), 1)
311 p = safe_int(self.request.GET.get('page', 1), 1)
287 try:
312 try:
288 self._load_changelog_data(
313 self._load_changelog_data(
289 c, collection, p, chunk_size, dynamic=True)
314 c, collection, p, chunk_size, dynamic=True,
315 f_path=f_path, commit_id=commit_id)
290 except EmptyRepositoryError as e:
316 except EmptyRepositoryError as e:
291 return wrap_for_error(safe_str(e))
317 return wrap_for_error(safe_str(e))
292 except (RepositoryError, CommitDoesNotExistError, Exception) as e:
318 except (RepositoryError, CommitDoesNotExistError, Exception) as e:
@@ -296,7 +322,7 b' class RepoChangelogView(RepoAppView):'
296 prev_data = None
322 prev_data = None
297 next_data = None
323 next_data = None
298
324
299 prev_graph = json.loads(self.request.POST.get('graph', ''))
325 prev_graph = json.loads(self.request.POST.get('graph') or '{}')
300
326
301 if self.request.GET.get('chunk') == 'prev':
327 if self.request.GET.get('chunk') == 'prev':
302 next_data = prev_graph
328 next_data = prev_graph
@@ -64,6 +64,12 b' class GitCommit(base.BaseCommit):'
64 "status",
64 "status",
65 # mercurial specific property not supported here
65 # mercurial specific property not supported here
66 "_file_paths",
66 "_file_paths",
67 # mercurial specific property not supported here
68 'obsolete',
69 # mercurial specific property not supported here
70 'phase',
71 # mercurial specific property not supported here
72 'hidden'
67 ]
73 ]
68
74
69 def __init__(self, repository, raw_id, idx, pre_load=None):
75 def __init__(self, repository, raw_id, idx, pre_load=None):
@@ -261,9 +267,10 b' class GitCommit(base.BaseCommit):'
261 child_ids.extend(found_ids)
267 child_ids.extend(found_ids)
262 return self._make_commits(child_ids)
268 return self._make_commits(child_ids)
263
269
264 def _make_commits(self, commit_ids):
270 def _make_commits(self, commit_ids, pre_load=None):
265 return [self.repository.get_commit(commit_id=commit_id)
271 return [
266 for commit_id in commit_ids]
272 self.repository.get_commit(commit_id=commit_id, pre_load=pre_load)
273 for commit_id in commit_ids]
267
274
268 def get_file_mode(self, path):
275 def get_file_mode(self, path):
269 """
276 """
@@ -81,6 +81,8 b' class MercurialCommit(base.BaseCommit):'
81 value = utcdate_fromtimestamp(*value)
81 value = utcdate_fromtimestamp(*value)
82 elif attr in ["children", "parents"]:
82 elif attr in ["children", "parents"]:
83 value = self._make_commits(value)
83 value = self._make_commits(value)
84 elif attr in ["phase"]:
85 value = self._get_phase_text(value)
84 self.__dict__[attr] = value
86 self.__dict__[attr] = value
85
87
86 @LazyProperty
88 @LazyProperty
@@ -147,8 +149,8 b' class MercurialCommit(base.BaseCommit):'
147 def short_id(self):
149 def short_id(self):
148 return self.raw_id[:12]
150 return self.raw_id[:12]
149
151
150 def _make_commits(self, indexes):
152 def _make_commits(self, indexes, pre_load=None):
151 return [self.repository.get_commit(commit_idx=idx)
153 return [self.repository.get_commit(commit_idx=idx, pre_load=pre_load)
152 for idx in indexes if idx >= 0]
154 for idx in indexes if idx >= 0]
153
155
154 @LazyProperty
156 @LazyProperty
@@ -159,14 +161,17 b' class MercurialCommit(base.BaseCommit):'
159 parents = self._remote.ctx_parents(self.idx)
161 parents = self._remote.ctx_parents(self.idx)
160 return self._make_commits(parents)
162 return self._make_commits(parents)
161
163
164 def _get_phase_text(self, phase_id):
165 return {
166 0: 'public',
167 1: 'draft',
168 2: 'secret',
169 }.get(phase_id) or ''
170
162 @LazyProperty
171 @LazyProperty
163 def phase(self):
172 def phase(self):
164 phase_id = self._remote.ctx_phase(self.idx)
173 phase_id = self._remote.ctx_phase(self.idx)
165 phase_text = {
174 phase_text = self._get_phase_text(phase_id)
166 0: 'public',
167 1: 'draft',
168 2: 'secret',
169 }.get(phase_id) or ''
170
175
171 return safe_unicode(phase_text)
176 return safe_unicode(phase_text)
172
177
@@ -166,6 +166,7 b' function registerRCRoutes() {'
166 pyroutes.register('repo_changelog', '/%(repo_name)s/changelog', ['repo_name']);
166 pyroutes.register('repo_changelog', '/%(repo_name)s/changelog', ['repo_name']);
167 pyroutes.register('repo_changelog_file', '/%(repo_name)s/changelog/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
167 pyroutes.register('repo_changelog_file', '/%(repo_name)s/changelog/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
168 pyroutes.register('repo_changelog_elements', '/%(repo_name)s/changelog_elements', ['repo_name']);
168 pyroutes.register('repo_changelog_elements', '/%(repo_name)s/changelog_elements', ['repo_name']);
169 pyroutes.register('repo_changelog_elements_file', '/%(repo_name)s/changelog_elements/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
169 pyroutes.register('repo_compare_select', '/%(repo_name)s/compare', ['repo_name']);
170 pyroutes.register('repo_compare_select', '/%(repo_name)s/compare', ['repo_name']);
170 pyroutes.register('repo_compare', '/%(repo_name)s/compare/%(source_ref_type)s@%(source_ref)s...%(target_ref_type)s@%(target_ref)s', ['repo_name', 'source_ref_type', 'source_ref', 'target_ref_type', 'target_ref']);
171 pyroutes.register('repo_compare', '/%(repo_name)s/compare/%(source_ref_type)s@%(source_ref)s...%(target_ref_type)s@%(target_ref)s', ['repo_name', 'source_ref_type', 'source_ref', 'target_ref_type', 'target_ref']);
171 pyroutes.register('tags_home', '/%(repo_name)s/tags', ['repo_name']);
172 pyroutes.register('tags_home', '/%(repo_name)s/tags', ['repo_name']);
@@ -94,7 +94,7 b' var CommitsController = function () {'
94 $('#graph_nodes').css({'padding-top': padding});
94 $('#graph_nodes').css({'padding-top': padding});
95 };
95 };
96
96
97 this.getChunkUrl = function (page, chunk, branch) {
97 this.getChunkUrl = function (page, chunk, branch, commit_id, f_path) {
98 var urlData = {
98 var urlData = {
99 'repo_name': templateContext.repo_name,
99 'repo_name': templateContext.repo_name,
100 'page': page,
100 'page': page,
@@ -104,12 +104,24 b' var CommitsController = function () {'
104 if (branch !== undefined && branch !== '') {
104 if (branch !== undefined && branch !== '') {
105 urlData['branch'] = branch;
105 urlData['branch'] = branch;
106 }
106 }
107 if (commit_id !== undefined && commit_id !== '') {
108 urlData['commit_id'] = commit_id;
109 }
110 if (f_path !== undefined && f_path !== '') {
111 urlData['f_path'] = f_path;
112 }
107
113
108 return pyroutes.url('repo_changelog_elements', urlData);
114 if (urlData['commit_id'] && urlData['f_path']) {
115 return pyroutes.url('repo_changelog_elements_file', urlData);
116 }
117 else {
118 return pyroutes.url('repo_changelog_elements', urlData);
119 }
120
109 };
121 };
110
122
111 this.loadNext = function (node, page, branch) {
123 this.loadNext = function (node, page, branch, commit_id, f_path) {
112 var loadUrl = this.getChunkUrl(page, 'next', branch);
124 var loadUrl = this.getChunkUrl(page, 'next', branch, commit_id, f_path);
113 var postData = {'graph': JSON.stringify(this.getCurrentGraphData())};
125 var postData = {'graph': JSON.stringify(this.getCurrentGraphData())};
114
126
115 $.post(loadUrl, postData, function (data) {
127 $.post(loadUrl, postData, function (data) {
@@ -119,8 +131,8 b' var CommitsController = function () {'
119 })
131 })
120 };
132 };
121
133
122 this.loadPrev = function (node, page, branch) {
134 this.loadPrev = function (node, page, branch, commit_id, f_path) {
123 var loadUrl = this.getChunkUrl(page, 'prev', branch);
135 var loadUrl = this.getChunkUrl(page, 'prev', branch, commit_id, f_path);
124 var postData = {'graph': JSON.stringify(this.getCurrentGraphData())};
136 var postData = {'graph': JSON.stringify(this.getCurrentGraphData())};
125
137
126 $.post(loadUrl, postData, function (data) {
138 $.post(loadUrl, postData, function (data) {
@@ -5,7 +5,7 b''
5 % if c.prev_page:
5 % if c.prev_page:
6 <tr>
6 <tr>
7 <td colspan="9" class="load-more-commits">
7 <td colspan="9" class="load-more-commits">
8 <a class="prev-commits" href="#loadPrevCommits" onclick="commitsController.loadPrev(this, ${c.prev_page}, '${c.branch_name}');return false">
8 <a class="prev-commits" href="#loadPrevCommits" onclick="commitsController.loadPrev(this, ${c.prev_page}, '${c.branch_name}', '${c.commit_id}', '${c.f_path}');return false">
9 ${_('load previous')}
9 ${_('load previous')}
10 </a>
10 </a>
11 </td>
11 </td>
@@ -131,7 +131,7 b''
131 % if c.next_page:
131 % if c.next_page:
132 <tr>
132 <tr>
133 <td colspan="9" class="load-more-commits">
133 <td colspan="9" class="load-more-commits">
134 <a class="next-commits" href="#loadNextCommits" onclick="commitsController.loadNext(this, ${c.next_page}, '${c.branch_name}');return false">
134 <a class="next-commits" href="#loadNextCommits" onclick="commitsController.loadNext(this, ${c.next_page}, '${c.branch_name}', '${c.commit_id}', '${c.f_path}');return false">
135 ${_('load next')}
135 ${_('load next')}
136 </a>
136 </a>
137 </td>
137 </td>
General Comments 0
You need to be logged in to leave comments. Login now