コード例 #1
0
def error_handler(exception, request):
    # TODO: dan: replace the old pylons error controller with this
    from rhodecode.model.settings import SettingsModel
    from rhodecode.lib.utils2 import AttributeDict

    try:
        rc_config = SettingsModel().get_all_settings()
    except Exception:
        log.exception('failed to fetch settings')
        rc_config = {}

    base_response = HTTPInternalServerError()
    # prefer original exception for the response since it may have headers set
    if isinstance(exception, HTTPError):
        base_response = exception

    c = AttributeDict()
    c.error_message = base_response.status
    c.error_explanation = base_response.explanation or str(base_response)
    c.visual = AttributeDict()

    c.visual.rhodecode_support_url = (
        request.registry.settings.get('rhodecode_support_url')
        or request.route_url('rhodecode_support'))
    c.redirect_time = 0
    c.rhodecode_name = rc_config.get('rhodecode_title', '')
    if not c.rhodecode_name:
        c.rhodecode_name = 'Rhodecode'

    response = render_to_response('/errors/error_document.html', {'c': c},
                                  request=request,
                                  response=base_response)

    return response
コード例 #2
0
    def get_commits(self, commit_ids):
        commits = []
        if not filter(lambda v: v != '', commit_ids):
            return commits

        repo = None
        if self.parse_commits:
            repo = self.user_log.repository.scm_instance()

        for commit_id in commit_ids[:self.commits_top_limit]:
            _op, _name = _get_op(commit_id)

            # we want parsed commits, or new log store format is bad
            if self.parse_commits:
                try:
                    commit = repo.get_commit(commit_id=commit_id)
                    commits.append(commit)
                except CommitDoesNotExistError:
                    log.error(
                        'cannot find commit id %s in this repository',
                        commit_id)
                    commits.append(commit_id)
                    continue
            else:
                fake_commit = AttributeDict({
                    'short_id': commit_id[:12],
                    'raw_id': commit_id,
                    'message': '',
                    'op': _op,
                    'ref_name': _name
                })
                commits.append(fake_commit)

        return commits
コード例 #3
0
    def settings_issuetracker(self):
        """GET /admin/settings/issue-tracker: All items in the collection"""
        # url('admin_settings_issuetracker')
        c.active = 'issuetracker'
        defaults = SettingsModel().get_all_settings()

        entry_key = 'rhodecode_issuetracker_pat_'

        c.issuetracker_entries = {}
        for k, v in defaults.items():
            if k.startswith(entry_key):
                uid = k[len(entry_key):]
                c.issuetracker_entries[uid] = None

        for uid in c.issuetracker_entries:
            c.issuetracker_entries[uid] = AttributeDict({
                'pat':
                defaults.get('rhodecode_issuetracker_pat_' + uid),
                'url':
                defaults.get('rhodecode_issuetracker_url_' + uid),
                'pref':
                defaults.get('rhodecode_issuetracker_pref_' + uid),
                'desc':
                defaults.get('rhodecode_issuetracker_desc_' + uid),
            })

        return render('admin/settings/settings.html')
コード例 #4
0
    def __before__(self):
        """
        __before__ is called before controller methods and after __call__
        """
        c.rhodecode_version = __version__
        c.rhodecode_instanceid = config.get('instance_id')
        c.rhodecode_name = config.get('rhodecode_title')
        c.rhodecode_bugtracker = config.get('bugtracker', 'http://bitbucket.org/marcinkuzminski/rhodecode/issues')
        c.use_gravatar = str2bool(config.get('use_gravatar'))
        c.ga_code = config.get('rhodecode_ga_code')
        # Visual options
        c.visual = AttributeDict({})
        rc_config = RhodeCodeSetting.get_app_settings()
        ## DB stored
        c.visual.show_public_icon = str2bool(rc_config.get('rhodecode_show_public_icon'))
        c.visual.show_private_icon = str2bool(rc_config.get('rhodecode_show_private_icon'))
        c.visual.stylify_metatags = str2bool(rc_config.get('rhodecode_stylify_metatags'))
        c.visual.dashboard_items = safe_int(rc_config.get('rhodecode_dashboard_items', 100))
        c.visual.repository_fields = str2bool(rc_config.get('rhodecode_repository_fields'))
        c.visual.show_version = str2bool(rc_config.get('rhodecode_show_version'))

        ## INI stored
        self.cut_off_limit = int(config.get('cut_off_limit'))
        c.visual.allow_repo_location_change = str2bool(config.get('allow_repo_location_change', True))
        c.visual.allow_custom_hooks_settings = str2bool(config.get('allow_custom_hooks_settings', True))

        c.repo_name = get_repo_slug(request)  # can be empty
        c.backends = BACKENDS.keys()
        c.unread_notifications = NotificationModel()\
                        .get_unread_cnt_for_user(c.rhodecode_user.user_id)
        self.sa = meta.Session
        self.scm_model = ScmModel(self.sa)
