• R/O
  • SSH
  • HTTPS

shibuya-trac: Commit


Commit MetaInfo

Revision804 (tree)
Time2011-07-03 16:08:18
Authortacky21jp

Log Message

trac0.11用

Change Summary

Incremental Difference

Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
--- plugins/stepcounterplugin/branches/trac_0.11/license.txt (nonexistent)
+++ plugins/stepcounterplugin/branches/trac_0.11/license.txt (revision 804)
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
--- plugins/stepcounterplugin/branches/trac_0.11/setup.py (nonexistent)
+++ plugins/stepcounterplugin/branches/trac_0.11/setup.py (revision 804)
@@ -0,0 +1,16 @@
1+from setuptools import find_packages, setup
2+
3+setup(
4+ name='StepCounterPlugin', version='0.1.0',
5+ author = "tacky21jp",
6+ author_email = "tacky21jp@gmail.com",
7+ description = "Step Counter for repository.",
8+ license = "NEW BSD",
9+ url = "http://d.hatena.ne.jp/tacky21jp/",
10+ packages=find_packages(exclude=['*.tests*']),
11+ package_data={'stepcounter': ['templates/*.html','htdocs/css/*.css']},
12+
13+ entry_points = {'trac.plugins':
14+ ['stepcounter.StepCounter = stepcounter.StepCounter',],},
15+
16+)
--- plugins/stepcounterplugin/branches/trac_0.11/stepcounter/StepCounter.py (nonexistent)
+++ plugins/stepcounterplugin/branches/trac_0.11/stepcounter/StepCounter.py (revision 804)
@@ -0,0 +1,225 @@
1+'''
2+Created on 2010/09/12
3+
4+@author: tacky21jp
5+'''
6+import re
7+from datetime import datetime
8+
9+from trac.core import *
10+from trac.web import IRequestHandler
11+from trac.env import IEnvironmentSetupParticipant
12+from trac.web.chrome import INavigationContributor, ITemplateProvider, add_stylesheet, add_script, add_link
13+from trac.perm import IPermissionRequestor
14+from trac.mimeview.api import Context
15+from trac.resource import ResourceNotFound
16+from trac.util import sorted, embedded_numbers
17+from trac.config import Configuration
18+
19+from trac.versioncontrol.api import NoSuchChangeset, NoSuchNode
20+from trac.versioncontrol.web_ui.util import *
21+
22+from genshi.builder import tag
23+from stepcounter.StepCounterBuilder import *
24+
25+class StepCounterPlugin(Component):
26+ implements(IEnvironmentSetupParticipant,
27+ INavigationContributor, IRequestHandler, ITemplateProvider,IPermissionRequestor)
28+
29+ counterBuilder = StepCounterBuilder()
30+
31+ # INavigationContributor methods
32+ def get_active_navigation_item(self, req):
33+ return 'StepCounter'
34+
35+ def get_navigation_items(self, req):
36+ default_path = Configuration.get(self.config, 'stepcounter', 'default_path', default='/')
37+
38+ yield ('mainnav', 'StepCounter',
39+ tag.a('StepCounter', href=req.href.stepcounter(default_path)))
40+
41+ # IEnvironmentSetupParticipant methods
42+ def environment_created(self):
43+ pass
44+
45+ def environment_needs_upgrade(self, db):
46+ return False
47+
48+ def upgrade_environment(self, db):
49+ pass
50+
51+ # IRequestHandler methods
52+ def match_request(self, req):
53+ match = re.match(r'/(stepcounter)(/.*)?$', req.path_info)
54+ if match:
55+ mode, path = match.groups()
56+ req.args['path'] = path or '/'
57+ return True
58+
59+
60+ def process_request(self, req):
61+ req.perm.assert_permission('BROWSER_VIEW')
62+
63+ path = req.args.get('path', '/')
64+ rev = req.args.get('rev', None)
65+ order = req.args.get('order', None)
66+ desc = req.args.get('desc', None)
67+ xhr = req.get_header('X-Requested-With') == 'XMLHttpRequest'
68+ commiter = req.args.get('commiter', None)
69+
70+ repos = self.env.get_repository(req.authname)
71+
72+ try:
73+ if rev:
74+ rev = repos.normalize_rev(rev)
75+ rev_or_latest = rev or repos.youngest_rev
76+ node = get_existing_node(req, repos, path, rev_or_latest)
77+ except NoSuchChangeset, e:
78+ raise ResourceNotFound(e.message, _('Invalid Changeset Number'))
79+
80+ context = Context.from_request(req, 'source', path, rev_or_latest)
81+
82+ path_links = self.get_counter_path_links(req.href, path, rev, order, desc)
83+ if len(path_links) > 1:
84+ try:
85+ add_link(req, 'up', path_links[-2]['href'], _('Parent directory'))
86+ except Exception,e:
87+ pass
88+
89+ dir = node.isdir and self.count_dir(req, repos, node, rev, commiter)
90+
91+ if dir:
92+ sum_step=0
93+ sum_comment=0
94+ for r in dir['counts']:
95+ if r.step:
96+ sum_step = sum_step + r.step
97+ if r.commentStep:
98+ sum_comment = sum_comment + r.commentStep
99+ dir['sum_step']=sum_step
100+ dir['sum_comment']=sum_comment
101+
102+ data = {
103+ 'context': context,
104+ 'path': path, 'rev': node.rev, 'stickyrev': rev,
105+ 'created_path': node.created_path,
106+ 'created_rev': node.created_rev,
107+ 'path_links': path_links,
108+ 'dir':dir
109+ }
110+
111+ add_stylesheet(req, 'stepcounter/css/stepcounter.css')
112+
113+ return 'stepcounter.html',data, None
114+
115+ # ITemplateProvider methods
116+ def get_templates_dirs(self):
117+ from pkg_resources import resource_filename
118+ return [resource_filename(__name__, 'templates')]
119+
120+ def get_htdocs_dirs(self):
121+ from pkg_resources import resource_filename
122+ return [('stepcounter',resource_filename(__name__, 'htdocs'))]
123+
124+ #IPermissionRequestor methods
125+ def get_permission_actions(self):
126+ return ['BROWSER_VIEW ','BROWSER_VIEW ']
127+
128+
129+ # Internal methods
130+
131+ def count_dir(self, req, repos, node, rev=None, commiter=None):
132+
133+ # Entries metadata
134+ class entry(object):
135+ __slots__ = 'name rev kind isdir path content_length'.split()
136+ def __init__(self, node):
137+ for f in self.__slots__:
138+ setattr(self, f, getattr(node, f))
139+
140+ entries = [entry(n) for n in node.get_entries()]
141+ result = []
142+ count_result = []
143+
144+ changes = get_changes(repos, [i.rev for i in entries])
145+
146+ for e in entries:
147+ if not(e.isdir):
148+ _node = get_existing_node(req, repos, e.path, rev)
149+ rev_or_latest = rev or repos.youngest_rev
150+ if commiter is None or changes[e.rev] is None or (changes[e.rev] and commiter == changes[e.rev].author):
151+ context = Context.from_request(req, 'source', e.path, rev_or_latest)
152+ count = self.count_file(req,context,repos,_node,rev)
153+
154+ if count:
155+ result.append(e)
156+ count_result.append(count)
157+ for e in entries:
158+ if e.isdir:
159+ _node = get_existing_node(req, repos, e.path, rev)
160+ rev_or_latest = rev or repos.youngest_rev
161+ _dat = self.count_dir(req, repos, _node, rev_or_latest, commiter)
162+
163+ result.extend(_dat['entries'])
164+ count_result.extend(_dat['counts'])
165+
166+ if rev:
167+ newest = repos.get_changeset(rev).date
168+ else:
169+ newest = datetime.now(req.tz)
170+
171+ # Ordering of entries
172+ order = req.args.get('order', 'name').lower()
173+ desc = req.args.has_key('desc')
174+
175+ if order == 'date':
176+ def file_order(a):
177+ return changes[a.rev].date
178+ elif order == 'size':
179+ def file_order(a):
180+ return (a.content_length,
181+ embedded_numbers(a.name.lower()))
182+ else:
183+ def file_order(a):
184+ return embedded_numbers(a.name.lower())
185+
186+ dir_order = desc and 1 or -1
187+
188+ def browse_order(a):
189+ return a.isdir and dir_order or 0, file_order(a)
190+ entries = sorted(entries, key=browse_order, reverse=desc)
191+
192+
193+ add_script(req, 'common/js/expand_dir.js')
194+ add_script(req, 'common/js/keyboard_nav.js')
195+
196+ return {'order': order, 'desc': desc and 1 or None,
197+ 'entries': result, 'changes': changes, 'counts':count_result,
198+ }
199+
200+ def count_file(self, req, context, repos, node, rev=None):
201+
202+ result = None
203+
204+ counter = self.counterBuilder.getCounter(node.path)
205+
206+ if counter:
207+ content = node.get_content()
208+ result = counter.countContent(content.read())
209+ #self.log.debug('%s' % node.path)
210+ else:
211+ #result = StepCountResult('','',0,0,0)
212+ result = None
213+ return result
214+
215+ def get_counter_path_links(self,href, fullpath, rev, order=None, desc=None):
216+ links = [{'name': 'root',
217+ 'href': href.stepcounter(rev=rev, order=order, desc=desc)}]
218+ path = ''
219+ for part in [p for p in fullpath.split('/') if p]:
220+ path += part + '/'
221+ links.append({
222+ 'name': part,
223+ 'href': href.stepcounter(path, rev=rev, order=order, desc=desc)
224+ })
225+ return links
\ No newline at end of file
--- plugins/stepcounterplugin/branches/trac_0.11/stepcounter/htdocs/css/stepcounter.css (nonexistent)
+++ plugins/stepcounterplugin/branches/trac_0.11/stepcounter/htdocs/css/stepcounter.css (revision 804)
@@ -0,0 +1,67 @@
1+@charset "utf-8";
2+
3+.message{
4+ padding:3px;
5+ border: 2px solid green;
6+ background-color:#66CC99;
7+ text-align:left;
8+}
9+
10+.error{
11+ padding:3px;
12+ border: 2px solid #DD0000;
13+ background-color:#FFDDCC;
14+ text-align:left;
15+}
16+
17+.list {
18+ border-collapse:collapse;
19+ border:solid 1px #BBBBBB;
20+ margin:0px 2px 0px 2px;
21+}
22+
23+.list .odd {
24+ background:#FFFFFF;
25+}
26+
27+.list .even {
28+ background:#F4F4F4;
29+}
30+
31+.list .expired {
32+ background:#FF8888;
33+}
34+
35+.list .warn {
36+ background:#FFFF88;
37+}
38+
39+.list th {
40+ background:url(../img/list_label.gif) repeat-x;
41+ border-right:solid 1px #BBBBBB;
42+ border-bottom:solid 1px #BBBBBB;
43+ text-align:center;
44+ color:#444444;
45+ padding:2px 0px 2px 0px;
46+ white-space: nowrap;
47+}
48+
49+.list tbody td {
50+ border-right:solid 1px #BBBBBB;
51+ border-bottom:solid 1px #BBBBBB;
52+ color:#444444;
53+ padding:3px 5px;
54+ white-space: nowrap;
55+}
56+
57+.list input {
58+ height:20px;
59+ padding:0px 2px;
60+ margin:0px auto;
61+ white-space: nowrap;
62+}
63+
64+.count{
65+ text-align:right;
66+}
67+
--- plugins/stepcounterplugin/branches/trac_0.11/stepcounter/__init__.py (nonexistent)
+++ plugins/stepcounterplugin/branches/trac_0.11/stepcounter/__init__.py (revision 804)
@@ -0,0 +1 @@
1+from StepCounter import *
--- plugins/stepcounterplugin/branches/trac_0.11/stepcounter/StepCounterBuilder.py (nonexistent)
+++ plugins/stepcounterplugin/branches/trac_0.11/stepcounter/StepCounterBuilder.py (revision 804)
@@ -0,0 +1,443 @@
1+'''
2+Created on 2010/09/12
3+
4+@author: tacky21jp
5+'''
6+class StepCounterBuilder:
7+
8+ counter_map = {}
9+
10+ def getCounter(self,fileName):
11+
12+ if(fileName.endswith(".java")):
13+ counter = None
14+ if self.counter_map.has_key("Java"):
15+ counter = self.counter_map["Java"]
16+ else:
17+ counter = self.createJavaCounter("Java")
18+ self.counter_map["Java"] = counter
19+ return counter
20+
21+ elif (fileName.endswith(".jsp")):
22+ counter = None
23+ if self.counter_map.has_key("JSP"):
24+ counter = self.counter_map["JSP"]
25+ else:
26+ counter = DefaultStepCounter();
27+ counter.addSingleLineComment("//")
28+ counter.addMultiLineComment("/*","*/")
29+ counter.addMultiLineComment("<%--","--%>")
30+ counter.addMultiLineComment("<!--","-->")
31+ counter.setFileType("JSP")
32+ self.counter_map["JSP"] = counter
33+ return counter
34+
35+ elif (fileName.endswith(".js")):
36+ counter = None
37+ if self.counter_map.has_key("js"):
38+ counter = self.counter_map["js"]
39+ else:
40+ counter = self.createJavaCounter("js")
41+ self.counter_map["js"] = counter
42+ return counter
43+
44+ elif (fileName.endswith(".cpp") or fileName.endswith(".c")):
45+ counter = None
46+ if self.counter_map.has_key("C/C++"):
47+ counter = self.counter_map["C/C++"]
48+ else:
49+ counter = self.createJavaCounter("C/C++")
50+ self.counter_map["C/C++"] = counter
51+ return counter
52+
53+ elif (fileName.endswith(".h")):
54+ counter = None
55+ if self.counter_map.has_key("h"):
56+ counter = self.counter_map["h"]
57+ else:
58+ counter = self.createJavaCounter("h")
59+ self.counter_map["h"] = counter
60+ return counter
61+
62+ elif (fileName.endswith(".cs")):
63+ counter = None
64+ if self.counter_map.has_key("C#"):
65+ counter = self.counter_map["C#"]
66+ else:
67+ counter = self.createJavaCounter("C#")
68+ self.counter_map["C#"] = counter
69+ return counter
70+
71+ elif (fileName.endswith(".php") or fileName.endswith(".php3")):
72+ counter = None
73+ if self.counter_map.has_key("PHP"):
74+ counter = self.counter_map["PHP"]
75+ else:
76+ counter = DefaultStepCounter()
77+ counter.addSingleLineComment("//")
78+ counter.addMultiLineComment("/*","*/")
79+ counter.addMultiLineComment("<!--","-->")
80+ counter.setFileType("PHP")
81+ self.counter_map["PHP"] = counter
82+ return counter
83+
84+ elif (fileName.endswith(".asp") or fileName.endswith(".asa") or fileName.endswith(".aspx") or fileName.endswith(".asax") or fileName.endswith(".ascx")):
85+ counter = None
86+ if self.counter_map.has_key("ASP"):
87+ counter = self.counter_map["ASP"]
88+ else:
89+ counter = DefaultStepCounter()
90+ counter.addSingleLineComment("'")
91+ counter.addSingleLineComment("//")
92+ counter.addMultiLineComment("/*","*/")
93+ counter.addMultiLineComment("<%--","--%>")
94+ counter.addMultiLineComment("<!--","-->")
95+ counter.setFileType("ASP")
96+ self.counter_map["ASP"] = counter
97+ return counter
98+
99+ elif (fileName.endswith(".html") or fileName.endswith(".htm")):
100+ counter = None
101+ if self.counter_map.has_key("HTML"):
102+ counter = self.counter_map["HTML"]
103+ else:
104+ counter = self.createXMLCounter("HTML")
105+ self.counter_map["HTML"] = counter
106+ return counter
107+
108+ elif (fileName.endswith(".vbs")):
109+ counter = None
110+ if self.counter_map.has_key("vbs"):
111+ counter = self.counter_map["vbs"]
112+ else:
113+ counter = self.createVBCounter("vbs")
114+ self.counter_map["vbs"] = counter
115+ return counter
116+
117+ elif (fileName.endswith(".bas") or fileName.endswith(".frm") or fileName.endswith(".cls")):
118+ counter = None
119+ if self.counter_map.has_key("VB"):
120+ counter = self.counter_map["VB"]
121+ else:
122+ counter = self.createVBCounter("VB")
123+ self.counter_map["VB"] = counter
124+ return counter
125+
126+ elif (fileName.endswith(".vb")):
127+ counter = None
128+ if self.counter_map.has_key("VB.NET"):
129+ counter = self.counter_map["VB.NET"]
130+ else:
131+ counter = self.createVBCounter("VB.NET")
132+ self.counter_map["VB.NET"] = counter
133+ return counter
134+
135+ elif (fileName.endswith(".pl") or fileName.endswith(".pm")):
136+ counter = None
137+ if self.counter_map.has_key("Perl"):
138+ counter = self.counter_map["Perl"]
139+ else:
140+ counter = DefaultStepCounter()
141+ counter.addSingleLineComment("#")
142+ counter.addMultiLineComment("=pod","=cut")
143+ counter.setFileType("Perl")
144+ self.counter_map["Perl"] = counter
145+ return counter
146+
147+ elif (fileName.endswith(".py")):
148+ counter = None
149+ if self.counter_map.has_key("Python"):
150+ counter = self.counter_map["Python"]
151+ else:
152+ counter = DefaultStepCounter()
153+ counter.addSingleLineComment("#")
154+ counter.setFileType("Python")
155+ self.counter_map["Python"] = counter
156+ return counter
157+
158+ elif (fileName.endswith(".rb")):
159+ counter = None
160+ if self.counter_map.has_key("Ruby"):
161+ counter = self.counter_map["Ruby"]
162+ else:
163+ counter = DefaultStepCounter()
164+ counter.addSingleLineComment("#")
165+ counter.addMultiLineComment("=begin","=end")
166+ counter.setFileType("Ruby")
167+ self.counter_map["Ruby"] = counter
168+ return counter
169+
170+ elif (fileName.endswith(".tcl")):
171+ return self.createShellCounter("Tcl");
172+
173+ elif (fileName.endswith(".sql")):
174+ counter = None
175+ if self.counter_map.has_key("SQL"):
176+ counter = self.counter_map["SQL"]
177+ else:
178+ counter = DefaultStepCounter()
179+ counter.addSingleLineComment("#")
180+ counter.addSingleLineComment("--")
181+ counter.addSingleLineComment("REM")
182+ counter.addMultiLineComment("/*","*/");
183+ counter.setFileType("SQL")
184+ self.counter_map["SQL"] = counter
185+ return counter
186+
187+ elif (fileName.endswith(".cfm")):
188+ counter = None
189+ if self.counter_map.has_key("CFM"):
190+ counter = self.counter_map["CFM"]
191+ else:
192+ counter = DefaultStepCounter()
193+ counter.addMultiLineComment("<!--","-->")
194+ counter.addMultiLineComment("<!---","--->")
195+ counter.setFileType("CFM")
196+ self.counter_map["CFM"] = counter
197+ return counter
198+
199+ elif (fileName.endswith(".properties")):
200+ counter = None
201+ if self.counter_map.has_key("Properties"):
202+ counter = self.counter_map["Properties"]
203+ else:
204+ counter = self.createShellCounter("Properties")
205+ self.counter_map["Properties"] = counter
206+ return counter
207+
208+ elif (fileName.endswith(".xml")):
209+ counter = None
210+ if self.counter_map.has_key("XML"):
211+ counter = self.counter_map["XML"]
212+ else:
213+ counter = self.createXMLCounter("XML")
214+ self.counter_map["XML"] = counter
215+ return counter
216+
217+ elif (fileName.endswith(".xsl") or fileName.endswith(".xslt")):
218+ counter = None
219+ if self.counter_map.has_key("XSLT"):
220+ counter = self.counter_map["XSLT"]
221+ else:
222+ counter = self.createXMLCounter("XSLT")
223+ self.counter_map["XSLT"] = counter
224+ return counter
225+
226+ elif (fileName.endswith(".dtd")):
227+ counter = None
228+ if self.counter_map.has_key("DTD"):
229+ counter = self.counter_map["DTD"]
230+ else:
231+ counter = self.createXMLCounter("DTD")
232+ self.counter_map["DTD"] = counter
233+ return counter
234+
235+ elif (fileName.endswith(".tld")):
236+ counter = None
237+ if self.counter_map.has_key("TLD"):
238+ counter = self.counter_map["TLD"]
239+ else:
240+ counter = self.createXMLCounter("TLD")
241+ self.counter_map["TLD"] = counter
242+ return counter
243+
244+ elif (fileName.endswith(".xsd")):
245+ counter = None
246+ if self.counter_map.has_key("XMLSchema"):
247+ counter = self.counter_map["XMLSchema"]
248+ else:
249+ counter = self.createXMLCounter("XMLSchema")
250+ self.counter_map["XMLSchema"] = counter
251+ return counter
252+
253+ elif (fileName.endswith(".bat")):
254+ counter = None
255+ if self.counter_map.has_key("BAT"):
256+ counter = self.counter_map["BAT"]
257+ else:
258+ counter = DefaultStepCounter()
259+ counter.addSingleLineComment("REM")
260+ counter.setFileType("BAT")
261+ self.counter_map["BAT"] = counter
262+ return counter
263+
264+ elif (fileName.endswith(".css")):
265+ counter = None
266+ if self.counter_map.has_key("CSS"):
267+ counter = self.counter_map["CSS"]
268+ else:
269+ counter = DefaultStepCounter()
270+ counter.addMultiLineComment("/*","*/")
271+ counter.setFileType("CSS")
272+ self.counter_map["CSS"] = counter
273+ return counter
274+
275+ elif (fileName.endswith(".l") or fileName.endswith(".el") or fileName.endswith(".cl")):
276+ counter = None
277+ if self.counter_map.has_key("Lisp"):
278+ counter = self.counter_map["Lisp"]
279+ else:
280+ counter = DefaultStepCounter()
281+ counter.addSingleLineComment(";")
282+ counter.setFileType("Lisp")
283+ self.counter_map["Lisp"] = counter
284+ return counter
285+
286+ elif (fileName.endswith(".ini")):
287+ counter = None
288+ if self.counter_map.has_key("INI"):
289+ counter = self.counter_map["INI"]
290+ else:
291+ counter = DefaultStepCounter()
292+ counter.addSingleLineComment(";")
293+ counter.setFileType("INI")
294+ self.counter_map["INI"] = counter
295+ return counter
296+
297+ else:
298+ return None
299+
300+ def createJavaCounter(self,name):
301+ counter = DefaultStepCounter()
302+ counter.addSingleLineComment("//")
303+ counter.addMultiLineComment("/*","*/")
304+ counter.setFileType(name)
305+ return counter
306+
307+ def createVBCounter(self,name):
308+ counter = DefaultStepCounter()
309+ counter.addSingleLineComment("'")
310+ counter.addSingleLineComment("REM")
311+ counter.setFileType(name)
312+ return counter
313+
314+ def createShellCounter(self,name):
315+ counter = DefaultStepCounter()
316+ counter.addSingleLineComment("#")
317+ counter.setFileType(name)
318+ return counter
319+
320+ def createXMLCounter(self,name):
321+ counter = DefaultStepCounter()
322+ counter.addMultiLineComment("<!--","-->")
323+ counter.setFileType(name)
324+ return counter
325+
326+class DefaultStepCounter:
327+
328+ singleLineComment = []
329+ multiLineComment = []
330+ fileType = "UNDEF"
331+
332+ def setFileType(self, fileType):
333+ self.fileType = fileType
334+
335+ def getFileType(self):
336+ return self.fileType
337+
338+ def addSingleLineComment(self, str):
339+ self.singleLineComment.append(str)
340+
341+ def getSingleLineComment(self):
342+ return self.singleLineComment
343+
344+ def addMultiLineComment(self, comment_from,comment_to):
345+ self.multiLineComment.append([comment_from,comment_to])
346+
347+ def getMultiLineComment(self):
348+ return self.multiLineComment
349+
350+ def countContent(self,content):
351+ step = 0
352+ non = 0
353+ comment = 0
354+ multiLineFlag = False
355+ lastLineComment = []
356+ for line in content.split("\n"):
357+ if(multiLineFlag==False):
358+ if(self.nonCheck(line.strip())):
359+ non = non + 1
360+ elif(self.isSingleLineComment(line.strip())):
361+ comment = comment + 1
362+ else:
363+ lastLineComment = self.isMultiLineCommentStart(line,comment)
364+ if(lastLineComment!=None):
365+ comment = comment + 1
366+ multiLineFlag = True
367+ else:
368+ step = step + 1
369+ else:
370+ comment = comment + 1
371+ if (self.isMultiLineCommentEnd(line,lastLineComment)):
372+ multiLineFlag = False
373+
374+ return StepCountResult('',self.getFileType(),step,non,comment)
375+
376+ def nonCheck(self,line):
377+ if(line==''):
378+ return True
379+ else:
380+ return False
381+
382+ def isSingleLineComment(self, line):
383+ dim = self.getSingleLineComment()
384+ for d in dim:
385+ if(line.startswith(d)):
386+ return True
387+
388+ area = self.getMultiLineComment()
389+ for a in area:
390+ start = a[0]
391+ end = a[1]
392+
393+ idx = line.find(start);
394+ if(idx==0 and line.find(end,idx)==len(line)-len(end)):
395+ return True
396+
397+ return False
398+
399+ def isMultiLineCommentStart(self,line,comment):
400+ area = self.getMultiLineComment()
401+ for a in area:
402+ start = a[0]
403+ end = a[1]
404+
405+ idx = line.find(start)
406+ if(idx>=0 and line.find(end,idx)<0):
407+ return a
408+ return None
409+
410+ def isMultiLineCommentEnd(self,line,area):
411+ end = area[1]
412+ if(line.find(end)>=0):
413+ return True
414+ else:
415+ return False
416+
417+class StepCountResult:
418+
419+ def __init__(self,fileName,fileType,step,nonStep,comment):
420+ self.fileName = fileName
421+ self.fileType = fileType
422+ self.step = step
423+ self.nonStep = nonStep
424+ self.commentStep = comment
425+
426+ def getFileName(self):
427+ return self.fileName
428+
429+ def getFileType(self):
430+ return self.fileType
431+
432+ def getStep(self):
433+ return self.step
434+
435+ def getNonStep(self):
436+ return self.nonStep
437+
438+ def getCommentStep(self):
439+ return self.commentStep
440+
441+ def toString(self):
442+ return "%s,%s,%d,%d,%d" % self.getFileName(),self.getFileType(),self.getStep(),self.getNonStep,self.getCommentStep()
443+
--- plugins/stepcounterplugin/branches/trac_0.11/stepcounter/templates/stepcounter.html (nonexistent)
+++ plugins/stepcounterplugin/branches/trac_0.11/stepcounter/templates/stepcounter.html (revision 804)
@@ -0,0 +1,105 @@
1+<!DOCTYPE html
2+ PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
3+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
4+<html xmlns="http://www.w3.org/1999/xhtml"
5+ xmlns:py="http://genshi.edgewall.org/"
6+ xmlns:xi="http://www.w3.org/2001/XInclude">
7+ <xi:include href="layout.html" />
8+ <xi:include href="macros.html" />
9+ <head>
10+ <title>$path</title>
11+ </head>
12+<?python
13+import os
14+?>
15+ <body>
16+ <div id="content" class="browser">
17+ <div id="jumprev">
18+ <form action="" method="get">
19+ <div>
20+ <B>PATH:${path}</B>
21+ </div>
22+ <div>
23+ <label for="rev" title="${stickyrev and _('Hint: clear the field to view latest revision') or None}">
24+ ${_('View revision')}:</label>
25+ <input type="text" id="rev" name="rev" value="$stickyrev" size="6" />
26+ </div>
27+ </form>
28+ </div>
29+
30+ <table class="listing" id="dirlist">
31+ <thead>
32+ <tr>
33+ <th class="rev">${_('Directory Name')}</th>
34+ <th class="rev">${_('File Name')}</th>
35+ <th class="rev">${_('Size')}</th>
36+ <th class="rev">${_('Rev')}</th>
37+ <th class="rev">${_('Age')}</th>
38+ <th class="change">${_('Last Change')}</th>
39+ <th class="change">ログ</th>
40+ <th class="change">タイプ</th>
41+ <th class="change">実ステップ行数</th>
42+ <th class="change">コメント行数</th>
43+ <th class="change">コメント率</th>
44+ </tr>
45+ </thead>
46+ <tbody>
47+ <tr class="odd" py:if="path != '/'">
48+ <td colspan='11'><a href="${href.stepcounter(path[0:path.rindex('/')], rev=stickyrev, order=(dir.order != 'name' and dir.order or None), desc=dir.desc)}">..</a></td>
49+ </tr>
50+
51+ <py:for each="idx, entry in enumerate(dir.entries)">
52+ <py:with vars="change = dir.changes.get(entry.rev)">
53+ <tr class="${idx % 2 and 'even' or 'odd'}">
54+ <td class="name">
55+ <a class="$entry.kind" title="${_('View %(kind)s', kind=(entry.kind == entry.DIRECTORY and _('Directory') or _('File')))}"
56+ href="${href.stepcounter(os.path.dirname(entry.path), rev=stickyrev, order=(dir.order != 'name' and dir.order or None), desc=dir.desc)}">${os.path.dirname(entry.path)}</a>
57+ </td>
58+ <td class="name">
59+ <a class="$entry.kind" title="${_('View %(kind)s', kind=(entry.kind == entry.DIRECTORY and _('Directory') or _('File')))}"
60+ href="${href.browser(entry.path, rev=stickyrev, order=(dir.order != 'name' and dir.order or None), desc=dir.desc)}">$entry.name</a>
61+ </td>
62+ <td class="size">${sizeinfo(entry.content_length)}</td>
63+ <td class="rev">
64+ <a title="${_('View Revision Log')}" href="${href.log(entry.path, rev=rev)}">$entry.rev</a>
65+ </td>
66+ <td class="age" style="${None}">
67+ ${change and dateinfo(change.date) or '-'}
68+ </td>
69+ <td class="author">
70+ <span class="author" py:if="change"><a class="$entry.kind" href="${href.stepcounter(path, rev=stickyrev, order=(dir.order != 'name' and dir.order or None), desc=dir.desc,commiter=change.author)}">${authorinfo(change.author)}</a></span>
71+ </td>
72+ <td class="change">
73+ <span class="change" py:choose="" py:with="chgset_context = context('changeset', change.rev)">
74+ <py:when test="not change or 'CHANGESET_VIEW' not in perm(chgset_context.resource)">-</py:when>
75+ <py:when test="wiki_format_messages">
76+ ${change and wiki_to_oneliner(chgset_context, change.message, shorten=True)}
77+ </py:when>
78+ <py:otherwise>${change and shorten_line(change.message)}</py:otherwise>
79+ </span>
80+ </td>
81+ <td py:if="entry.isdir==False">${dir.counts[idx].fileType}</td>
82+ <td py:if="entry.isdir==False" class="count">${dir.counts[idx].step}</td>
83+ <td py:if="entry.isdir==False" class="count">${dir.counts[idx].commentStep}</td>
84+ <td py:if="entry.isdir==False" class="count">
85+ <py:choose>
86+ <py:when test="dir.counts[idx].step == 0">N/A</py:when>
87+ <py:otherwise>
88+ ${'%3.1f' % (float(dir.counts[idx].commentStep*100)/float(dir.counts[idx].commentStep+dir.counts[idx].step))}%
89+ </py:otherwise>
90+ </py:choose>
91+ </td>
92+ </tr>
93+ </py:with>
94+ </py:for>
95+ <tr>
96+ <td colspan='8'>合計</td>
97+ <td class="count">${dir.sum_step}</td>
98+ <td class="count">${dir.sum_comment}</td>
99+ <td class="count">${'%3.1f' % (float(dir.sum_comment*100)/float(dir.sum_step+dir.sum_comment))}%</td>
100+ </tr>
101+ </tbody>
102+ </table>
103+ </div>
104+ </body>
105+</html>
Show on old repository browser