Changeset - b7563ad4e7ee
[Not reviewed]
beta
0 12 0
Marcin Kuzminski - 14 years ago 2011-06-30 01:25:37
marcin@python-works.com
Unicode fixes, added safe_str method for global str() operations +better test sandboxing
12 files changed with 92 insertions and 60 deletions:
0 comments (0 inline, 0 general)
rhodecode/config/environment.py
Show inline comments
 
@@ -52,25 +52,25 @@ def load_environment(global_conf, app_co
 
        error_handler=handle_mako_error,
 
        module_directory=os.path.join(app_conf['cache_dir'], 'templates'),
 
        input_encoding='utf-8', default_filters=['escape'],
 
        imports=['from webhelpers.html import escape'])
 

	
 
    #sets the c attribute access when don't existing attribute are accessed
 
    config['pylons.strict_tmpl_context'] = True
 
    test = os.path.split(config['__file__'])[-1] == 'test.ini'
 
    if test:
 
        from rhodecode.lib.utils import create_test_env, create_test_index
 
        from rhodecode.tests import  TESTS_TMP_PATH
 
        create_test_env(TESTS_TMP_PATH, config)
 
        create_test_index(TESTS_TMP_PATH, True)
 
        create_test_index(TESTS_TMP_PATH, config, True)
 

	
 
    #MULTIPLE DB configs
 
    # Setup the SQLAlchemy database engine
 
    sa_engine_db1 = engine_from_config(config, 'sqlalchemy.db1.')
 

	
 
    init_model(sa_engine_db1)
 

	
 
    repos_path = make_ui('db').configitems('paths')[0][1]
 
    repo2db_mapper(ScmModel().repo_scan(repos_path))
 
    set_available_permissions(config)
 
    config['base_path'] = repos_path
 
    set_rhodecode_config(config)
rhodecode/controllers/files.py
Show inline comments
 
@@ -29,25 +29,25 @@ import mimetypes
 
import traceback
 

	
 
from pylons import request, response, session, tmpl_context as c, url
 
from pylons.i18n.translation import _
 
from pylons.controllers.util import redirect
 

	
 
from vcs.backends import ARCHIVE_SPECS
 
from vcs.exceptions import RepositoryError, ChangesetDoesNotExistError, \
 
    EmptyRepositoryError, ImproperArchiveTypeError, VCSError
 
from vcs.nodes import FileNode, NodeKind
 
from vcs.utils import diffs as differ
 

	
 
from rhodecode.lib import convert_line_endings, detect_mode
 
from rhodecode.lib import convert_line_endings, detect_mode, safe_str
 
from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
 
from rhodecode.lib.base import BaseRepoController, render
 
from rhodecode.lib.utils import EmptyChangeset
 
import rhodecode.lib.helpers as h
 
from rhodecode.model.repo import RepoModel
 

	
 
log = logging.getLogger(__name__)
 

	
 

	
 
class FilesController(BaseRepoController):
 

	
 
    @LoginRequired()
 
