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