コード例 #5
0
    def update(self, gist, description, owner, gist_mapping, gist_type,
               lifetime, gist_acl_level):
        gist = self._get_gist(gist)
        gist_repo = gist.scm_instance()

        lifetime = safe_int(lifetime, -1)
        if lifetime == 0:  # preserve old value
            gist_expires = gist.gist_expires
        else:
            gist_expires = (
                time.time() + (lifetime * 60) if lifetime != -1 else -1)

        # calculate operation type based on given data
        gist_mapping_op = {}
        for k, v in gist_mapping.items():
            # add, mod, del
            if not v['org_filename'] and v['filename']:
                op = 'add'
            elif v['org_filename'] and not v['filename']:
                op = 'del'
            else:
                op = 'mod'

            v['op'] = op
            gist_mapping_op[k] = v

        gist.gist_description = description
        gist.gist_expires = gist_expires
        gist.owner = owner
        gist.gist_type = gist_type
        gist.acl_level = gist_acl_level
        self.sa.add(gist)
        self.sa.flush()

        message = 'updated file'
        message += 's: ' if len(gist_mapping) > 1 else ': '
        message += ', '.join([x for x in gist_mapping])

        # fake RhodeCode Repository object
        fake_repo = AttributeDict({
            'repo_name': gist_repo.path,
            'scm_instance': lambda *args, **kwargs: gist_repo,
        })

        self._store_metadata(gist_repo, gist.gist_id, gist.gist_access_id,
                             owner.user_id, owner.username, gist.gist_type,
                             gist.gist_expires, gist_acl_level)

        # this can throw NodeNotChangedError, if changes we're trying to commit
        # are not actually changes...
        ScmModel().update_nodes(
            user=owner.user_id,
            repo=fake_repo,
            message=message,
            nodes=gist_mapping_op,
            trigger_push_hook=False
        )

        return gist
コード例 #6
0
def test_get_visual_attr(pylonsapp):
    c = ContextObj()
    assert None is helpers.get_visual_attr(c, 'fakse')

    # emulate the c.visual behaviour
    c.visual = AttributeDict({})
    assert None is helpers.get_visual_attr(c, 'some_var')

    c.visual.some_var = 'foobar'
    assert 'foobar' == helpers.get_visual_attr(c, 'some_var')
コード例 #7
0
    def _call_hook(self, hook, extras):
        extras = AttributeDict(extras)

        try:
            result = hook(extras)
        except Exception as error:
            log.exception('Exception when handling hook %s', hook)
            error_args = error.args
            return {
                'status': 128,
                'output': '',
                'exception': type(error).__name__,
                'exception_args': error_args,
            }
        return {
            'status': result.status,
            'output': result.output,
        }
コード例 #8
0
    def _rss_feed(self, repos, public=True):
        journal = self._get_journal_data(repos)
        if public:
            _link = url('public_journal_atom', qualified=True)
            _desc = '%s %s %s' % (c.rhodecode_name, _('public journal'),
                                  'rss feed')
        else:
            _link = url('journal_atom', qualified=True)
            _desc = '%s %s %s' % (c.rhodecode_name, _('journal'), 'rss feed')

        feed = Rss201rev2Feed(title=_desc,
                              link=_link,
                              description=_desc,
                              language=self.language,
                              ttl=self.ttl)

        for entry in journal[:self.feed_nr]:
            user = entry.user
            if user is None:
                #fix deleted users
                user = AttributeDict({
                    'short_contact': entry.username,
                    'email': '',
                    'full_contact': ''
                })
            action, action_extra, ico = h.action_parser(entry, feed=True)
            title = "%s - %s %s" % (user.short_contact, action(),
                                    entry.repository.repo_name)
            desc = action_extra()
            _url = None
            if entry.repository is not None:
                _url = url('changelog_home',
                           repo_name=entry.repository.repo_name,
                           qualified=True)

            feed.add_item(title=title,
                          pubdate=entry.action_date,
                          link=_url or url('', qualified=True),
                          author_email=user.email,
                          author_name=user.full_contact,
                          description=desc)

        response.content_type = feed.mime_type
        return feed.writeString('utf-8')
