diff --git a/rhodecode/lib/celerylib/tasks.py b/rhodecode/lib/celerylib/tasks.py --- a/rhodecode/lib/celerylib/tasks.py +++ b/rhodecode/lib/celerylib/tasks.py @@ -28,7 +28,7 @@ from celery.decorators import task import os import traceback import logging -from os.path import dirname as dn, join as jn +from os.path import join as jn from time import mktime from operator import itemgetter @@ -37,69 +37,76 @@ from string import lower from pylons import config, url from pylons.i18n.translation import _ +from rhodecode.lib.vcs import get_backend + +from rhodecode import CELERY_ON from rhodecode.lib import LANGUAGES_EXTENSIONS_MAP, safe_str -from rhodecode.lib.celerylib import run_task, locked_task, str2bool, \ - __get_lockkey, LockHeld, DaemonLock, get_session, dbsession +from rhodecode.lib.celerylib import run_task, locked_task, dbsession, \ + str2bool, __get_lockkey, LockHeld, DaemonLock, get_session from rhodecode.lib.helpers import person -from rhodecode.lib.smtp_mailer import SmtpMailer -from rhodecode.lib.utils import add_cache +from rhodecode.lib.rcmail.smtp_mailer import SmtpMailer +from rhodecode.lib.utils import add_cache, action_logger from rhodecode.lib.compat import json, OrderedDict -from rhodecode.model.db import RhodeCodeUi, Statistics, Repository, User +from rhodecode.model.db import Statistics, Repository, User -from vcs.backends import get_repo -from vcs import get_backend add_cache(config) __all__ = ['whoosh_index', 'get_commits_stats', 'reset_user_password', 'send_email'] -CELERY_ON = str2bool(config['app_conf'].get('use_celery')) - -def get_repos_path(): - sa = get_session() - q = sa.query(RhodeCodeUi).filter(RhodeCodeUi.ui_key == '/').one() - return q.ui_value +def get_logger(cls): + if CELERY_ON: + try: + log = cls.get_logger() + except: + log = logging.getLogger(__name__) + else: + log = logging.getLogger(__name__) + + return log @task(ignore_result=True) @locked_task @dbsession def whoosh_index(repo_location, full_index): - #log = whoosh_index.get_logger() from rhodecode.lib.indexers.daemon import WhooshIndexingDaemon + log = whoosh_index.get_logger(whoosh_index) + DBS = get_session() + index_location = config['index_dir'] WhooshIndexingDaemon(index_location=index_location, - repo_location=repo_location, sa=get_session())\ + repo_location=repo_location, sa=DBS)\ .run(full_index=full_index) @task(ignore_result=True) @dbsession def get_commits_stats(repo_name, ts_min_y, ts_max_y): - try: - log = get_commits_stats.get_logger() - except: - log = logging.getLogger(__name__) - + log = get_logger(get_commits_stats) + DBS = get_session() lockkey = __get_lockkey('get_commits_stats', repo_name, ts_min_y, ts_max_y) lockkey_path = config['here'] - log.info('running task with lockkey %s', lockkey) + log.info('running task with lockkey %s' % lockkey) + try: - sa = get_session() lock = l = DaemonLock(file_=jn(lockkey_path, lockkey)) - # for js data compatibilty cleans the key for person from ' + # for js data compatibility cleans the key for person from ' akc = lambda k: person(k).replace('"', "") co_day_auth_aggr = {} commits_by_day_aggregate = {} - repos_path = get_repos_path() - repo = get_repo(safe_str(os.path.join(repos_path, repo_name))) + repo = Repository.get_by_repo_name(repo_name) + if repo is None: + return True + + repo = repo.scm_instance repo_size = repo.count() # return if repo have no revisions if repo_size < 1: @@ -112,9 +119,9 @@ def get_commits_stats(repo_name, ts_min_ last_cs = None timegetter = itemgetter('time') - dbrepo = sa.query(Repository)\ + dbrepo = DBS.query(Repository)\ .filter(Repository.repo_name == repo_name).scalar() - cur_stats = sa.query(Statistics)\ + cur_stats = DBS.query(Statistics)\ .filter(Statistics.repository == dbrepo).scalar() if cur_stats is not None: @@ -132,7 +139,7 @@ def get_commits_stats(repo_name, ts_min_ cur_stats.commit_activity_combined)) co_day_auth_aggr = json.loads(cur_stats.commit_activity) - log.debug('starting parsing %s', parse_limit) + log.debug('starting parsing %s' % parse_limit) lmktime = mktime last_rev = last_rev + 1 if last_rev >= 0 else 0 @@ -207,9 +214,9 @@ def get_commits_stats(repo_name, ts_min_ stats.commit_activity = json.dumps(co_day_auth_aggr) stats.commit_activity_combined = json.dumps(overview_data) - log.debug('last revison %s', last_rev) + log.debug('last revison %s' % last_rev) leftovers = len(repo.revisions[last_rev:]) - log.debug('revisions to parse %s', leftovers) + log.debug('revisions to parse %s' % leftovers) if last_rev == 0 or leftovers < parse_limit: log.debug('getting code trending stats') @@ -218,18 +225,18 @@ def get_commits_stats(repo_name, ts_min_ try: stats.repository = dbrepo stats.stat_on_revision = last_cs.revision if last_cs else 0 - sa.add(stats) - sa.commit() + DBS.add(stats) + DBS.commit() except: log.error(traceback.format_exc()) - sa.rollback() + DBS.rollback() lock.release() return False - # final release + #final release lock.release() - # execute another task if celery is enabled + #execute another task if celery is enabled if len(repo.revisions) > 1 and CELERY_ON: run_task(get_commits_stats, repo_name, ts_min_y, ts_max_y) return True @@ -240,38 +247,28 @@ def get_commits_stats(repo_name, ts_min_ @task(ignore_result=True) @dbsession def send_password_link(user_email): - try: - log = reset_user_password.get_logger() - except: - log = logging.getLogger(__name__) + from rhodecode.model.notification import EmailNotificationModel - from rhodecode.lib import auth + log = get_logger(send_password_link) + DBS = get_session() try: - sa = get_session() - user = sa.query(User).filter(User.email == user_email).scalar() - + user = User.get_by_email(user_email) if user: + log.debug('password reset user found %s' % user) link = url('reset_password_confirmation', key=user.api_key, qualified=True) - tmpl = """ -Hello %s - -We received a request to create a new password for your account. - -You can generate it by clicking following URL: - -%s - -If you didn't request new password please ignore this email. - """ + reg_type = EmailNotificationModel.TYPE_PASSWORD_RESET + body = EmailNotificationModel().get_email_tmpl(reg_type, + **{'user':user.short_contact, + 'reset_url':link}) + log.debug('sending email') run_task(send_email, user_email, - "RhodeCode password reset link", - tmpl % (user.short_contact, link)) - log.info('send new password mail to %s', user_email) - + _("password reset link"), body) + log.info('send new password mail to %s' % user_email) + else: + log.debug("password reset email %s not found" % user_email) except: - log.error('Failed to update user password') log.error(traceback.format_exc()) return False @@ -280,36 +277,32 @@ If you didn't request new password pleas @task(ignore_result=True) @dbsession def reset_user_password(user_email): - try: - log = reset_user_password.get_logger() - except: - log = logging.getLogger(__name__) + from rhodecode.lib import auth - from rhodecode.lib import auth + log = get_logger(reset_user_password) + DBS = get_session() try: try: - sa = get_session() - user = sa.query(User).filter(User.email == user_email).scalar() + user = User.get_by_email(user_email) new_passwd = auth.PasswordGenerator().gen_password(8, auth.PasswordGenerator.ALPHABETS_BIG_SMALL) if user: user.password = auth.get_crypt_password(new_passwd) user.api_key = auth.generate_api_key(user.username) - sa.add(user) - sa.commit() - log.info('change password for %s', user_email) + DBS.add(user) + DBS.commit() + log.info('change password for %s' % user_email) if new_passwd is None: raise Exception('unable to generate new password') - except: log.error(traceback.format_exc()) - sa.rollback() + DBS.rollback() run_task(send_email, user_email, - "Your new RhodeCode password", + 'Your new password', 'Your new RhodeCode password:%s' % (new_passwd)) - log.info('send new password mail to %s', user_email) + log.info('send new password mail to %s' % user_email) except: log.error('Failed to update user password') @@ -320,7 +313,7 @@ def reset_user_password(user_email): @task(ignore_result=True) @dbsession -def send_email(recipients, subject, body): +def send_email(recipients, subject, body, html_body=''): """ Sends an email with defined parameters from the .ini files. @@ -328,23 +321,20 @@ def send_email(recipients, subject, body address from field 'email_to' is used instead :param subject: subject of the mail :param body: body of the mail + :param html_body: html version of body """ - try: - log = send_email.get_logger() - except: - log = logging.getLogger(__name__) - - sa = get_session() + log = get_logger(send_email) + DBS = get_session() + email_config = config - + subject = "%s %s" % (email_config.get('email_prefix'), subject) if not recipients: # if recipients are not defined we send to email_config + all admins - admins = [ - u.email for u in sa.query(User).filter(User.admin==True).all() - ] + admins = [u.email for u in User.query() + .filter(User.admin == True).all()] recipients = [email_config.get('email_to')] + admins - mail_from = email_config.get('app_email_from') + mail_from = email_config.get('app_email_from', 'RhodeCode') user = email_config.get('smtp_username') passwd = email_config.get('smtp_password') mail_server = email_config.get('smtp_server') @@ -355,9 +345,9 @@ def send_email(recipients, subject, body smtp_auth = email_config.get('smtp_auth') try: - m = SmtpMailer(mail_from, user, passwd, mail_server,smtp_auth, + m = SmtpMailer(mail_from, user, passwd, mail_server, smtp_auth, mail_port, ssl, tls, debug=debug) - m.send(recipients, subject, body) + m.send(recipients, subject, body, html_body) except: log.error('Mail sending failed') log.error(traceback.format_exc()) @@ -368,29 +358,45 @@ def send_email(recipients, subject, body @task(ignore_result=True) @dbsession def create_repo_fork(form_data, cur_user): + """ + Creates a fork of repository using interval VCS methods + + :param form_data: + :param cur_user: + """ from rhodecode.model.repo import RepoModel - try: - log = create_repo_fork.get_logger() - except: - log = logging.getLogger(__name__) + log = get_logger(create_repo_fork) + DBS = get_session() + + base_path = Repository.base_path() + + RepoModel(DBS).create(form_data, cur_user, just_db=True, fork=True) + + alias = form_data['repo_type'] + org_repo_name = form_data['org_path'] + fork_name = form_data['repo_name_full'] + update_after_clone = form_data['update_after_clone'] + source_repo_path = os.path.join(base_path, org_repo_name) + destination_fork_path = os.path.join(base_path, fork_name) - repo_model = RepoModel(get_session()) - repo_model.create(form_data, cur_user, just_db=True, fork=True) - repo_name = form_data['repo_name'] - repos_path = get_repos_path() - repo_path = os.path.join(repos_path, repo_name) - repo_fork_path = os.path.join(repos_path, form_data['fork_name']) - alias = form_data['repo_type'] + log.info('creating fork of %s as %s', source_repo_path, + destination_fork_path) + backend = get_backend(alias) + backend(safe_str(destination_fork_path), create=True, + src_url=safe_str(source_repo_path), + update_after_clone=update_after_clone) + action_logger(cur_user, 'user_forked_repo:%s' % fork_name, + org_repo_name, '', DBS) - log.info('creating repo fork %s as %s', repo_name, repo_path) - backend = get_backend(alias) - backend(str(repo_fork_path), create=True, src_url=str(repo_path)) - + action_logger(cur_user, 'user_created_fork:%s' % fork_name, + fork_name, '', DBS) + # finally commit at latest possible stage + DBS.commit() def __get_codes_stats(repo_name): - repos_path = get_repos_path() - repo = get_repo(safe_str(os.path.join(repos_path, repo_name))) + repo = Repository.get_by_repo_name(repo_name).scm_instance + tip = repo.get_changeset() code_stats = {}