# HG changeset patch # User Weblate # Date 1420634248 -3600 # Node ID 0c8efa0c45a11fe1a077c492f76f4e206a670285 # Parent fc8ab968fe107fe4be5287d090e97db55fc59fb0# Parent 971d9ecdcc707c7de8de7b68da47e36d4b358f01 Merge diff -r fc8ab968fe10 -r 0c8efa0c45a1 kallithea/bin/base.py --- a/kallithea/bin/base.py Mon Jan 05 10:58:24 2015 +0100 +++ b/kallithea/bin/base.py Wed Jan 07 13:37:28 2015 +0100 @@ -31,13 +31,7 @@ import urllib2 import pprint -try: - from kallithea.lib.ext_json import json -except ImportError: - try: - import simplejson as json - except ImportError: - import json +from kallithea.lib.compat import json CONFIG_NAME = '.config/kallithea' FORMAT_PRETTY = 'pretty' diff -r fc8ab968fe10 -r 0c8efa0c45a1 kallithea/bin/kallithea_api.py --- a/kallithea/bin/kallithea_api.py Mon Jan 05 10:58:24 2015 +0100 +++ b/kallithea/bin/kallithea_api.py Wed Jan 07 13:37:28 2015 +0100 @@ -101,7 +101,7 @@ try: margs = dict(map(lambda s: s.split(':', 1), other)) - except Exception: + except ValueError: sys.stderr.write('Error parsing arguments \n') sys.exit() if args.format == FORMAT_PRETTY: diff -r fc8ab968fe10 -r 0c8efa0c45a1 kallithea/bin/kallithea_config.py --- a/kallithea/bin/kallithea_config.py Mon Jan 05 10:58:24 2015 +0100 +++ b/kallithea/bin/kallithea_config.py Wed Jan 07 13:37:28 2015 +0100 @@ -152,10 +152,7 @@ if argv is None: argv = sys.argv - try: - return _run(argv) - except Exception: - raise + return _run(argv) if __name__ == '__main__': diff -r fc8ab968fe10 -r 0c8efa0c45a1 kallithea/bin/ldap_sync.py --- a/kallithea/bin/ldap_sync.py Mon Jan 05 10:58:24 2015 +0100 +++ b/kallithea/bin/ldap_sync.py Wed Jan 07 13:37:28 2015 +0100 @@ -29,13 +29,7 @@ import urllib2 import uuid -try: - from kallithea.lib.compat import json -except ImportError: - try: - import simplejson as json - except ImportError: - import json +from kallithea.lib.compat import json from ConfigParser import ConfigParser diff -r fc8ab968fe10 -r 0c8efa0c45a1 kallithea/controllers/admin/admin.py --- a/kallithea/controllers/admin/admin.py Mon Jan 05 10:58:24 2015 +0100 +++ b/kallithea/controllers/admin/admin.py Wed Jan 07 13:37:28 2015 +0100 @@ -131,11 +131,7 @@ #FILTERING c.search_term = request.GET.get('filter') - try: - users_log = _journal_filter(users_log, c.search_term) - except Exception: - # we want this to crash for now - raise + users_log = _journal_filter(users_log, c.search_term) users_log = users_log.order_by(UserLog.action_date.desc()) diff -r fc8ab968fe10 -r 0c8efa0c45a1 kallithea/controllers/admin/repo_groups.py --- a/kallithea/controllers/admin/repo_groups.py Mon Jan 05 10:58:24 2015 +0100 +++ b/kallithea/controllers/admin/repo_groups.py Wed Jan 07 13:37:28 2015 +0100 @@ -146,7 +146,7 @@ "group_name": repo_group_name(repo_gr.group_name, children_groups), "desc": repo_gr.group_description, "repos": repo_count, - "owner": h.person(repo_gr.user.username), + "owner": h.person(repo_gr.user), "action": repo_group_actions(repo_gr.group_id, repo_gr.group_name, repo_count) }) diff -r fc8ab968fe10 -r 0c8efa0c45a1 kallithea/controllers/admin/settings.py --- a/kallithea/controllers/admin/settings.py Mon Jan 05 10:58:24 2015 +0100 +++ b/kallithea/controllers/admin/settings.py Wed Jan 07 13:37:28 2015 +0100 @@ -208,12 +208,13 @@ filesystem_repos = ScmModel().repo_scan() added, removed = repo2db_mapper(filesystem_repos, rm_obsolete, - install_git_hook=install_git_hooks) - _repr = lambda l: ', '.join(map(safe_unicode, l)) or '-' - h.flash(_('Repositories successfully ' - 'rescanned added: %s ; removed: %s') % - (_repr(added), _repr(removed)), - category='success') + install_git_hook=install_git_hooks, + user=c.authuser.username) + h.flash(h.literal(_('Repositories successfully rescanned. Added: %s. Removed: %s.') % + (', '.join(h.link_to(safe_unicode(repo_name), h.url('summary_home', repo_name=repo_name)) + for repo_name in added) or '-', + ', '.join(h.escape(safe_unicode(repo_name)) for repo_name in removed) or '-')), + category='success') return redirect(url('admin_settings_mapping')) defaults = Setting.get_app_settings() diff -r fc8ab968fe10 -r 0c8efa0c45a1 kallithea/controllers/admin/user_groups.py --- a/kallithea/controllers/admin/user_groups.py Mon Jan 05 10:58:24 2015 +0100 +++ b/kallithea/controllers/admin/user_groups.py Wed Jan 07 13:37:28 2015 +0100 @@ -138,16 +138,17 @@ users_group_form = UserGroupForm()() try: form_result = users_group_form.to_python(dict(request.POST)) - UserGroupModel().create(name=form_result['users_group_name'], - description=form_result['user_group_description'], - owner=self.authuser.user_id, - active=form_result['users_group_active']) + ug = UserGroupModel().create(name=form_result['users_group_name'], + description=form_result['user_group_description'], + owner=self.authuser.user_id, + active=form_result['users_group_active']) gr = form_result['users_group_name'] action_logger(self.authuser, 'admin_created_users_group:%s' % gr, None, self.ip_addr, self.sa) - h.flash(_('Created user group %s') % gr, category='success') + h.flash(h.literal(_('Created user group %s') % h.link_to(h.escape(gr), url('edit_users_group', id=ug.users_group_id))), + category='success') Session().commit() except formencode.Invalid, errors: return htmlfill.render( diff -r fc8ab968fe10 -r 0c8efa0c45a1 kallithea/controllers/admin/users.py --- a/kallithea/controllers/admin/users.py Mon Jan 05 10:58:24 2015 +0100 +++ b/kallithea/controllers/admin/users.py Wed Jan 07 13:37:28 2015 +0100 @@ -94,9 +94,8 @@ .render(user_id, username, _=_, h=h, c=c)) for user in c.users_list: - users_data.append({ - "gravatar": grav_tmpl(user. email, 20), + "gravatar": grav_tmpl(user.email, 20), "raw_name": user.username, "username": username(user.user_id, user.username), "firstname": user.name, @@ -128,11 +127,11 @@ user_form = UserForm()() try: form_result = user_form.to_python(dict(request.POST)) - user_model.create(form_result) + user = user_model.create(form_result) usr = form_result['username'] action_logger(self.authuser, 'admin_created_user:%s' % usr, None, self.ip_addr, self.sa) - h.flash(_('Created user %s') % usr, + h.flash(h.literal(_('Created user %s') % h.link_to(h.escape(usr), url('edit_user', id=user.user_id))), category='success') Session().commit() except formencode.Invalid, errors: diff -r fc8ab968fe10 -r 0c8efa0c45a1 kallithea/controllers/changeset.py --- a/kallithea/controllers/changeset.py Mon Jan 05 10:58:24 2015 +0100 +++ b/kallithea/controllers/changeset.py Wed Jan 07 13:37:28 2015 +0100 @@ -75,10 +75,7 @@ ig_ws_global = GET.get('ignorews') ig_ws = filter(lambda k: k.startswith('WS'), GET.getall(fid)) if ig_ws: - try: - return int(ig_ws[0].split(':')[-1]) - except Exception: - pass + return int(ig_ws[0].split(':')[-1]) return ig_ws_global diff -r fc8ab968fe10 -r 0c8efa0c45a1 kallithea/controllers/error.py --- a/kallithea/controllers/error.py Mon Jan 05 10:58:24 2015 +0100 +++ b/kallithea/controllers/error.py Wed Jan 07 13:37:28 2015 +0100 @@ -57,20 +57,15 @@ resp = request.environ.get('pylons.original_response') c.site_name = config.get('title') - log.debug('### %s ###' % resp.status) + log.debug('### %s ###' % resp and resp.status) e = request.environ c.serv_p = r'%(protocol)s://%(host)s/' \ % {'protocol': e.get('wsgi.url_scheme'), 'host': e.get('HTTP_HOST'), } - c.error_message = cgi.escape(request.GET.get('code', str(resp.status))) - c.error_explanation = self.get_error_explanation(resp.status_int) - - # redirect to when error with given seconds - c.redirect_time = 0 - c.redirect_module = _('Home page') - c.url_redirect = "/" + c.error_message = resp and cgi.escape(request.GET.get('code', str(resp.status))) + c.error_explanation = resp and self.get_error_explanation(resp.status_int) return render('/errors/error_document.html') @@ -94,7 +89,7 @@ [400, 401, 403, 404, 500]""" try: code = int(code) - except Exception: + except ValueError: code = 500 if code == 400: diff -r fc8ab968fe10 -r 0c8efa0c45a1 kallithea/controllers/files.py --- a/kallithea/controllers/files.py Mon Jan 05 10:58:24 2015 +0100 +++ b/kallithea/controllers/files.py Wed Jan 07 13:37:28 2015 +0100 @@ -190,7 +190,7 @@ return render('files/files_ypjax.html') # TODO: tags and bookmarks? - c.revision_options = [(c.changeset.raw_id, + c.revision_options = [(c.changeset.raw_id, _('%s at %s') % (c.changeset.branch, h.short_id(c.changeset.raw_id)))] + \ [(n, b) for b, n in c.db_repo_scm_instance.branches.items()] if c.db_repo_scm_instance.closed_branches: diff -r fc8ab968fe10 -r 0c8efa0c45a1 kallithea/controllers/journal.py --- a/kallithea/controllers/journal.py Mon Jan 05 10:58:24 2015 +0100 +++ b/kallithea/controllers/journal.py Wed Jan 07 13:37:28 2015 +0100 @@ -27,6 +27,7 @@ """ import logging +import traceback from itertools import groupby from sqlalchemy import or_ @@ -95,11 +96,7 @@ .options(joinedload(UserLog.user))\ .options(joinedload(UserLog.repository)) #filter - try: - journal = _journal_filter(journal, c.search_term) - except Exception: - # we want this to crash for now - raise + journal = _journal_filter(journal, c.search_term) journal = journal.filter(filtering_criterion)\ .order_by(UserLog.action_date.desc()) else: @@ -320,6 +317,7 @@ Session.commit() return 'ok' except Exception: + log.error(traceback.format_exc()) raise HTTPBadRequest() repo_id = request.POST.get('follows_repo_id') @@ -330,6 +328,7 @@ Session.commit() return 'ok' except Exception: + log.error(traceback.format_exc()) raise HTTPBadRequest() log.debug('token mismatch %s vs %s' % (cur_token, token)) diff -r fc8ab968fe10 -r 0c8efa0c45a1 kallithea/controllers/pullrequests.py --- a/kallithea/controllers/pullrequests.py Mon Jan 05 10:58:24 2015 +0100 +++ b/kallithea/controllers/pullrequests.py Wed Jan 07 13:37:28 2015 +0100 @@ -578,17 +578,18 @@ if org_scm_instance.alias == 'hg' and c.a_ref_name != 'ancestor': if c.cs_ref_type != 'branch': c.cs_branch_name = org_scm_instance.get_changeset(c.cs_ref_name).branch # use ref_type ? - other_branch_name = c.a_ref_name + c.a_branch_name = c.a_ref_name if c.a_ref_type != 'branch': try: - other_branch_name = other_scm_instance.get_changeset(c.a_ref_name).branch # use ref_type ? + c.a_branch_name = other_scm_instance.get_changeset(c.a_ref_name).branch # use ref_type ? except EmptyRepositoryError: - other_branch_name = 'null' # not a branch name ... but close enough + c.a_branch_name = 'null' # not a branch name ... but close enough + arevs = [] # candidates: descendants of old head that are on the right branch # and not are the old head itself ... # and nothing at all if old head is a descendent of target ref name - if other_scm_instance._repo.revs('present(%s)::&%s', c.cs_ranges[-1].raw_id, other_branch_name): - c.update_msg = _('This pull request has already been merged to %s.') % other_branch_name + if other_scm_instance._repo.revs('present(%s)::&%s', c.cs_ranges[-1].raw_id, c.a_branch_name): + c.update_msg = _('This pull request has already been merged to %s.') % c.a_branch_name else: # look for children of PR head on source branch in org repo arevs = org_scm_instance._repo.revs('%s:: & branch(%s) - %s', revs[0], c.cs_branch_name, revs[0]) @@ -601,12 +602,11 @@ else: c.update_msg = _('No changesets found for updating this pull request.') - revs = org_scm_instance._repo.revs('head() & not (%s::) & branch(%s) & !closed()', revs[0], c.cs_branch_name) - if revs: - c.update_msg_other = _('Note: Branch %s also contains unrelated changes, such as %s.') % (c.cs_branch_name, - h.short_id(org_scm_instance.get_changeset((max(revs))).raw_id)) - else: - c.update_msg_other = _('Branch %s does not contain other changes.') % c.cs_branch_name + brevs = org_scm_instance._repo.revs('%s - %d - %ld', c.cs_branch_name, revs[0], arevs) + if brevs: + c.update_msg_other = _('Note: Branch %s has another head: %s.') % (c.cs_branch_name, + h.short_id(org_scm_instance.get_changeset((max(brevs))).raw_id)) + elif org_scm_instance.alias == 'git': c.update_msg = _("Git pull requests don't support updates yet.") diff -r fc8ab968fe10 -r 0c8efa0c45a1 kallithea/controllers/summary.py --- a/kallithea/controllers/summary.py Mon Jan 05 10:58:24 2015 +0100 +++ b/kallithea/controllers/summary.py Wed Jan 07 13:37:28 2015 +0100 @@ -118,8 +118,6 @@ pass except EmptyRepositoryError: pass - except Exception: - log.error(traceback.format_exc()) return readme_data, readme_file diff -r fc8ab968fe10 -r 0c8efa0c45a1 kallithea/lib/auth.py --- a/kallithea/lib/auth.py Mon Jan 05 10:58:24 2015 +0100 +++ b/kallithea/lib/auth.py Wed Jan 07 13:37:28 2015 +0100 @@ -711,8 +711,6 @@ sa = meta.Session all_perms = sa.query(Permission).all() config['available_permissions'] = [x.permission_name for x in all_perms] - except Exception: - log.error(traceback.format_exc()) finally: meta.Session.remove() @@ -1175,12 +1173,7 @@ # dict by unicode repo_name = safe_unicode(repo_name) usr = AuthUser(user.user_id) - try: - self.user_perms = set([usr.permissions['repositories'][repo_name]]) - except Exception: - log.error('Exception while accessing permissions %s' % - traceback.format_exc()) - self.user_perms = set() + self.user_perms = set([usr.permissions['repositories'][repo_name]]) self.username = user.username self.repo_name = repo_name return self.check_permissions() @@ -1318,15 +1311,8 @@ log.debug('checking if ip:%s is subnet of %s' % (source_ip, allowed_ips)) if isinstance(allowed_ips, (tuple, list, set)): for ip in allowed_ips: - try: - if ipaddr.IPAddress(source_ip) in ipaddr.IPNetwork(ip): - log.debug('IP %s is network %s' % - (ipaddr.IPAddress(source_ip), ipaddr.IPNetwork(ip))) - return True - # for any case we cannot determine the IP, don't crash just - # skip it and log as error, we want to say forbidden still when - # sending bad IP - except Exception: - log.error(traceback.format_exc()) - continue + if ipaddr.IPAddress(source_ip) in ipaddr.IPNetwork(ip): + log.debug('IP %s is network %s' % + (ipaddr.IPAddress(source_ip), ipaddr.IPNetwork(ip))) + return True return False diff -r fc8ab968fe10 -r 0c8efa0c45a1 kallithea/lib/auth_modules/__init__.py --- a/kallithea/lib/auth_modules/__init__.py Mon Jan 05 10:58:24 2015 +0100 +++ b/kallithea/lib/auth_modules/__init__.py Wed Jan 07 13:37:28 2015 +0100 @@ -293,12 +293,8 @@ Session().flush() # enforce user is just in given groups, all of them has to be ones # created from plugins. We store this info in _group_data JSON field - try: - groups = auth['groups'] or [] - UserGroupModel().enforce_groups(user, groups, self.name) - except Exception: - # for any reason group syncing fails, we should proceed with login - log.error(traceback.format_exc()) + groups = auth['groups'] or [] + UserGroupModel().enforce_groups(user, groups, self.name) Session().commit() return auth @@ -417,6 +413,7 @@ return plugin_user # we failed to Auth because .auth() method didn't return proper the user - log.warning("User `%s` failed to authenticate against %s" - % (username, plugin.__module__)) + if username: + log.warning("User `%s` failed to authenticate against %s" + % (username, plugin.__module__)) return None diff -r fc8ab968fe10 -r 0c8efa0c45a1 kallithea/lib/auth_modules/auth_pam.py --- a/kallithea/lib/auth_modules/auth_pam.py Mon Jan 05 10:58:24 2015 +0100 +++ b/kallithea/lib/auth_modules/auth_pam.py Wed Jan 07 13:37:28 2015 +0100 @@ -132,7 +132,7 @@ user_attrs["firstname"] = match.group('first_name') user_attrs["lastname"] = match.group('last_name') except Exception: - log.warning("Cannot extract additional info for PAM user") + log.warning("Cannot extract additional info for PAM user %s", username) pass log.debug("pamuser: \n%s" % formatted_json(user_attrs)) diff -r fc8ab968fe10 -r 0c8efa0c45a1 kallithea/lib/celerylib/tasks.py --- a/kallithea/lib/celerylib/tasks.py Mon Jan 05 10:58:24 2015 +0100 +++ b/kallithea/lib/celerylib/tasks.py Wed Jan 07 13:37:28 2015 +0100 @@ -59,13 +59,10 @@ def get_logger(cls): if CELERY_ON: try: - log = cls.get_logger() - except Exception: - log = logging.getLogger(__name__) - else: - log = logging.getLogger(__name__) - - return log + return cls.get_logger() + except AttributeError: + pass + return logging.getLogger(__name__) @task(ignore_result=True) diff -r fc8ab968fe10 -r 0c8efa0c45a1 kallithea/lib/db_manage.py --- a/kallithea/lib/db_manage.py Mon Jan 05 10:58:24 2015 +0100 +++ b/kallithea/lib/db_manage.py Wed Jan 07 13:37:28 2015 +0100 @@ -190,12 +190,8 @@ paths.ui_value = paths.ui_value.replace('*', '') - try: - self.sa.add(paths) - self.sa.commit() - except Exception: - self.sa.rollback() - raise + self.sa.add(paths) + self.sa.commit() def fix_default_user(self): """ @@ -210,12 +206,8 @@ def_user.lastname = 'User' def_user.email = 'anonymous@kallithea-scm.org' - try: - self.sa.add(def_user) - self.sa.commit() - except Exception: - self.sa.rollback() - raise + self.sa.add(def_user) + self.sa.commit() def fix_settings(self): """ @@ -224,12 +216,8 @@ hgsettings3 = Setting('ga_code', '') - try: - self.sa.add(hgsettings3) - self.sa.commit() - except Exception: - self.sa.rollback() - raise + self.sa.add(hgsettings3) + self.sa.commit() def admin_prompt(self, second=False): if not self.tests: @@ -286,7 +274,6 @@ def create_ui_settings(self, repo_store_path): """ Creates ui settings, fills out hooks - and disables dotencode """ #HOOKS diff -r fc8ab968fe10 -r 0c8efa0c45a1 kallithea/lib/dbmigrate/schema/db_1_2_0.py --- a/kallithea/lib/dbmigrate/schema/db_1_2_0.py Mon Jan 05 10:58:24 2015 +0100 +++ b/kallithea/lib/dbmigrate/schema/db_1_2_0.py Wed Jan 07 13:37:28 2015 +0100 @@ -711,9 +711,6 @@ repo = backend(safe_str(repo_full_path), create=False, baseui=self._ui) - # skip hidden web repository - if repo._get_hidden(): - return else: repo = backend(repo_full_path, create=False) diff -r fc8ab968fe10 -r 0c8efa0c45a1 kallithea/lib/dbmigrate/schema/db_1_3_0.py --- a/kallithea/lib/dbmigrate/schema/db_1_3_0.py Mon Jan 05 10:58:24 2015 +0100 +++ b/kallithea/lib/dbmigrate/schema/db_1_3_0.py Wed Jan 07 13:37:28 2015 +0100 @@ -729,9 +729,6 @@ repo = backend(safe_str(repo_full_path), create=False, baseui=self._ui) - # skip hidden web repository - if repo._get_hidden(): - return else: repo = backend(repo_full_path, create=False) diff -r fc8ab968fe10 -r 0c8efa0c45a1 kallithea/lib/dbmigrate/schema/db_1_4_0.py --- a/kallithea/lib/dbmigrate/schema/db_1_4_0.py Mon Jan 05 10:58:24 2015 +0100 +++ b/kallithea/lib/dbmigrate/schema/db_1_4_0.py Wed Jan 07 13:37:28 2015 +0100 @@ -990,9 +990,6 @@ repo = backend(safe_str(repo_full_path), create=False, baseui=self._ui) - # skip hidden web repository - if repo._get_hidden(): - return else: repo = backend(repo_full_path, create=False) diff -r fc8ab968fe10 -r 0c8efa0c45a1 kallithea/lib/dbmigrate/schema/db_1_5_0.py --- a/kallithea/lib/dbmigrate/schema/db_1_5_0.py Mon Jan 05 10:58:24 2015 +0100 +++ b/kallithea/lib/dbmigrate/schema/db_1_5_0.py Wed Jan 07 13:37:28 2015 +0100 @@ -1009,9 +1009,6 @@ repo = backend(safe_str(repo_full_path), create=False, baseui=self._ui) - # skip hidden web repository - if repo._get_hidden(): - return else: repo = backend(repo_full_path, create=False) diff -r fc8ab968fe10 -r 0c8efa0c45a1 kallithea/lib/dbmigrate/schema/db_1_5_2.py --- a/kallithea/lib/dbmigrate/schema/db_1_5_2.py Mon Jan 05 10:58:24 2015 +0100 +++ b/kallithea/lib/dbmigrate/schema/db_1_5_2.py Wed Jan 07 13:37:28 2015 +0100 @@ -1130,9 +1130,6 @@ repo = backend(safe_str(repo_full_path), create=False, baseui=self._ui) - # skip hidden web repository - if repo._get_hidden(): - return else: repo = backend(repo_full_path, create=False) diff -r fc8ab968fe10 -r 0c8efa0c45a1 kallithea/lib/dbmigrate/schema/db_1_6_0.py --- a/kallithea/lib/dbmigrate/schema/db_1_6_0.py Mon Jan 05 10:58:24 2015 +0100 +++ b/kallithea/lib/dbmigrate/schema/db_1_6_0.py Wed Jan 07 13:37:28 2015 +0100 @@ -1206,9 +1206,6 @@ repo = backend(safe_str(repo_full_path), create=False, baseui=self._ui) - # skip hidden web repository - if repo._get_hidden(): - return else: repo = backend(repo_full_path, create=False) diff -r fc8ab968fe10 -r 0c8efa0c45a1 kallithea/lib/dbmigrate/schema/db_1_7_0.py --- a/kallithea/lib/dbmigrate/schema/db_1_7_0.py Mon Jan 05 10:58:24 2015 +0100 +++ b/kallithea/lib/dbmigrate/schema/db_1_7_0.py Wed Jan 07 13:37:28 2015 +0100 @@ -1223,9 +1223,6 @@ repo = backend(safe_str(repo_full_path), create=False, baseui=self._ui) - # skip hidden web repository - if repo._get_hidden(): - return else: repo = backend(repo_full_path, create=False) diff -r fc8ab968fe10 -r 0c8efa0c45a1 kallithea/lib/dbmigrate/schema/db_1_8_0.py --- a/kallithea/lib/dbmigrate/schema/db_1_8_0.py Mon Jan 05 10:58:24 2015 +0100 +++ b/kallithea/lib/dbmigrate/schema/db_1_8_0.py Wed Jan 07 13:37:28 2015 +0100 @@ -1253,9 +1253,6 @@ repo = backend(safe_str(repo_full_path), create=False, baseui=self._ui) - # skip hidden web repository - if repo._get_hidden(): - return else: repo = backend(repo_full_path, create=False) diff -r fc8ab968fe10 -r 0c8efa0c45a1 kallithea/lib/dbmigrate/schema/db_2_0_0.py --- a/kallithea/lib/dbmigrate/schema/db_2_0_0.py Mon Jan 05 10:58:24 2015 +0100 +++ b/kallithea/lib/dbmigrate/schema/db_2_0_0.py Wed Jan 07 13:37:28 2015 +0100 @@ -1310,9 +1310,6 @@ repo = backend(safe_str(repo_full_path), create=False, baseui=self._ui) - # skip hidden web repository - if repo._get_hidden(): - return else: repo = backend(repo_full_path, create=False) diff -r fc8ab968fe10 -r 0c8efa0c45a1 kallithea/lib/dbmigrate/schema/db_2_0_1.py --- a/kallithea/lib/dbmigrate/schema/db_2_0_1.py Mon Jan 05 10:58:24 2015 +0100 +++ b/kallithea/lib/dbmigrate/schema/db_2_0_1.py Wed Jan 07 13:37:28 2015 +0100 @@ -1309,9 +1309,6 @@ repo = backend(safe_str(repo_full_path), create=False, baseui=self._ui) - # skip hidden web repository - if repo._get_hidden(): - return else: repo = backend(repo_full_path, create=False) diff -r fc8ab968fe10 -r 0c8efa0c45a1 kallithea/lib/dbmigrate/schema/db_2_0_2.py --- a/kallithea/lib/dbmigrate/schema/db_2_0_2.py Mon Jan 05 10:58:24 2015 +0100 +++ b/kallithea/lib/dbmigrate/schema/db_2_0_2.py Wed Jan 07 13:37:28 2015 +0100 @@ -1329,9 +1329,6 @@ repo = backend(safe_str(repo_full_path), create=False, baseui=self._ui) - # skip hidden web repository - if repo._get_hidden(): - return else: repo = backend(repo_full_path, create=False) diff -r fc8ab968fe10 -r 0c8efa0c45a1 kallithea/lib/dbmigrate/schema/db_2_1_0.py --- a/kallithea/lib/dbmigrate/schema/db_2_1_0.py Mon Jan 05 10:58:24 2015 +0100 +++ b/kallithea/lib/dbmigrate/schema/db_2_1_0.py Wed Jan 07 13:37:28 2015 +0100 @@ -1368,9 +1368,6 @@ repo = backend(safe_str(repo_full_path), create=False, baseui=self._ui) - # skip hidden web repository - if repo._get_hidden(): - return else: repo = backend(repo_full_path, create=False) diff -r fc8ab968fe10 -r 0c8efa0c45a1 kallithea/lib/dbmigrate/schema/db_2_2_0.py --- a/kallithea/lib/dbmigrate/schema/db_2_2_0.py Mon Jan 05 10:58:24 2015 +0100 +++ b/kallithea/lib/dbmigrate/schema/db_2_2_0.py Wed Jan 07 13:37:28 2015 +0100 @@ -1414,9 +1414,6 @@ repo = backend(safe_str(repo_full_path), create=False, baseui=self._ui) - # skip hidden web repository - if repo._get_hidden(): - return else: repo = backend(repo_full_path, create=False) diff -r fc8ab968fe10 -r 0c8efa0c45a1 kallithea/lib/dbmigrate/schema/db_2_2_3.py --- a/kallithea/lib/dbmigrate/schema/db_2_2_3.py Mon Jan 05 10:58:24 2015 +0100 +++ b/kallithea/lib/dbmigrate/schema/db_2_2_3.py Wed Jan 07 13:37:28 2015 +0100 @@ -1441,9 +1441,6 @@ repo = backend(safe_str(repo_full_path), create=False, baseui=self._ui) - # skip hidden web repository - if repo._get_hidden(): - return else: repo = backend(repo_full_path, create=False) diff -r fc8ab968fe10 -r 0c8efa0c45a1 kallithea/lib/diffs.py --- a/kallithea/lib/diffs.py Mon Jan 05 10:58:24 2015 +0100 +++ b/kallithea/lib/diffs.py Wed Jan 07 13:37:28 2015 +0100 @@ -196,7 +196,7 @@ #used for inline highlighter word split _token_re = re.compile(r'()(>|<|&|\t| |\W+?)') - _escape_re = re.compile(r'(&)|(<)|(>)|(\t)|(?<=.)( \n| $)') + _escape_re = re.compile(r'(&)|(<)|(>)|(\t)|(\r)|(?<=.)( \n| $)') def __init__(self, diff, vcs='hg', format='gitdiff', diff_limit=None): @@ -264,6 +264,8 @@ if groups[3]: return '\t' if groups[4]: + return '' + if groups[5]: return ' ' assert False diff -r fc8ab968fe10 -r 0c8efa0c45a1 kallithea/lib/ext_json.py --- a/kallithea/lib/ext_json.py Mon Jan 05 10:58:24 2015 +0100 +++ b/kallithea/lib/ext_json.py Wed Jan 07 13:37:28 2015 +0100 @@ -1,14 +1,20 @@ +""" +Extended JSON encoder for json + +json.org do not specify how date time can be represented - monkeypatch it to do something. +""" + import datetime import functools import decimal -import imp +import json # is re-exported after monkey patching -__all__ = ['json', 'simplejson', 'stdlibjson'] +__all__ = ['json'] -def _is_aware(value): +def _is_tz_aware(value): """ - Determines if a given datetime.time is aware. + Determines if a given datetime.time is timezone aware. The logic is described in Python's docs: http://docs.python.org/library/datetime.html#datetime.tzinfo @@ -16,7 +22,6 @@ return (value.tzinfo is not None and value.tzinfo.utcoffset(value) is not None) - def _obj_dump(obj): """ Custom function for dumping objects to JSON, if obj has __json__ attribute @@ -41,7 +46,7 @@ elif isinstance(obj, decimal.Decimal): return str(obj) elif isinstance(obj, datetime.time): - if _is_aware(obj): + if _is_tz_aware(obj): raise ValueError("JSON can't represent timezone-aware times.") r = obj.isoformat() if obj.microsecond: @@ -58,65 +63,15 @@ raise NotImplementedError -# Import simplejson -try: - # import simplejson initially - _sj = imp.load_module('_sj', *imp.find_module('simplejson')) - - def extended_encode(obj): +class ExtendedEncoder(json.JSONEncoder): + def default(self, obj): try: return _obj_dump(obj) except NotImplementedError: pass raise TypeError("%r is not JSON serializable" % (obj,)) - # we handle decimals our own it makes unified behavior of json vs - # simplejson - sj_version = [int(x) for x in _sj.__version__.split('.')] - major, minor = sj_version[0], sj_version[1] - if major < 2 or (major == 2 and minor < 1): - # simplejson < 2.1 doesnt support use_decimal - _sj.dumps = functools.partial(_sj.dumps, - default=extended_encode) - _sj.dump = functools.partial(_sj.dump, - default=extended_encode) - else: - _sj.dumps = functools.partial(_sj.dumps, - default=extended_encode, - use_decimal=False) - _sj.dump = functools.partial(_sj.dump, - default=extended_encode, - use_decimal=False) - simplejson = _sj - -except ImportError: - # no simplejson set it to None - simplejson = None -try: - # simplejson not found try out regular json module - _json = imp.load_module('_json', *imp.find_module('json')) - - # extended JSON encoder for json - class ExtendedEncoder(_json.JSONEncoder): - def default(self, obj): - try: - return _obj_dump(obj) - except NotImplementedError: - pass - raise TypeError("%r is not JSON serializable" % (obj,)) - # monkey-patch JSON encoder to use extended version - _json.dumps = functools.partial(_json.dumps, cls=ExtendedEncoder) - _json.dump = functools.partial(_json.dump, cls=ExtendedEncoder) - - stdlibjson = _json -except ImportError: - stdlibjson = None - -# set all available json modules -if simplejson: - json = _sj -elif stdlibjson: - json = _json -else: - raise ImportError('Could not find any json modules') +# monkey-patch and export JSON encoder to use custom encoding method +json.dumps = functools.partial(json.dumps, cls=ExtendedEncoder) +json.dump = functools.partial(json.dump, cls=ExtendedEncoder) diff -r fc8ab968fe10 -r 0c8efa0c45a1 kallithea/lib/helpers.py --- a/kallithea/lib/helpers.py Mon Jan 05 10:58:24 2015 +0100 +++ b/kallithea/lib/helpers.py Wed Jan 07 13:37:28 2015 +0100 @@ -519,6 +519,8 @@ def person(author, show_attr="username"): + """Find the user identified by 'author', return one of the users attributes, + default to the username attribute, None if there is no user""" # attr to return from fetched user person_getter = lambda usr: getattr(usr, show_attr) @@ -1281,8 +1283,18 @@ 'rev': rev, } - return re.sub(r'(?:^|(?<=\s))([0-9a-fA-F]{12,40})(?=$|\s|[.,:])', url_func, text_) + return re.sub(r'(?:^|(?<=[\s(),]))([0-9a-fA-F]{12,40})(?=$|\s|[.,:()])', url_func, text_) +def linkify_others(t, l): + urls = re.compile(r'(\)',) + links = [] + for e in urls.split(t): + if not urls.match(e): + links.append('%s' % (l, e)) + else: + links.append(e) + + return ''.join(links) def urlify_commit(text_, repository, link_=None): """ @@ -1294,91 +1306,77 @@ :param repository: :param link_: changeset link """ - import traceback - from pylons import url # doh, we need to re-import url to mock it later - def escaper(string): return string.replace('<', '<').replace('>', '>') - def linkify_others(t, l): - urls = re.compile(r'(\)',) - links = [] - for e in urls.split(t): - if not urls.match(e): - links.append('%s' % (l, e)) - else: - links.append(e) - - return ''.join(links) - # urlify changesets - extract revisions and make link out of them newtext = urlify_changesets(escaper(text_), repository) # extract http/https links and make them real urls newtext = urlify_text(newtext, safe=False) - try: - from kallithea import CONFIG - conf = CONFIG + newtext = urlify_issues(newtext, repository, link_) + + return literal(newtext) + +def urlify_issues(newtext, repository, link_=None): + from kallithea import CONFIG as conf - # allow multiple issue servers to be used - valid_indices = [ - x.group(1) - for x in map(lambda x: re.match(r'issue_pat(.*)', x), conf.keys()) - if x and 'issue_server_link%s' % x.group(1) in conf - and 'issue_prefix%s' % x.group(1) in conf - ] + # allow multiple issue servers to be used + valid_indices = [ + x.group(1) + for x in map(lambda x: re.match(r'issue_pat(.*)', x), conf.keys()) + if x and 'issue_server_link%s' % x.group(1) in conf + and 'issue_prefix%s' % x.group(1) in conf + ] + if valid_indices: log.debug('found issue server suffixes `%s` during valuation of: %s' % (','.join(valid_indices), newtext)) - for pattern_index in valid_indices: - ISSUE_PATTERN = conf.get('issue_pat%s' % pattern_index) - ISSUE_SERVER_LNK = conf.get('issue_server_link%s' % pattern_index) - ISSUE_PREFIX = conf.get('issue_prefix%s' % pattern_index) - - log.debug('pattern suffix `%s` PAT:%s SERVER_LINK:%s PREFIX:%s' - % (pattern_index, ISSUE_PATTERN, ISSUE_SERVER_LNK, - ISSUE_PREFIX)) - - URL_PAT = re.compile(r'%s' % ISSUE_PATTERN) + for pattern_index in valid_indices: + ISSUE_PATTERN = conf.get('issue_pat%s' % pattern_index) + ISSUE_SERVER_LNK = conf.get('issue_server_link%s' % pattern_index) + ISSUE_PREFIX = conf.get('issue_prefix%s' % pattern_index) - def url_func(match_obj): - pref = '' - if match_obj.group().startswith(' '): - pref = ' ' + log.debug('pattern suffix `%s` PAT:%s SERVER_LINK:%s PREFIX:%s' + % (pattern_index, ISSUE_PATTERN, ISSUE_SERVER_LNK, + ISSUE_PREFIX)) - issue_id = ''.join(match_obj.groups()) - issue_url = ISSUE_SERVER_LNK.replace('{id}', issue_id) - if repository: - issue_url = issue_url.replace('{repo}', repository) - repo_name = repository.split(URL_SEP)[-1] - issue_url = issue_url.replace('{repo_name}', repo_name) + URL_PAT = re.compile(r'%s' % ISSUE_PATTERN) + + def url_func(match_obj): + pref = '' + if match_obj.group().startswith(' '): + pref = ' ' - return ( - '%(pref)s' - '%(issue-prefix)s%(id-repr)s' - '' - ) % { - 'pref': pref, - 'cls': 'issue-tracker-link', - 'url': issue_url, - 'id-repr': issue_id, - 'issue-prefix': ISSUE_PREFIX, - 'serv': ISSUE_SERVER_LNK, - } - newtext = URL_PAT.sub(url_func, newtext) - log.debug('processed prefix:`%s` => %s' % (pattern_index, newtext)) + issue_id = ''.join(match_obj.groups()) + issue_url = ISSUE_SERVER_LNK.replace('{id}', issue_id) + if repository: + issue_url = issue_url.replace('{repo}', repository) + repo_name = repository.split(URL_SEP)[-1] + issue_url = issue_url.replace('{repo_name}', repo_name) - # if we actually did something above - if link_: - # wrap not links into final link => link_ - newtext = linkify_others(newtext, link_) - except Exception: - log.error(traceback.format_exc()) - pass + return ( + '%(pref)s' + '%(issue-prefix)s%(id-repr)s' + '' + ) % { + 'pref': pref, + 'cls': 'issue-tracker-link', + 'url': issue_url, + 'id-repr': issue_id, + 'issue-prefix': ISSUE_PREFIX, + 'serv': ISSUE_SERVER_LNK, + } + newtext = URL_PAT.sub(url_func, newtext) + log.debug('processed prefix:`%s` => %s' % (pattern_index, newtext)) - return literal(newtext) + # if we actually did something above + if link_: + # wrap not links into final link => link_ + newtext = linkify_others(newtext, link_) + return newtext def rst(source): diff -r fc8ab968fe10 -r 0c8efa0c45a1 kallithea/lib/paster_commands/update_repoinfo.py --- a/kallithea/lib/paster_commands/update_repoinfo.py Mon Jan 05 10:58:24 2015 +0100 +++ b/kallithea/lib/paster_commands/update_repoinfo.py Wed Jan 07 13:37:28 2015 +0100 @@ -12,10 +12,10 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . """ -kallithea.lib.paster_commands.make_rcextensions -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +kallithea.lib.paster_commands.update_repoinfo +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -uodate-repoinfo paster command for Kallithea +update-repoinfo paster command for Kallithea This file was forked by the Kallithea project in July 2014. Original author and date, and relevant copyright and licensing information is below: @@ -65,8 +65,8 @@ if self.options.repo_update_list else None if repo_update_list: - repo_list = Repository.query()\ - .filter(Repository.repo_name.in_(repo_update_list)) + repo_list = list(Repository.query()\ + .filter(Repository.repo_name.in_(repo_update_list))) else: repo_list = Repository.getAll() RepoModel.update_repoinfo(repositories=repo_list) @@ -75,7 +75,7 @@ if self.options.invalidate_cache: for r in repo_list: r.set_invalidate() - log.info('Updated cache for %s repositories' % (len(repo_list))) + print 'Updated cache for %s repositories' % (len(repo_list)) def update_parser(self): self.parser.add_option('--update-only', diff -r fc8ab968fe10 -r 0c8efa0c45a1 kallithea/lib/utils.py --- a/kallithea/lib/utils.py Mon Jan 05 10:58:24 2015 +0100 +++ b/kallithea/lib/utils.py Wed Jan 07 13:37:28 2015 +0100 @@ -120,16 +120,10 @@ def get_user_group_slug(request): _group = request.environ['pylons.routes_dict'].get('id') - try: - _group = UserGroup.get(_group) - if _group: - _group = _group.users_group_name - except Exception: - log.debug(traceback.format_exc()) - #catch all failures here - pass - - return _group + _group = UserGroup.get(_group) + if _group: + return _group.users_group_name + return None def _extract_id_from_repo_name(repo_name): @@ -147,15 +141,14 @@ :param repo_name: :return: repo_name if matched else None """ - try: - _repo_id = _extract_id_from_repo_name(repo_name) - if _repo_id: - from kallithea.model.db import Repository - return Repository.get(_repo_id).repo_name - except Exception: - log.debug('Failed to extract repo_name from URL %s' % ( - traceback.format_exc())) - return + _repo_id = _extract_id_from_repo_name(repo_name) + if _repo_id: + from kallithea.model.db import Repository + repo = Repository.get(_repo_id) + if repo: + # TODO: return repo instead of reponame? or would that be a layering violation? + return repo.repo_name + return None def action_logger(user, action, repo, ipaddr='', sa=None, commit=False): @@ -180,43 +173,39 @@ if not ipaddr: ipaddr = getattr(get_current_authuser(), 'ip_addr', '') - try: - if getattr(user, 'user_id', None): - user_obj = User.get(user.user_id) - elif isinstance(user, basestring): - user_obj = User.get_by_username(user) - else: - raise Exception('You have to provide a user object or a username') + if getattr(user, 'user_id', None): + user_obj = User.get(user.user_id) + elif isinstance(user, basestring): + user_obj = User.get_by_username(user) + else: + raise Exception('You have to provide a user object or a username') - if getattr(repo, 'repo_id', None): - repo_obj = Repository.get(repo.repo_id) - repo_name = repo_obj.repo_name - elif isinstance(repo, basestring): - repo_name = repo.lstrip('/') - repo_obj = Repository.get_by_repo_name(repo_name) - else: - repo_obj = None - repo_name = '' + if getattr(repo, 'repo_id', None): + repo_obj = Repository.get(repo.repo_id) + repo_name = repo_obj.repo_name + elif isinstance(repo, basestring): + repo_name = repo.lstrip('/') + repo_obj = Repository.get_by_repo_name(repo_name) + else: + repo_obj = None + repo_name = '' - user_log = UserLog() - user_log.user_id = user_obj.user_id - user_log.username = user_obj.username - user_log.action = safe_unicode(action) + user_log = UserLog() + user_log.user_id = user_obj.user_id + user_log.username = user_obj.username + user_log.action = safe_unicode(action) - user_log.repository = repo_obj - user_log.repository_name = repo_name + user_log.repository = repo_obj + user_log.repository_name = repo_name - user_log.action_date = datetime.datetime.now() - user_log.user_ip = ipaddr - sa.add(user_log) + user_log.action_date = datetime.datetime.now() + user_log.user_ip = ipaddr + sa.add(user_log) - log.info('Logging action:%s on %s by user:%s ip:%s' % - (action, safe_unicode(repo), user_obj, ipaddr)) - if commit: - sa.commit() - except Exception: - log.error(traceback.format_exc()) - raise + log.info('Logging action:%s on %s by user:%s ip:%s' % + (action, safe_unicode(repo), user_obj, ipaddr)) + if commit: + sa.commit() def get_filesystem_repos(path, recursive=False, skip_removed_repos=True): @@ -373,9 +362,7 @@ elif read_from == 'db': sa = meta.Session() - ret = sa.query(Ui)\ - .options(FromCache("sql_cache_short", "get_hg_ui_settings"))\ - .all() + ret = sa.query(Ui).all() hg_ui = ret for ui_ in hg_ui: @@ -471,7 +458,7 @@ def repo2db_mapper(initial_repo_list, remove_obsolete=False, - install_git_hook=False): + install_git_hook=False, user=None): """ maps all repos given in initial_repo_list, non existing repositories are created, if remove_obsolete is True it also check for db entries @@ -486,7 +473,8 @@ from kallithea.model.scm import ScmModel sa = meta.Session() repo_model = RepoModel() - user = User.get_first_admin() + if user is None: + user = User.get_first_admin() added = [] ##creation defaults @@ -815,7 +803,7 @@ ver = '.'.join(ver.split('.')[:3]) try: _ver = StrictVersion(ver) - except Exception: + except ValueError: _ver = StrictVersion('0.0.0') stderr = traceback.format_exc() diff -r fc8ab968fe10 -r 0c8efa0c45a1 kallithea/lib/utils2.py --- a/kallithea/lib/utils2.py Mon Jan 05 10:58:24 2015 +0100 +++ b/kallithea/lib/utils2.py Wed Jan 07 13:37:28 2015 +0100 @@ -32,7 +32,6 @@ import time import uuid import datetime -import traceback import webob import urllib import urlobject @@ -409,6 +408,18 @@ deltas['month'] += 12 deltas['year'] -= 1 + # In short version, we want nicer handling of ages of more than a year + if show_short_version: + if deltas['year'] == 1: + # ages between 1 and 2 years: show as months + deltas['month'] += 12 + deltas['year'] = 0 + if deltas['year'] >= 2: + # ages 2+ years: round + if deltas['month'] > 6: + deltas['year'] += 1 + deltas['month'] = 0 + # Format the result fmt_funcs = { 'year': lambda d: ungettext(u'%d year', '%d years', d) % d, @@ -596,14 +607,14 @@ def obfuscate_url_pw(engine): - _url = engine or '' from sqlalchemy.engine import url as sa_url + from sqlalchemy.exc import ArgumentError try: - _url = sa_url.make_url(engine) - if _url.password: - _url.password = 'XXXXX' - except Exception: - pass + _url = sa_url.make_url(engine or '') + except ArgumentError: + return engine + if _url.password: + _url.password = 'XXXXX' return str(_url) @@ -622,9 +633,7 @@ try: rc_extras = json.loads(env['KALLITHEA_EXTRAS']) - except Exception: - print os.environ - print >> sys.stderr, traceback.format_exc() + except KeyError: rc_extras = {} try: diff -r fc8ab968fe10 -r 0c8efa0c45a1 kallithea/lib/vcs/backends/git/repository.py --- a/kallithea/lib/vcs/backends/git/repository.py Mon Jan 05 10:58:24 2015 +0100 +++ b/kallithea/lib/vcs/backends/git/repository.py Wed Jan 07 13:37:28 2015 +0100 @@ -294,7 +294,7 @@ or isinstance(revision, int) or is_null(revision)): try: revision = self.revisions[int(revision)] - except Exception: + except IndexError: msg = ("Revision %s does not exist for %s" % (revision, self)) raise ChangesetDoesNotExistError(msg) diff -r fc8ab968fe10 -r 0c8efa0c45a1 kallithea/lib/vcs/backends/hg/repository.py --- a/kallithea/lib/vcs/backends/hg/repository.py Mon Jan 05 10:58:24 2015 +0100 +++ b/kallithea/lib/vcs/backends/hg/repository.py Wed Jan 07 13:37:28 2015 +0100 @@ -121,34 +121,16 @@ if self._empty: return {} - def _branchtags(localrepo): - """ - Patched version of mercurial branchtags to not return the closed - branches - - :param localrepo: locarepository instance - """ + bt = OrderedDict() + for bn, _heads, tip, isclosed in sorted(self._repo.branchmap().iterbranches()): + if isclosed: + if closed: + bt[safe_unicode(bn)] = hex(tip) + else: + if normal: + bt[safe_unicode(bn)] = hex(tip) - bt = {} - bt_closed = {} - for bn, heads in localrepo.branchmap().iteritems(): - tip = heads[-1] - if 'close' in localrepo.changelog.read(tip)[5]: - bt_closed[bn] = tip - else: - bt[bn] = tip - - if not normal: - return bt_closed - if closed: - bt.update(bt_closed) - return bt - - sortkey = lambda ctx: ctx[0] # sort by name - _branches = [(safe_unicode(n), hex(h),) for n, h in - _branchtags(self._repo).items()] - - return OrderedDict(sorted(_branches, key=sortkey, reverse=False)) + return bt @LazyProperty def tags(self): @@ -362,13 +344,8 @@ opts = {} if not update_after_clone: opts.update({'noupdate': True}) - try: - MercurialRepository._check_url(url, self.baseui) - clone(self.baseui, url, self.path, **opts) -# except urllib2.URLError: -# raise Abort("Got HTTP 404 error") - except Exception: - raise + MercurialRepository._check_url(url, self.baseui) + clone(self.baseui, url, self.path, **opts) # Don't try to create if we've already cloned repo create = False @@ -417,9 +394,6 @@ else: return os.stat(st_path).st_mtime - def _get_hidden(self): - return self._repo.ui.configbool("web", "hidden", untrusted=True) - def _get_revision(self, revision): """ Gets an ID revision given as str. This will always return a fill diff -r fc8ab968fe10 -r 0c8efa0c45a1 kallithea/lib/vcs/nodes.py --- a/kallithea/lib/vcs/nodes.py Mon Jan 05 10:58:24 2015 +0100 +++ b/kallithea/lib/vcs/nodes.py Wed Jan 07 13:37:28 2015 +0100 @@ -340,9 +340,9 @@ #try with pygments try: - from pygments.lexers import get_lexer_for_filename - mt = get_lexer_for_filename(self.name).mimetypes - except Exception: + from pygments import lexers + mt = lexers.get_lexer_for_filename(self.name).mimetypes + except lexers.ClassNotFound: mt = None if mt: diff -r fc8ab968fe10 -r 0c8efa0c45a1 kallithea/lib/vcs/subprocessio.py --- a/kallithea/lib/vcs/subprocessio.py Mon Jan 05 10:58:24 2015 +0100 +++ b/kallithea/lib/vcs/subprocessio.py Wed Jan 07 13:37:28 2015 +0100 @@ -45,15 +45,9 @@ else: # can be either file pointer or file-like if type(source) in (int, long): # file pointer it is ## converting file descriptor (int) stdin into file-like - try: - source = os.fdopen(source, 'rb', 16384) - except Exception: - pass + source = os.fdopen(source, 'rb', 16384) # let's see if source is file-like by now - try: - filelike = source.read - except Exception: - pass + filelike = hasattr(source, 'read') if not filelike and not self.bytes: raise TypeError("StreamFeeder's source object must be a readable " "file-like, a file descriptor, or a string-like.") diff -r fc8ab968fe10 -r 0c8efa0c45a1 kallithea/lib/vcs/utils/__init__.py --- a/kallithea/lib/vcs/utils/__init__.py Mon Jan 05 10:58:24 2015 +0100 +++ b/kallithea/lib/vcs/utils/__init__.py Wed Jan 07 13:37:28 2015 +0100 @@ -158,6 +158,8 @@ Regex taken from http://www.regular-expressions.info/email.html """ + if not author: + return '' import re r = author.find('>') l = author.find('<') @@ -180,9 +182,9 @@ It'll try to find an email in the author string and just cut it off to get the username """ - + if not author: + return '' if not '@' in author: return author - else: - return author.replace(author_email(author), '').replace('<', '')\ - .replace('>', '').strip() + return author.replace(author_email(author), '').replace('<', '')\ + .replace('>', '').strip() diff -r fc8ab968fe10 -r 0c8efa0c45a1 kallithea/model/api_key.py --- a/kallithea/model/api_key.py Mon Jan 05 10:58:24 2015 +0100 +++ b/kallithea/model/api_key.py Wed Jan 07 13:37:28 2015 +0100 @@ -28,7 +28,6 @@ from __future__ import with_statement import time import logging -import traceback from sqlalchemy import or_ from kallithea.lib.utils2 import generate_api_key @@ -71,11 +70,7 @@ api_key = api_key.filter(UserApiKeys.user_id == user.user_id) api_key = api_key.scalar() - try: - Session().delete(api_key) - except Exception: - log.error(traceback.format_exc()) - raise + Session().delete(api_key) def get_api_keys(self, user, show_expired=True): user = self._get_user(user) diff -r fc8ab968fe10 -r 0c8efa0c45a1 kallithea/model/changeset_status.py --- a/kallithea/model/changeset_status.py Mon Jan 05 10:58:24 2015 +0100 +++ b/kallithea/model/changeset_status.py Wed Jan 07 13:37:28 2015 +0100 @@ -28,6 +28,7 @@ import logging from collections import defaultdict +from sqlalchemy.orm import joinedload from kallithea.model import BaseModel from kallithea.model.db import ChangesetStatus, PullRequest @@ -103,6 +104,7 @@ with_revisions=False): q = self._get_status_query(repo, revision, pull_request, with_revisions) + q = q.options(joinedload('author')) return q.all() def get_status(self, repo, revision=None, pull_request=None, as_str=True): diff -r fc8ab968fe10 -r 0c8efa0c45a1 kallithea/model/db.py --- a/kallithea/model/db.py Mon Jan 05 10:58:24 2015 +0100 +++ b/kallithea/model/db.py Wed Jan 07 13:37:28 2015 +0100 @@ -421,6 +421,8 @@ user_perms = relationship('UserToPerm', primaryjoin="User.user_id==UserToPerm.user_id", cascade='all') repositories = relationship('Repository') + repo_groups = relationship('RepoGroup') + user_groups = relationship('UserGroup') user_followers = relationship('UserFollowing', primaryjoin='UserFollowing.follows_user_id==User.user_id', cascade='all') followings = relationship('UserFollowing', primaryjoin='UserFollowing.user_id==User.user_id', cascade='all') @@ -793,7 +795,7 @@ created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) _group_data = Column("group_data", LargeBinary(), nullable=True) # JSON data - members = relationship('UserGroupMember', cascade="all, delete, delete-orphan", lazy="joined") + members = relationship('UserGroupMember', cascade="all, delete-orphan", lazy="joined") users_group_to_perm = relationship('UserGroupToPerm', cascade='all') users_group_repo_to_perm = relationship('UserGroupRepoToPerm', cascade='all') users_group_repo_group_to_perm = relationship('UserGroupRepoGroupToPerm', cascade='all') @@ -971,18 +973,18 @@ primaryjoin='UserFollowing.follows_repo_id==Repository.repo_id', cascade='all') extra_fields = relationship('RepositoryField', - cascade="all, delete, delete-orphan") + cascade="all, delete-orphan") logs = relationship('UserLog') - comments = relationship('ChangesetComment', cascade="all, delete, delete-orphan") + comments = relationship('ChangesetComment', cascade="all, delete-orphan") pull_requests_org = relationship('PullRequest', primaryjoin='PullRequest.org_repo_id==Repository.repo_id', - cascade="all, delete, delete-orphan") + cascade="all, delete-orphan") pull_requests_other = relationship('PullRequest', primaryjoin='PullRequest.other_repo_id==Repository.repo_id', - cascade="all, delete, delete-orphan") + cascade="all, delete-orphan") def __unicode__(self): return u"<%s('%s:%s')>" % (self.__class__.__name__, self.repo_id, @@ -1266,7 +1268,7 @@ try: from pylons import tmpl_context as c uri_tmpl = c.clone_uri_tmpl - except Exception: + except AttributeError: # in any case if we call this outside of request context, # ie, not having tmpl_context set up pass @@ -1362,7 +1364,8 @@ def statuses(self, revisions): """ - Returns statuses for this repository + Returns statuses for this repository. + PRs without any votes do _not_ show up as unreviewed. :param revisions: list of revisions to get statuses for """ @@ -1373,16 +1376,8 @@ .filter(ChangesetStatus.repo == self)\ .filter(ChangesetStatus.version == 0)\ .filter(ChangesetStatus.revision.in_(revisions)) + grouped = {} - - stat = ChangesetStatus.DEFAULT - status_lbl = ChangesetStatus.get_status_lbl(stat) - for pr in PullRequest.query().filter(PullRequest.org_repo == self).all(): - for rev in pr.revisions: - pr_id = pr.pull_request_id - pr_repo = pr.other_repo.repo_name - grouped[rev] = [stat, status_lbl, pr_id, pr_repo] - for stat in statuses.all(): pr_id = pr_repo = None if stat.pull_request: @@ -1434,25 +1429,15 @@ def __get_instance(self): repo_full_path = self.repo_full_path - try: - alias = get_scm(repo_full_path)[0] - log.debug('Creating instance of %s repository from %s' - % (alias, repo_full_path)) - backend = get_backend(alias) - except VCSError: - log.error(traceback.format_exc()) - log.error('Perhaps this repository is in db and not in ' - 'filesystem run rescan repositories with ' - '"destroy old data " option from admin panel') - return + + alias = get_scm(repo_full_path)[0] + log.debug('Creating instance of %s repository from %s' + % (alias, repo_full_path)) + backend = get_backend(alias) if alias == 'hg': - repo = backend(safe_str(repo_full_path), create=False, baseui=self._ui) - # skip hidden web repository - if repo._get_hidden(): - return else: repo = backend(repo_full_path, create=False) @@ -2101,19 +2086,16 @@ inv_objs = Session().query(cls).filter(cls.cache_args == repo_name).all() log.debug('for repo %s got %s invalidation objects' % (safe_str(repo_name), inv_objs)) - try: - for inv_obj in inv_objs: - log.debug('marking %s key for invalidation based on repo_name=%s' - % (inv_obj, safe_str(repo_name))) - if delete: - Session().delete(inv_obj) - else: - inv_obj.cache_active = False - Session().add(inv_obj) - Session().commit() - except Exception: - log.error(traceback.format_exc()) - Session().rollback() + + for inv_obj in inv_objs: + log.debug('marking %s key for invalidation based on repo_name=%s' + % (inv_obj, safe_str(repo_name))) + if delete: + Session().delete(inv_obj) + else: + inv_obj.cache_active = False + Session().add(inv_obj) + Session().commit() @classmethod def test_and_set_valid(cls, repo_name, kind, valid_cache_keys=None): @@ -2129,19 +2111,15 @@ if valid_cache_keys and cache_key in valid_cache_keys: return True - try: - inv_obj = cls.query().filter(cls.cache_key == cache_key).scalar() - if not inv_obj: - inv_obj = CacheInvalidation(cache_key, repo_name) - was_valid = inv_obj.cache_active - inv_obj.cache_active = True - Session().add(inv_obj) - Session().commit() - return was_valid - except Exception: - log.error(traceback.format_exc()) - Session().rollback() - return False + inv_obj = cls.query().filter(cls.cache_key == cache_key).scalar() + if not inv_obj: + inv_obj = CacheInvalidation(cache_key, repo_name) + if inv_obj.cache_active: + return True + inv_obj.cache_active = True + Session().add(inv_obj) + Session().commit() + return False @classmethod def get_valid_cache_keys(cls): @@ -2156,6 +2134,7 @@ __tablename__ = 'changeset_comments' __table_args__ = ( Index('cc_revision_idx', 'revision'), + Index('cc_pull_request_id_idx', 'pull_request_id'), {'extend_existing': True, 'mysql_engine': 'InnoDB', 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, ) @@ -2173,7 +2152,10 @@ author = relationship('User', lazy='joined') repo = relationship('Repository') - status_change = relationship('ChangesetStatus', cascade="all, delete, delete-orphan") + # status_change is frequently used directly in templates - make it a lazy + # join to avoid fetching each related ChangesetStatus on demand. + # There will only be one ChangesetStatus referencing each comment so the join will not explode. + status_change = relationship('ChangesetStatus', cascade="all, delete-orphan", lazy='joined') pull_request = relationship('PullRequest') @classmethod @@ -2199,6 +2181,8 @@ __table_args__ = ( Index('cs_revision_idx', 'revision'), Index('cs_version_idx', 'version'), + Index('cs_pull_request_id_idx', 'pull_request_id'), + Index('cs_changeset_comment_id_idx', 'changeset_comment_id'), UniqueConstraint('repo_id', 'revision', 'version'), {'extend_existing': True, 'mysql_engine': 'InnoDB', 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} @@ -2248,6 +2232,8 @@ class PullRequest(Base, BaseModel): __tablename__ = 'pull_requests' __table_args__ = ( + Index('pr_org_repo_id_idx', 'org_repo_id'), + Index('pr_other_repo_id_idx', 'other_repo_id'), {'extend_existing': True, 'mysql_engine': 'InnoDB', 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, ) @@ -2275,7 +2261,7 @@ @revisions.setter def revisions(self, val): - self._revisions = ':'.join(val) + self._revisions = safe_unicode(':'.join(val)) @property def org_ref_parts(self): @@ -2287,12 +2273,12 @@ author = relationship('User', lazy='joined') reviewers = relationship('PullRequestReviewers', - cascade="all, delete, delete-orphan") + cascade="all, delete-orphan") org_repo = relationship('Repository', primaryjoin='PullRequest.org_repo_id==Repository.repo_id') other_repo = relationship('Repository', primaryjoin='PullRequest.other_repo_id==Repository.repo_id') statuses = relationship('ChangesetStatus') comments = relationship('ChangesetComment', - cascade="all, delete, delete-orphan") + cascade="all, delete-orphan") def is_closed(self): return self.status == self.STATUS_CLOSED @@ -2364,7 +2350,7 @@ created_by_user = relationship('User') notifications_to_users = relationship('UserNotification', lazy='joined', - cascade="all, delete, delete-orphan") + cascade="all, delete-orphan") @property def recipients(self): @@ -2387,8 +2373,10 @@ for u in recipients: assoc = UserNotification() assoc.notification = notification - u.notifications.append(assoc) + assoc.user_id = u.user_id + Session().add(assoc) Session().add(notification) + Session().flush() # assign notificaiton.notification_id return notification @property @@ -2410,8 +2398,7 @@ sent_on = Column('sent_on', DateTime(timezone=False), nullable=True, unique=None) user = relationship('User', lazy="joined") - notification = relationship('Notification', lazy="joined", - order_by=lambda: Notification.created_on.desc(),) + notification = relationship('Notification', lazy="joined") def mark_as_read(self): self.read = True diff -r fc8ab968fe10 -r 0c8efa0c45a1 kallithea/model/forms.py --- a/kallithea/model/forms.py Mon Jan 05 10:58:24 2015 +0100 +++ b/kallithea/model/forms.py Wed Jan 07 13:37:28 2015 +0100 @@ -514,11 +514,11 @@ filename = All(v.BasePath()(), v.UnicodeString(strip=True, required=False)) - description = v.UnicodeString(required=False, if_missing='') + description = v.UnicodeString(required=False, if_missing=u'') lifetime = v.OneOf(lifetime_options) mimetype = v.UnicodeString(required=False, if_missing=None) content = v.UnicodeString(required=True, not_empty=True) - public = v.UnicodeString(required=False, if_missing='') - private = v.UnicodeString(required=False, if_missing='') + public = v.UnicodeString(required=False, if_missing=u'') + private = v.UnicodeString(required=False, if_missing=u'') return _GistForm diff -r fc8ab968fe10 -r 0c8efa0c45a1 kallithea/model/meta.py --- a/kallithea/model/meta.py Mon Jan 05 10:58:24 2015 +0100 +++ b/kallithea/model/meta.py Wed Jan 07 13:37:28 2015 +0100 @@ -25,17 +25,17 @@ cache_manager = cache.CacheManager() __all__ = ['Base', 'Session'] + # -# SQLAlchemy session manager. Updated by model.init_model() +# SQLAlchemy session manager. # -Session = scoped_session( - sessionmaker( - query_cls=caching_query.query_callable(cache_manager), - expire_on_commit=True, - ) - ) +session_factory = sessionmaker( + query_cls=caching_query.query_callable(cache_manager), + expire_on_commit=True) +Session = scoped_session(session_factory) -# The declarative Base +# The base class for declarative schemas in db.py +# Engine is injected when model.__init__.init_model() sets meta.Base.metadata.bind Base = declarative_base() #to use cache use this in query diff -r fc8ab968fe10 -r 0c8efa0c45a1 kallithea/model/notification.py --- a/kallithea/model/notification.py Mon Jan 05 10:58:24 2015 +0100 +++ b/kallithea/model/notification.py Wed Jan 07 13:37:28 2015 +0100 @@ -31,6 +31,7 @@ from pylons import tmpl_context as c from pylons.i18n.translation import _ +from sqlalchemy.orm import joinedload, subqueryload import kallithea from kallithea.lib import helpers as h @@ -167,7 +168,10 @@ q = UserNotification.query()\ .filter(UserNotification.user == user)\ .join((Notification, UserNotification.notification_id == - Notification.notification_id)) + Notification.notification_id))\ + .options(joinedload('notification'))\ + .options(subqueryload('notification.created_by_user'))\ + .order_by(Notification.created_on.desc()) if filter_: q = q.filter(Notification.type_.in_(filter_)) diff -r fc8ab968fe10 -r 0c8efa0c45a1 kallithea/model/repo.py --- a/kallithea/model/repo.py Mon Jan 05 10:58:24 2015 +0100 +++ b/kallithea/model/repo.py Wed Jan 07 13:37:28 2015 +0100 @@ -32,8 +32,9 @@ import logging import traceback from datetime import datetime +from sqlalchemy.orm import subqueryload + from kallithea.lib.utils import make_ui - from kallithea.lib.vcs.backends import get_backend from kallithea.lib.compat import json from kallithea.lib.utils2 import LazyProperty, safe_str, safe_unicode, \ @@ -44,7 +45,7 @@ from kallithea.model import BaseModel from kallithea.model.db import Repository, UserRepoToPerm, UserGroupRepoToPerm, \ UserRepoGroupToPerm, UserGroupRepoGroupToPerm, User, Permission, \ - Statistics, UserGroup, Ui, RepoGroup, \ + Statistics, UserGroup, UserGroupMember, Ui, RepoGroup, \ Setting, RepositoryField from kallithea.lib import helpers as h @@ -146,7 +147,9 @@ def get_user_groups_js(self): user_groups = self.sa.query(UserGroup) \ - .filter(UserGroup.users_group_active == True).all() + .filter(UserGroup.users_group_active == True) \ + .options(subqueryload(UserGroup.members)) \ + .all() user_groups = UserGroupList(user_groups, perm_set=['usergroup.read', 'usergroup.write', 'usergroup.admin']) @@ -238,7 +241,7 @@ "last_changeset": last_rev(repo.repo_name, cs_cache), "last_rev_raw": cs_cache.get('revision'), "desc": desc(repo.description), - "owner": h.person(repo.user.username), + "owner": h.person(repo.user), "state": state(repo.repo_state), "rss": rss_lnk(repo.repo_name), "atom": atom_lnk(repo.repo_name), @@ -248,7 +251,7 @@ row.update({ "action": repo_actions(repo.repo_name), "owner": owner_actions(repo.user.user_id, - h.person(repo.user.username)) + h.person(repo.user)) }) repos_data.append(row) diff -r fc8ab968fe10 -r 0c8efa0c45a1 kallithea/model/user.py --- a/kallithea/model/user.py Mon Jan 05 10:58:24 2015 +0100 +++ b/kallithea/model/user.py Wed Jan 07 13:37:28 2015 +0100 @@ -91,23 +91,20 @@ # raises UserCreationError if it's not allowed check_allowed_create_user(user_data, cur_user) from kallithea.lib.auth import get_crypt_password - try: - new_user = User() - for k, v in form_data.items(): - if k == 'password': - v = get_crypt_password(v) - if k == 'firstname': - k = 'name' - setattr(new_user, k, v) - new_user.api_key = generate_api_key(form_data['username']) - self.sa.add(new_user) + new_user = User() + for k, v in form_data.items(): + if k == 'password': + v = get_crypt_password(v) + if k == 'firstname': + k = 'name' + setattr(new_user, k, v) - log_create_user(new_user.get_dict(), cur_user) - return new_user - except Exception: - log.error(traceback.format_exc()) - raise + new_user.api_key = generate_api_key(form_data['username']) + self.sa.add(new_user) + + log_create_user(new_user.get_dict(), cur_user) + return new_user def create_or_update(self, username, password, email, firstname='', lastname='', active=True, admin=False, @@ -185,104 +182,104 @@ from kallithea.model.notification import NotificationModel import kallithea.lib.helpers as h - try: - form_data['admin'] = False - form_data['extern_name'] = EXTERN_TYPE_INTERNAL - form_data['extern_type'] = EXTERN_TYPE_INTERNAL - new_user = self.create(form_data) + form_data['admin'] = False + form_data['extern_name'] = EXTERN_TYPE_INTERNAL + form_data['extern_type'] = EXTERN_TYPE_INTERNAL + new_user = self.create(form_data) - self.sa.add(new_user) - self.sa.flush() + self.sa.add(new_user) + self.sa.flush() - # notification to admins - subject = _('New user registration') - body = ('New user registration\n' - '---------------------\n' - '- Username: %s\n' - '- Full Name: %s\n' - '- Email: %s\n') - body = body % (new_user.username, new_user.full_name, new_user.email) - edit_url = h.canonical_url('edit_user', id=new_user.user_id) - email_kwargs = {'registered_user_url': edit_url, 'new_username': new_user.username} - NotificationModel().create(created_by=new_user, subject=subject, - body=body, recipients=None, - type_=Notification.TYPE_REGISTRATION, - email_kwargs=email_kwargs) - except Exception: - log.error(traceback.format_exc()) - raise + # notification to admins + subject = _('New user registration') + body = ('New user registration\n' + '---------------------\n' + '- Username: %s\n' + '- Full Name: %s\n' + '- Email: %s\n') + body = body % (new_user.username, new_user.full_name, new_user.email) + edit_url = h.canonical_url('edit_user', id=new_user.user_id) + email_kwargs = {'registered_user_url': edit_url, 'new_username': new_user.username} + NotificationModel().create(created_by=new_user, subject=subject, + body=body, recipients=None, + type_=Notification.TYPE_REGISTRATION, + email_kwargs=email_kwargs) def update(self, user_id, form_data, skip_attrs=[]): from kallithea.lib.auth import get_crypt_password - try: - user = self.get(user_id, cache=False) - if user.username == User.DEFAULT_USER: - raise DefaultUserException( - _("You can't Edit this user since it's " - "crucial for entire application")) + + user = self.get(user_id, cache=False) + if user.username == User.DEFAULT_USER: + raise DefaultUserException( + _("You can't Edit this user since it's " + "crucial for entire application")) - for k, v in form_data.items(): - if k in skip_attrs: - continue - if k == 'new_password' and v: - user.password = get_crypt_password(v) - else: - # old legacy thing orm models store firstname as name, - # need proper refactor to username - if k == 'firstname': - k = 'name' - setattr(user, k, v) - self.sa.add(user) - except Exception: - log.error(traceback.format_exc()) - raise + for k, v in form_data.items(): + if k in skip_attrs: + continue + if k == 'new_password' and v: + user.password = get_crypt_password(v) + else: + # old legacy thing orm models store firstname as name, + # need proper refactor to username + if k == 'firstname': + k = 'name' + setattr(user, k, v) + self.sa.add(user) def update_user(self, user, **kwargs): from kallithea.lib.auth import get_crypt_password - try: - user = self._get_user(user) - if user.username == User.DEFAULT_USER: - raise DefaultUserException( - _("You can't Edit this user since it's" - " crucial for entire application") - ) + + user = self._get_user(user) + if user.username == User.DEFAULT_USER: + raise DefaultUserException( + _("You can't Edit this user since it's" + " crucial for entire application") + ) - for k, v in kwargs.items(): - if k == 'password' and v: - v = get_crypt_password(v) + for k, v in kwargs.items(): + if k == 'password' and v: + v = get_crypt_password(v) - setattr(user, k, v) - self.sa.add(user) - return user - except Exception: - log.error(traceback.format_exc()) - raise + setattr(user, k, v) + self.sa.add(user) + return user def delete(self, user, cur_user=None): if not cur_user: cur_user = getattr(get_current_authuser(), 'username', None) user = self._get_user(user) - try: - if user.username == User.DEFAULT_USER: - raise DefaultUserException( - _(u"You can't remove this user since it's" - " crucial for entire application") - ) - if user.repositories: - repos = [x.repo_name for x in user.repositories] - raise UserOwnsReposException( - _(u'user "%s" still owns %s repositories and cannot be ' - 'removed. Switch owners or remove those repositories. %s') - % (user.username, len(repos), ', '.join(repos)) - ) - self.sa.delete(user) + if user.username == User.DEFAULT_USER: + raise DefaultUserException( + _(u"You can't remove this user since it's" + " crucial for entire application") + ) + if user.repositories: + repos = [x.repo_name for x in user.repositories] + raise UserOwnsReposException( + _(u'User "%s" still owns %s repositories and cannot be ' + 'removed. Switch owners or remove those repositories: %s') + % (user.username, len(repos), ', '.join(repos)) + ) + if user.repo_groups: + repogroups = [x.group_name for x in user.repo_groups] + raise UserOwnsReposException( + _(u'User "%s" still owns %s repository groups and cannot be ' + 'removed. Switch owners or remove those repository groups: %s') + % (user.username, len(repogroups), ', '.join(repogroups)) + ) + if user.user_groups: + usergroups = [x.users_group_name for x in user.user_groups] + raise UserOwnsReposException( + _(u'User "%s" still owns %s user groups and cannot be ' + 'removed. Switch owners or remove those user groups: %s') + % (user.username, len(usergroups), ', '.join(usergroups)) + ) + self.sa.delete(user) - from kallithea.lib.hooks import log_delete_user - log_delete_user(user.get_dict(), cur_user) - except Exception: - log.error(traceback.format_exc()) - raise + from kallithea.lib.hooks import log_delete_user + log_delete_user(user.get_dict(), cur_user) def reset_password_link(self, data): from kallithea.lib.celerylib import tasks, run_task @@ -290,29 +287,25 @@ import kallithea.lib.helpers as h user_email = data['email'] - try: - user = User.get_by_email(user_email) - if user: - log.debug('password reset user found %s' % user) - link = h.canonical_url('reset_password_confirmation', key=user.api_key) - reg_type = EmailNotificationModel.TYPE_PASSWORD_RESET - body = EmailNotificationModel().get_email_tmpl(reg_type, - 'txt', - user=user.short_contact, - reset_url=link) - html_body = EmailNotificationModel().get_email_tmpl(reg_type, - 'html', - user=user.short_contact, - reset_url=link) - log.debug('sending email') - run_task(tasks.send_email, [user_email], - _("Password reset link"), body, html_body) - log.info('send new password mail to %s' % user_email) - else: - log.debug("password reset email %s not found" % user_email) - except Exception: - log.error(traceback.format_exc()) - return False + user = User.get_by_email(user_email) + if user: + log.debug('password reset user found %s' % user) + link = h.canonical_url('reset_password_confirmation', key=user.api_key) + reg_type = EmailNotificationModel.TYPE_PASSWORD_RESET + body = EmailNotificationModel().get_email_tmpl(reg_type, + 'txt', + user=user.short_contact, + reset_url=link) + html_body = EmailNotificationModel().get_email_tmpl(reg_type, + 'html', + user=user.short_contact, + reset_url=link) + log.debug('sending email') + run_task(tasks.send_email, [user_email], + _("Password reset link"), body, html_body) + log.info('send new password mail to %s' % user_email) + else: + log.debug("password reset email %s not found" % user_email) return True @@ -320,32 +313,21 @@ from kallithea.lib.celerylib import tasks, run_task from kallithea.lib import auth user_email = data['email'] - pre_db = True - try: - 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) - Session().add(user) - Session().commit() - log.info('change password for %s' % user_email) - if new_passwd is None: - raise Exception('unable to generate new password') + 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) + Session().add(user) + Session().commit() + log.info('change password for %s' % user_email) + if new_passwd is None: + raise Exception('unable to generate new password') - pre_db = False - run_task(tasks.send_email, [user_email], - _('Your new password'), - _('Your new Kallithea password:%s') % (new_passwd,)) - log.info('send new password mail to %s' % user_email) - - except Exception: - log.error('Failed to update user password') - log.error(traceback.format_exc()) - if pre_db: - # we rollback only if local db stuff fails. If it goes into - # run_task, we're pass rollback state this wouldn't work then - Session().rollback() + run_task(tasks.send_email, [user_email], + _('Your new password'), + _('Your new Kallithea password:%s') % (new_passwd,)) + log.info('send new password mail to %s' % user_email) return True @@ -364,29 +346,21 @@ if user_id is None and api_key is None and username is None: raise Exception('You need to pass user_id, api_key or username') - try: - dbuser = None - if user_id: - dbuser = self.get(user_id) - elif api_key: - dbuser = self.get_by_api_key(api_key) - elif username: - dbuser = self.get_by_username(username) + dbuser = None + if user_id: + dbuser = self.get(user_id) + elif api_key: + dbuser = self.get_by_api_key(api_key) + elif username: + dbuser = self.get_by_username(username) - if dbuser is not None and dbuser.active: - log.debug('filling %s data' % dbuser) - for k, v in dbuser.get_dict().iteritems(): - if k not in ['api_keys', 'permissions']: - setattr(auth_user, k, v) - else: - return False - - except Exception: - log.error(traceback.format_exc()) - auth_user.is_authenticated = False - return False - - return True + if dbuser is not None and dbuser.active: + log.debug('filling %s data' % dbuser) + for k, v in dbuser.get_dict().iteritems(): + if k not in ['api_keys', 'permissions']: + setattr(auth_user, k, v) + return True + return False def has_perm(self, user, perm): perm = self._get_perm(perm) diff -r fc8ab968fe10 -r 0c8efa0c45a1 kallithea/model/validators.py --- a/kallithea/model/validators.py Mon Jan 05 10:58:24 2015 +0100 +++ b/kallithea/model/validators.py Wed Jan 07 13:37:28 2015 +0100 @@ -22,6 +22,7 @@ from collections import defaultdict from pylons.i18n.translation import _ from webhelpers.pylonslib.secure_form import authentication_token +import sqlalchemy from formencode.validators import ( UnicodeString, OneOf, Int, Number, Regex, Email, Bool, StringBoolean, Set, @@ -87,7 +88,7 @@ value = aslist(value, ',') seen = set() return [c for c in value if not (c in seen or seen.add(c))] - + def empty_value(self, value): return [] @@ -142,7 +143,7 @@ try: User.query().filter(User.active == True)\ .filter(User.username == value).one() - except Exception: + except sqlalchemy.exc.InvalidRequestError: # NoResultFound/MultipleResultsFound msg = M(self, 'invalid_username', state, username=value) raise formencode.Invalid(msg, value, state, error_dict=dict(username=msg) diff -r fc8ab968fe10 -r 0c8efa0c45a1 kallithea/public/css/style.css --- a/kallithea/public/css/style.css Mon Jan 05 10:58:24 2015 +0100 +++ b/kallithea/public/css/style.css Wed Jan 07 13:37:28 2015 +0100 @@ -4856,6 +4856,12 @@ display: inline-block; width: 0; } +table.code-highlighttable div.code-highlight pre u.cr:before, +table.code-difftable td.code pre u.cr:before { + content: "\21a4"; + display: inline-block; + color: rgba(0,0,0,0.5); +} table.code-highlighttable div.code-highlight pre u, table.code-difftable td.code pre u { color: rgba(0,0,0,0.15); @@ -4864,7 +4870,7 @@ table.code-difftable td.code pre i { border-style: solid; border-left-width: 1px; - color: rgba(0,0,0,0.15); + color: rgba(0,0,0,0.5); } /** LINE NUMBERS **/ diff -r fc8ab968fe10 -r 0c8efa0c45a1 kallithea/public/js/base.js --- a/kallithea/public/js/base.js Mon Jan 05 10:58:24 2015 +0100 +++ b/kallithea/public/js/base.js Wed Jan 07 13:37:28 2015 +0100 @@ -669,16 +669,16 @@ if(lineno === undefined){ alert('Error submitting, line ' + lineno + ' not found.'); - return + return; } if(f_path === undefined){ alert('Error submitting, file path ' + f_path + ' not found.'); - return + return; } var text = $('#text_'+lineno).val(); if(text == ""){ - return + return; } $overlay.show(); @@ -1471,7 +1471,7 @@ ' \n'+ '
\n'+ ' \n'+ - '
\n'+ + ' (add not saved)\n'+ ' \n'+ ' \n' ).format(gravatar_link, displayname, id); @@ -1490,7 +1490,7 @@ var $li = $('#reviewer_{0}'.format(reviewer_id)); $li.find('div div').css("text-decoration", "line-through"); $li.find('input').remove(); - $li.find('.reviewer_member_remove').remove(); + $li.find('.reviewer_member_remove').replaceWith(' (remove not saved)'); } /* handle "Save Changes" of addReviewMember and removeReviewMember on PR */ @@ -1778,12 +1778,6 @@ $('#remove_element').click(function(e){ $availableselect.append($selectedselect.children('option:selected')); }); - $('#add_all_elements').click(function(e){ - $selectedselect.append($availableselect.children('option')); - }); - $('#remove_all_elements').click(function(e){ - $availableselect.append($selectedselect.children('option')); - }); $('#'+form_id).submit(function(){ $selectedselect.children('option').each(function(i, e){ diff -r fc8ab968fe10 -r 0c8efa0c45a1 kallithea/public/js/pyroutes_map.js --- a/kallithea/public/js/pyroutes_map.js Mon Jan 05 10:58:24 2015 +0100 +++ b/kallithea/public/js/pyroutes_map.js Wed Jan 07 13:37:28 2015 +0100 @@ -1,10 +1,10 @@ //Format is key == name // "mark_error_fixed": [ # key -// "/mark_error_fixed/%(error_id)s", #url template -// [ +// "/mark_error_fixed/%(error_id)s", #url template +// [ // "error_id" # list of args // ] -// ], +// ], // var PROUTES_MAP = { diff -r fc8ab968fe10 -r 0c8efa0c45a1 kallithea/templates/admin/repo_groups/repo_group_edit_advanced.html --- a/kallithea/templates/admin/repo_groups/repo_group_edit_advanced.html Mon Jan 05 10:58:24 2015 +0100 +++ b/kallithea/templates/admin/repo_groups/repo_group_edit_advanced.html Wed Jan 07 13:37:28 2015 +0100 @@ -7,7 +7,7 @@ (_('Total repositories'), c.repo_group.repositories_recursive_count, ''), (_('Children groups'), c.repo_group.children.count(), ''), (_('Created on'), h.fmt_date(c.repo_group.created_on), ''), - (_('Owner'), h.person(c.repo_group.user.username), '') + (_('Owner'), h.person(c.repo_group.user), '') ] %> %for dt, dd, tt in elems: diff -r fc8ab968fe10 -r 0c8efa0c45a1 kallithea/templates/admin/user_groups/user_group_edit_advanced.html --- a/kallithea/templates/admin/user_groups/user_group_edit_advanced.html Mon Jan 05 10:58:24 2015 +0100 +++ b/kallithea/templates/admin/user_groups/user_group_edit_advanced.html Wed Jan 07 13:37:28 2015 +0100 @@ -5,7 +5,7 @@ elems = [ (_('Members'), len(c.group_members_obj), ''), (_('Created on'), h.fmt_date(c.user_group.created_on), ''), - (_('Owner'), h.person(c.user_group.user.username), '') + (_('Owner'), h.person(c.user_group.user), '') ] %> %for dt, dd, tt in elems: diff -r fc8ab968fe10 -r 0c8efa0c45a1 kallithea/templates/admin/user_groups/user_group_edit_settings.html --- a/kallithea/templates/admin/user_groups/user_group_edit_settings.html Mon Jan 05 10:58:24 2015 +0100 +++ b/kallithea/templates/admin/user_groups/user_group_edit_settings.html Wed Jan 07 13:37:28 2015 +0100 @@ -39,10 +39,6 @@
${_('Chosen group members')}
${h.select('users_group_members',[x[0] for x in c.group_members],c.group_members,multiple=True,size=8,style="min-width:210px")} -
- ${_('Remove all elements')} - -
@@ -52,9 +48,6 @@
${_('Available members')}
${h.select('available_members',[],c.available_members,multiple=True,size=8,style="min-width:210px")} -
- ${_('Add all elements')} -
diff -r fc8ab968fe10 -r 0c8efa0c45a1 kallithea/templates/base/base.html --- a/kallithea/templates/base/base.html Mon Jan 05 10:58:24 2015 +0100 +++ b/kallithea/templates/base/base.html Wed Jan 07 13:37:28 2015 +0100 @@ -7,7 +7,7 @@ - diff -r fc8ab968fe10 -r 0c8efa0c45a1 kallithea/templates/login.html --- a/kallithea/templates/login.html Mon Jan 05 10:58:24 2015 +0100 +++ b/kallithea/templates/login.html Wed Jan 07 13:37:28 2015 +0100 @@ -14,7 +14,7 @@