コード例 #9
0
    def _make_dict_for_settings(self, qs):
        prefix_match = self._get_keyname('pat', '', 'rhodecode_')

        issuetracker_entries = {}
        # create keys
        for k, v in qs.items():
            if k.startswith(prefix_match):
                uid = k[len(prefix_match):]
                issuetracker_entries[uid] = None

        # populate
        for uid in issuetracker_entries:
            issuetracker_entries[uid] = AttributeDict({
                'pat': qs.get(self._get_keyname('pat', uid, 'rhodecode_')),
                'url': qs.get(self._get_keyname('url', uid, 'rhodecode_')),
                'pref': qs.get(self._get_keyname('pref', uid, 'rhodecode_')),
                'desc': qs.get(self._get_keyname('desc', uid, 'rhodecode_')),
            })
        return issuetracker_entries
コード例 #10
0
    def create_registration(self, form_data):
        from rhodecode.model.notification import NotificationModel
        from rhodecode.model.notification import EmailNotificationModel

        try:
            form_data['admin'] = False
            form_data['extern_name'] = 'rhodecode'
            form_data['extern_type'] = 'rhodecode'
            new_user = self.create(form_data)

            self.sa.add(new_user)
            self.sa.flush()

            user_data = new_user.get_dict()
            kwargs = {
                # use SQLALCHEMY safe dump of user data
                'user': AttributeDict(user_data),
                'date': datetime.datetime.now()
            }
            notification_type = EmailNotificationModel.TYPE_REGISTRATION
            # pre-generate the subject for notification itself
            (subject,
             _h, _e,  # we don't care about those
             body_plaintext) = EmailNotificationModel().render_email(
                notification_type, **kwargs)

            # create notification objects, and emails
            NotificationModel().create(
                created_by=new_user,
                notification_subject=subject,
                notification_body=body_plaintext,
                notification_type=notification_type,
                recipients=None,  # all admins
                email_kwargs=kwargs,
            )

            return new_user
        except Exception:
            log.error(traceback.format_exc())
            raise
