##// END OF EJS Templates
Implemented #111 copy github node finder solution
marcink -
r1452:8585fbf3 beta
parent child Browse files
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 25px 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')}">&laquo;</a>
14 <a class="rev" href="${c.url_prev}" title="${_('previous revision')}">&laquo;</a>
15 ${h.text('at_rev',value=c.changeset.revision,size=3)}
15 ${h.text('at_rev',value=c.changeset.revision,size=5)}
16 <a class="rev" href="${c.url_next}" title="${_('next revision')}">&raquo;</a>
16 <a class="rev" href="${c.url_next}" title="${_('next revision')}">&raquo;</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 <script type="text/javascript">
36 <script type="text/javascript">
37
25 YUE.on('stay_at_branch','click',function(e){
38 YUE.on('stay_at_branch','click',function(e){
26 if(e.target.checked){
39 if(e.target.checked){
27 var uri = "${h.url.current(branch='__BRANCH__')}"
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 </script>
146 </script>
147
148 </div>
149 </div>
37 </div>
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