##// END OF EJS Templates
code stats speed improvments
marcink -
r804:b92d9a03 beta
parent child Browse files
Show More
@@ -1,363 +1,358
1 from celery.decorators import task
1 from celery.decorators import task
2
2
3 import os
3 import os
4 import traceback
4 import traceback
5 from time import mktime
5 from time import mktime
6 from operator import itemgetter
6 from operator import itemgetter
7
7
8 from pylons import config
8 from pylons import config
9 from pylons.i18n.translation import _
9 from pylons.i18n.translation import _
10
10
11 from rhodecode.lib.celerylib import run_task, locked_task, str2bool
11 from rhodecode.lib.celerylib import run_task, locked_task, str2bool
12 from rhodecode.lib.helpers import person
12 from rhodecode.lib.helpers import person
13 from rhodecode.lib.smtp_mailer import SmtpMailer
13 from rhodecode.lib.smtp_mailer import SmtpMailer
14 from rhodecode.lib.utils import OrderedDict, add_cache
14 from rhodecode.lib.utils import OrderedDict, add_cache
15 from rhodecode.model import init_model
15 from rhodecode.model import init_model
16 from rhodecode.model import meta
16 from rhodecode.model import meta
17 from rhodecode.model.db import RhodeCodeUi
17 from rhodecode.model.db import RhodeCodeUi
18
18
19 from vcs.backends import get_repo
19 from vcs.backends import get_repo
20
20
21 from sqlalchemy import engine_from_config
21 from sqlalchemy import engine_from_config
22
22
23 add_cache(config)
23 add_cache(config)
24
24
25 try:
25 try:
26 import json
26 import json
27 except ImportError:
27 except ImportError:
28 #python 2.5 compatibility
28 #python 2.5 compatibility
29 import simplejson as json
29 import simplejson as json
30
30
31 __all__ = ['whoosh_index', 'get_commits_stats',
31 __all__ = ['whoosh_index', 'get_commits_stats',
32 'reset_user_password', 'send_email']
32 'reset_user_password', 'send_email']
33
33
34 CELERY_ON = str2bool(config['app_conf'].get('use_celery'))
34 CELERY_ON = str2bool(config['app_conf'].get('use_celery'))
35
35
36 def get_session():
36 def get_session():
37 if CELERY_ON:
37 if CELERY_ON:
38 engine = engine_from_config(config, 'sqlalchemy.db1.')
38 engine = engine_from_config(config, 'sqlalchemy.db1.')
39 init_model(engine)
39 init_model(engine)
40 sa = meta.Session()
40 sa = meta.Session()
41 return sa
41 return sa
42
42
43 def get_repos_path():
43 def get_repos_path():
44 sa = get_session()
44 sa = get_session()
45 q = sa.query(RhodeCodeUi).filter(RhodeCodeUi.ui_key == '/').one()
45 q = sa.query(RhodeCodeUi).filter(RhodeCodeUi.ui_key == '/').one()
46 return q.ui_value
46 return q.ui_value
47
47
48 @task
48 @task
49 @locked_task
49 @locked_task
50 def whoosh_index(repo_location, full_index):
50 def whoosh_index(repo_location, full_index):
51 log = whoosh_index.get_logger()
51 log = whoosh_index.get_logger()
52 from rhodecode.lib.indexers.daemon import WhooshIndexingDaemon
52 from rhodecode.lib.indexers.daemon import WhooshIndexingDaemon
53 index_location = config['index_dir']
53 index_location = config['index_dir']
54 WhooshIndexingDaemon(index_location=index_location,
54 WhooshIndexingDaemon(index_location=index_location,
55 repo_location=repo_location, sa=get_session())\
55 repo_location=repo_location, sa=get_session())\
56 .run(full_index=full_index)
56 .run(full_index=full_index)
57
57
58 @task
58 @task
59 @locked_task
59 @locked_task
60 def get_commits_stats(repo_name, ts_min_y, ts_max_y):
60 def get_commits_stats(repo_name, ts_min_y, ts_max_y):
61 from rhodecode.model.db import Statistics, Repository
61 from rhodecode.model.db import Statistics, Repository
62 log = get_commits_stats.get_logger()
62 log = get_commits_stats.get_logger()
63
63
64 #for js data compatibilty
64 #for js data compatibilty
65 author_key_cleaner = lambda k: person(k).replace('"', "")
65 author_key_cleaner = lambda k: person(k).replace('"', "")
66
66
67 commits_by_day_author_aggregate = {}
67 commits_by_day_author_aggregate = {}
68 commits_by_day_aggregate = {}
68 commits_by_day_aggregate = {}
69 repos_path = get_repos_path()
69 repos_path = get_repos_path()
70 p = os.path.join(repos_path, repo_name)
70 p = os.path.join(repos_path, repo_name)
71 repo = get_repo(p)
71 repo = get_repo(p)
72
72
73 skip_date_limit = True
73 skip_date_limit = True
74 parse_limit = 250 #limit for single task changeset parsing optimal for
74 parse_limit = 250 #limit for single task changeset parsing optimal for
75 last_rev = 0
75 last_rev = 0
76 last_cs = None
76 last_cs = None
77 timegetter = itemgetter('time')
77 timegetter = itemgetter('time')
78
78
79 sa = get_session()
79 sa = get_session()
80
80
81 dbrepo = sa.query(Repository)\
81 dbrepo = sa.query(Repository)\
82 .filter(Repository.repo_name == repo_name).scalar()
82 .filter(Repository.repo_name == repo_name).scalar()
83 cur_stats = sa.query(Statistics)\
83 cur_stats = sa.query(Statistics)\
84 .filter(Statistics.repository == dbrepo).scalar()
84 .filter(Statistics.repository == dbrepo).scalar()
85 if cur_stats:
85 if cur_stats:
86 last_rev = cur_stats.stat_on_revision
86 last_rev = cur_stats.stat_on_revision
87 if not repo.revisions:
87 if not repo.revisions:
88 return True
88 return True
89
89
90 if last_rev == repo.revisions[-1] and len(repo.revisions) > 1:
90 if last_rev == repo.revisions[-1] and len(repo.revisions) > 1:
91 #pass silently without any work if we're not on first revision or
91 #pass silently without any work if we're not on first revision or
92 #current state of parsing revision(from db marker) is the last revision
92 #current state of parsing revision(from db marker) is the last revision
93 return True
93 return True
94
94
95 if cur_stats:
95 if cur_stats:
96 commits_by_day_aggregate = OrderedDict(
96 commits_by_day_aggregate = OrderedDict(
97 json.loads(
97 json.loads(
98 cur_stats.commit_activity_combined))
98 cur_stats.commit_activity_combined))
99 commits_by_day_author_aggregate = json.loads(cur_stats.commit_activity)
99 commits_by_day_author_aggregate = json.loads(cur_stats.commit_activity)
100
100
101 log.debug('starting parsing %s', parse_limit)
101 log.debug('starting parsing %s', parse_limit)
102 lmktime = mktime
102 lmktime = mktime
103
103
104 last_rev = last_rev + 1 if last_rev > 0 else last_rev
104 last_rev = last_rev + 1 if last_rev > 0 else last_rev
105 for rev in repo.revisions[last_rev:last_rev + parse_limit]:
105 for rev in repo.revisions[last_rev:last_rev + parse_limit]:
106 last_cs = cs = repo.get_changeset(rev)
106 last_cs = cs = repo.get_changeset(rev)
107 k = '%s-%s-%s' % (cs.date.timetuple()[0], cs.date.timetuple()[1],
107 k = lmktime([cs.date.timetuple()[0], cs.date.timetuple()[1],
108 cs.date.timetuple()[2])
108 cs.date.timetuple()[2], 0, 0, 0, 0, 0, 0])
109 timetupple = [int(x) for x in k.split('-')]
109
110 timetupple.extend([0 for _ in xrange(6)])
111 k = lmktime(timetupple)
112 if commits_by_day_author_aggregate.has_key(author_key_cleaner(cs.author)):
110 if commits_by_day_author_aggregate.has_key(author_key_cleaner(cs.author)):
113 try:
111 try:
114 l = [timegetter(x) for x in commits_by_day_author_aggregate\
112 l = [timegetter(x) for x in commits_by_day_author_aggregate\
115 [author_key_cleaner(cs.author)]['data']]
113 [author_key_cleaner(cs.author)]['data']]
116 time_pos = l.index(k)
114 time_pos = l.index(k)
117 except ValueError:
115 except ValueError:
118 time_pos = False
116 time_pos = False
119
117
120 if time_pos >= 0 and time_pos is not False:
118 if time_pos >= 0 and time_pos is not False:
121
119
122 datadict = commits_by_day_author_aggregate\
120 datadict = commits_by_day_author_aggregate\
123 [author_key_cleaner(cs.author)]['data'][time_pos]
121 [author_key_cleaner(cs.author)]['data'][time_pos]
124
122
125 datadict["commits"] += 1
123 datadict["commits"] += 1
126 datadict["added"] += len(cs.added)
124 datadict["added"] += len(cs.added)
127 datadict["changed"] += len(cs.changed)
125 datadict["changed"] += len(cs.changed)
128 datadict["removed"] += len(cs.removed)
126 datadict["removed"] += len(cs.removed)
129
127
130 else:
128 else:
131 if k >= ts_min_y and k <= ts_max_y or skip_date_limit:
129 if k >= ts_min_y and k <= ts_max_y or skip_date_limit:
132
130
133 datadict = {"time":k,
131 datadict = {"time":k,
134 "commits":1,
132 "commits":1,
135 "added":len(cs.added),
133 "added":len(cs.added),
136 "changed":len(cs.changed),
134 "changed":len(cs.changed),
137 "removed":len(cs.removed),
135 "removed":len(cs.removed),
138 }
136 }
139 commits_by_day_author_aggregate\
137 commits_by_day_author_aggregate\
140 [author_key_cleaner(cs.author)]['data'].append(datadict)
138 [author_key_cleaner(cs.author)]['data'].append(datadict)
141
139
142 else:
140 else:
143 if k >= ts_min_y and k <= ts_max_y or skip_date_limit:
141 if k >= ts_min_y and k <= ts_max_y or skip_date_limit:
144 commits_by_day_author_aggregate[author_key_cleaner(cs.author)] = {
142 commits_by_day_author_aggregate[author_key_cleaner(cs.author)] = {
145 "label":author_key_cleaner(cs.author),
143 "label":author_key_cleaner(cs.author),
146 "data":[{"time":k,
144 "data":[{"time":k,
147 "commits":1,
145 "commits":1,
148 "added":len(cs.added),
146 "added":len(cs.added),
149 "changed":len(cs.changed),
147 "changed":len(cs.changed),
150 "removed":len(cs.removed),
148 "removed":len(cs.removed),
151 }],
149 }],
152 "schema":["commits"],
150 "schema":["commits"],
153 }
151 }
154
152
155 #gather all data by day
153 #gather all data by day
156 if commits_by_day_aggregate.has_key(k):
154 if commits_by_day_aggregate.has_key(k):
157 commits_by_day_aggregate[k] += 1
155 commits_by_day_aggregate[k] += 1
158 else:
156 else:
159 commits_by_day_aggregate[k] = 1
157 commits_by_day_aggregate[k] = 1
160
158
161 overview_data = []
159 overview_data = sorted(commits_by_day_aggregate.items(), key=itemgetter(0))
162 for k, v in commits_by_day_aggregate.items():
163 overview_data.append([k, v])
164 overview_data = sorted(overview_data, key=itemgetter(0))
165 if not commits_by_day_author_aggregate:
160 if not commits_by_day_author_aggregate:
166 commits_by_day_author_aggregate[author_key_cleaner(repo.contact)] = {
161 commits_by_day_author_aggregate[author_key_cleaner(repo.contact)] = {
167 "label":author_key_cleaner(repo.contact),
162 "label":author_key_cleaner(repo.contact),
168 "data":[0, 1],
163 "data":[0, 1],
169 "schema":["commits"],
164 "schema":["commits"],
170 }
165 }
171
166
172 stats = cur_stats if cur_stats else Statistics()
167 stats = cur_stats if cur_stats else Statistics()
173 stats.commit_activity = json.dumps(commits_by_day_author_aggregate)
168 stats.commit_activity = json.dumps(commits_by_day_author_aggregate)
174 stats.commit_activity_combined = json.dumps(overview_data)
169 stats.commit_activity_combined = json.dumps(overview_data)
175
170
176 log.debug('last revison %s', last_rev)
171 log.debug('last revison %s', last_rev)
177 leftovers = len(repo.revisions[last_rev:])
172 leftovers = len(repo.revisions[last_rev:])
178 log.debug('revisions to parse %s', leftovers)
173 log.debug('revisions to parse %s', leftovers)
179
174
180 if last_rev == 0 or leftovers < parse_limit:
175 if last_rev == 0 or leftovers < parse_limit:
181 stats.languages = json.dumps(__get_codes_stats(repo_name))
176 stats.languages = json.dumps(__get_codes_stats(repo_name))
182
177
183 stats.repository = dbrepo
178 stats.repository = dbrepo
184 stats.stat_on_revision = last_cs.revision
179 stats.stat_on_revision = last_cs.revision
185
180
186 try:
181 try:
187 sa.add(stats)
182 sa.add(stats)
188 sa.commit()
183 sa.commit()
189 except:
184 except:
190 log.error(traceback.format_exc())
185 log.error(traceback.format_exc())
191 sa.rollback()
186 sa.rollback()
192 return False
187 return False
193 if len(repo.revisions) > 1:
188 if len(repo.revisions) > 1:
194 run_task(get_commits_stats, repo_name, ts_min_y, ts_max_y)
189 run_task(get_commits_stats, repo_name, ts_min_y, ts_max_y)
195
190
196 return True
191 return True
197
192
198 @task
193 @task
199 def reset_user_password(user_email):
194 def reset_user_password(user_email):
200 log = reset_user_password.get_logger()
195 log = reset_user_password.get_logger()
201 from rhodecode.lib import auth
196 from rhodecode.lib import auth
202 from rhodecode.model.db import User
197 from rhodecode.model.db import User
203
198
204 try:
199 try:
205 try:
200 try:
206 sa = get_session()
201 sa = get_session()
207 user = sa.query(User).filter(User.email == user_email).scalar()
202 user = sa.query(User).filter(User.email == user_email).scalar()
208 new_passwd = auth.PasswordGenerator().gen_password(8,
203 new_passwd = auth.PasswordGenerator().gen_password(8,
209 auth.PasswordGenerator.ALPHABETS_BIG_SMALL)
204 auth.PasswordGenerator.ALPHABETS_BIG_SMALL)
210 if user:
205 if user:
211 user.password = auth.get_crypt_password(new_passwd)
206 user.password = auth.get_crypt_password(new_passwd)
212 sa.add(user)
207 sa.add(user)
213 sa.commit()
208 sa.commit()
214 log.info('change password for %s', user_email)
209 log.info('change password for %s', user_email)
215 if new_passwd is None:
210 if new_passwd is None:
216 raise Exception('unable to generate new password')
211 raise Exception('unable to generate new password')
217
212
218 except:
213 except:
219 log.error(traceback.format_exc())
214 log.error(traceback.format_exc())
220 sa.rollback()
215 sa.rollback()
221
216
222 run_task(send_email, user_email,
217 run_task(send_email, user_email,
223 "Your new rhodecode password",
218 "Your new rhodecode password",
224 'Your new rhodecode password:%s' % (new_passwd))
219 'Your new rhodecode password:%s' % (new_passwd))
225 log.info('send new password mail to %s', user_email)
220 log.info('send new password mail to %s', user_email)
226
221
227
222
228 except:
223 except:
229 log.error('Failed to update user password')
224 log.error('Failed to update user password')
230 log.error(traceback.format_exc())
225 log.error(traceback.format_exc())
231
226
232 return True
227 return True
233
228
234 @task
229 @task
235 def send_email(recipients, subject, body):
230 def send_email(recipients, subject, body):
236 """
231 """
237 Sends an email with defined parameters from the .ini files.
232 Sends an email with defined parameters from the .ini files.
238
233
239
234
240 :param recipients: list of recipients, it this is empty the defined email
235 :param recipients: list of recipients, it this is empty the defined email
241 address from field 'email_to' is used instead
236 address from field 'email_to' is used instead
242 :param subject: subject of the mail
237 :param subject: subject of the mail
243 :param body: body of the mail
238 :param body: body of the mail
244 """
239 """
245 log = send_email.get_logger()
240 log = send_email.get_logger()
246 email_config = config
241 email_config = config
247
242
248 if not recipients:
243 if not recipients:
249 recipients = [email_config.get('email_to')]
244 recipients = [email_config.get('email_to')]
250
245
251 mail_from = email_config.get('app_email_from')
246 mail_from = email_config.get('app_email_from')
252 user = email_config.get('smtp_username')
247 user = email_config.get('smtp_username')
253 passwd = email_config.get('smtp_password')
248 passwd = email_config.get('smtp_password')
254 mail_server = email_config.get('smtp_server')
249 mail_server = email_config.get('smtp_server')
255 mail_port = email_config.get('smtp_port')
250 mail_port = email_config.get('smtp_port')
256 tls = str2bool(email_config.get('smtp_use_tls'))
251 tls = str2bool(email_config.get('smtp_use_tls'))
257 ssl = str2bool(email_config.get('smtp_use_ssl'))
252 ssl = str2bool(email_config.get('smtp_use_ssl'))
258
253
259 try:
254 try:
260 m = SmtpMailer(mail_from, user, passwd, mail_server,
255 m = SmtpMailer(mail_from, user, passwd, mail_server,
261 mail_port, ssl, tls)
256 mail_port, ssl, tls)
262 m.send(recipients, subject, body)
257 m.send(recipients, subject, body)
263 except:
258 except:
264 log.error('Mail sending failed')
259 log.error('Mail sending failed')
265 log.error(traceback.format_exc())
260 log.error(traceback.format_exc())
266 return False
261 return False
267 return True
262 return True
268
263
269 @task
264 @task
270 def create_repo_fork(form_data, cur_user):
265 def create_repo_fork(form_data, cur_user):
271 from rhodecode.model.repo import RepoModel
266 from rhodecode.model.repo import RepoModel
272 from vcs import get_backend
267 from vcs import get_backend
273 log = create_repo_fork.get_logger()
268 log = create_repo_fork.get_logger()
274 repo_model = RepoModel(get_session())
269 repo_model = RepoModel(get_session())
275 repo_model.create(form_data, cur_user, just_db=True, fork=True)
270 repo_model.create(form_data, cur_user, just_db=True, fork=True)
276 repo_name = form_data['repo_name']
271 repo_name = form_data['repo_name']
277 repos_path = get_repos_path()
272 repos_path = get_repos_path()
278 repo_path = os.path.join(repos_path, repo_name)
273 repo_path = os.path.join(repos_path, repo_name)
279 repo_fork_path = os.path.join(repos_path, form_data['fork_name'])
274 repo_fork_path = os.path.join(repos_path, form_data['fork_name'])
280 alias = form_data['repo_type']
275 alias = form_data['repo_type']
281
276
282 log.info('creating repo fork %s as %s', repo_name, repo_path)
277 log.info('creating repo fork %s as %s', repo_name, repo_path)
283 backend = get_backend(alias)
278 backend = get_backend(alias)
284 backend(str(repo_fork_path), create=True, src_url=str(repo_path))
279 backend(str(repo_fork_path), create=True, src_url=str(repo_path))
285
280
286 def __get_codes_stats(repo_name):
281 def __get_codes_stats(repo_name):
287 LANGUAGES_EXTENSIONS_MAP = {'scm': 'Scheme', 'asmx': 'VbNetAspx', 'Rout':
282 LANGUAGES_EXTENSIONS_MAP = {'scm': 'Scheme', 'asmx': 'VbNetAspx', 'Rout':
288 'RConsole', 'rest': 'Rst', 'abap': 'ABAP', 'go': 'Go', 'phtml': 'HtmlPhp',
283 'RConsole', 'rest': 'Rst', 'abap': 'ABAP', 'go': 'Go', 'phtml': 'HtmlPhp',
289 'ns2': 'Newspeak', 'xml': 'EvoqueXml', 'sh-session': 'BashSession', 'ads':
284 'ns2': 'Newspeak', 'xml': 'EvoqueXml', 'sh-session': 'BashSession', 'ads':
290 'Ada', 'clj': 'Clojure', 'll': 'Llvm', 'ebuild': 'Bash', 'adb': 'Ada',
285 'Ada', 'clj': 'Clojure', 'll': 'Llvm', 'ebuild': 'Bash', 'adb': 'Ada',
291 'ada': 'Ada', 'c++-objdump': 'CppObjdump', 'aspx':
286 'ada': 'Ada', 'c++-objdump': 'CppObjdump', 'aspx':
292 'VbNetAspx', 'ksh': 'Bash', 'coffee': 'CoffeeScript', 'vert': 'GLShader',
287 'VbNetAspx', 'ksh': 'Bash', 'coffee': 'CoffeeScript', 'vert': 'GLShader',
293 'Makefile.*': 'Makefile', 'di': 'D', 'dpatch': 'DarcsPatch', 'rake':
288 'Makefile.*': 'Makefile', 'di': 'D', 'dpatch': 'DarcsPatch', 'rake':
294 'Ruby', 'moo': 'MOOCode', 'erl-sh': 'ErlangShell', 'geo': 'GLShader',
289 'Ruby', 'moo': 'MOOCode', 'erl-sh': 'ErlangShell', 'geo': 'GLShader',
295 'pov': 'Povray', 'bas': 'VbNet', 'bat': 'Batch', 'd': 'D', 'lisp':
290 'pov': 'Povray', 'bas': 'VbNet', 'bat': 'Batch', 'd': 'D', 'lisp':
296 'CommonLisp', 'h': 'C', 'rbx': 'Ruby', 'tcl': 'Tcl', 'c++': 'Cpp', 'md':
291 'CommonLisp', 'h': 'C', 'rbx': 'Ruby', 'tcl': 'Tcl', 'c++': 'Cpp', 'md':
297 'MiniD', '.vimrc': 'Vim', 'xsd': 'Xml', 'ml': 'Ocaml', 'el': 'CommonLisp',
292 'MiniD', '.vimrc': 'Vim', 'xsd': 'Xml', 'ml': 'Ocaml', 'el': 'CommonLisp',
298 'befunge': 'Befunge', 'xsl': 'Xslt', 'pyx': 'Cython', 'cfm':
293 'befunge': 'Befunge', 'xsl': 'Xslt', 'pyx': 'Cython', 'cfm':
299 'ColdfusionHtml', 'evoque': 'Evoque', 'cfg': 'Ini', 'htm': 'Html',
294 'ColdfusionHtml', 'evoque': 'Evoque', 'cfg': 'Ini', 'htm': 'Html',
300 'Makefile': 'Makefile', 'cfc': 'ColdfusionHtml', 'tex': 'Tex', 'cs':
295 'Makefile': 'Makefile', 'cfc': 'ColdfusionHtml', 'tex': 'Tex', 'cs':
301 'CSharp', 'mxml': 'Mxml', 'patch': 'Diff', 'apache.conf': 'ApacheConf',
296 'CSharp', 'mxml': 'Mxml', 'patch': 'Diff', 'apache.conf': 'ApacheConf',
302 'scala': 'Scala', 'applescript': 'AppleScript', 'GNUmakefile': 'Makefile',
297 'scala': 'Scala', 'applescript': 'AppleScript', 'GNUmakefile': 'Makefile',
303 'c-objdump': 'CObjdump', 'lua': 'Lua', 'apache2.conf': 'ApacheConf', 'rb':
298 'c-objdump': 'CObjdump', 'lua': 'Lua', 'apache2.conf': 'ApacheConf', 'rb':
304 'Ruby', 'gemspec': 'Ruby', 'rl': 'RagelObjectiveC', 'vala': 'Vala', 'tmpl':
299 'Ruby', 'gemspec': 'Ruby', 'rl': 'RagelObjectiveC', 'vala': 'Vala', 'tmpl':
305 'Cheetah', 'bf': 'Brainfuck', 'plt': 'Gnuplot', 'G': 'AntlrRuby', 'xslt':
300 'Cheetah', 'bf': 'Brainfuck', 'plt': 'Gnuplot', 'G': 'AntlrRuby', 'xslt':
306 'Xslt', 'flxh': 'Felix', 'asax': 'VbNetAspx', 'Rakefile': 'Ruby', 'S': 'S',
301 'Xslt', 'flxh': 'Felix', 'asax': 'VbNetAspx', 'Rakefile': 'Ruby', 'S': 'S',
307 'wsdl': 'Xml', 'js': 'Javascript', 'autodelegate': 'Myghty', 'properties':
302 'wsdl': 'Xml', 'js': 'Javascript', 'autodelegate': 'Myghty', 'properties':
308 'Ini', 'bash': 'Bash', 'c': 'C', 'g': 'AntlrRuby', 'r3': 'Rebol', 's':
303 'Ini', 'bash': 'Bash', 'c': 'C', 'g': 'AntlrRuby', 'r3': 'Rebol', 's':
309 'Gas', 'ashx': 'VbNetAspx', 'cxx': 'Cpp', 'boo': 'Boo', 'prolog': 'Prolog',
304 'Gas', 'ashx': 'VbNetAspx', 'cxx': 'Cpp', 'boo': 'Boo', 'prolog': 'Prolog',
310 'sqlite3-console': 'SqliteConsole', 'cl': 'CommonLisp', 'cc': 'Cpp', 'pot':
305 'sqlite3-console': 'SqliteConsole', 'cl': 'CommonLisp', 'cc': 'Cpp', 'pot':
311 'Gettext', 'vim': 'Vim', 'pxi': 'Cython', 'yaml': 'Yaml', 'SConstruct':
306 'Gettext', 'vim': 'Vim', 'pxi': 'Cython', 'yaml': 'Yaml', 'SConstruct':
312 'Python', 'diff': 'Diff', 'txt': 'Text', 'cw': 'Redcode', 'pxd': 'Cython',
307 'Python', 'diff': 'Diff', 'txt': 'Text', 'cw': 'Redcode', 'pxd': 'Cython',
313 'plot': 'Gnuplot', 'java': 'Java', 'hrl': 'Erlang', 'py': 'Python',
308 'plot': 'Gnuplot', 'java': 'Java', 'hrl': 'Erlang', 'py': 'Python',
314 'makefile': 'Makefile', 'squid.conf': 'SquidConf', 'asm': 'Nasm', 'toc':
309 'makefile': 'Makefile', 'squid.conf': 'SquidConf', 'asm': 'Nasm', 'toc':
315 'Tex', 'kid': 'Genshi', 'rhtml': 'Rhtml', 'po': 'Gettext', 'pl': 'Prolog',
310 'Tex', 'kid': 'Genshi', 'rhtml': 'Rhtml', 'po': 'Gettext', 'pl': 'Prolog',
316 'pm': 'Perl', 'hx': 'Haxe', 'ascx': 'VbNetAspx', 'ooc': 'Ooc', 'asy':
311 'pm': 'Perl', 'hx': 'Haxe', 'ascx': 'VbNetAspx', 'ooc': 'Ooc', 'asy':
317 'Asymptote', 'hs': 'Haskell', 'SConscript': 'Python', 'pytb':
312 'Asymptote', 'hs': 'Haskell', 'SConscript': 'Python', 'pytb':
318 'PythonTraceback', 'myt': 'Myghty', 'hh': 'Cpp', 'R': 'S', 'aux': 'Tex',
313 'PythonTraceback', 'myt': 'Myghty', 'hh': 'Cpp', 'R': 'S', 'aux': 'Tex',
319 'rst': 'Rst', 'cpp-objdump': 'CppObjdump', 'lgt': 'Logtalk', 'rss': 'Xml',
314 'rst': 'Rst', 'cpp-objdump': 'CppObjdump', 'lgt': 'Logtalk', 'rss': 'Xml',
320 'flx': 'Felix', 'b': 'Brainfuck', 'f': 'Fortran', 'rbw': 'Ruby',
315 'flx': 'Felix', 'b': 'Brainfuck', 'f': 'Fortran', 'rbw': 'Ruby',
321 '.htaccess': 'ApacheConf', 'cxx-objdump': 'CppObjdump', 'j': 'ObjectiveJ',
316 '.htaccess': 'ApacheConf', 'cxx-objdump': 'CppObjdump', 'j': 'ObjectiveJ',
322 'mll': 'Ocaml', 'yml': 'Yaml', 'mu': 'MuPAD', 'r': 'Rebol', 'ASM': 'Nasm',
317 'mll': 'Ocaml', 'yml': 'Yaml', 'mu': 'MuPAD', 'r': 'Rebol', 'ASM': 'Nasm',
323 'erl': 'Erlang', 'mly': 'Ocaml', 'mo': 'Modelica', 'def': 'Modula2', 'ini':
318 'erl': 'Erlang', 'mly': 'Ocaml', 'mo': 'Modelica', 'def': 'Modula2', 'ini':
324 'Ini', 'control': 'DebianControl', 'vb': 'VbNet', 'vapi': 'Vala', 'pro':
319 'Ini', 'control': 'DebianControl', 'vb': 'VbNet', 'vapi': 'Vala', 'pro':
325 'Prolog', 'spt': 'Cheetah', 'mli': 'Ocaml', 'as': 'ActionScript3', 'cmd':
320 'Prolog', 'spt': 'Cheetah', 'mli': 'Ocaml', 'as': 'ActionScript3', 'cmd':
326 'Batch', 'cpp': 'Cpp', 'io': 'Io', 'tac': 'Python', 'haml': 'Haml', 'rkt':
321 'Batch', 'cpp': 'Cpp', 'io': 'Io', 'tac': 'Python', 'haml': 'Haml', 'rkt':
327 'Racket', 'st':'Smalltalk', 'inc': 'Povray', 'pas': 'Delphi', 'cmake':
322 'Racket', 'st':'Smalltalk', 'inc': 'Povray', 'pas': 'Delphi', 'cmake':
328 'CMake', 'csh':'Tcsh', 'hpp': 'Cpp', 'feature': 'Gherkin', 'html': 'Html',
323 'CMake', 'csh':'Tcsh', 'hpp': 'Cpp', 'feature': 'Gherkin', 'html': 'Html',
329 'php':'Php', 'php3':'Php', 'php4':'Php', 'php5':'Php', 'xhtml': 'Html',
324 'php':'Php', 'php3':'Php', 'php4':'Php', 'php5':'Php', 'xhtml': 'Html',
330 'hxx': 'Cpp', 'eclass': 'Bash', 'css': 'Css',
325 'hxx': 'Cpp', 'eclass': 'Bash', 'css': 'Css',
331 'frag': 'GLShader', 'd-objdump': 'DObjdump', 'weechatlog': 'IrcLogs',
326 'frag': 'GLShader', 'd-objdump': 'DObjdump', 'weechatlog': 'IrcLogs',
332 'tcsh': 'Tcsh', 'objdump': 'Objdump', 'pyw': 'Python', 'h++': 'Cpp',
327 'tcsh': 'Tcsh', 'objdump': 'Objdump', 'pyw': 'Python', 'h++': 'Cpp',
333 'py3tb': 'Python3Traceback', 'jsp': 'Jsp', 'sql': 'Sql', 'mak': 'Makefile',
328 'py3tb': 'Python3Traceback', 'jsp': 'Jsp', 'sql': 'Sql', 'mak': 'Makefile',
334 'php': 'Php', 'mao': 'Mako', 'man': 'Groff', 'dylan': 'Dylan', 'sass':
329 'php': 'Php', 'mao': 'Mako', 'man': 'Groff', 'dylan': 'Dylan', 'sass':
335 'Sass', 'cfml': 'ColdfusionHtml', 'darcspatch': 'DarcsPatch', 'tpl':
330 'Sass', 'cfml': 'ColdfusionHtml', 'darcspatch': 'DarcsPatch', 'tpl':
336 'Smarty', 'm': 'ObjectiveC', 'f90': 'Fortran', 'mod': 'Modula2', 'sh':
331 'Smarty', 'm': 'ObjectiveC', 'f90': 'Fortran', 'mod': 'Modula2', 'sh':
337 'Bash', 'lhs': 'LiterateHaskell', 'sources.list': 'SourcesList', 'axd':
332 'Bash', 'lhs': 'LiterateHaskell', 'sources.list': 'SourcesList', 'axd':
338 'VbNetAspx', 'sc': 'Python'}
333 'VbNetAspx', 'sc': 'Python'}
339
334
340 repos_path = get_repos_path()
335 repos_path = get_repos_path()
341 p = os.path.join(repos_path, repo_name)
336 p = os.path.join(repos_path, repo_name)
342 repo = get_repo(p)
337 repo = get_repo(p)
343 tip = repo.get_changeset()
338 tip = repo.get_changeset()
344 code_stats = {}
339 code_stats = {}
345
340
346 def aggregate(cs):
341 def aggregate(cs):
347 for f in cs[2]:
342 for f in cs[2]:
348 ext = f.extension
343 ext = f.extension
349 key = LANGUAGES_EXTENSIONS_MAP.get(ext, ext)
344 key = LANGUAGES_EXTENSIONS_MAP.get(ext, ext)
350 key = key or ext
345 key = key or ext
351 if ext in LANGUAGES_EXTENSIONS_MAP.keys() and not f.is_binary:
346 if ext in LANGUAGES_EXTENSIONS_MAP.keys() and not f.is_binary:
352 if code_stats.has_key(key):
347 if code_stats.has_key(key):
353 code_stats[key] += 1
348 code_stats[key] += 1
354 else:
349 else:
355 code_stats[key] = 1
350 code_stats[key] = 1
356
351
357 map(aggregate, tip.walk('/'))
352 map(aggregate, tip.walk('/'))
358
353
359 return code_stats or {}
354 return code_stats or {}
360
355
361
356
362
357
363
358
General Comments 0
You need to be logged in to leave comments. Login now