コード例 #11
0
def attach_context_attributes(context):
    rc_config = SettingsModel().get_all_settings(cache=True)

    context.rhodecode_version = rhodecode.__version__
    context.rhodecode_edition = config.get('rhodecode.edition')
    # unique secret + version does not leak the version but keep consistency
    context.rhodecode_version_hash = md5(
        config.get('beaker.session.secret', '') +
        rhodecode.__version__)[:8]

    # Default language set for the incoming request
    context.language = translation.get_lang()[0]

    # Visual options
    context.visual = AttributeDict({})

    # DB store
    context.visual.show_public_icon = str2bool(
        rc_config.get('rhodecode_show_public_icon'))
    context.visual.show_private_icon = str2bool(
        rc_config.get('rhodecode_show_private_icon'))
    context.visual.stylify_metatags = str2bool(
        rc_config.get('rhodecode_stylify_metatags'))
    context.visual.dashboard_items = safe_int(
        rc_config.get('rhodecode_dashboard_items', 100))
    context.visual.admin_grid_items = safe_int(
        rc_config.get('rhodecode_admin_grid_items', 100))
    context.visual.repository_fields = str2bool(
        rc_config.get('rhodecode_repository_fields'))
    context.visual.show_version = str2bool(
        rc_config.get('rhodecode_show_version'))
    context.visual.use_gravatar = str2bool(
        rc_config.get('rhodecode_use_gravatar'))
    context.visual.gravatar_url = rc_config.get('rhodecode_gravatar_url')
    context.visual.default_renderer = rc_config.get(
        'rhodecode_markup_renderer', 'rst')
    context.visual.rhodecode_support_url = \
        rc_config.get('rhodecode_support_url') or url('rhodecode_support')

    context.pre_code = rc_config.get('rhodecode_pre_code')
    context.post_code = rc_config.get('rhodecode_post_code')
    context.rhodecode_name = rc_config.get('rhodecode_title')
    context.default_encodings = aslist(config.get('default_encoding'), sep=',')
    # if we have specified default_encoding in the request, it has more
    # priority
    if request.GET.get('default_encoding'):
        context.default_encodings.insert(0, request.GET.get('default_encoding'))
    context.clone_uri_tmpl = rc_config.get('rhodecode_clone_uri_tmpl')

    # INI stored
    context.labs_active = str2bool(
        config.get('labs_settings_active', 'false'))
    context.visual.allow_repo_location_change = str2bool(
        config.get('allow_repo_location_change', True))
    context.visual.allow_custom_hooks_settings = str2bool(
        config.get('allow_custom_hooks_settings', True))
    context.debug_style = str2bool(config.get('debug_style', False))

    context.rhodecode_instanceid = config.get('instance_id')

    # AppEnlight
    context.appenlight_enabled = str2bool(config.get('appenlight', 'false'))
    context.appenlight_api_public_key = config.get(
        'appenlight.api_public_key', '')
    context.appenlight_server_url = config.get('appenlight.server_url', '')

    # END CONFIG VARS

    # TODO: This dosn't work when called from pylons compatibility tween.
    # Fix this and remove it from base controller.
    # context.repo_name = get_repo_slug(request)  # can be empty

    context.csrf_token = auth.get_csrf_token()
    context.backends = rhodecode.BACKENDS.keys()
    context.backends.sort()
    context.unread_notifications = NotificationModel().get_unread_cnt_for_user(
        context.rhodecode_user.user_id)
コード例 #12
0
    def create(self, description, owner, gist_mapping,
               gist_type=Gist.GIST_PUBLIC, lifetime=-1):
        """

        :param description: description of the gist
        :param owner: user who created this gist
        :param gist_mapping: mapping {filename:{'content':content},...}
        :param gist_type: type of gist private/public
        :param lifetime: in minutes, -1 == forever
        """
        gist_id = safe_unicode(unique_id(20))
        lifetime = safe_int(lifetime, -1)
        gist_expires = time.time() + (lifetime * 60) if lifetime != -1 else -1
        log.debug('set GIST expiration date to: %s'
                  % (time_to_datetime(gist_expires)
                   if gist_expires != -1 else 'forever'))
        #create the Database version
        gist = Gist()
        gist.gist_description = description
        gist.gist_access_id = gist_id
        gist.gist_owner = owner.user_id
        gist.gist_expires = gist_expires
        gist.gist_type = safe_unicode(gist_type)
        self.sa.add(gist)
        self.sa.flush()
        if gist_type == Gist.GIST_PUBLIC:
            # use DB ID for easy to use GIST ID
            gist_id = safe_unicode(gist.gist_id)
            gist.gist_access_id = gist_id
            self.sa.add(gist)

        gist_repo_path = os.path.join(GIST_STORE_LOC, gist_id)
        log.debug('Creating new %s GIST repo in %s' % (gist_type, gist_repo_path))
        repo = RepoModel()._create_repo(repo_name=gist_repo_path, alias='hg',
                                        parent=None)

        processed_mapping = {}
        for filename in gist_mapping:
            if filename != os.path.basename(filename):
                raise Exception('Filename cannot be inside a directory')

            content = gist_mapping[filename]['content']
            #TODO: expand support for setting explicit lexers
