diff --git a/docs/api/api.rst b/docs/api/api.rst --- a/docs/api/api.rst +++ b/docs/api/api.rst @@ -113,7 +113,15 @@ OUTPUT:: "email" : "", "active" : "", "admin" :  "", - "ldap_dn" : "" + "ldap_dn" : "", + "last_login": "", + "permissions": { + "global": ["hg.create.repository", + "repository.read", + "hg.register.manual_activate"], + "repositories": {"repo1": "repository.none"}, + "repositories_groups": {"Group1": "group.read"} + }, } error: null @@ -144,7 +152,8 @@ OUTPUT:: "email" : "", "active" : "", "admin" :  "", - "ldap_dn" : "" + "ldap_dn" : "", + "last_login": "", }, … ] diff --git a/docs/changelog.rst b/docs/changelog.rst --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -43,6 +43,8 @@ fixes - fixed #393 py2.5 fixes for routes url generator - fixed #397 Private repository groups shows up before login - fixed #396 fixed problems with revoking users in nested groups +- fixed mysql unicode issues + specified InnoDB as default engine with + utf8 charset 1.3.3 (**2012-03-02**) ---------------------- diff --git a/rhodecode/controllers/api/__init__.py b/rhodecode/controllers/api/__init__.py --- a/rhodecode/controllers/api/__init__.py +++ b/rhodecode/controllers/api/__init__.py @@ -233,10 +233,10 @@ class JSONRPCController(WSGIController): try: return json.dumps(response) except TypeError, e: - log.debug('Error encoding response: %s' % e) + log.error('API FAILED. Error encoding response: %s' % e) return json.dumps( dict( - self._req_id, + id=self._req_id, result=None, error="Error encoding response" ) diff --git a/rhodecode/controllers/api/api.py b/rhodecode/controllers/api/api.py --- a/rhodecode/controllers/api/api.py +++ b/rhodecode/controllers/api/api.py @@ -30,18 +30,16 @@ import logging from rhodecode.controllers.api import JSONRPCController, JSONRPCError from rhodecode.lib.auth import HasPermissionAllDecorator, \ - HasPermissionAnyDecorator, PasswordGenerator + HasPermissionAnyDecorator, PasswordGenerator, AuthUser from rhodecode.model.meta import Session from rhodecode.model.scm import ScmModel -from rhodecode.model.db import User, UsersGroup, RepoGroup, Repository +from rhodecode.model.db import User, UsersGroup, Repository from rhodecode.model.repo import RepoModel from rhodecode.model.user import UserModel from rhodecode.model.users_group import UsersGroupModel -from rhodecode.model.repos_group import ReposGroupModel from rhodecode.lib.utils import map_groups - log = logging.getLogger(__name__) @@ -101,7 +99,9 @@ class ApiController(JSONRPCController): email=user.email, active=user.active, admin=user.admin, - ldap_dn=user.ldap_dn + ldap_dn=user.ldap_dn, + last_login=user.last_login, + permissions=AuthUser(user_id=user.user_id).permissions ) @HasPermissionAllDecorator('hg.admin') @@ -123,7 +123,8 @@ class ApiController(JSONRPCController): email=user.email, active=user.active, admin=user.admin, - ldap_dn=user.ldap_dn + ldap_dn=user.ldap_dn, + last_login=user.last_login, ) ) return result diff --git a/rhodecode/lib/compat.py b/rhodecode/lib/compat.py --- a/rhodecode/lib/compat.py +++ b/rhodecode/lib/compat.py @@ -25,16 +25,55 @@ # along with this program. If not, see . import os +import datetime +import functools from rhodecode import __platform__, PLATFORM_WIN #============================================================================== # json #============================================================================== + + +def __obj_dump(obj): + DATETIME_FORMAT = "%Y-%m-%dT%H:%M:%S" + DATE_FORMAT = "%Y-%m-%d" + if isinstance(obj, complex): + return [obj.real, obj.imag] + elif isinstance(obj, datetime.datetime): + return obj.strftime(DATETIME_FORMAT) + elif isinstance(obj, datetime.date): + return obj.strftime(DATE_FORMAT) + elif isinstance(obj, set): + return list(obj) + elif isinstance(obj, OrderedDict): + return obj.as_dict() + else: + raise NotImplementedError + try: import json + + # extended JSON encoder for json + class ExtendedEncoder(json.JSONEncoder): + def default(self, obj): + try: + return __obj_dump(obj) + except NotImplementedError: + pass + return json.JSONEncoder.default(self, obj) + # monkey-patch JSON encoder to use extended version + json.dumps = functools.partial(json.dumps, cls=ExtendedEncoder) except ImportError: import simplejson as json + def extended_encode(obj): + try: + return __obj_dump(obj) + except NotImplementedError: + pass + raise TypeError("%r is not JSON serializable" % (obj,)) + json.dumps = functools.partial(json.dumps, default=extended_encode) + #============================================================================== # izip_longest @@ -44,11 +83,11 @@ try: except ImportError: import itertools - def izip_longest(*args, **kwds): # noqa + def izip_longest(*args, **kwds): fillvalue = kwds.get("fillvalue") def sentinel(counter=([fillvalue] * (len(args) - 1)).pop): - yield counter() # yields the fillvalue, or raises IndexError + yield counter() # yields the fillvalue, or raises IndexError fillers = itertools.repeat(fillvalue) iters = [itertools.chain(it, sentinel(), fillers)