@@ -144,25 +144,25 @@ class FilesController(BaseRepoController
 
            redirect(h.url('files_home', repo_name=repo_name,
 
                           revision=revision))
 

	
 
        return render('files/files.html')
 

	
 
    @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
 
                                   'repository.admin')
 
    def rawfile(self, repo_name, revision, f_path):
 
        cs = self.__get_cs_or_redirect(revision, repo_name)
 
        file_node = self.__get_filenode_or_redirect(repo_name, cs, f_path)
 

	
 
        response.content_disposition = 'attachment; filename=%s' % \
 
            f_path.split(os.sep)[-1].encode('utf8', 'replace')
 
            safe_str(f_path.split(os.sep)[-1])
 

	
 
        response.content_type = file_node.mimetype
 
        return file_node.content
 

	
 
    @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
 
                                   'repository.admin')
 
    def raw(self, repo_name, revision, f_path):
 
        cs = self.__get_cs_or_redirect(revision, repo_name)
 
        file_node = self.__get_filenode_or_redirect(repo_name, cs, f_path)
 

	
 
        raw_mimetype_mapping = {
 
            # map original mimetype to a mimetype used for "show as raw"
 
@@ -189,25 +189,25 @@ class FilesController(BaseRepoController
 
            else:
 
                # do not just use the original mimetype, but force text/plain,
 
                # otherwise it would serve text/html and that might be unsafe.
 
                # Note: underlying vcs library fakes text/plain mimetype if the
 
                # mimetype can not be determined and it thinks it is not
 
                # binary.This might lead to erroneous text display in some
 
                # cases, but helps in other cases, like with text files
 
                # without extension.
 
                mimetype, dispo = 'text/plain', 'inline'
 

	
 
        if dispo == 'attachment':
 
            dispo = 'attachment; filename=%s' % \
 
                        f_path.split(os.sep)[-1].encode('utf8', 'replace')
 
                        safe_str(f_path.split(os.sep)[-1])
 

	
 
        response.content_disposition = dispo
 
        response.content_type = mimetype
 
        return file_node.content
 

	
 
    @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
 
                                   'repository.admin')
 
    def annotate(self, repo_name, revision, f_path):
 
        c.cs = self.__get_cs_or_redirect(revision, repo_name)
 
        c.file = self.__get_filenode_or_redirect(repo_name, c.cs, f_path)
 

	
 
        c.file_history = self._get_node_history(c.cs, f_path)
rhodecode/lib/__init__.py
Show inline comments
 
@@ -151,42 +151,64 @@ def generate_api_key(username, salt=None
 
    from tempfile import _RandomNameSequence
 
    import hashlib
 

	
 
    if salt is None:
 
        salt = _RandomNameSequence().next()
 

	
 
    return hashlib.sha1(username + salt).hexdigest()
 

	
 

	
 
def safe_unicode(_str, from_encoding='utf8'):
 
    """
 
    safe unicode function. In case of UnicodeDecode error we try to return
 
    unicode with errors replace
 
    unicode with errors replaceed
 

	
 
    :param _str: string to decode
 
    :rtype: unicode
 
    :returns: unicode object
 
    """
 

	
 
    if isinstance(_str, unicode):
 
        return _str
 

	
 
    try:
 
        u_str = unicode(_str, from_encoding)
 
    except UnicodeDecodeError:
 
        u_str = unicode(_str, from_encoding, 'replace')
 

	
 
    return u_str
 

	
 

	
 
def safe_str(_unicode, to_encoding='utf8'):
 
    """
 
    safe str function. In case of UnicodeEncode error we try to return
 
    str with errors replaceed
 

	
 
    :param _unicode: unicode to encode
 
    :rtype: str
 
    :returns: str object
 
    """
 

	
 
    if isinstance(_unicode, str):
 
        return _unicode
 

	
 
    try:
 
        safe_str = str(_unicode)
 
    except UnicodeEncodeError:
 
        safe_str = _unicode.encode(to_encoding, 'replace')
 

	
 
    return safe_str
 

	
 

	
 

	
 
def engine_from_config(configuration, prefix='sqlalchemy.', **kwargs):
 
    """
 
    Custom engine_from_config functions that makes sure we use NullPool for
 
    file based sqlite databases. This prevents errors on sqlite. This only 
 
    applies to sqlalchemy versions < 0.7.0
 

	
 
    """
 
    import sqlalchemy
 
    from sqlalchemy import engine_from_config as efc
 
    import logging
 

	
 
    if int(sqlalchemy.__version__.split('.')[1]) < 7:
rhodecode/lib/celerylib/tasks.py
Show inline comments
 
@@ -28,25 +28,25 @@ from celery.decorators import task
 
import os
 
import traceback
 
import logging
 
from os.path import dirname as dn, join as jn
 

	
 
from time import mktime
 
from operator import itemgetter
 
from string import lower
 

	
 
from pylons import config
 
from pylons.i18n.translation import _
 

	
 
from rhodecode.lib import LANGUAGES_EXTENSIONS_MAP
 
from rhodecode.lib import LANGUAGES_EXTENSIONS_MAP, safe_str
 
from rhodecode.lib.celerylib import run_task, locked_task, str2bool, \
 
    __get_lockkey, LockHeld, DaemonLock
 
from rhodecode.lib.helpers import person
 
from rhodecode.lib.smtp_mailer import SmtpMailer
 
from rhodecode.lib.utils import add_cache
 
from rhodecode.lib.odict import OrderedDict
 
from rhodecode.model import init_model
 
from rhodecode.model import meta
 
from rhodecode.model.db import RhodeCodeUi, Statistics, Repository
 

	
 
from vcs.backends import get_repo
 

	
 
@@ -57,25 +57,24 @@ add_cache(config)
 
try:
 
    import json
 
except ImportError:
 
    #python 2.5 compatibility
 
    import simplejson as json
 

	
 
__all__ = ['whoosh_index', 'get_commits_stats',
 
           'reset_user_password', 'send_email']
 

	
 
CELERY_ON = str2bool(config['app_conf'].get('use_celery'))
 

	
 

	
 

	
 
def get_session():
 
    if CELERY_ON:
 
        engine = engine_from_config(config, 'sqlalchemy.db1.')
 
        init_model(engine)
 
    sa = meta.Session()
 
    return sa
 

	
 

	
 
def get_repos_path():
 
    sa = get_session()
 
    q = sa.query(RhodeCodeUi).filter(RhodeCodeUi.ui_key == '/').one()
 
    return q.ui_value
 
@@ -103,26 +102,25 @@ def get_commits_stats(repo_name, ts_min_
 
                            ts_max_y)
 
    lockkey_path = dn(dn(dn(dn(os.path.abspath(__file__)))))
 
    log.info('running task with lockkey %s', lockkey)
 
    try:
 
        lock = l = DaemonLock(jn(lockkey_path, lockkey))
 

	
 
        #for js data compatibilty cleans the key for person from '
 
        akc = lambda k: person(k).replace('"', "")
 

	
 
        co_day_auth_aggr = {}
 
        commits_by_day_aggregate = {}
 
        repos_path = get_repos_path()
 
        p = os.path.join(repos_path, repo_name)
 
        repo = get_repo(p)
 
        repo = get_repo(safe_str(os.path.join(repos_path, repo_name)))
 
        repo_size = len(repo.revisions)
 
        #return if repo have no revisions
 
        if repo_size < 1:
 
            lock.release()
 
            return True
 

	
 
        skip_date_limit = True
 
        parse_limit = int(config['app_conf'].get('commit_parse_limit'))
 
        last_rev = 0
 
        last_cs = None
 
        timegetter = itemgetter('time')
 

	
 
@@ -349,26 +347,25 @@ def create_repo_fork(form_data, cur_user
 
    repos_path = get_repos_path()
 
    repo_path = os.path.join(repos_path, repo_name)
 
    repo_fork_path = os.path.join(repos_path, form_data['fork_name'])
 
    alias = form_data['repo_type']
 

	
 
    log.info('creating repo fork %s as %s', repo_name, repo_path)
 
    backend = get_backend(alias)
 
    backend(str(repo_fork_path), create=True, src_url=str(repo_path))
 

	
 

	
 
def __get_codes_stats(repo_name):
 
    repos_path = get_repos_path()
 
    p = os.path.join(repos_path, repo_name)
 
    repo = get_repo(p)
 
    repo = get_repo(safe_str(os.path.join(repos_path, repo_name)))
 
    tip = repo.get_changeset()
 
    code_stats = {}
 

	
 
    def aggregate(cs):
 
        for f in cs[2]:
 
            ext = lower(f.extension)
 
            if ext in LANGUAGES_EXTENSIONS_MAP.keys() and not f.is_binary:
 
                if ext in code_stats:
 
                    code_stats[ext] += 1
 
                else:
 
                    code_stats[ext] = 1
 

	
rhodecode/lib/helpers.py
Show inline comments
 
@@ -27,25 +27,25 @@ from webhelpers.number import format_byt
 
from webhelpers.pylonslib import Flash as _Flash
 
from webhelpers.pylonslib.secure_form import secure_form
 
from webhelpers.text import chop_at, collapse, convert_accented_entities, \
 
    convert_misc_entities, lchop, plural, rchop, remove_formatting, \
 
    replace_whitespace, urlify, truncate, wrap_paragraphs
 
from webhelpers.date import time_ago_in_words
 
from webhelpers.paginate import Page
 
from webhelpers.html.tags import _set_input_attrs, _set_id_attr, \
 
    convert_boolean_attrs, NotGiven
 

	
 
from vcs.utils.annotate import annotate_highlight
 
from rhodecode.lib.utils import repo_name_slug
 
from rhodecode.lib import str2bool, safe_unicode
 
from rhodecode.lib import str2bool, safe_unicode, safe_str
 

	
 
def _reset(name, value=None, id=NotGiven, type="reset", **attrs):
 
    """
 
    Reset button
 
    """
 
    _set_input_attrs(attrs, type, name, value)
 
    _set_id_attr(attrs, id, name)
 
    convert_boolean_attrs(attrs, ["disabled"])
 
    return HTML.input(**attrs)
 

	
 
reset = _reset
 

	
 
@@ -493,25 +493,25 @@ def gravatar_url(email_address, size=30)
 
    if not str2bool(config['app_conf'].get('use_gravatar')) or \
 
        email_address == 'anonymous@rhodecode.org':
 
        return "/images/user%s.png" % size
 

	
 
    ssl_enabled = 'https' == request.environ.get('wsgi.url_scheme')
 
    default = 'identicon'
 
    baseurl_nossl = "http://www.gravatar.com/avatar/"
 
    baseurl_ssl = "https://secure.gravatar.com/avatar/"
 
    baseurl = baseurl_ssl if ssl_enabled else baseurl_nossl
 

	
 
    if isinstance(email_address, unicode):
 
        #hashlib crashes on unicode items
 
        email_address = email_address.encode('utf8', 'replace')
 
        email_address = safe_str(email_address)
 
    # construct the url
 
    gravatar_url = baseurl + hashlib.md5(email_address.lower()).hexdigest() + "?"
 
    gravatar_url += urllib.urlencode({'d':default, 's':str(size)})
 

	
 
    return gravatar_url
 

	
 

	
 
#==============================================================================
 
# REPO PAGER, PAGER FOR REPOSITORY
 
#==============================================================================
 
class RepoPage(Page):
 

	
rhodecode/lib/middleware/simplegit.py
Show inline comments
 
@@ -60,24 +60,25 @@ class SimpleGitUploadPackHandler(dulserv
 

	
 
dulserver.DEFAULT_HANDLERS = {
 
  'git-upload-pack': SimpleGitUploadPackHandler,
 
  'git-receive-pack': dulserver.ReceivePackHandler,
 
}
 

	
 
from dulwich.repo import Repo
 
from dulwich.web import HTTPGitApplication
 

	
 
from paste.auth.basic import AuthBasicAuthenticator
 
from paste.httpheaders import REMOTE_USER, AUTH_TYPE
 

	
 
from rhodecode.lib import safe_str
 
from rhodecode.lib.auth import authfunc, HasPermissionAnyMiddleware
 
from rhodecode.lib.utils import invalidate_cache, check_repo_fast
 
from rhodecode.model.user import UserModel
 

	
 
from webob.exc import HTTPNotFound, HTTPForbidden, HTTPInternalServerError
 

	
 
log = logging.getLogger(__name__)
 

	
 

	
 
def is_git(environ):
 
    """Returns True if request's target is git server.
 
    ``HTTP_USER_AGENT`` would then have git client version given.
 
@@ -138,26 +139,26 @@ class SimpleGit(object):
 
                if anonymous_perm is not True:
 
                    log.debug('Not enough credentials to access this '
 
                              'repository as anonymous user')
 
                if anonymous_user.active is False:
 
                    log.debug('Anonymous access is disabled, running '
 
                              'authentication')
 
                #==============================================================
 
                # DEFAULT PERM FAILED OR ANONYMOUS ACCESS IS DISABLED SO WE
 
                # NEED TO AUTHENTICATE AND ASK FOR AUTH USER PERMISSIONS
 
                #==============================================================
 

	
 
                if not REMOTE_USER(environ):
 
                    self.authenticate.realm = self.config['rhodecode_realm'].\
 
                        encode('utf8', 'replace')
 
                    self.authenticate.realm = \
 
                        safe_str(self.config['rhodecode_realm'])
 
                    result = self.authenticate(environ)
 
                    if isinstance(result, str):
 
                        AUTH_TYPE.update(environ, 'basic')
 
                        REMOTE_USER.update(environ, result)
 
                    else:
 
                        return result.wsgi_application(environ, start_response)
 

	
 
                #==============================================================
 
                # CHECK PERMISSIONS FOR THIS REQUEST USING GIVEN USERNAME FROM
 
                # BASIC AUTH
 
                #==============================================================
 

	
rhodecode/lib/middleware/simplehg.py
Show inline comments
 
@@ -26,24 +26,25 @@
 

	
 
import os
 
import logging
 
import traceback
 

	
 
from mercurial.error import RepoError
 
from mercurial.hgweb import hgweb
 
from mercurial.hgweb.request import wsgiapplication
 

	
 
from paste.auth.basic import AuthBasicAuthenticator
 
from paste.httpheaders import REMOTE_USER, AUTH_TYPE
 

	
 
from rhodecode.lib import safe_str
 
from rhodecode.lib.auth import authfunc, HasPermissionAnyMiddleware
 
from rhodecode.lib.utils import make_ui, invalidate_cache, \
 
    check_repo_fast, ui_sections
 
from rhodecode.model.user import UserModel
 

	
 
from webob.exc import HTTPNotFound, HTTPForbidden, HTTPInternalServerError
 

	
 
log = logging.getLogger(__name__)
 

	
 

	
 
def is_mercurial(environ):
 
    """Returns True if request's target is mercurial server - header
 
@@ -103,26 +104,26 @@ class SimpleHg(object):
 
                if anonymous_perm is not True:
 
                    log.debug('Not enough credentials to access this '
 
                              'repository as anonymous user')
 
                if anonymous_user.active is False:
 
                    log.debug('Anonymous access is disabled, running '
 
                              'authentication')
 
                #==============================================================
 
                # DEFAULT PERM FAILED OR ANONYMOUS ACCESS IS DISABLED SO WE
 
                # NEED TO AUTHENTICATE AND ASK FOR AUTH USER PERMISSIONS
 
                #==============================================================
 

	
 
                if not REMOTE_USER(environ):
 
                    self.authenticate.realm = self.config['rhodecode_realm'].\
 
                        encode('utf8', 'replace')
 
                    self.authenticate.realm = \
 
                        safe_str(self.config['rhodecode_realm'])
 
                    result = self.authenticate(environ)
 
                    if isinstance(result, str):
 
                        AUTH_TYPE.update(environ, 'basic')
 
                        REMOTE_USER.update(environ, result)
 
                    else:
 
                        return result.wsgi_application(environ, start_response)
 

	
 
                #==============================================================
 
                # CHECK PERMISSIONS FOR THIS REQUEST USING GIVEN USERNAME FROM
 
                # BASIC AUTH
 
                #==============================================================
 

	
rhodecode/lib/utils.py
Show inline comments
 
@@ -449,36 +449,40 @@ def get_current_revision():
 
        repo = get_repo(path=repopath, alias=scm)
 
        tip = repo.get_changeset()
 
        return (tip.revision, tip.short_id)
 
    except (ImportError, RepositoryError, VCSError), err:
 
        logging.debug("Cannot retrieve rhodecode's revision. Original error "
 
                      "was: %s" % err)
 
        return None
 

	
 

	
 
#==============================================================================
 
# TEST FUNCTIONS AND CREATORS
 
#==============================================================================
 
def create_test_index(repo_location, full_index):
 
    """Makes default test index
 
    :param repo_location:
 
def create_test_index(repo_location, config, full_index):
 
    """
 
    Makes default test index
 
    
 
    :param config: test config
 
    :param full_index:
 
    """
 

	
 
    from rhodecode.lib.indexers.daemon import WhooshIndexingDaemon
 
    from rhodecode.lib.pidlock import DaemonLock, LockHeld
 
    import shutil
 

	
 
    repo_location = repo_location
 

	
 
    index_location = os.path.join(repo_location, 'index')
 
    if os.path.exists(index_location):
 
        shutil.rmtree(index_location)
 
    index_location = os.path.join(config['app_conf']['index_dir'], 'index')
 
    if not os.path.exists(index_location):
 
        os.makedirs(index_location)
 

	
 
    try:
 
        l = DaemonLock(file=jn(dn(index_location), 'make_index.lock'))
 
        WhooshIndexingDaemon(index_location=index_location,
 
                             repo_location=repo_location)\
 
            .run(full_index=full_index)
 
        l.release()
 
    except LockHeld:
 
        pass
 

	
 

	
 
def create_test_env(repos_test_path, config):
rhodecode/model/db.py
Show inline comments
 
@@ -33,25 +33,25 @@ from sqlalchemy import *
 
from sqlalchemy.exc import DatabaseError
 
from sqlalchemy.orm import relationship, backref, joinedload, class_mapper
 
from sqlalchemy.orm.interfaces import MapperExtension
 

	
 
from beaker.cache import cache_region, region_invalidate
 

	
 
from vcs import get_backend
 
from vcs.utils.helpers import get_scm
 
from vcs.exceptions import RepositoryError, VCSError
 
from vcs.utils.lazy import LazyProperty
 
from vcs.nodes import FileNode
 

	
 
from rhodecode.lib import str2bool, json
 
from rhodecode.lib import str2bool, json, safe_str
 
from rhodecode.model.meta import Base, Session
 
from rhodecode.model.caching_query import FromCache
 

	
 
log = logging.getLogger(__name__)
 

	
 
#==============================================================================
 
# BASE CLASSES
 
#==============================================================================
 

	
 
class ModelSerializer(json.JSONEncoder):
 
    """
 
    Simple Serializer for JSON,
 
@@ -470,43 +470,48 @@ class Repository(Base, BaseModel):
 
        @cache_region('long_term')
 
        def _c(repo_name):
 
            return self.__get_instance()
 

	
 
        inv = self.invalidate
 
        if inv:
 
            region_invalidate(_c, None, self.repo_name)
 
            #update our cache
 
            inv.cache_key.cache_active = True
 
            Session.add(inv)
 
            Session.commit()
 

	
 
        return _c(self.repo_name)
 
        # TODO: remove this trick when beaker 1.6 is released
 
        # and have fixed this issue
 
        rn = safe_str(self.repo_name)
 

	
 
        return _c(rn)
 

	
 
    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', alias)
 
            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
 

	
 
        if alias == 'hg':
 
            repo = backend(repo_full_path, create=False,
 

	
 
            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)
 

	
 
        return repo
 

	
 

	
 
class Group(Base, BaseModel):
 
    __tablename__ = 'groups'
rhodecode/model/repo.py
Show inline comments
 
@@ -24,24 +24,26 @@
 
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
import os
 
import shutil
 
import logging
 
import traceback
 
from datetime import datetime
 

	
 
from sqlalchemy.orm import joinedload, make_transient
 

	
 
from vcs.utils.lazy import LazyProperty
 
from vcs.backends import get_backend
 

	
 
from rhodecode.lib import safe_str
 

	
 
from rhodecode.model import BaseModel
 
from rhodecode.model.caching_query import FromCache
 
from rhodecode.model.db import Repository, RepoToPerm, User, Permission, \
 
    Statistics, UsersGroup, UsersGroupRepoToPerm, RhodeCodeUi, Group
 
from rhodecode.model.user import UserModel
 

	
 
log = logging.getLogger(__name__)
 

	
 

	
 
class RepoModel(BaseModel):
 

	
 
    @LazyProperty
 
@@ -162,31 +164,30 @@ class RepoModel(BaseModel):
 
                                   new=form_data['repo_name_full'])
 

	
 
            self.sa.commit()
 
        except:
 
            log.error(traceback.format_exc())
 
            self.sa.rollback()
 
            raise
 

	
 
    def create(self, form_data, cur_user, just_db=False, fork=False):
 

	
 
        try:
 
            if fork:
 
                #force str since hg doesn't go with unicode
 
                repo_name = str(form_data['fork_name'])
 
                org_name = str(form_data['repo_name'])
 
                org_full_name = org_name#str(form_data['fork_name_full'])
 
                repo_name = form_data['fork_name']
 
                org_name = form_data['repo_name']
 
                org_full_name = org_name
 

	
 
            else:
 
                org_name = repo_name = str(form_data['repo_name'])
 
                org_name = repo_name = form_data['repo_name']
 
                repo_name_full = form_data['repo_name_full']
 

	
 
            new_repo = Repository()
 
            new_repo.enable_statistics = False
 
            for k, v in form_data.items():
 
                if k == 'repo_name':
 
                    if fork:
 
                        v = repo_name
 
                    else:
 
                        v = repo_name_full
 
                if k == 'repo_group':
 
                    k = 'group_id'
 
@@ -293,39 +294,41 @@ class RepoModel(BaseModel):
 
        """
 
        makes repository on filesystem. It's group aware means it'll create
 
        a repository within a group, and alter the paths accordingly of
 
        group location
 

	
 
        :param repo_name:
 
        :param alias:
 
        :param parent_id:
 
        :param clone_uri:
 
        """
 
        from rhodecode.lib.utils import check_repo
 

	
 

	
 
        if new_parent_id:
 
            paths = Group.get(new_parent_id).full_path.split(Group.url_sep())
 
            new_parent_path = os.sep.join(paths)
 
        else:
 
            new_parent_path = ''
 

	
 
        repo_path = os.path.join(self.repos_path, new_parent_path, repo_name)
 
        repo_path = os.path.join(*map(lambda x:safe_str(x),
 
                                [self.repos_path, new_parent_path, repo_name]))
 

	
 
        if check_repo(repo_name, self.repos_path):
 
        if check_repo(repo_path, self.repos_path):
 
            log.info('creating repo %s in %s @ %s', repo_name, repo_path,
 
                    clone_uri)
 
            backend = get_backend(alias)
 

	
 
            backend(repo_path, create=True, src_url=clone_uri)
 

	
 

	
 
    def __rename_repo(self, old, new):
 
        """
 
        renames repository on filesystem
 

	
 
        :param old: old name
 
        :param new: new name
 
        """
 
        log.info('renaming repo from %s to %s', old, new)
 

	
 
        old_path = os.path.join(self.repos_path, old)
 
        new_path = os.path.join(self.repos_path, new)
 
        if os.path.isdir(new_path):
rhodecode/model/scm.py
Show inline comments
 
@@ -18,48 +18,42 @@
 
# This program is distributed in the hope that it will be useful,
 
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
# GNU General Public License for more details.
 
#
 
# You should have received a copy of the GNU General Public License
 
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
import os
 
import time
 
import traceback
 
import logging
 

	
 
from mercurial import ui
 

	
 
from sqlalchemy.exc import DatabaseError
 
from sqlalchemy.orm import make_transient
 

	
 
from beaker.cache import cache_region, region_invalidate
 

	
 
from vcs import get_backend
 
from vcs.utils.helpers import get_scm
 
from vcs.exceptions import RepositoryError, VCSError
 
from vcs.utils.lazy import LazyProperty
 
from vcs.nodes import FileNode
 

	
 
from rhodecode import BACKENDS
 
from rhodecode.lib import helpers as h
 
from rhodecode.lib import safe_str
 
from rhodecode.lib.auth import HasRepoPermissionAny
 
from rhodecode.lib.utils import get_repos as get_filesystem_repos, make_ui, \
 
    action_logger
 
from rhodecode.model import BaseModel
 
from rhodecode.model.user import UserModel
 
from rhodecode.model.repo import RepoModel
 
from rhodecode.model.db import Repository, RhodeCodeUi, CacheInvalidation, \
 
    UserFollowing, UserLog
 
from rhodecode.model.caching_query import FromCache
 

	
 
log = logging.getLogger(__name__)
 

	
 

	
 
class UserTemp(object):
 
    def __init__(self, user_id):
 
        self.user_id = user_id
 

	
 
    def __repr__(self):
 
        return "<%s('id:%s')>" % (self.__class__.__name__, self.user_id)
 

	
 

	
 
@@ -173,25 +167,28 @@ class ScmModel(BaseModel):
 
        repos_list = {}
 

	
 
        for name, path in get_filesystem_repos(repos_path, recursive=True):
 
            try:
 
                if name in repos_list:
 
                    raise RepositoryError('Duplicate repository name %s '
 
                                    'found in %s' % (name, path))
 
                else:
 

	
 
                    klass = get_backend(path[0])
 

	
 
                    if path[0] == 'hg' and path[0] in BACKENDS.keys():
 
                        repos_list[name] = klass(path[1], baseui=baseui)
 

	
 
                        # for mercurial we need to have an str path
 
                        repos_list[name] = klass(safe_str(path[1]),
 
                                                 baseui=baseui)
 

	
 
                    if path[0] == 'git' and path[0] in BACKENDS.keys():
 
                        repos_list[name] = klass(path[1])
 
            except OSError:
 
                continue
 

	
 
        return repos_list
 

	
 
    def get_repos(self, all_repos=None, sort_key=None):
 
        """
 
        Get all repos from db and for each repo create it's
 
        backend instance and fill that backed with information from database
 
@@ -355,28 +352,28 @@ class ScmModel(BaseModel):
 

	
 

	
 
    def commit_change(self, repo, repo_name, cs, user, author, message, content,
 
                      f_path):
 

	
 
        if repo.alias == 'hg':
 
            from vcs.backends.hg import MercurialInMemoryChangeset as IMC
 
        elif repo.alias == 'git':
 
            from vcs.backends.git import GitInMemoryChangeset as IMC
 

	
 
        # decoding here will force that we have proper encoded values
 
        # in any other case this will throw exceptions and deny commit
 
        content = content.encode('utf8')
 
        message = message.encode('utf8')
 
        path = f_path.encode('utf8')
 
        author = author.encode('utf8')
 
        content = safe_str(content)
 
        message = safe_str(message)
 
        path = safe_str(f_path)
 
        author = safe_str(author)
 
        m = IMC(repo)
 
        m.change(FileNode(path, content))
 
        tip = m.commit(message=message,
 
                 author=author,
 
                 parents=[cs], branch=cs.branch)
 

	
 
        new_cs = tip.short_id
 
        action = 'push_local:%s' % new_cs
 

	
 
        action_logger(user, action, repo_name)
 

	
 
        self.mark_for_invalidation(repo_name)
rhodecode/tests/functional/test_search.py
Show inline comments
 
from rhodecode.tests import *
 
import os
 
from nose.plugins.skip import SkipTest
 

	
 
class TestSearchController(TestController):
 

	
 
    def test_index(self):
 
        self.log_user()
 
        response = self.app.get(url(controller='search', action='index'))
 
        print response.body
 
        assert 'class="small" id="q" name="q" type="text"' in response.body, 'Search box content error'
 

	
 
        self.assertTrue('class="small" id="q" name="q" type="text"' in
 
                        response.body)
 
        # Test response...
 

	
 
    def test_empty_search(self):
 
        if os.path.isdir(self.index_location):
 
            raise SkipTest('skipped due to existing index')
 
        else:
 
            self.log_user()
 
            response = self.app.get(url(controller='search', action='index'), {'q':HG_REPO})
 
            assert 'There is no index to search in. Please run whoosh indexer' in response.body, 'No error message about empty index'
 
            response = self.app.get(url(controller='search', action='index'),
 
                                    {'q':HG_REPO})
 
            self.assertTrue('There is no index to search in. '
 
                            'Please run whoosh indexer' in response.body)
 

	
 
    def test_normal_search(self):
 
        self.log_user()
 
        response = self.app.get(url(controller='search', action='index'), {'q':'def repo'})
 
        print response.body
 
        assert '10 results' in response.body, 'no message about proper search results'
 
        assert 'Permission denied' not in response.body, 'Wrong permissions settings for that repo and user'
 

	
 
        response = self.app.get(url(controller='search', action='index'),
 
                                {'q':'def repo'})
 
        self.assertTrue('10 results' in response.body)
 
        self.assertTrue('Permission denied' not in response.body)
 

	
 
    def test_repo_search(self):
 
        self.log_user()
 
        response = self.app.get(url(controller='search', action='index'), {'q':'repository:%s def test' % HG_REPO})
 
        print response.body
 
        assert '4 results' in response.body, 'no message about proper search results'
 
        assert 'Permission denied' not in response.body, 'Wrong permissions settings for that repo and user'
 
        response = self.app.get(url(controller='search', action='index'),
 
                                {'q':'repository:%s def test' % HG_REPO})
 
        self.assertTrue('4 results' in response.body)
 
        self.assertTrue('Permission denied' not in response.body)
0 comments (0 inline, 0 general)