#             if lexer is None:
#                 try:
#                     lexer = pygments.lexers.guess_lexer_for_filename(filename,content)
#                 except pygments.util.ClassNotFound:
#                     lexer = 'text'
            processed_mapping[filename] = {'content': content}

        # now create single multifile commit
        message = 'added file'
        message += 's: ' if len(processed_mapping) > 1 else ': '
        message += ', '.join([x for x in processed_mapping])

        #fake RhodeCode Repository object
        fake_repo = AttributeDict(dict(
            repo_name=gist_repo_path,
            scm_instance_no_cache=lambda: repo,
        ))
        ScmModel().create_nodes(
            user=owner.user_id, repo=fake_repo,
            message=message,
            nodes=processed_mapping,
            trigger_push_hook=False
        )
        # store metadata inside the gist, this can be later used for imports
        # or gist identification
        metadata = {
            'gist_db_id': gist.gist_id,
            'gist_access_id': gist.gist_access_id,
            'gist_owner_id': owner.user_id,
            'gist_type': gist.gist_type,
            'gist_exipres': gist.gist_expires
        }
        with open(os.path.join(repo.path, '.hg', GIST_METADATA_FILE), 'wb') as f:
            f.write(json.dumps(metadata))
        return gist
コード例 #13
0
    def get_cs_links():
        revs_limit = 3  # display this amount always
        revs_top_limit = 50  # show upto this amount of changesets hidden
        revs_ids = action_params.split(',')
        deleted = user_log.repository is None
        if deleted:
            return ','.join(revs_ids)

        repo_name = user_log.repository.repo_name

        def lnk(rev, repo_name):
            if isinstance(rev, BaseChangeset) or isinstance(
                    rev, AttributeDict):
                lazy_cs = True
                if getattr(rev, 'op', None) and getattr(rev, 'ref_name', None):
                    lazy_cs = False
                    lbl = '?'
                    if rev.op == 'delete_branch':
                        lbl = '%s' % _('Deleted branch: %s') % rev.ref_name
                        title = ''
                    elif rev.op == 'tag':
                        lbl = '%s' % _('Created tag: %s') % rev.ref_name
                        title = ''
                    _url = '#'

                else:
                    lbl = '%s' % (rev.short_id[:8])
                    _url = url('changeset_home',
                               repo_name=repo_name,
                               revision=rev.raw_id)
                    title = tooltip(rev.message)
            else:
                ## changeset cannot be found/striped/removed etc.
                lbl = ('%s' % rev)[:12]
                _url = '#'
                title = _('Changeset not found')
            if parse_cs:
                return link_to(lbl, _url, title=title, class_='tooltip')
            return link_to(lbl,
                           _url,
                           raw_id=rev.raw_id,
                           repo_name=repo_name,
                           class_='lazy-cs' if lazy_cs else '')

        def _get_op(rev_txt):
            _op = None
            _name = rev_txt
            if len(rev_txt.split('=>')) == 2:
                _op, _name = rev_txt.split('=>')
            return _op, _name

        revs = []
        if len(filter(lambda v: v != '', revs_ids)) > 0:
            repo = None
            for rev in revs_ids[:revs_top_limit]:
                _op, _name = _get_op(rev)

                # we want parsed changesets, or new log store format is bad
                if parse_cs:
                    try:
                        if repo is None:
                            repo = user_log.repository.scm_instance
                        _rev = repo.get_changeset(rev)
                        revs.append(_rev)
                    except ChangesetDoesNotExistError:
                        log.error('cannot find revision %s in this repo' % rev)
                        revs.append(rev)
                        continue
                else:
                    _rev = AttributeDict({
                        'short_id': rev[:12],
                        'raw_id': rev,
                        'message': '',
                        'op': _op,
                        'ref_name': _name
                    })
                    revs.append(_rev)
        cs_links = [
            " " + ', '.join([lnk(rev, repo_name) for rev in revs[:revs_limit]])
        ]
        _op1, _name1 = _get_op(revs_ids[0])
        _op2, _name2 = _get_op(revs_ids[-1])

        _rev = '%s...%s' % (_name1, _name2)

        compare_view = (
            ' <div class="compare_view tooltip" title="%s">'
            '<a href="%s">%s</a> </div>' %
            (_('Show all combined changesets %s->%s') %
             (revs_ids[0][:12], revs_ids[-1][:12]),
             url('changeset_home', repo_name=repo_name,
                 revision=_rev), _('compare view')))

        # if we have exactly one more than normally displayed
        # just display it, takes less space than displaying
        # "and 1 more revisions"
        if len(revs_ids) == revs_limit + 1:
            rev = revs[revs_limit]
            cs_links.append(", " + lnk(rev, repo_name))

        # hidden-by-default ones
        if len(revs_ids) > revs_limit + 1:
            uniq_id = revs_ids[0]
            html_tmpl = ('<span> %s <a class="show_more" id="_%s" '
                         'href="#more">%s</a> %s</span>')
            if not feed:
                cs_links.append(html_tmpl %
                                (_('and'), uniq_id, _('%s more') %
                                 (len(revs_ids) - revs_limit), _('revisions')))

            if not feed:
                html_tmpl = '<span id="%s" style="display:none">, %s </span>'
            else:
                html_tmpl = '<span id="%s"> %s </span>'

            morelinks = ', '.join(
                [lnk(rev, repo_name) for rev in revs[revs_limit:]])

            if len(revs_ids) > revs_top_limit:
                morelinks += ', ...'

            cs_links.append(html_tmpl % (uniq_id, morelinks))
        if len(revs) > 1:
            cs_links.append(compare_view)
        return ''.join(cs_links)
