##// END OF EJS Templates
added missing installation of git hooks when doing a fork
marcink -
r2991:578a152f beta
parent child Browse files
Show More
@@ -1,445 +1,448
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 rhodecode.lib.celerylib.tasks
3 rhodecode.lib.celerylib.tasks
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5
5
6 RhodeCode task modules, containing all task that suppose to be run
6 RhodeCode task modules, containing all task that suppose to be run
7 by celery daemon
7 by celery daemon
8
8
9 :created_on: Oct 6, 2010
9 :created_on: Oct 6, 2010
10 :author: marcink
10 :author: marcink
11 :copyright: (C) 2010-2012 Marcin Kuzminski <marcin@python-works.com>
11 :copyright: (C) 2010-2012 Marcin Kuzminski <marcin@python-works.com>
12 :license: GPLv3, see COPYING for more details.
12 :license: GPLv3, see COPYING for more details.
13 """
13 """
14 # This program is free software: you can redistribute it and/or modify
14 # This program is free software: you can redistribute it and/or modify
15 # it under the terms of the GNU General Public License as published by
15 # it under the terms of the GNU General Public License as published by
16 # the Free Software Foundation, either version 3 of the License, or
16 # the Free Software Foundation, either version 3 of the License, or
17 # (at your option) any later version.
17 # (at your option) any later version.
18 #
18 #
19 # This program is distributed in the hope that it will be useful,
19 # This program is distributed in the hope that it will be useful,
20 # but WITHOUT ANY WARRANTY; without even the implied warranty of
20 # but WITHOUT ANY WARRANTY; without even the implied warranty of
21 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 # GNU General Public License for more details.
22 # GNU General Public License for more details.
23 #
23 #
24 # You should have received a copy of the GNU General Public License
24 # You should have received a copy of the GNU General Public License
25 # along with this program. If not, see <http://www.gnu.org/licenses/>.
25 # along with this program. If not, see <http://www.gnu.org/licenses/>.
26 from celery.decorators import task
26 from celery.decorators import task
27
27
28 import os
28 import os
29 import traceback
29 import traceback
30 import logging
30 import logging
31 from os.path import join as jn
31 from os.path import join as jn
32
32
33 from time import mktime
33 from time import mktime
34 from operator import itemgetter
34 from operator import itemgetter
35 from string import lower
35 from string import lower
36
36
37 from pylons import config, url
37 from pylons import config, url
38 from pylons.i18n.translation import _
38 from pylons.i18n.translation import _
39
39
40 from rhodecode.lib.vcs import get_backend
40 from rhodecode.lib.vcs import get_backend
41
41
42 from rhodecode import CELERY_ON, CELERY_EAGER
42 from rhodecode import CELERY_ON, CELERY_EAGER
43 from rhodecode.lib.utils2 import safe_str
43 from rhodecode.lib.utils2 import safe_str
44 from rhodecode.lib.celerylib import run_task, locked_task, dbsession, \
44 from rhodecode.lib.celerylib import run_task, locked_task, dbsession, \
45 str2bool, __get_lockkey, LockHeld, DaemonLock, get_session
45 str2bool, __get_lockkey, LockHeld, DaemonLock, get_session
46 from rhodecode.lib.helpers import person
46 from rhodecode.lib.helpers import person
47 from rhodecode.lib.rcmail.smtp_mailer import SmtpMailer
47 from rhodecode.lib.rcmail.smtp_mailer import SmtpMailer
48 from rhodecode.lib.utils import add_cache, action_logger
48 from rhodecode.lib.utils import add_cache, action_logger
49 from rhodecode.lib.compat import json, OrderedDict
49 from rhodecode.lib.compat import json, OrderedDict
50 from rhodecode.lib.hooks import log_create_repository
50 from rhodecode.lib.hooks import log_create_repository
51
51
52 from rhodecode.model.db import Statistics, Repository, User
52 from rhodecode.model.db import Statistics, Repository, User
53 from rhodecode.model.scm import ScmModel
53
54
54
55
55 add_cache(config)
56 add_cache(config)
56
57
57 __all__ = ['whoosh_index', 'get_commits_stats',
58 __all__ = ['whoosh_index', 'get_commits_stats',
58 'reset_user_password', 'send_email']
59 'reset_user_password', 'send_email']
59
60
60
61
61 def get_logger(cls):
62 def get_logger(cls):
62 if CELERY_ON:
63 if CELERY_ON:
63 try:
64 try:
64 log = cls.get_logger()
65 log = cls.get_logger()
65 except:
66 except:
66 log = logging.getLogger(__name__)
67 log = logging.getLogger(__name__)
67 else:
68 else:
68 log = logging.getLogger(__name__)
69 log = logging.getLogger(__name__)
69
70
70 return log
71 return log
71
72
72
73
73 @task(ignore_result=True)
74 @task(ignore_result=True)
74 @locked_task
75 @locked_task
75 @dbsession
76 @dbsession
76 def whoosh_index(repo_location, full_index):
77 def whoosh_index(repo_location, full_index):
77 from rhodecode.lib.indexers.daemon import WhooshIndexingDaemon
78 from rhodecode.lib.indexers.daemon import WhooshIndexingDaemon
78 log = get_logger(whoosh_index)
79 log = get_logger(whoosh_index)
79 DBS = get_session()
80 DBS = get_session()
80
81
81 index_location = config['index_dir']
82 index_location = config['index_dir']
82 WhooshIndexingDaemon(index_location=index_location,
83 WhooshIndexingDaemon(index_location=index_location,
83 repo_location=repo_location, sa=DBS)\
84 repo_location=repo_location, sa=DBS)\
84 .run(full_index=full_index)
85 .run(full_index=full_index)
85
86
86
87
87 @task(ignore_result=True)
88 @task(ignore_result=True)
88 @dbsession
89 @dbsession
89 def get_commits_stats(repo_name, ts_min_y, ts_max_y):
90 def get_commits_stats(repo_name, ts_min_y, ts_max_y):
90 log = get_logger(get_commits_stats)
91 log = get_logger(get_commits_stats)
91 DBS = get_session()
92 DBS = get_session()
92 lockkey = __get_lockkey('get_commits_stats', repo_name, ts_min_y,
93 lockkey = __get_lockkey('get_commits_stats', repo_name, ts_min_y,
93 ts_max_y)
94 ts_max_y)
94 lockkey_path = config['here']
95 lockkey_path = config['here']
95
96
96 log.info('running task with lockkey %s' % lockkey)
97 log.info('running task with lockkey %s' % lockkey)
97
98
98 try:
99 try:
99 lock = l = DaemonLock(file_=jn(lockkey_path, lockkey))
100 lock = l = DaemonLock(file_=jn(lockkey_path, lockkey))
100
101
101 # for js data compatibility cleans the key for person from '
102 # for js data compatibility cleans the key for person from '
102 akc = lambda k: person(k).replace('"', "")
103 akc = lambda k: person(k).replace('"', "")
103
104
104 co_day_auth_aggr = {}
105 co_day_auth_aggr = {}
105 commits_by_day_aggregate = {}
106 commits_by_day_aggregate = {}
106 repo = Repository.get_by_repo_name(repo_name)
107 repo = Repository.get_by_repo_name(repo_name)
107 if repo is None:
108 if repo is None:
108 return True
109 return True
109
110
110 repo = repo.scm_instance
111 repo = repo.scm_instance
111 repo_size = repo.count()
112 repo_size = repo.count()
112 # return if repo have no revisions
113 # return if repo have no revisions
113 if repo_size < 1:
114 if repo_size < 1:
114 lock.release()
115 lock.release()
115 return True
116 return True
116
117
117 skip_date_limit = True
118 skip_date_limit = True
118 parse_limit = int(config['app_conf'].get('commit_parse_limit'))
119 parse_limit = int(config['app_conf'].get('commit_parse_limit'))
119 last_rev = None
120 last_rev = None
120 last_cs = None
121 last_cs = None
121 timegetter = itemgetter('time')
122 timegetter = itemgetter('time')
122
123
123 dbrepo = DBS.query(Repository)\
124 dbrepo = DBS.query(Repository)\
124 .filter(Repository.repo_name == repo_name).scalar()
125 .filter(Repository.repo_name == repo_name).scalar()
125 cur_stats = DBS.query(Statistics)\
126 cur_stats = DBS.query(Statistics)\
126 .filter(Statistics.repository == dbrepo).scalar()
127 .filter(Statistics.repository == dbrepo).scalar()
127
128
128 if cur_stats is not None:
129 if cur_stats is not None:
129 last_rev = cur_stats.stat_on_revision
130 last_rev = cur_stats.stat_on_revision
130
131
131 if last_rev == repo.get_changeset().revision and repo_size > 1:
132 if last_rev == repo.get_changeset().revision and repo_size > 1:
132 # pass silently without any work if we're not on first revision or
133 # pass silently without any work if we're not on first revision or
133 # current state of parsing revision(from db marker) is the
134 # current state of parsing revision(from db marker) is the
134 # last revision
135 # last revision
135 lock.release()
136 lock.release()
136 return True
137 return True
137
138
138 if cur_stats:
139 if cur_stats:
139 commits_by_day_aggregate = OrderedDict(json.loads(
140 commits_by_day_aggregate = OrderedDict(json.loads(
140 cur_stats.commit_activity_combined))
141 cur_stats.commit_activity_combined))
141 co_day_auth_aggr = json.loads(cur_stats.commit_activity)
142 co_day_auth_aggr = json.loads(cur_stats.commit_activity)
142
143
143 log.debug('starting parsing %s' % parse_limit)
144 log.debug('starting parsing %s' % parse_limit)
144 lmktime = mktime
145 lmktime = mktime
145
146
146 last_rev = last_rev + 1 if last_rev >= 0 else 0
147 last_rev = last_rev + 1 if last_rev >= 0 else 0
147 log.debug('Getting revisions from %s to %s' % (
148 log.debug('Getting revisions from %s to %s' % (
148 last_rev, last_rev + parse_limit)
149 last_rev, last_rev + parse_limit)
149 )
150 )
150 for cs in repo[last_rev:last_rev + parse_limit]:
151 for cs in repo[last_rev:last_rev + parse_limit]:
151 log.debug('parsing %s' % cs)
152 log.debug('parsing %s' % cs)
152 last_cs = cs # remember last parsed changeset
153 last_cs = cs # remember last parsed changeset
153 k = lmktime([cs.date.timetuple()[0], cs.date.timetuple()[1],
154 k = lmktime([cs.date.timetuple()[0], cs.date.timetuple()[1],
154 cs.date.timetuple()[2], 0, 0, 0, 0, 0, 0])
155 cs.date.timetuple()[2], 0, 0, 0, 0, 0, 0])
155
156
156 if akc(cs.author) in co_day_auth_aggr:
157 if akc(cs.author) in co_day_auth_aggr:
157 try:
158 try:
158 l = [timegetter(x) for x in
159 l = [timegetter(x) for x in
159 co_day_auth_aggr[akc(cs.author)]['data']]
160 co_day_auth_aggr[akc(cs.author)]['data']]
160 time_pos = l.index(k)
161 time_pos = l.index(k)
161 except ValueError:
162 except ValueError:
162 time_pos = False
163 time_pos = False
163
164
164 if time_pos >= 0 and time_pos is not False:
165 if time_pos >= 0 and time_pos is not False:
165
166
166 datadict = \
167 datadict = \
167 co_day_auth_aggr[akc(cs.author)]['data'][time_pos]
168 co_day_auth_aggr[akc(cs.author)]['data'][time_pos]
168
169
169 datadict["commits"] += 1
170 datadict["commits"] += 1
170 datadict["added"] += len(cs.added)
171 datadict["added"] += len(cs.added)
171 datadict["changed"] += len(cs.changed)
172 datadict["changed"] += len(cs.changed)
172 datadict["removed"] += len(cs.removed)
173 datadict["removed"] += len(cs.removed)
173
174
174 else:
175 else:
175 if k >= ts_min_y and k <= ts_max_y or skip_date_limit:
176 if k >= ts_min_y and k <= ts_max_y or skip_date_limit:
176
177
177 datadict = {"time": k,
178 datadict = {"time": k,
178 "commits": 1,
179 "commits": 1,
179 "added": len(cs.added),
180 "added": len(cs.added),
180 "changed": len(cs.changed),
181 "changed": len(cs.changed),
181 "removed": len(cs.removed),
182 "removed": len(cs.removed),
182 }
183 }
183 co_day_auth_aggr[akc(cs.author)]['data']\
184 co_day_auth_aggr[akc(cs.author)]['data']\
184 .append(datadict)
185 .append(datadict)
185
186
186 else:
187 else:
187 if k >= ts_min_y and k <= ts_max_y or skip_date_limit:
188 if k >= ts_min_y and k <= ts_max_y or skip_date_limit:
188 co_day_auth_aggr[akc(cs.author)] = {
189 co_day_auth_aggr[akc(cs.author)] = {
189 "label": akc(cs.author),
190 "label": akc(cs.author),
190 "data": [{"time":k,
191 "data": [{"time":k,
191 "commits":1,
192 "commits":1,
192 "added":len(cs.added),
193 "added":len(cs.added),
193 "changed":len(cs.changed),
194 "changed":len(cs.changed),
194 "removed":len(cs.removed),
195 "removed":len(cs.removed),
195 }],
196 }],
196 "schema": ["commits"],
197 "schema": ["commits"],
197 }
198 }
198
199
199 #gather all data by day
200 #gather all data by day
200 if k in commits_by_day_aggregate:
201 if k in commits_by_day_aggregate:
201 commits_by_day_aggregate[k] += 1
202 commits_by_day_aggregate[k] += 1
202 else:
203 else:
203 commits_by_day_aggregate[k] = 1
204 commits_by_day_aggregate[k] = 1
204
205
205 overview_data = sorted(commits_by_day_aggregate.items(),
206 overview_data = sorted(commits_by_day_aggregate.items(),
206 key=itemgetter(0))
207 key=itemgetter(0))
207
208
208 if not co_day_auth_aggr:
209 if not co_day_auth_aggr:
209 co_day_auth_aggr[akc(repo.contact)] = {
210 co_day_auth_aggr[akc(repo.contact)] = {
210 "label": akc(repo.contact),
211 "label": akc(repo.contact),
211 "data": [0, 1],
212 "data": [0, 1],
212 "schema": ["commits"],
213 "schema": ["commits"],
213 }
214 }
214
215
215 stats = cur_stats if cur_stats else Statistics()
216 stats = cur_stats if cur_stats else Statistics()
216 stats.commit_activity = json.dumps(co_day_auth_aggr)
217 stats.commit_activity = json.dumps(co_day_auth_aggr)
217 stats.commit_activity_combined = json.dumps(overview_data)
218 stats.commit_activity_combined = json.dumps(overview_data)
218
219
219 log.debug('last revison %s' % last_rev)
220 log.debug('last revison %s' % last_rev)
220 leftovers = len(repo.revisions[last_rev:])
221 leftovers = len(repo.revisions[last_rev:])
221 log.debug('revisions to parse %s' % leftovers)
222 log.debug('revisions to parse %s' % leftovers)
222
223
223 if last_rev == 0 or leftovers < parse_limit:
224 if last_rev == 0 or leftovers < parse_limit:
224 log.debug('getting code trending stats')
225 log.debug('getting code trending stats')
225 stats.languages = json.dumps(__get_codes_stats(repo_name))
226 stats.languages = json.dumps(__get_codes_stats(repo_name))
226
227
227 try:
228 try:
228 stats.repository = dbrepo
229 stats.repository = dbrepo
229 stats.stat_on_revision = last_cs.revision if last_cs else 0
230 stats.stat_on_revision = last_cs.revision if last_cs else 0
230 DBS.add(stats)
231 DBS.add(stats)
231 DBS.commit()
232 DBS.commit()
232 except:
233 except:
233 log.error(traceback.format_exc())
234 log.error(traceback.format_exc())
234 DBS.rollback()
235 DBS.rollback()
235 lock.release()
236 lock.release()
236 return False
237 return False
237
238
238 # final release
239 # final release
239 lock.release()
240 lock.release()
240
241
241 # execute another task if celery is enabled
242 # execute another task if celery is enabled
242 if len(repo.revisions) > 1 and CELERY_ON:
243 if len(repo.revisions) > 1 and CELERY_ON:
243 run_task(get_commits_stats, repo_name, ts_min_y, ts_max_y)
244 run_task(get_commits_stats, repo_name, ts_min_y, ts_max_y)
244 return True
245 return True
245 except LockHeld:
246 except LockHeld:
246 log.info('LockHeld')
247 log.info('LockHeld')
247 return 'Task with key %s already running' % lockkey
248 return 'Task with key %s already running' % lockkey
248
249
249 @task(ignore_result=True)
250 @task(ignore_result=True)
250 @dbsession
251 @dbsession
251 def send_password_link(user_email):
252 def send_password_link(user_email):
252 from rhodecode.model.notification import EmailNotificationModel
253 from rhodecode.model.notification import EmailNotificationModel
253
254
254 log = get_logger(send_password_link)
255 log = get_logger(send_password_link)
255 DBS = get_session()
256 DBS = get_session()
256
257
257 try:
258 try:
258 user = User.get_by_email(user_email)
259 user = User.get_by_email(user_email)
259 if user:
260 if user:
260 log.debug('password reset user found %s' % user)
261 log.debug('password reset user found %s' % user)
261 link = url('reset_password_confirmation', key=user.api_key,
262 link = url('reset_password_confirmation', key=user.api_key,
262 qualified=True)
263 qualified=True)
263 reg_type = EmailNotificationModel.TYPE_PASSWORD_RESET
264 reg_type = EmailNotificationModel.TYPE_PASSWORD_RESET
264 body = EmailNotificationModel().get_email_tmpl(reg_type,
265 body = EmailNotificationModel().get_email_tmpl(reg_type,
265 **{'user':user.short_contact,
266 **{'user':user.short_contact,
266 'reset_url':link})
267 'reset_url':link})
267 log.debug('sending email')
268 log.debug('sending email')
268 run_task(send_email, user_email,
269 run_task(send_email, user_email,
269 _("password reset link"), body)
270 _("password reset link"), body)
270 log.info('send new password mail to %s' % user_email)
271 log.info('send new password mail to %s' % user_email)
271 else:
272 else:
272 log.debug("password reset email %s not found" % user_email)
273 log.debug("password reset email %s not found" % user_email)
273 except:
274 except:
274 log.error(traceback.format_exc())
275 log.error(traceback.format_exc())
275 return False
276 return False
276
277
277 return True
278 return True
278
279
279 @task(ignore_result=True)
280 @task(ignore_result=True)
280 @dbsession
281 @dbsession
281 def reset_user_password(user_email):
282 def reset_user_password(user_email):
282 from rhodecode.lib import auth
283 from rhodecode.lib import auth
283
284
284 log = get_logger(reset_user_password)
285 log = get_logger(reset_user_password)
285 DBS = get_session()
286 DBS = get_session()
286
287
287 try:
288 try:
288 try:
289 try:
289 user = User.get_by_email(user_email)
290 user = User.get_by_email(user_email)
290 new_passwd = auth.PasswordGenerator().gen_password(8,
291 new_passwd = auth.PasswordGenerator().gen_password(8,
291 auth.PasswordGenerator.ALPHABETS_BIG_SMALL)
292 auth.PasswordGenerator.ALPHABETS_BIG_SMALL)
292 if user:
293 if user:
293 user.password = auth.get_crypt_password(new_passwd)
294 user.password = auth.get_crypt_password(new_passwd)
294 user.api_key = auth.generate_api_key(user.username)
295 user.api_key = auth.generate_api_key(user.username)
295 DBS.add(user)
296 DBS.add(user)
296 DBS.commit()
297 DBS.commit()
297 log.info('change password for %s' % user_email)
298 log.info('change password for %s' % user_email)
298 if new_passwd is None:
299 if new_passwd is None:
299 raise Exception('unable to generate new password')
300 raise Exception('unable to generate new password')
300 except:
301 except:
301 log.error(traceback.format_exc())
302 log.error(traceback.format_exc())
302 DBS.rollback()
303 DBS.rollback()
303
304
304 run_task(send_email, user_email,
305 run_task(send_email, user_email,
305 'Your new password',
306 'Your new password',
306 'Your new RhodeCode password:%s' % (new_passwd))
307 'Your new RhodeCode password:%s' % (new_passwd))
307 log.info('send new password mail to %s' % user_email)
308 log.info('send new password mail to %s' % user_email)
308
309
309 except:
310 except:
310 log.error('Failed to update user password')
311 log.error('Failed to update user password')
311 log.error(traceback.format_exc())
312 log.error(traceback.format_exc())
312
313
313 return True
314 return True
314
315
315
316
316 @task(ignore_result=True)
317 @task(ignore_result=True)
317 @dbsession
318 @dbsession
318 def send_email(recipients, subject, body, html_body=''):
319 def send_email(recipients, subject, body, html_body=''):
319 """
320 """
320 Sends an email with defined parameters from the .ini files.
321 Sends an email with defined parameters from the .ini files.
321
322
322 :param recipients: list of recipients, it this is empty the defined email
323 :param recipients: list of recipients, it this is empty the defined email
323 address from field 'email_to' is used instead
324 address from field 'email_to' is used instead
324 :param subject: subject of the mail
325 :param subject: subject of the mail
325 :param body: body of the mail
326 :param body: body of the mail
326 :param html_body: html version of body
327 :param html_body: html version of body
327 """
328 """
328 log = get_logger(send_email)
329 log = get_logger(send_email)
329 DBS = get_session()
330 DBS = get_session()
330
331
331 email_config = config
332 email_config = config
332 subject = "%s %s" % (email_config.get('email_prefix', ''), subject)
333 subject = "%s %s" % (email_config.get('email_prefix', ''), subject)
333 if not recipients:
334 if not recipients:
334 # if recipients are not defined we send to email_config + all admins
335 # if recipients are not defined we send to email_config + all admins
335 admins = [u.email for u in User.query()
336 admins = [u.email for u in User.query()
336 .filter(User.admin == True).all()]
337 .filter(User.admin == True).all()]
337 recipients = [email_config.get('email_to')] + admins
338 recipients = [email_config.get('email_to')] + admins
338
339
339 mail_from = email_config.get('app_email_from', 'RhodeCode')
340 mail_from = email_config.get('app_email_from', 'RhodeCode')
340 user = email_config.get('smtp_username')
341 user = email_config.get('smtp_username')
341 passwd = email_config.get('smtp_password')
342 passwd = email_config.get('smtp_password')
342 mail_server = email_config.get('smtp_server')
343 mail_server = email_config.get('smtp_server')
343 mail_port = email_config.get('smtp_port')
344 mail_port = email_config.get('smtp_port')
344 tls = str2bool(email_config.get('smtp_use_tls'))
345 tls = str2bool(email_config.get('smtp_use_tls'))
345 ssl = str2bool(email_config.get('smtp_use_ssl'))
346 ssl = str2bool(email_config.get('smtp_use_ssl'))
346 debug = str2bool(config.get('debug'))
347 debug = str2bool(config.get('debug'))
347 smtp_auth = email_config.get('smtp_auth')
348 smtp_auth = email_config.get('smtp_auth')
348
349
349 try:
350 try:
350 m = SmtpMailer(mail_from, user, passwd, mail_server, smtp_auth,
351 m = SmtpMailer(mail_from, user, passwd, mail_server, smtp_auth,
351 mail_port, ssl, tls, debug=debug)
352 mail_port, ssl, tls, debug=debug)
352 m.send(recipients, subject, body, html_body)
353 m.send(recipients, subject, body, html_body)
353 except:
354 except:
354 log.error('Mail sending failed')
355 log.error('Mail sending failed')
355 log.error(traceback.format_exc())
356 log.error(traceback.format_exc())
356 return False
357 return False
357 return True
358 return True
358
359
359
360
360 @task(ignore_result=True)
361 @task(ignore_result=True)
361 @dbsession
362 @dbsession
362 def create_repo_fork(form_data, cur_user):
363 def create_repo_fork(form_data, cur_user):
363 """
364 """
364 Creates a fork of repository using interval VCS methods
365 Creates a fork of repository using interval VCS methods
365
366
366 :param form_data:
367 :param form_data:
367 :param cur_user:
368 :param cur_user:
368 """
369 """
369 from rhodecode.model.repo import RepoModel
370 from rhodecode.model.repo import RepoModel
370 from rhodecode.model.user import UserModel
371 from rhodecode.model.user import UserModel
371
372
372 log = get_logger(create_repo_fork)
373 log = get_logger(create_repo_fork)
373 DBS = get_session()
374 DBS = get_session()
374
375
375 base_path = Repository.base_path()
376 base_path = Repository.base_path()
376 cur_user = UserModel(DBS)._get_user(cur_user)
377 cur_user = UserModel(DBS)._get_user(cur_user)
377
378
378 fork_name = form_data['repo_name_full']
379 fork_name = form_data['repo_name_full']
379 repo_type = form_data['repo_type']
380 repo_type = form_data['repo_type']
380 description = form_data['description']
381 description = form_data['description']
381 owner = cur_user
382 owner = cur_user
382 private = form_data['private']
383 private = form_data['private']
383 clone_uri = form_data.get('clone_uri')
384 clone_uri = form_data.get('clone_uri')
384 repos_group = form_data['repo_group']
385 repos_group = form_data['repo_group']
385 landing_rev = form_data['landing_rev']
386 landing_rev = form_data['landing_rev']
386 copy_fork_permissions = form_data.get('copy_permissions')
387 copy_fork_permissions = form_data.get('copy_permissions')
387 fork_of = RepoModel(DBS)._get_repo(form_data.get('fork_parent_id'))
388 fork_of = RepoModel(DBS)._get_repo(form_data.get('fork_parent_id'))
388
389
389 fork_repo = RepoModel(DBS).create_repo(
390 fork_repo = RepoModel(DBS).create_repo(
390 fork_name, repo_type, description, owner, private, clone_uri,
391 fork_name, repo_type, description, owner, private, clone_uri,
391 repos_group, landing_rev, just_db=True, fork_of=fork_of,
392 repos_group, landing_rev, just_db=True, fork_of=fork_of,
392 copy_fork_permissions=copy_fork_permissions
393 copy_fork_permissions=copy_fork_permissions
393 )
394 )
394
395
395 update_after_clone = form_data['update_after_clone']
396 update_after_clone = form_data['update_after_clone']
396
397
397 source_repo_path = os.path.join(base_path, fork_of.repo_name)
398 source_repo_path = os.path.join(base_path, fork_of.repo_name)
398 destination_fork_path = os.path.join(base_path, fork_name)
399 destination_fork_path = os.path.join(base_path, fork_name)
399
400
400 log.info('creating fork of %s as %s', source_repo_path,
401 log.info('creating fork of %s as %s', source_repo_path,
401 destination_fork_path)
402 destination_fork_path)
402 backend = get_backend(repo_type)
403 backend = get_backend(repo_type)
403
404
404 if repo_type == 'git':
405 if repo_type == 'git':
405 backend(safe_str(destination_fork_path), create=True,
406 r = backend(safe_str(destination_fork_path), create=True,
406 src_url=safe_str(source_repo_path),
407 src_url=safe_str(source_repo_path),
407 update_after_clone=update_after_clone,
408 update_after_clone=update_after_clone,
408 bare=True)
409 bare=True)
409 elif repo_type == 'hg':
410 elif repo_type == 'hg':
410 backend(safe_str(destination_fork_path), create=True,
411 r = backend(safe_str(destination_fork_path), create=True,
411 src_url=safe_str(source_repo_path),
412 src_url=safe_str(source_repo_path),
412 update_after_clone=update_after_clone)
413 update_after_clone=update_after_clone)
413 else:
414 else:
414 raise Exception('Unknown backend type %s' % repo_type)
415 raise Exception('Unknown backend type %s' % repo_type)
415
416
417 # add rhodecode hook into this repo
418 ScmModel().install_git_hook(repo=r)
416 log_create_repository(fork_repo.get_dict(), created_by=cur_user.username)
419 log_create_repository(fork_repo.get_dict(), created_by=cur_user.username)
417
420
418 action_logger(cur_user, 'user_forked_repo:%s' % fork_name,
421 action_logger(cur_user, 'user_forked_repo:%s' % fork_name,
419 fork_of.repo_name, '', DBS)
422 fork_of.repo_name, '', DBS)
420
423
421 action_logger(cur_user, 'user_created_fork:%s' % fork_name,
424 action_logger(cur_user, 'user_created_fork:%s' % fork_name,
422 fork_name, '', DBS)
425 fork_name, '', DBS)
423 # finally commit at latest possible stage
426 # finally commit at latest possible stage
424 DBS.commit()
427 DBS.commit()
425
428
426
429
427 def __get_codes_stats(repo_name):
430 def __get_codes_stats(repo_name):
428 from rhodecode.config.conf import LANGUAGES_EXTENSIONS_MAP
431 from rhodecode.config.conf import LANGUAGES_EXTENSIONS_MAP
429 repo = Repository.get_by_repo_name(repo_name).scm_instance
432 repo = Repository.get_by_repo_name(repo_name).scm_instance
430
433
431 tip = repo.get_changeset()
434 tip = repo.get_changeset()
432 code_stats = {}
435 code_stats = {}
433
436
434 def aggregate(cs):
437 def aggregate(cs):
435 for f in cs[2]:
438 for f in cs[2]:
436 ext = lower(f.extension)
439 ext = lower(f.extension)
437 if ext in LANGUAGES_EXTENSIONS_MAP.keys() and not f.is_binary:
440 if ext in LANGUAGES_EXTENSIONS_MAP.keys() and not f.is_binary:
438 if ext in code_stats:
441 if ext in code_stats:
439 code_stats[ext] += 1
442 code_stats[ext] += 1
440 else:
443 else:
441 code_stats[ext] = 1
444 code_stats[ext] = 1
442
445
443 map(aggregate, tip.walk('/'))
446 map(aggregate, tip.walk('/'))
444
447
445 return code_stats or {}
448 return code_stats or {}
General Comments 0
You need to be logged in to leave comments. Login now