Mercurial > kallithea
changeset 1861:3f5be4dbbd57 beta
merge upstream
author | Aras Pranckevicius <aras@unity3d.com> |
---|---|
date | Sun, 08 Jan 2012 12:18:16 +0200 |
parents | 1f06cd49cb3e (current diff) 349a0ca30a75 (diff) |
children | 2a159aa3ed2d |
files | docs/usage/api_key_access.rst rhodecode/public/css/style.css rhodecode/templates/changelog/changelog.html rhodecode/templates/changeset/changeset.html rhodecode/templates/changeset/diff_block.html |
diffstat | 25 files changed, 422 insertions(+), 206 deletions(-) [+] |
line wrap: on
line diff
--- a/README.rst Sat Jan 07 21:44:18 2012 +0200 +++ b/README.rst Sun Jan 08 12:18:16 2012 +0200 @@ -1,6 +1,6 @@ -================================================= -Welcome to RhodeCode (RhodiumCode) documentation! -================================================= +======================== +RhodeCode documentation! +======================== ``RhodeCode`` is a fast and powerful management tool for Mercurial_ and GIT_ with a built in push/pull server and full text search. @@ -102,7 +102,6 @@ - pull requests and web based merges - per line file history - SSH based authentication with server side key management -- Redmine and other bugtrackers integration - Commit based built in wiki system - More statistics and graph (global annotation + some more statistics) - Other advancements as development continues (or you can of course make
--- a/development.ini Sat Jan 07 21:44:18 2012 +0200 +++ b/development.ini Sun Jan 08 12:18:16 2012 +0200 @@ -58,13 +58,34 @@ proxypass_auth_enabled = false ## overwrite schema of clone url -# available vars: -# scheme - http/https -# user - current user -# pass - password -# netloc - network location -# path - usually repo_name -# clone_uri = {scheme}://{user}{pass}{netloc}{path} +## available vars: +## scheme - http/https +## user - current user +## pass - password +## netloc - network location +## path - usually repo_name + +#clone_uri = {scheme}://{user}{pass}{netloc}{path} + +## issue tracking mapping for commits messages +## uncomment url_pat, issue_server, issue_prefix to enable + + +## pattern to get the issues from commit messages +## default one used here is #1234 + +#url_pat = (?:^#|\s#)(\w+) + +## server url to the issue, each {id} will be replaced with id +## fetched from the regex + +#issue_server = https://myissueserver.com/issue/{id} + +## prefix to add to link to indicate it's an url +## #314 will be replaced by <issue_prefix><id> + +#issue_prefix = # + #################################### ### CELERY CONFIG ####
--- a/docs/api/api.rst Sat Jan 07 21:44:18 2012 +0200 +++ b/docs/api/api.rst Sun Jan 08 12:18:16 2012 +0200 @@ -10,6 +10,8 @@ with JSON protocol both ways. An url to send API request in RhodeCode is <your_server>/_admin/api +API ACCESS FOR WEB VIEWS +++++++++++++++++++++++++ API access can also be turned on for each view decorated with `@LoginRequired` decorator. To enable API access simple change standard login decorator into @@ -18,6 +20,9 @@ enabled on RSS/ATOM feed views. +API ACCESS +++++++++++ + All clients are required to send JSON-RPC spec JSON data:: { @@ -69,15 +74,47 @@ api_key : "<api_key>" method : "pull" args : { - "repo" : "<repo_name>" + "repo_name" : "<reponame>" } OUTPUT:: - result : "Pulled from <repo_name>" + result : "Pulled from <reponame>" error : null +get_user +-------- + +Get's an user by username, Returns empty result if user is not found. +This command can be executed only using api_key belonging to user with admin +rights. + +INPUT:: + + api_key : "<api_key>" + method : "get_user" + args : { + "username" : "<username>" + } + +OUTPUT:: + + result: None if user does not exist or + { + "id" : "<id>", + "username" : "<username>", + "firstname": "<firstname>", + "lastname" : "<lastname>", + "email" : "<email>", + "active" : "<bool>", + "admin" : "<bool>", + "ldap" : "<ldap_dn>" + } + + error: null + + get_users --------- @@ -131,46 +168,11 @@ OUTPUT:: result: { + "id" : "<new_user_id>", "msg" : "created new user <username>" } error: null -get_users_groups ----------------- - -Lists all existing users groups. This command can be executed only using api_key -belonging to user with admin rights. - -INPUT:: - - api_key : "<api_key>" - method : "get_users_groups" - args : { } - -OUTPUT:: - - result : [ - { - "id" : "<id>", - "name" : "<name>", - "active": "<bool>", - "members" : [ - { - "id" : "<userid>", - "username" : "<username>", - "firstname": "<firstname>", - "lastname" : "<lastname>", - "email" : "<email>", - "active" : "<bool>", - "admin" : "<bool>", - "ldap" : "<ldap_dn>" - }, - … - ] - } - ] - error : null - get_users_group --------------- @@ -189,24 +191,61 @@ result : None if group not exist { - "id" : "<id>", - "name" : "<name>", - "active": "<bool>", + "id" : "<id>", + "group_name" : "<groupname>", + "active": "<bool>", "members" : [ - { "id" : "<userid>", - "username" : "<username>", - "firstname": "<firstname>", - "lastname" : "<lastname>", - "email" : "<email>", - "active" : "<bool>", - "admin" : "<bool>", - "ldap" : "<ldap_dn>" - }, - … - ] + { "id" : "<userid>", + "username" : "<username>", + "firstname": "<firstname>", + "lastname" : "<lastname>", + "email" : "<email>", + "active" : "<bool>", + "admin" : "<bool>", + "ldap" : "<ldap_dn>" + }, + … + ] } error : null +get_users_groups +---------------- + +Lists all existing users groups. This command can be executed only using +api_key belonging to user with admin rights. + +INPUT:: + + api_key : "<api_key>" + method : "get_users_groups" + args : { } + +OUTPUT:: + + result : [ + { + "id" : "<id>", + "group_name" : "<groupname>", + "active": "<bool>", + "members" : [ + { + "id" : "<userid>", + "username" : "<username>", + "firstname": "<firstname>", + "lastname" : "<lastname>", + "email" : "<email>", + "active" : "<bool>", + "admin" : "<bool>", + "ldap" : "<ldap_dn>" + }, + … + ] + } + ] + error : null + + create_users_group ------------------ @@ -218,7 +257,7 @@ api_key : "<api_key>" method : "create_users_group" args: { - "name": "<name>", + "group_name": "<groupname>", "active":"<bool> = True" } @@ -226,7 +265,7 @@ result: { "id": "<newusersgroupid>", - "msg": "created new users group <name>" + "msg": "created new users group <groupname>" } error: null @@ -253,6 +292,51 @@ } error: null +get_repo +-------- + +Gets an existing repository. This command can be executed only using api_key +belonging to user with admin rights + +INPUT:: + + api_key : "<api_key>" + method : "get_repo" + args: { + "repo_name" : "<reponame>" + } + +OUTPUT:: + + result: None if repository does not exist or + { + "id" : "<id>", + "repo_name" : "<reponame>" + "type" : "<type>", + "description" : "<description>", + "members" : [ + { "id" : "<userid>", + "username" : "<username>", + "firstname": "<firstname>", + "lastname" : "<lastname>", + "email" : "<email>", + "active" : "<bool>", + "admin" : "<bool>", + "ldap" : "<ldap_dn>", + "permission" : "repository.(read|write|admin)" + }, + … + { + "id" : "<usersgroupid>", + "name" : "<usersgroupname>", + "active": "<bool>", + "permission" : "repository.(read|write|admin)" + }, + … + ] + } + error: null + get_repos --------- @@ -270,7 +354,7 @@ result: [ { "id" : "<id>", - "name" : "<name>" + "repo_name" : "<reponame>" "type" : "<type>", "description" : "<description>" }, @@ -278,57 +362,13 @@ ] error: null -get_repo --------- - -Gets an existing repository. This command can be executed only using api_key -belonging to user with admin rights - -INPUT:: - - api_key : "<api_key>" - method : "get_repo" - args: { - "name" : "<name>" - } - -OUTPUT:: - - result: None if repository not exist - { - "id" : "<id>", - "name" : "<name>" - "type" : "<type>", - "description" : "<description>", - "members" : [ - { "id" : "<userid>", - "username" : "<username>", - "firstname": "<firstname>", - "lastname" : "<lastname>", - "email" : "<email>", - "active" : "<bool>", - "admin" : "<bool>", - "ldap" : "<ldap_dn>", - "permission" : "repository.(read|write|admin)" - }, - … - { - "id" : "<usersgroupid>", - "name" : "<usersgroupname>", - "active": "<bool>", - "permission" : "repository.(read|write|admin)" - }, - … - ] - } - error: null get_repo_nodes -------------- returns a list of nodes and it's children in a flat list for a given path -at given revision. It's possible to specify ret_type to show only files or -dirs. This command can be executed only using api_key belonging to user +at given revision. It's possible to specify ret_type to show only `files` or +`dirs`. This command can be executed only using api_key belonging to user with admin rights INPUT:: @@ -336,7 +376,7 @@ api_key : "<api_key>" method : "get_repo_nodes" args: { - "repo_name" : "<name>", + "repo_name" : "<reponame>", "revision" : "<revision>", "root_path" : "<root_path>", "ret_type" : "<ret_type>" = 'all' @@ -369,7 +409,7 @@ api_key : "<api_key>" method : "create_repo" args: { - "name" : "<name>", + "repo_name" : "<reponame>", "owner_name" : "<ownername>", "description" : "<description> = ''", "repo_type" : "<type> = 'hg'", @@ -378,7 +418,10 @@ OUTPUT:: - result: None + result: { + "id": "<newrepoid>", + "msg": "Created new repository <reponame>", + } error: null add_user_to_repo @@ -394,13 +437,15 @@ method : "add_user_to_repo" args: { "repo_name" : "<reponame>", - "username" : "<username>", + "username" : "<username>", "perm" : "(None|repository.(read|write|admin))", } OUTPUT:: - result: None + result: { + "msg" : "Added perm: <perm> for <username> in repo: <reponame>" + } error: null add_users_group_to_repo @@ -416,6 +461,12 @@ method : "add_users_group_to_repo" args: { "repo_name" : "<reponame>", - "group_name" : "<groupname>", + "group_name" : "<groupname>", "perm" : "(None|repository.(read|write|admin))", - } \ No newline at end of file + } +OUTPUT:: + + result: { + "msg" : Added perm: <perm> for <groupname> in repo: <reponame>" + } +
--- a/docs/api/index.rst Sat Jan 07 21:44:18 2012 +0200 +++ b/docs/api/index.rst Sun Jan 08 12:18:16 2012 +0200 @@ -1,4 +1,4 @@ -.. _api: +.. _indexapi: API Reference =============
--- a/docs/api/models.rst Sat Jan 07 21:44:18 2012 +0200 +++ b/docs/api/models.rst Sun Jan 08 12:18:16 2012 +0200 @@ -6,14 +6,29 @@ .. automodule:: rhodecode.model :members: +.. automodule:: rhodecode.model.comment + :members: + +.. automodule:: rhodecode.model.notification + :members: + .. automodule:: rhodecode.model.permission :members: - + +.. automodule:: rhodecode.model.repo_permission + :members: + .. automodule:: rhodecode.model.repo :members: +.. automodule:: rhodecode.model.repos_group + :members: + .. automodule:: rhodecode.model.scm :members: - + .. automodule:: rhodecode.model.user :members: + +.. automodule:: rhodecode.model.users_group + :members: \ No newline at end of file
--- a/docs/changelog.rst Sat Jan 07 21:44:18 2012 +0200 +++ b/docs/changelog.rst Sun Jan 08 12:18:16 2012 +0200 @@ -33,7 +33,9 @@ - implements #330 api method for listing nodes ar particular revision - fixed #331 RhodeCode mangles repository names if the a repository group contains the "full path" to the repositories - +- #73 added linking issues in commit messages to choosen issue tracker url + based on user defined regular expression + fixes -----
--- a/docs/index.rst Sat Jan 07 21:44:18 2012 +0200 +++ b/docs/index.rst Sun Jan 08 12:18:16 2012 +0200 @@ -2,8 +2,8 @@ .. include:: ./../README.rst -Documentation -------------- +Users Guide +----------- **Installation:** @@ -23,7 +23,6 @@ usage/enable_git usage/statistics usage/backup - usage/api_key_access **Develop** @@ -36,7 +35,7 @@ **API** .. toctree:: - :maxdepth: 2 + :maxdepth: 1 api/index
--- a/docs/setup.rst Sat Jan 07 21:44:18 2012 +0200 +++ b/docs/setup.rst Sun Jan 08 12:18:16 2012 +0200 @@ -425,7 +425,25 @@ forge the authentication header and could effectively become authenticated using any account of their liking. +Integration with Issue trackers +------------------------------- +RhodeCode provides a simple integration with issue trackers. It's possible +to define a regular expression that will fetch issue id stored in commit +messages and replace that with an url to this issue. To enable this simply +uncomment following variables in the ini file:: + + url_pat = (?:^#|\s#)(\w+) + issue_server = https://myissueserver.com/issue/{id} + issue_prefix = # + +`url_pat` is the regular expression that will match issues, default given regex +will match issues in format of #<number> eg. #300. +Matched issues will be replace with the `issue_server` url replacing {id} with +id fetched from regex. Since the # is striped `issue_prefix` is added as a +prefix to url. `issue_prefix` can be something different than # if you pass +ISSUE- as issue prefix this will generate an url in format +`<a href="https://myissueserver.com/issue/300">ISSUE-300</a>` Hook management ---------------
--- a/docs/usage/api_key_access.rst Sat Jan 07 21:44:18 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,11 +0,0 @@ -.. _api_key_access: - -Access to RhodeCode via API KEY -=============================== - -Starting from version 1.2 rss/atom feeds and journal feeds -can be accessed via **api_key**. This unique key is automatically generated for -each user in RhodeCode application. Using this key it is possible to access -feeds without having to log in. When user changes his password a new API KEY -is generated for him automatically. You can check your API KEY in account -settings page. \ No newline at end of file
--- a/production.ini Sat Jan 07 21:44:18 2012 +0200 +++ b/production.ini Sun Jan 08 12:18:16 2012 +0200 @@ -58,13 +58,34 @@ proxypass_auth_enabled = false ## overwrite schema of clone url -# available vars: -# scheme - http/https -# user - current user -# pass - password -# netloc - network location -# path - usually repo_name -# clone_uri = {scheme}://{user}{pass}{netloc}{path} +## available vars: +## scheme - http/https +## user - current user +## pass - password +## netloc - network location +## path - usually repo_name + +#clone_uri = {scheme}://{user}{pass}{netloc}{path} + +## issue tracking mapping for commits messages +## uncomment url_pat, issue_server, issue_prefix to enable + + +## pattern to get the issues from commit messages +## default one used here is #1234 + +#url_pat = (?:^#|\s#)(\w+) + +## server url to the issue, each {id} will be replaced with id +## fetched from the regex + +#issue_server = https://myissueserver.com/issue/{id} + +## prefix to add to link to indicate it's an url +## #314 will be replaced by <issue_prefix><id> + +#issue_prefix = # + #################################### ### CELERY CONFIG ####
--- a/rhodecode/config/deployment.ini_tmpl Sat Jan 07 21:44:18 2012 +0200 +++ b/rhodecode/config/deployment.ini_tmpl Sun Jan 08 12:18:16 2012 +0200 @@ -58,14 +58,35 @@ proxypass_auth_enabled = false ## overwrite schema of clone url -# available vars: -# scheme - http/https -# user - current user -# pass - password -# netloc - network location -# path - usually repo_name +## available vars: +## scheme - http/https +## user - current user +## pass - password +## netloc - network location +## path - usually repo_name + # clone_uri = {scheme}://{user}{pass}{netloc}{path} +## issue tracking mapping for commits messages +## uncomment url_pat, issue_server, issue_prefix to enable + + +## pattern to get the issues from commit messages +## default one used here is #1234 + +#url_pat = (?:^#|\s#)(\w+) + +## server url to the issue, each {id} will be replaced with id +## fetched from the regex + +#issue_server = https://myissueserver.com/issue/{id} + +## prefix to add to link to indicate it's an url +## #314 will be replaced by <issue_prefix><id> + +#issue_prefix = # + + #################################### ### CELERY CONFIG #### ####################################
--- a/rhodecode/controllers/api/api.py Sat Jan 07 21:44:18 2012 +0200 +++ b/rhodecode/controllers/api/api.py Sun Jan 08 12:18:16 2012 +0200 @@ -64,23 +64,23 @@ """ @HasPermissionAllDecorator('hg.admin') - def pull(self, apiuser, repo): + def pull(self, apiuser, repo_name): """ Dispatch pull action on given repo :param user: - :param repo: + :param repo_name: """ - if Repository.is_valid(repo) is False: - raise JSONRPCError('Unknown repo "%s"' % repo) + if Repository.is_valid(repo_name) is False: + raise JSONRPCError('Unknown repo "%s"' % repo_name) try: - ScmModel().pull_changes(repo, self.rhodecode_user.username) - return 'Pulled from %s' % repo + ScmModel().pull_changes(repo_name, self.rhodecode_user.username) + return 'Pulled from %s' % repo_name except Exception: - raise JSONRPCError('Unable to pull changes from "%s"' % repo) + raise JSONRPCError('Unable to pull changes from "%s"' % repo_name) @HasPermissionAllDecorator('hg.admin') def get_user(self, apiuser, username): @@ -151,10 +151,15 @@ raise JSONRPCError("user %s already exist" % username) try: - UserModel().create_or_update(username, password, email, firstname, - lastname, active, admin, ldap_dn) + usr = UserModel().create_or_update( + username, password, email, firstname, + lastname, active, admin, ldap_dn + ) Session.commit() - return dict(msg='created new user %s' % username) + return dict( + id=usr.user_id, + msg='created new user %s' % username + ) except Exception: log.error(traceback.format_exc()) raise JSONRPCError('failed to create user %s' % username) @@ -185,7 +190,7 @@ ldap=user.ldap_dn)) return dict(id=users_group.users_group_id, - name=users_group.users_group_name, + group_name=users_group.users_group_name, active=users_group.users_group_active, members=members) @@ -212,31 +217,31 @@ ldap=user.ldap_dn)) result.append(dict(id=users_group.users_group_id, - name=users_group.users_group_name, + group_name=users_group.users_group_name, active=users_group.users_group_active, members=members)) return result @HasPermissionAllDecorator('hg.admin') - def create_users_group(self, apiuser, name, active=True): + def create_users_group(self, apiuser, group_name, active=True): """ Creates an new usergroup - :param name: + :param group_name: :param active: """ - if self.get_users_group(apiuser, name): - raise JSONRPCError("users group %s already exist" % name) + if self.get_users_group(apiuser, group_name): + raise JSONRPCError("users group %s already exist" % group_name) try: - ug = UsersGroupModel().create(name=name, active=active) + ug = UsersGroupModel().create(name=group_name, active=active) Session.commit() return dict(id=ug.users_group_id, - msg='created new users group %s' % name) + msg='created new users group %s' % group_name) except Exception: log.error(traceback.format_exc()) - raise JSONRPCError('failed to create group %s' % name) + raise JSONRPCError('failed to create group %s' % group_name) @HasPermissionAllDecorator('hg.admin') def add_user_to_users_group(self, apiuser, group_name, username): @@ -312,7 +317,7 @@ return dict( id=repo.repo_id, - name=repo.repo_name, + repo_name=repo.repo_name, type=repo.repo_type, description=repo.description, members=members @@ -331,7 +336,7 @@ result.append( dict( id=repository.repo_id, - name=repository.repo_name, + repo_name=repository.repo_name, type=repository.repo_type, description=repository.description ) @@ -367,13 +372,13 @@ raise JSONRPCError(e) @HasPermissionAnyDecorator('hg.admin', 'hg.create.repository') - def create_repo(self, apiuser, name, owner_name, description='', + def create_repo(self, apiuser, repo_name, owner_name, description='', repo_type='hg', private=False): """ Create a repository :param apiuser: - :param name: + :param repo_name: :param description: :param type: :param private: @@ -386,10 +391,10 @@ except NoResultFound: raise JSONRPCError('unknown user %s' % owner) - if self.get_repo(apiuser, name): - raise JSONRPCError("repo %s already exist" % name) + if Repository.get_by_repo_name(repo_name): + raise JSONRPCError("repo %s already exist" % repo_name) - groups = name.split('/') + groups = repo_name.split('/') real_name = groups[-1] groups = groups[:-1] parent_id = None @@ -405,10 +410,10 @@ ) parent_id = group.group_id - RepoModel().create( + repo = RepoModel().create( dict( repo_name=real_name, - repo_name_full=name, + repo_name_full=repo_name, description=description, private=private, repo_type=repo_type, @@ -418,9 +423,15 @@ owner ) Session.commit() + + return dict( + id=repo.repo_id, + msg="Created new repository %s" % repo.repo_name + ) + except Exception: log.error(traceback.format_exc()) - raise JSONRPCError('failed to create repository %s' % name) + raise JSONRPCError('failed to create repository %s' % repo_name) @HasPermissionAnyDecorator('hg.admin') def add_user_to_repo(self, apiuser, repo_name, username, perm):
--- a/rhodecode/lib/db_manage.py Sat Jan 07 21:44:18 2012 +0200 +++ b/rhodecode/lib/db_manage.py Sun Jan 08 12:18:16 2012 +0200 @@ -97,6 +97,13 @@ from rhodecode.lib.dbmigrate.migrate.exceptions import \ DatabaseNotControlledError + if 'sqlite' in self.dburi: + print ( + '********************** WARNING **********************\n' + 'Make sure your version of sqlite is at least 3.7.X. \n' + 'Earlier versions are known to fail on some migrations\n' + '*****************************************************\n' + ) upgrade = ask_ok('You are about to perform database upgrade, make ' 'sure You backed up your database before. ' 'Continue ? [y/n]') @@ -161,6 +168,9 @@ print ('Adding ldap defaults') self.klass.create_ldap_options(skip_existing=True) + def step_4(self): + print ('TODO:') + upgrade_steps = [0] + range(curr_version + 1, __dbversion__ + 1) # CALL THE PROPER ORDER OF STEPS TO PERFORM FULL UPGRADE
--- a/rhodecode/lib/helpers.py Sat Jan 07 21:44:18 2012 +0200 +++ b/rhodecode/lib/helpers.py Sun Jan 08 12:18:16 2012 +0200 @@ -8,6 +8,7 @@ import StringIO import urllib import math +import logging from datetime import datetime from pygments.formatters.html import HtmlFormatter @@ -41,6 +42,8 @@ from rhodecode.lib import str2bool, safe_unicode, safe_str, get_changeset_safe from rhodecode.lib.markup_renderer import MarkupRenderer +log = logging.getLogger(__name__) + def _reset(name, value=None, id=NotGiven, type="reset", **attrs): """ @@ -728,7 +731,7 @@ return literal('<div style="width:%spx">%s%s</div>' % (width, d_a, d_d)) -def urlify_text(text): +def urlify_text(text_): import re url_pat = re.compile(r'''(http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]''' @@ -738,8 +741,42 @@ url_full = match_obj.groups()[0] return '<a href="%(url)s">%(url)s</a>' % ({'url':url_full}) - return literal(url_pat.sub(url_func, text)) + return literal(url_pat.sub(url_func, text_)) +def urlify_commit(text_): + import re + import traceback + + try: + conf = config['app_conf'] + + URL_PAT = re.compile(r'%s' % conf.get('url_pat')) + + if URL_PAT: + ISSUE_SERVER = conf.get('issue_server') + ISSUE_PREFIX = conf.get('issue_prefix') + def url_func(match_obj): + issue_id = match_obj.groups()[0] + tmpl = ( + '<a class="%(cls)s" href="%(url)s">' + ' %(issue-prefix)s%(id-repr)s' + '</a>' + ) + return tmpl % ( + { + 'cls':'issue-tracker-link', + 'url':ISSUE_SERVER.replace('{id}',issue_id), + 'id-repr':issue_id, + 'issue-prefix':ISSUE_PREFIX, + 'serv':ISSUE_SERVER, + } + ) + return literal(URL_PAT.sub(url_func, text_)) + except: + log.error(traceback.format_exc()) + pass + + return text_ def rst(source): return literal('<div class="rst-block">%s</div>' %
--- a/rhodecode/lib/rcmail/exceptions.py Sat Jan 07 21:44:18 2012 +0200 +++ b/rhodecode/lib/rcmail/exceptions.py Sun Jan 08 12:18:16 2012 +0200 @@ -1,3 +1,4 @@ + class InvalidMessage(RuntimeError): """ @@ -5,6 +6,7 @@ as recipients or sender address. """ + class BadHeaders(RuntimeError): """ Raised if message contains newlines in headers.
--- a/rhodecode/lib/rcmail/message.py Sat Jan 07 21:44:18 2012 +0200 +++ b/rhodecode/lib/rcmail/message.py Sun Jan 08 12:18:16 2012 +0200 @@ -45,6 +45,8 @@ :param bcc: BCC list :param extra_headers: dict of extra email headers :param attachments: list of Attachment instances + :param recipients_separator: alternative separator for any of + 'From', 'To', 'Delivered-To', 'Cc', 'Bcc' fields """ def __init__(self, @@ -56,8 +58,8 @@ cc=None, bcc=None, extra_headers=None, - attachments=None): - + attachments=None, + recipients_separator="; "): self.subject = subject or '' self.sender = sender @@ -70,6 +72,8 @@ self.bcc = bcc or [] self.extra_headers = extra_headers or {} + self.recipients_separator = recipients_separator + @property def send_to(self): return set(self.recipients) | set(self.bcc or ()) | set(self.cc or ()) @@ -92,7 +96,8 @@ To=self.recipients, From=self.sender, Body=self.body, - Html=self.html) + Html=self.html, + separator=self.recipients_separator) if self.bcc: response.base['Bcc'] = self.bcc
--- a/rhodecode/lib/rcmail/response.py Sat Jan 07 21:44:18 2012 +0200 +++ b/rhodecode/lib/rcmail/response.py Sun Jan 08 12:18:16 2012 +0200 @@ -141,12 +141,14 @@ MailResponse.to_message. This lets you change it and work with it, then send it out when it's ready. """ - def __init__(self, To=None, From=None, Subject=None, Body=None, Html=None): + def __init__(self, To=None, From=None, Subject=None, Body=None, Html=None, + separator="; "): self.Body = Body self.Html = Html self.base = MailBase([('To', To), ('From', From), ('Subject', Subject)]) self.multipart = self.Body and self.Html self.attachments = [] + self.separator = separator def __contains__(self, key): return self.base.__contains__(key) @@ -298,7 +300,7 @@ self.base.body = self.Html self.base.content_encoding['Content-Type'] = ('text/html', {}) - return to_message(self.base) + return to_message(self.base, separator=self.separator) def all_parts(self): """ @@ -310,7 +312,7 @@ def keys(self): return self.base.keys() -def to_message(mail): +def to_message(mail, separator="; "): """ Given a MailBase message, this will construct a MIMEPart that is canonicalized for use with the Python email API. @@ -339,10 +341,16 @@ for k in mail.keys(): if k in ADDRESS_HEADERS_WHITELIST: - out[k.encode('ascii')] = header_to_mime_encoding(mail[k]) + out[k.encode('ascii')] = header_to_mime_encoding( + mail[k], + not_email=False, + separator=separator + ) else: - out[k.encode('ascii')] = header_to_mime_encoding(mail[k], - not_email=True) + out[k.encode('ascii')] = header_to_mime_encoding( + mail[k], + not_email=True + ) out.extract_payload(mail) @@ -403,12 +411,12 @@ self.is_multipart()) -def header_to_mime_encoding(value, not_email=False): +def header_to_mime_encoding(value, not_email=False, separator=", "): if not value: return "" encoder = Charset(DEFAULT_ENCODING) if type(value) == list: - return "; ".join(properly_encode_header( + return separator.join(properly_encode_header( v, encoder, not_email) for v in value) else: return properly_encode_header(value, encoder, not_email)
--- a/rhodecode/lib/rcmail/smtp_mailer.py Sat Jan 07 21:44:18 2012 +0200 +++ b/rhodecode/lib/rcmail/smtp_mailer.py Sun Jan 08 12:18:16 2012 +0200 @@ -59,7 +59,8 @@ if isinstance(recipients, basestring): recipients = [recipients] - msg = Message(subject, recipients, body, html, self.mail_from) + msg = Message(subject, recipients, body, html, self.mail_from, + recipients_separator=", ") raw_msg = msg.to_message() if self.ssl:
--- a/rhodecode/lib/utils.py Sat Jan 07 21:44:18 2012 +0200 +++ b/rhodecode/lib/utils.py Sun Jan 08 12:18:16 2012 +0200 @@ -152,12 +152,12 @@ """ Scans given path for repos and return (name,(type,path)) tuple - :param path: path to scann for repositories + :param path: path to scan for repositories :param recursive: recursive search and return names with subdirs in front """ # remove ending slash for better results - path = path.rstrip('/') + path = path.rstrip(os.sep) def _get_repos(p): if not os.access(p, os.W_OK):
--- a/rhodecode/model/notification.py Sat Jan 07 21:44:18 2012 +0200 +++ b/rhodecode/model/notification.py Sun Jan 08 12:18:16 2012 +0200 @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- """ rhodecode.model.notification - ~~~~~~~~~~~~~~ + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Model for notifications
--- a/rhodecode/templates/changelog/changelog.html Sat Jan 07 21:44:18 2012 +0200 +++ b/rhodecode/templates/changelog/changelog.html Sun Jan 08 12:18:16 2012 +0200 @@ -48,7 +48,7 @@ <div class="left"> <div> ${h.checkbox(cs.short_id,class_="changeset_range")} - <span class="changeset_id">${cs.revision}:<span class="changeset_hash">${h.short_id(cs.raw_id)}</span></span> + <span class="tooltip" title="${cs.date}"><a href="${h.url('changeset_home',repo_name=c.repo_name,revision=cs.raw_id)}"><span class="changeset_id">${cs.revision}:<span class="changeset_hash">${h.short_id(cs.raw_id)}</span></span></a></span> </div> <div class="author"> <div class="gravatar">
--- a/rhodecode/templates/changeset/changeset.html Sat Jan 07 21:44:18 2012 +0200 +++ b/rhodecode/templates/changeset/changeset.html Sun Jan 08 12:18:16 2012 +0200 @@ -49,7 +49,7 @@ <span>${h.person(c.changeset.author)}</span><br/> <span><a href="mailto:${h.email_or_none(c.changeset.author)}">${h.email_or_none(c.changeset.author)}</a></span><br/> </div> - <div class="message">${h.wrap_paragraphs(c.changeset.message)}</div> + <div class="message">${h.urlify_commit(h.wrap_paragraphs(c.changeset.message))}</div> </div> <div class="right"> <div class="changes"> @@ -95,7 +95,7 @@ <div class="cs_${change}"> <div class="node"> %if change != 'removed': - ${h.link_to(h.safe_unicode(filenode.path),c.anchor_url(filenode.changeset.raw_id,filenode.path))} + ${h.link_to(h.safe_unicode(filenode.path),c.anchor_url(filenode.changeset.raw_id,filenode.path)+"_target")} %else: ${h.link_to(h.safe_unicode(filenode.path),h.url.current(anchor=h.FID('',filenode.path)))} %endif @@ -138,11 +138,15 @@ YUE.on(YUQ('.show-inline-comments'),'change',function(e){ var show = 'none'; var target = e.currentTarget; + console.log(target); if(target.checked){ var show = '' } + console.log('aa') var boxid = YUD.getAttribute(target,'id_for'); + console.log(boxid); var comments = YUQ('#{0} .inline-comments'.format(boxid)); + console.log(comments) for(c in comments){ YUD.setStyle(comments[c],'display',show); }
--- a/rhodecode/templates/changeset/changeset_range.html Sat Jan 07 21:44:18 2012 +0200 +++ b/rhodecode/templates/changeset/changeset_range.html Sun Jan 08 12:18:16 2012 +0200 @@ -41,7 +41,7 @@ <td>${h.link_to('r%s:%s' % (cs.revision,h.short_id(cs.raw_id)),h.url('changeset_home',repo_name=c.repo_name,revision=cs.raw_id))}</td> <td><div class="author">${h.person(cs.author)}</div></td> <td><span class="tooltip" title="${h.age(cs.date)}">${cs.date}</span></td> - <td><div class="message">${h.link_to(h.wrap_paragraphs(cs.message),h.url('changeset_home',repo_name=c.repo_name,revision=cs.raw_id))}</div></td> + <td><div class="message">${h.urlify_commit(h.wrap_paragraphs(cs.message))}</div></td> </tr> %endfor </table>
--- a/rhodecode/templates/changeset/diff_block.html Sat Jan 07 21:44:18 2012 +0200 +++ b/rhodecode/templates/changeset/diff_block.html Sun Jan 08 12:18:16 2012 +0200 @@ -7,8 +7,8 @@ %for change,filenode,diff,cs1,cs2,stat in changes: %if change !='removed': - <div id="${h.FID(filenode.changeset.raw_id,filenode.path)}" style="clear:both;height:90px;margin-top:-60px"></div> - <div class="diffblock margined comm"> + <div id="${h.FID(filenode.changeset.raw_id,filenode.path)}_target" style="clear:both;height:90px;margin-top:-60px"></div> + <div id="${h.FID(filenode.changeset.raw_id,filenode.path)}" class="diffblock margined comm"> <div class="code-header"> <div class="changeset_header"> <div class="changeset_file">
--- a/rhodecode/templates/shortlog/shortlog_data.html Sat Jan 07 21:44:18 2012 +0200 +++ b/rhodecode/templates/shortlog/shortlog_data.html Sun Jan 08 12:18:16 2012 +0200 @@ -2,16 +2,19 @@ %if c.repo_changesets: <table class="table_disp"> <tr> - <th class="left">${_('commit message')}</th> + <th class="left">${_('revision')}</th> + <th class="left">${_('commit message')}</th> <th class="left">${_('age')}</th> <th class="left">${_('author')}</th> - <th class="left">${_('revision')}</th> <th class="left">${_('branch')}</th> <th class="left">${_('tags')}</th> </tr> %for cnt,cs in enumerate(c.repo_changesets): <tr class="parity${cnt%2}"> <td> + <div><pre><a href="${h.url('files_home',repo_name=c.repo_name,revision=cs.raw_id)}">r${cs.revision}:${h.short_id(cs.raw_id)}</a></pre></div> + </td> + <td> ${h.link_to(h.truncate(cs.message,50), h.url('changeset_home',repo_name=c.repo_name,revision=cs.raw_id), title=cs.message)} @@ -20,7 +23,6 @@ ${h.age(cs.date)}</span> </td> <td title="${cs.author}">${h.person(cs.author)}</td> - <td><div><pre><a href="${h.url('files_home',repo_name=c.repo_name,revision=cs.raw_id)}">r${cs.revision}:${h.short_id(cs.raw_id)}</a></pre></div></td> <td> <span class="logtags"> <span class="branchtag">${cs.branch}</span>