コード例 #14
0
    def create(self, description, owner, gist_mapping,
               gist_type=Gist.GIST_PUBLIC, lifetime=-1, gist_id=None,
               gist_acl_level=Gist.ACL_LEVEL_PRIVATE):
        """
        Create a gist

        :param description: description of the gist
        :param owner: user who created this gist
        :param gist_mapping: mapping {filename:{'content':content},...}
        :param gist_type: type of gist private/public
        :param lifetime: in minutes, -1 == forever
        :param gist_acl_level: acl level for this gist
        """
        owner = self._get_user(owner)
        gist_id = safe_unicode(gist_id or unique_id(20))
        lifetime = safe_int(lifetime, -1)
        gist_expires = time.time() + (lifetime * 60) if lifetime != -1 else -1
        expiration = (time_to_datetime(gist_expires)
                      if gist_expires != -1 else 'forever')
        log.debug('set GIST expiration date to: %s', expiration)
        # create the Database version
        gist = Gist()
        gist.gist_description = description
        gist.gist_access_id = gist_id
        gist.gist_owner = owner.user_id
        gist.gist_expires = gist_expires
        gist.gist_type = safe_unicode(gist_type)
        gist.acl_level = gist_acl_level
        self.sa.add(gist)
        self.sa.flush()
        if gist_type == Gist.GIST_PUBLIC:
            # use DB ID for easy to use GIST ID
            gist_id = safe_unicode(gist.gist_id)
            gist.gist_access_id = gist_id
            self.sa.add(gist)

        gist_repo_path = os.path.join(GIST_STORE_LOC, gist_id)
        log.debug('Creating new %s GIST repo in %s', gist_type, gist_repo_path)
        repo = RepoModel()._create_filesystem_repo(
            repo_name=gist_id, repo_type='hg', repo_group=GIST_STORE_LOC,
            use_global_config=True)

        processed_mapping = {}
        for filename in gist_mapping:
            if filename != os.path.basename(filename):
                raise Exception('Filename cannot be inside a directory')

            content = gist_mapping[filename]['content']
            # TODO: expand support for setting explicit lexers
#             if lexer is None:
#                 try:
#                     guess_lexer = pygments.lexers.guess_lexer_for_filename
#                     lexer = guess_lexer(filename,content)
#                 except pygments.util.ClassNotFound:
#                     lexer = 'text'
            processed_mapping[filename] = {'content': content}

        # now create single multifile commit
        message = 'added file'
        message += 's: ' if len(processed_mapping) > 1 else ': '
        message += ', '.join([x for x in processed_mapping])

        # fake RhodeCode Repository object
        fake_repo = AttributeDict({
            'repo_name': gist_repo_path,
            'scm_instance': lambda *args, **kwargs: repo,
        })

        ScmModel().create_nodes(
            user=owner.user_id, repo=fake_repo,
            message=message,
            nodes=processed_mapping,
            trigger_push_hook=False
        )

        self._store_metadata(repo, gist.gist_id, gist.gist_access_id,
                             owner.user_id, owner.username, gist.gist_type,
                             gist.gist_expires, gist_acl_level)
        return gist