Show More
@@ -29,5 +29,18 b' def includeme(config):' | |||||
29 | name='repo_maintenance_execute', |
|
29 | name='repo_maintenance_execute', | |
30 | pattern='/{repo_name:.*?[^/]}/maintenance/execute', repo_route=True) |
|
30 | pattern='/{repo_name:.*?[^/]}/maintenance/execute', repo_route=True) | |
31 |
|
31 | |||
|
32 | ||||
|
33 | # Strip | |||
|
34 | config.add_route( | |||
|
35 | name='strip', | |||
|
36 | pattern='/{repo_name:.*?[^/]}/strip', repo_route=True) | |||
|
37 | ||||
|
38 | config.add_route( | |||
|
39 | name='strip_check', | |||
|
40 | pattern='/{repo_name:.*?[^/]}/strip_check', repo_route=True) | |||
|
41 | ||||
|
42 | config.add_route( | |||
|
43 | name='strip_execute', | |||
|
44 | pattern='/{repo_name:.*?[^/]}/strip_execute', repo_route=True) | |||
32 | # Scan module for configuration decorators. |
|
45 | # Scan module for configuration decorators. | |
33 | config.scan() |
|
46 | config.scan() |
@@ -19,18 +19,17 b'' | |||||
19 | # and proprietary license terms, please see https://rhodecode.com/licenses/ |
|
19 | # and proprietary license terms, please see https://rhodecode.com/licenses/ | |
20 |
|
20 | |||
21 | import logging |
|
21 | import logging | |
22 |
|
||||
23 | from pyramid.view import view_config |
|
22 | from pyramid.view import view_config | |
24 |
|
23 | |||
25 | from rhodecode.apps._base import RepoAppView |
|
24 | from rhodecode.apps._base import RepoAppView | |
26 | from rhodecode.lib.auth import (LoginRequired, HasRepoPermissionAnyDecorator, |
|
25 | from rhodecode.lib.auth import (LoginRequired, HasRepoPermissionAnyDecorator, | |
27 | NotAnonymous) |
|
26 | NotAnonymous) | |
28 | from rhodecode.lib import repo_maintenance |
|
27 | ||
29 |
|
28 | |||
30 | log = logging.getLogger(__name__) |
|
29 | log = logging.getLogger(__name__) | |
31 |
|
30 | |||
32 |
|
31 | |||
33 |
class |
|
32 | class StripView(RepoAppView): | |
34 | def load_default_context(self): |
|
33 | def load_default_context(self): | |
35 | c = self._get_local_tmpl_context() |
|
34 | c = self._get_local_tmpl_context() | |
36 |
|
35 | |||
@@ -44,27 +43,68 b' class RepoMaintenanceView(RepoAppView):' | |||||
44 | @NotAnonymous() |
|
43 | @NotAnonymous() | |
45 | @HasRepoPermissionAnyDecorator('repository.admin') |
|
44 | @HasRepoPermissionAnyDecorator('repository.admin') | |
46 | @view_config( |
|
45 | @view_config( | |
47 |
route_name=' |
|
46 | route_name='strip', request_method='GET', | |
48 | renderer='rhodecode:templates/admin/repos/repo_edit.mako') |
|
47 | renderer='rhodecode:templates/admin/repos/repo_edit.mako') | |
49 |
def |
|
48 | def strip(self): | |
50 | c = self.load_default_context() |
|
49 | c = self.load_default_context() | |
51 |
c.active = ' |
|
50 | c.active = 'strip' | |
52 | maintenance = repo_maintenance.RepoMaintenance() |
|
51 | c.strip_limit = 10 | |
53 | c.executable_tasks = maintenance.get_tasks_for_repo(self.db_repo) |
|
52 | ||
54 | return self._get_template_context(c) |
|
53 | return self._get_template_context(c) | |
55 |
|
54 | |||
56 | @LoginRequired() |
|
55 | @LoginRequired() | |
57 | @NotAnonymous() |
|
56 | @NotAnonymous() | |
58 | @HasRepoPermissionAnyDecorator('repository.admin') |
|
57 | @HasRepoPermissionAnyDecorator('repository.admin') | |
59 | @view_config( |
|
58 | @view_config( | |
60 |
route_name=' |
|
59 | route_name='strip_check', request_method='POST', | |
61 |
renderer='json', xhr=True |
|
60 | renderer='json', xhr=True | |
62 | def repo_maintenance_execute(self): |
|
61 | ) | |
|
62 | def strip_check(self): | |||
|
63 | from rhodecode.lib.vcs.backends.base import EmptyCommit | |||
|
64 | data = {} | |||
|
65 | rp = self.request.POST | |||
|
66 | for i in range(1, 11): | |||
|
67 | chset = 'changeset_id-%d'%(i,) | |||
|
68 | check = rp.get(chset) | |||
|
69 | if check: | |||
|
70 | data[i] = self.db_repo.get_changeset(rp[chset]) | |||
|
71 | if isinstance(data[i], EmptyCommit): | |||
|
72 | data[i] = {'rev': None, 'commit': rp[chset]} | |||
|
73 | else: | |||
|
74 | data[i] = {'rev': data[i].raw_id, 'branch': data[i].branch, 'author': data[i].author, | |||
|
75 | 'comment': data[i].message} | |||
|
76 | else: | |||
|
77 | break | |||
|
78 | return data | |||
|
79 | ||||
|
80 | @LoginRequired() | |||
|
81 | @NotAnonymous() | |||
|
82 | @HasRepoPermissionAnyDecorator('repository.admin') | |||
|
83 | @view_config( | |||
|
84 | route_name='strip_execute', request_method='POST', | |||
|
85 | renderer='json', xhr=True | |||
|
86 | ) | |||
|
87 | def strip_execute(self): | |||
|
88 | ||||
|
89 | from rhodecode.model.scm import ScmModel | |||
|
90 | from rhodecode.lib.ext_json import json | |||
|
91 | ||||
63 | c = self.load_default_context() |
|
92 | c = self.load_default_context() | |
64 | c.active = 'maintenance' |
|
93 | user = self._rhodecode_user | |
65 |
|
|
94 | rp = self.request.POST | |
66 |
|
95 | data = {} | ||
67 | maintenance = repo_maintenance.RepoMaintenance() |
|
96 | for idx in rp: | |
68 | executed_types = maintenance.execute(self.db_repo) |
|
97 | commit = json.loads(rp[idx]) | |
69 |
|
98 | #If someone put two times the same branch | ||
70 | return executed_types |
|
99 | if commit['branch'] in data.keys(): | |
|
100 | continue | |||
|
101 | try: | |||
|
102 | ScmModel().strip(repo=c.repo_info, | |||
|
103 | commit_id=commit['rev'], branch=commit['branch']) | |||
|
104 | log.info('Stripped commit %s from repo `%s` by %s' % (commit['rev'], c.repo_info.repo_name, user)) | |||
|
105 | data[commit['rev']] = True | |||
|
106 | except Exception, e: | |||
|
107 | data[commit['rev']] = False | |||
|
108 | log.debug('Stripped commit %s from repo `%s` failed by %s, exeption %s' % (commit['rev'], | |||
|
109 | c.repo_info.repo_name, user, e.message)) | |||
|
110 | return data |
@@ -74,6 +74,9 b'' | |||||
74 | <li class="${'active' if c.active=='maintenance' else ''}"> |
|
74 | <li class="${'active' if c.active=='maintenance' else ''}"> | |
75 | <a href="${h.route_path('repo_maintenance', repo_name=c.repo_name)}">${_('Maintenance')}</a> |
|
75 | <a href="${h.route_path('repo_maintenance', repo_name=c.repo_name)}">${_('Maintenance')}</a> | |
76 | </li> |
|
76 | </li> | |
|
77 | <li class="${'active' if c.active=='strip' else ''}"> | |||
|
78 | <a href="${h.route_path('strip', repo_name=c.repo_name)}">${_('Strip')}</a> | |||
|
79 | </li> | |||
77 | ## TODO: dan: replace repo navigation with navlist registry like with |
|
80 | ## TODO: dan: replace repo navigation with navlist registry like with | |
78 | ## admin menu. First must find way to allow runtime configuration |
|
81 | ## admin menu. First must find way to allow runtime configuration | |
79 | ## it to account for the c.repo_info.repo_type != 'svn' call above |
|
82 | ## it to account for the c.repo_info.repo_type != 'svn' call above |
@@ -1,58 +1,169 b'' | |||||
1 | <div class="panel panel-default"> |
|
1 | <div class="panel panel-default"> | |
2 | <div class="panel-heading"> |
|
2 | <div class="panel-heading"> | |
3 |
<h3 class="panel-title">${_(' |
|
3 | <h3 class="panel-title">${_('Strip')}</h3> | |
4 | </div> |
|
4 | </div> | |
5 | <div class="panel-body"> |
|
5 | <div class="panel-body"> | |
|
6 | %if c.repo_info.repo_type != 'svn': | |||
|
7 | <p> | |||
|
8 | <h4>${_('Please provide up to %s commits commits to strip')%c.strip_limit}</h4> | |||
|
9 | </p> | |||
|
10 | <p> | |||
|
11 | ${_('In the first step commits will be verified for existance in the repository')}. </br> | |||
|
12 | ${_('In the second step, correct commits will be available for stripping')}. | |||
|
13 | </p> | |||
|
14 | ${h.secure_form(h.route_path('strip_check', repo_name=c.repo_info.repo_name), method='post')} | |||
|
15 | <div id="change_body" class="field"> | |||
|
16 | <div id="box-1" class="inputx locked_input"> | |||
|
17 | <input class="text" id="changeset_id-1" name="changeset_id-1" size="59" | |||
|
18 | placeholder="${_('Enter full 40 character commit sha')}" type="text" value=""> | |||
|
19 | <div id = "plus_icon-1" class="btn btn-default plus_input_button"> | |||
|
20 | <i class="icon-plus" onclick="addNew(1);return false">${_('Add another commit')}</i> | |||
|
21 | </div> | |||
|
22 | </div> | |||
|
23 | </div> | |||
|
24 | <div id="results" style="display:none; padding: 10px 0px;"></div> | |||
|
25 | <div class="buttons"> | |||
|
26 | <button class="btn btn-small btn-primary" onclick="check_changsets();return false"> | |||
|
27 | ${_('Check commits')} | |||
|
28 | </button> | |||
|
29 | </div> | |||
|
30 | <div id="results" style="display:none; padding: 10px 0px;"></div> | |||
6 |
|
31 | |||
7 | <p> |
|
32 | ${h.end_form()} | |
8 | % if c.executable_tasks: |
|
33 | %else: | |
9 | ${_('Perform maintenance tasks for this repo, following tasks will be performed')}: |
|
34 | <p> | |
10 | <ol> |
|
35 | <h4>${_('Sorry this functionality is not available for SVN repository')}</h4> | |
11 | % for task in c.executable_tasks: |
|
36 | </p> | |
12 | <li>${task}</li> |
|
|||
13 | % endfor |
|
|||
14 | </ol> |
|
|||
15 | % else: |
|
|||
16 | ${_('No maintenance tasks for this repo available')} |
|
|||
17 | % endif |
|
|||
18 | </p> |
|
|||
19 |
|
37 | |||
20 | <div id="results" style="display:none; padding: 10px 0px;"></div> |
|
|||
21 |
|
|
38 | ||
22 | % if c.executable_tasks: |
|
39 | %endif | |
23 | <div class="form"> |
|
|||
24 | <div class="fields"> |
|
|||
25 | <button class="btn btn-small btn-primary" onclick="executeTask();return false"> |
|
|||
26 | ${_('Run Maintenance')} |
|
|||
27 | </button> |
|
|||
28 | </div> |
|
|||
29 | </div> |
|
|||
30 | % endif |
|
|||
31 |
|
40 | |||
32 | </div> |
|
41 | </div> | |
33 | </div> |
|
42 | </div> | |
34 |
|
43 | |||
35 |
|
44 | |||
36 | <script> |
|
45 | <script> | |
|
46 | var plus_leaf = 1; | |||
37 |
|
47 | |||
38 | executeTask = function() { |
|
48 | addNew = function(number){ | |
39 | var btn = $(this); |
|
49 | if (number >= ${c.strip_limit}){ | |
|
50 | return; | |||
|
51 | } | |||
|
52 | var minus = '<i id="i_minus_icon-'+(number+1)+'" class="icon-minus" onclick="delOld('+(number+1)+');return false">${_('Remove')}</i>'; | |||
|
53 | $('#plus_icon-'+number).detach(); | |||
|
54 | number++; | |||
|
55 | var input = '<div id="box-'+number+'" class="inputx locked_input">'+ | |||
|
56 | '<input class="text" id="changeset_id-'+number+'" name="changeset_id-'+number+'" size="59" type="text" value="">'+ | |||
|
57 | '<div id="plus_icon-'+number+'" class="btn btn-default plus_input_button">'+ | |||
|
58 | '<i id="i_plus_icon-'+(number)+'" class="icon-plus" onclick="addNew('+number+');return false">${_('Add another commit')}</i>'+ | |||
|
59 | '</div>'+ | |||
|
60 | '<div id="minus_icon-'+number+'" class="btn btn-default minus_input_button">'+ | |||
|
61 | minus + | |||
|
62 | '</div>' + | |||
|
63 | '</div>'; | |||
|
64 | $('#change_body').append(input); | |||
|
65 | plus_leaf++; | |||
|
66 | } | |||
|
67 | ||||
|
68 | function re_index(number){ | |||
|
69 | for(var i=number;i<=plus_leaf;i++){ | |||
|
70 | var check = $('#box-'+i); | |||
|
71 | if (check.length == 0){ | |||
|
72 | var change = $('#box-'+(i+1)); | |||
|
73 | ||||
|
74 | change.attr('id','box-'+i); | |||
|
75 | var plus = $('#plus_icon-'+(i+1)); | |||
|
76 | var i_plus = $('#i_plus_icon-'+(i+1)); | |||
|
77 | if (plus.length != 0){ | |||
|
78 | plus.attr('id','plus_icon-'+i); | |||
|
79 | i_plus.attr('id','i_plus_icon-'+i); | |||
|
80 | i_plus.attr('onclick','addNew('+i+');return false'); | |||
|
81 | plus_leaf--; | |||
|
82 | } | |||
|
83 | var minus = $('#minus_icon-'+(i+1)); | |||
|
84 | var i_minus = $('#i_minus_icon-'+(i+1)); | |||
|
85 | minus.attr('id','minus_icon-'+i); | |||
|
86 | i_minus.attr('id','i_minus_icon-'+i); | |||
|
87 | i_minus.attr('onclick','delOld('+i+');return false'); | |||
|
88 | } | |||
|
89 | } | |||
|
90 | } | |||
|
91 | ||||
|
92 | delOld = function(number){ | |||
|
93 | $('#box-'+number).remove(); | |||
|
94 | number = number - 1; | |||
|
95 | var box = $('#box-'+number); | |||
|
96 | var plus = '<div id="plus_icon-'+number+'" class="btn btn-default plus_input_button">'+ | |||
|
97 | '<i id="i_plus_icon-'+number+'" class="icon-plus" onclick="addNew('+number +');return false">${_('Add another commit')}</i></div>'; | |||
|
98 | var minus = $('#minus_icon-'+number); | |||
|
99 | if(number +1 == plus_leaf){ | |||
|
100 | minus.detach(); | |||
|
101 | box.append(plus); | |||
|
102 | box.append(minus); | |||
|
103 | } | |||
|
104 | re_index(number+1); | |||
|
105 | ||||
|
106 | } | |||
|
107 | ||||
|
108 | var result_data; | |||
|
109 | ||||
|
110 | check_changsets = function() { | |||
|
111 | var postData = $('form').serialize(); | |||
40 | $('#results').show(); |
|
112 | $('#results').show(); | |
41 |
$('#results').html('<h4>${_(' |
|
113 | $('#results').html('<h4>${_('Checking commits')}...</h4>'); | |
42 |
|
114 | var url = "${h.route_path('strip_check', repo_name=c.repo_info.repo_name)}"; | ||
|
115 | var btn = $('button'); | |||
43 | btn.attr('disabled', 'disabled'); |
|
116 | btn.attr('disabled', 'disabled'); | |
44 | btn.addClass('disabled'); |
|
117 | btn.addClass('disabled'); | |
45 |
|
118 | |||
46 | var url = "${h.route_path('repo_maintenance_execute', repo_name=c.repo_info.repo_name)}"; |
|
|||
47 | var success = function (data) { |
|
119 | var success = function (data) { | |
48 | var displayHtml = $('<pre></pre>'); |
|
120 | result_data = {}; | |
|
121 | var i = 0; | |||
|
122 | result =''; | |||
|
123 | $.each(data, function(index, value){ | |||
|
124 | i= index; | |||
|
125 | var box = $('#box-'+index); | |||
|
126 | if (value.rev){ | |||
|
127 | result_data[index] = JSON.stringify(value); | |||
|
128 | msg = '${_("author")}: ' + value.author + ' ${_("comment")}: ' + value.comment; | |||
|
129 | result += '<h4>' +value.rev+ '${_(' commit verified positive')}</br> '+ msg + '</h4>'; | |||
|
130 | } | |||
|
131 | else{ | |||
|
132 | result += '<h4>' +value.commit+ '${_('commit verified negative')}' + '</h4>'; | |||
|
133 | } | |||
|
134 | box.remove(); | |||
|
135 | }); | |||
|
136 | var box = $('#box-'+(parseInt(i)+1)); | |||
|
137 | box.remove(); | |||
|
138 | $('#results').html(result); | |||
|
139 | }; | |||
49 |
|
140 | |||
50 | $(displayHtml).append(data); |
|
141 | btn.html('Strip'); | |
51 | $('#results').html(displayHtml); |
|
142 | btn.removeAttr('disabled'); | |
52 |
|
|
143 | btn.removeClass('disabled'); | |
53 | btn.removeClass('disabled'); |
|
144 | btn.attr('onclick','strip();return false;'); | |
|
145 | ajaxPOST(url, postData, success, null); | |||
|
146 | }; | |||
|
147 | ||||
|
148 | strip = function(){ | |||
|
149 | var url = "${h.route_path('strip_execute', repo_name=c.repo_info.repo_name)}"; | |||
|
150 | var success = function(data){ | |||
|
151 | result = ''; | |||
|
152 | $.each(data, function(index, value){ | |||
|
153 | if(data[index]){ | |||
|
154 | result += '<h4>' +index+ '${_(' commit striped successful')}' + '</h4>'; | |||
|
155 | } | |||
|
156 | else{ | |||
|
157 | result += '<h4>' +index+ '${_(' commit striped failed')}' + '</h4>'; | |||
|
158 | } | |||
|
159 | }); | |||
|
160 | $('#results').html(result); | |||
|
161 | ||||
54 | }; |
|
162 | }; | |
55 |
ajax |
|
163 | ajaxPOST(url, result_data, success, null); | |
|
164 | var btn = $('button'); | |||
|
165 | btn.attr('disabled', 'disabled'); | |||
|
166 | btn.addClass('disabled'); | |||
56 |
|
167 | |||
57 | } |
|
168 | }; | |
58 | </script> |
|
169 | </script> |
General Comments 0
You need to be logged in to leave comments.
Login now