Show More
@@ -382,6 +382,11 b' def make_map(config):' | |||||
382 | controller='files', action='archivefile', |
|
382 | controller='files', action='archivefile', | |
383 | conditions=dict(function=check_repo)) |
|
383 | conditions=dict(function=check_repo)) | |
384 |
|
384 | |||
|
385 | rmap.connect('files_nodelist_home', | |||
|
386 | '/{repo_name:.*}/nodelist/{revision}/{f_path:.*}', | |||
|
387 | controller='files', action='nodelist', | |||
|
388 | conditions=dict(function=check_repo)) | |||
|
389 | ||||
385 | rmap.connect('repo_settings_delete', '/{repo_name:.*}/settings', |
|
390 | rmap.connect('repo_settings_delete', '/{repo_name:.*}/settings', | |
386 | controller='settings', action="delete", |
|
391 | controller='settings', action="delete", | |
387 | conditions=dict(method=["DELETE"], function=check_repo)) |
|
392 | conditions=dict(method=["DELETE"], function=check_repo)) |
@@ -25,12 +25,14 b'' | |||||
25 |
|
25 | |||
26 | import os |
|
26 | import os | |
27 | import logging |
|
27 | import logging | |
28 | import mimetypes |
|
|||
29 | import traceback |
|
28 | import traceback | |
30 |
|
29 | |||
|
30 | from os.path import join as jn | |||
|
31 | ||||
31 | from pylons import request, response, session, tmpl_context as c, url |
|
32 | from pylons import request, response, session, tmpl_context as c, url | |
32 | from pylons.i18n.translation import _ |
|
33 | from pylons.i18n.translation import _ | |
33 | from pylons.controllers.util import redirect |
|
34 | from pylons.controllers.util import redirect | |
|
35 | from pylons.decorators import jsonify | |||
34 |
|
36 | |||
35 | from vcs.backends import ARCHIVE_SPECS |
|
37 | from vcs.backends import ARCHIVE_SPECS | |
36 | from vcs.exceptions import RepositoryError, ChangesetDoesNotExistError, \ |
|
38 | from vcs.exceptions import RepositoryError, ChangesetDoesNotExistError, \ | |
@@ -95,6 +97,26 b' class FilesController(BaseRepoController' | |||||
95 |
|
97 | |||
96 | return file_node |
|
98 | return file_node | |
97 |
|
99 | |||
|
100 | ||||
|
101 | def __get_paths(self, changeset, starting_path): | |||
|
102 | """recursive walk in root dir and return a set of all path in that dir | |||
|
103 | based on repository walk function | |||
|
104 | """ | |||
|
105 | _files = list() | |||
|
106 | _dirs = list() | |||
|
107 | ||||
|
108 | try: | |||
|
109 | tip = changeset | |||
|
110 | for topnode, dirs, files in tip.walk(starting_path): | |||
|
111 | for f in files: | |||
|
112 | _files.append(f.path) | |||
|
113 | for d in dirs: | |||
|
114 | _dirs.append(d.path) | |||
|
115 | except RepositoryError, e: | |||
|
116 | log.debug(traceback.format_exc()) | |||
|
117 | pass | |||
|
118 | return _dirs, _files | |||
|
119 | ||||
98 | @HasRepoPermissionAnyDecorator('repository.read', 'repository.write', |
|
120 | @HasRepoPermissionAnyDecorator('repository.read', 'repository.write', | |
99 | 'repository.admin') |
|
121 | 'repository.admin') | |
100 | def index(self, repo_name, revision, f_path): |
|
122 | def index(self, repo_name, revision, f_path): | |
@@ -413,3 +435,13 b' class FilesController(BaseRepoController' | |||||
413 | hist_l.append(tags_group) |
|
435 | hist_l.append(tags_group) | |
414 |
|
436 | |||
415 | return hist_l |
|
437 | return hist_l | |
|
438 | ||||
|
439 | @jsonify | |||
|
440 | @HasRepoPermissionAnyDecorator('repository.read', 'repository.write', | |||
|
441 | 'repository.admin') | |||
|
442 | def nodelist(self, repo_name, revision, f_path): | |||
|
443 | if request.environ.get('HTTP_X_PARTIAL_XHR'): | |||
|
444 | cs = self.__get_cs_or_redirect(revision, repo_name) | |||
|
445 | _d, _f = self.__get_paths(cs, f_path) | |||
|
446 | return _d + _f | |||
|
447 |
@@ -52,7 +52,6 b' a {' | |||||
52 | color:#003367; |
|
52 | color:#003367; | |
53 | text-decoration:none; |
|
53 | text-decoration:none; | |
54 | cursor:pointer; |
|
54 | cursor:pointer; | |
55 | font-weight:700; |
|
|||
56 | } |
|
55 | } | |
57 |
|
56 | |||
58 | a:hover { |
|
57 | a:hover { | |
@@ -1863,7 +1862,7 b' padding:0;' | |||||
1863 |
|
1862 | |||
1864 | div.browserblock .browser-header { |
|
1863 | div.browserblock .browser-header { | |
1865 | background:#FFF; |
|
1864 | background:#FFF; | |
1866 |
padding:10px 0px |
|
1865 | padding:10px 0px 15px 0px; | |
1867 | width: 100%; |
|
1866 | width: 100%; | |
1868 | } |
|
1867 | } | |
1869 | div.browserblock .browser-nav { |
|
1868 | div.browserblock .browser-nav { | |
@@ -1884,6 +1883,25 b' margin-left:5px;' | |||||
1884 | font-weight:700; |
|
1883 | font-weight:700; | |
1885 | } |
|
1884 | } | |
1886 |
|
1885 | |||
|
1886 | div.browserblock .browser-search{ | |||
|
1887 | clear:both; | |||
|
1888 | padding:8px 8px 0px 5px; | |||
|
1889 | } | |||
|
1890 | ||||
|
1891 | div.browserblock .search_activate #filter_activate{ | |||
|
1892 | vertical-align: sub; | |||
|
1893 | border: 1px solid; | |||
|
1894 | padding:2px; | |||
|
1895 | border-radius: 4px 4px 4px 4px; | |||
|
1896 | background: url("../images/button.png") repeat-x scroll 0 0 #E5E3E3; | |||
|
1897 | border-color: #DDDDDD #DDDDDD #C6C6C6 #C6C6C6; | |||
|
1898 | color: #515151; | |||
|
1899 | } | |||
|
1900 | ||||
|
1901 | div.browserblock .search_activate a:hover{ | |||
|
1902 | text-decoration: none !important; | |||
|
1903 | } | |||
|
1904 | ||||
1887 | div.browserblock .browser-body { |
|
1905 | div.browserblock .browser-body { | |
1888 | background:#EEE; |
|
1906 | background:#EEE; | |
1889 | border-top:1px solid #CCC; |
|
1907 | border-top:1px solid #CCC; | |
@@ -2719,3 +2737,8 b' margin-top:-4px;' | |||||
2719 | padding-left:3px; |
|
2737 | padding-left:3px; | |
2720 | } |
|
2738 | } | |
2721 |
|
2739 | |||
|
2740 | #node_filter{ | |||
|
2741 | border:0px solid #545454; | |||
|
2742 | color:#AAAAAA; | |||
|
2743 | padding-left:3px; | |||
|
2744 | } |
@@ -12,7 +12,7 b'' | |||||
12 | <div class="info_box"> |
|
12 | <div class="info_box"> | |
13 | <span class="rev">${_('view')}@rev</span> |
|
13 | <span class="rev">${_('view')}@rev</span> | |
14 | <a class="rev" href="${c.url_prev}" title="${_('previous revision')}">«</a> |
|
14 | <a class="rev" href="${c.url_prev}" title="${_('previous revision')}">«</a> | |
15 |
${h.text('at_rev',value=c.changeset.revision,size= |
|
15 | ${h.text('at_rev',value=c.changeset.revision,size=5)} | |
16 | <a class="rev" href="${c.url_next}" title="${_('next revision')}">»</a> |
|
16 | <a class="rev" href="${c.url_next}" title="${_('next revision')}">»</a> | |
17 | ## ${h.submit('view',_('view'),class_="ui-button-small")} |
|
17 | ## ${h.submit('view',_('view'),class_="ui-button-small")} | |
18 | </div> |
|
18 | </div> | |
@@ -21,7 +21,20 b'' | |||||
21 | <div class="browser-branch"> |
|
21 | <div class="browser-branch"> | |
22 | ${h.checkbox('stay_at_branch',c.changeset.branch,c.changeset.branch==c.branch)} |
|
22 | ${h.checkbox('stay_at_branch',c.changeset.branch,c.changeset.branch==c.branch)} | |
23 | <label>${_('follow current branch')}</label> |
|
23 | <label>${_('follow current branch')}</label> | |
|
24 | </div> | |||
|
25 | <div class="browser-search"> | |||
|
26 | <div class="search_activate"> | |||
|
27 | <a id="filter_activate" href="#">${_('search file list')}</a> | |||
|
28 | </div> | |||
|
29 | ||||
|
30 | ||||
|
31 | <div> | |||
|
32 | <div id="node_filter_box_loading" style="display:none">${_('Loading file list...')}</div> | |||
|
33 | <div id="node_filter_box" style="display:none"> | |||
|
34 | ${h.files_breadcrumbs(c.repo_name,c.changeset.raw_id,c.files_list.path)}/<input type="text" value="type to search..." name="filter" size="25" id="node_filter" autocomplete="off"> | |||
|
35 | ||||
24 |
|
|
36 | <script type="text/javascript"> | |
|
37 | ||||
25 |
|
|
38 | YUE.on('stay_at_branch','click',function(e){ | |
26 |
|
|
39 | if(e.target.checked){ | |
27 |
|
|
40 | var uri = "${h.url.current(branch='__BRANCH__')}" | |
@@ -33,7 +46,107 b'' | |||||
33 |
|
|
46 | } | |
34 |
|
|
47 | ||
35 | }) |
|
48 | }) | |
|
49 | ||||
|
50 | var n_filter = YUD.get('node_filter'); | |||
|
51 | var F = YAHOO.namespace('node_filter'); | |||
|
52 | ||||
|
53 | var url = '${h.url("files_nodelist_home",repo_name="__REPO__",revision="__REVISION__",f_path="__FPATH__")}'; | |||
|
54 | var node_url = '${h.url("files_home",repo_name="__REPO__",revision="__REVISION__",f_path="__FPATH__")}'; | |||
|
55 | ||||
|
56 | url = url.replace('__REPO__','${c.repo_name}'); | |||
|
57 | url = url.replace('__REVISION__','${c.changeset.raw_id}'); | |||
|
58 | url = url.replace('__FPATH__','${c.files_list.path}'); | |||
|
59 | ||||
|
60 | node_url = node_url.replace('__REPO__','${c.repo_name}'); | |||
|
61 | node_url = node_url.replace('__REVISION__','${c.changeset.raw_id}'); | |||
|
62 | ||||
|
63 | ||||
|
64 | F.filterTimeout = null; | |||
|
65 | var nodes = null; | |||
|
66 | ||||
|
67 | ||||
|
68 | F.initFilter = function(){ | |||
|
69 | YUD.setStyle('node_filter_box_loading','display',''); | |||
|
70 | YUD.setStyle('filter_activate','display','none'); | |||
|
71 | YUC.initHeader('X-PARTIAL-XHR',true); | |||
|
72 | YUC.asyncRequest('GET',url,{ | |||
|
73 | success:function(o){ | |||
|
74 | nodes = JSON.parse(o.responseText); | |||
|
75 | YUD.setStyle('node_filter_box_loading','display','none'); | |||
|
76 | YUD.setStyle('node_filter_box','display',''); | |||
|
77 | }, | |||
|
78 | failure:function(o){ | |||
|
79 | console.log('failed to load'); | |||
|
80 | } | |||
|
81 | },null); | |||
|
82 | } | |||
|
83 | ||||
|
84 | F.updateFilter = function(e) { | |||
|
85 | ||||
|
86 | return function(){ | |||
|
87 | // Reset timeout | |||
|
88 | F.filterTimeout = null; | |||
|
89 | var query = e.target.value; | |||
|
90 | var match = []; | |||
|
91 | var matches = 0; | |||
|
92 | var matches_max = 20; | |||
|
93 | if (query != ""){ | |||
|
94 | for(var i=0;i<nodes.length;i++){ | |||
|
95 | var pos = nodes[i].toLowerCase().indexOf(query) | |||
|
96 | if(query && pos != -1){ | |||
|
97 | ||||
|
98 | matches++ | |||
|
99 | //show only certain amount to not kill browser | |||
|
100 | if (matches > matches_max){ | |||
|
101 | break; | |||
|
102 | } | |||
|
103 | ||||
|
104 | var n = nodes[i]; | |||
|
105 | var n_hl = n.substring(0,pos) | |||
|
106 | +"<b>{0}</b>".format(n.substring(pos,pos+query.length)) | |||
|
107 | +n.substring(pos+query.length) | |||
|
108 | match.push('<tr><td><a class="browser-file" href="{0}">{1}</a></td><td colspan="5"></td></tr>'.format(node_url.replace('__FPATH__',n),n_hl)); | |||
|
109 | } | |||
|
110 | if(match.length >= matches_max){ | |||
|
111 | match.push('<tr><td>{0}</td><td colspan="5"></td></tr>'.format("${_('search truncated')}")); | |||
|
112 | } | |||
|
113 | ||||
|
114 | } | |||
|
115 | } | |||
|
116 | ||||
|
117 | if(query != ""){ | |||
|
118 | YUD.setStyle('tbody','display','none'); | |||
|
119 | YUD.setStyle('tbody_filtered','display',''); | |||
|
120 | ||||
|
121 | if (match.length==0){ | |||
|
122 | match.push('<tr><td>{0}</td><td colspan="5"></td></tr>'.format("${_('no matching files')}")); | |||
|
123 | } | |||
|
124 | ||||
|
125 | YUD.get('tbody_filtered').innerHTML = match.join(""); | |||
|
126 | } | |||
|
127 | else{ | |||
|
128 | YUD.setStyle('tbody','display',''); | |||
|
129 | YUD.setStyle('tbody_filtered','display','none'); | |||
|
130 | } | |||
|
131 | ||||
|
132 | } | |||
|
133 | } | |||
|
134 | ||||
|
135 | ||||
|
136 | YUE.on(YUD.get('filter_activate'),'click',function(){ | |||
|
137 | F.initFilter(); | |||
|
138 | }) | |||
|
139 | YUE.on(n_filter,'click',function(){ | |||
|
140 | n_filter.value = ''; | |||
|
141 | }); | |||
|
142 | YUE.on(n_filter,'keyup',function(e){ | |||
|
143 | clearTimeout(F.filterTimeout); | |||
|
144 | F.filterTimeout = setTimeout(F.updateFilter(e),600); | |||
|
145 | }); | |||
36 |
|
|
146 | </script> | |
|
147 | ||||
|
148 | </div> | |||
|
149 | </div> | |||
37 |
|
|
150 | </div> | |
38 | </div> |
|
151 | </div> | |
39 |
|
152 | |||
@@ -50,6 +163,7 b'' | |||||
50 | </tr> |
|
163 | </tr> | |
51 | </thead> |
|
164 | </thead> | |
52 |
|
165 | |||
|
166 | <tbody id="tbody"> | |||
53 | %if c.files_list.parent: |
|
167 | %if c.files_list.parent: | |
54 | <tr class="parity0"> |
|
168 | <tr class="parity0"> | |
55 | <td> |
|
169 | <td> | |
@@ -97,6 +211,9 b'' | |||||
97 | </td> |
|
211 | </td> | |
98 | </tr> |
|
212 | </tr> | |
99 | %endfor |
|
213 | %endfor | |
|
214 | </tbody> | |||
|
215 | <tbody id="tbody_filtered" style="display:none"> | |||
|
216 | </tbody> | |||
100 | </table> |
|
217 | </table> | |
101 | </div> |
|
218 | </div> | |
102 | </div> No newline at end of file |
|
219 | </div> |
General Comments 0
You need to be logged in to leave comments.
Login now