Changeset - 322b53be49cc
[Not reviewed]
beta
0 3 0
Marcin Kuzminski - 15 years ago 2010-12-28 18:17:04
marcin@python-works.com
Fixed url bug when using numeric revision in file browser,
added follow branch checkbox for browsing only changesets from current branch
3 files changed with 49 insertions and 7 deletions:
0 comments (0 inline, 0 general)
rhodecode/controllers/files.py
Show inline comments
 
# -*- coding: utf-8 -*-
 
"""
 
    rhodecode.controllers.files
 
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~
 

	
 
    Files controller for RhodeCode
 
    
 
    :created_on: Apr 21, 2010
 
    :author: marcink
 
    :copyright: (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com>    
 
    :license: GPLv3, see COPYING for more details.
 
"""
 
# This program is free software; you can redistribute it and/or
 
# modify it under the terms of the GNU General Public License
 
# as published by the Free Software Foundation; version 2
 
# of the License or (at your opinion) any later version of the license.
 
# 
 
# 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, write to the Free Software
 
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 
# MA  02110-1301, USA.
 
import tempfile
 
import logging
 
import rhodecode.lib.helpers as h
 

	
 
from mercurial import archival
 

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

	
 
from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
 
from rhodecode.lib.base import BaseController, render
 
from rhodecode.lib.utils import EmptyChangeset
 
from rhodecode.model.scm import ScmModel
 

	
 
from vcs.exceptions import RepositoryError, ChangesetError, ChangesetDoesNotExistError
 
from vcs.nodes import FileNode
 
from vcs.utils import diffs as differ
 

	
 
log = logging.getLogger(__name__)
 

	
 
class FilesController(BaseController):
 

	
 
    @LoginRequired()
 
    @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
 
                                   'repository.admin')
 
    def __before__(self):
 
        super(FilesController, self).__before__()
 
        c.cut_off_limit = self.cut_off_limit
 

	
 
    def index(self, repo_name, revision, f_path):
 
        hg_model = ScmModel()
 
        c.repo = hg_model.get_repo(c.repo_name)
 
        revision = request.POST.get('at_rev', None) or revision
 

	
 
        c.f_path = f_path
 

	
 
        try:
 
            #reditect to given revision from form
 
            post_revision = request.POST.get('at_rev', None)
 
            if post_revision:
 
                post_revision = c.repo.get_changeset(post_revision).raw_id
 
                redirect(url('files_home', repo_name=c.repo_name,
 
                             revision=post_revision, f_path=f_path))
 

	
 
            c.branch = request.GET.get('branch', None)
 

	
 
            c.f_path = f_path
 

	
 
            c.changeset = c.repo.get_changeset(revision)
 
            cur_rev = c.changeset.revision
 

	
 
            #prev link
 
            try:
 
                prev_rev = c.repo.get_changeset(cur_rev).prev().raw_id
 
                prev_rev = c.repo.get_changeset(cur_rev).prev(c.branch).raw_id
 
                c.url_prev = url('files_home', repo_name=c.repo_name,
 
                             revision=prev_rev, f_path=f_path)
 
                if c.branch:
 
                    c.url_prev += '?branch=%s' % c.branch
 
            except ChangesetDoesNotExistError:
 
                c.url_prev = '#'
 

	
 
            #next link
 
            try:
 
                next_rev = c.repo.get_changeset(cur_rev).next().raw_id
 
                next_rev = c.repo.get_changeset(cur_rev).next(c.branch).raw_id
 
                c.url_next = url('files_home', repo_name=c.repo_name,
 
                         revision=next_rev, f_path=f_path)
 
                if c.branch:
 
                    c.url_next += '?branch=%s' % c.branch
 
            except ChangesetDoesNotExistError:
 
                c.url_next = '#'
 

	
 
            #files
 
            try:
 
                c.files_list = c.changeset.get_node(f_path)
 
                c.file_history = self._get_history(c.repo, c.files_list, f_path)
 
            except RepositoryError, e:
 
                h.flash(str(e), category='warning')
 
                redirect(h.url('files_home', repo_name=repo_name, revision=revision))
 

	
 
        except RepositoryError, e:
 
            h.flash(str(e), category='warning')
 
            redirect(h.url('files_home', repo_name=repo_name, revision='tip'))
 

	
 

	
 

	
 
        return render('files/files.html')
 

	
 
    def rawfile(self, repo_name, revision, f_path):
 
        hg_model = ScmModel()
 
        c.repo = hg_model.get_repo(c.repo_name)
 
        file_node = c.repo.get_changeset(revision).get_node(f_path)
 
        response.content_type = file_node.mimetype
 
        response.content_disposition = 'attachment; filename=%s' \
 
                                                    % f_path.split('/')[-1]
 
        return file_node.content
 

	
 
    def raw(self, repo_name, revision, f_path):
 
        hg_model = ScmModel()
 
        c.repo = hg_model.get_repo(c.repo_name)
 
        file_node = c.repo.get_changeset(revision).get_node(f_path)
 
        response.content_type = 'text/plain'
 

	
 
        return file_node.content
 

	
 
    def annotate(self, repo_name, revision, f_path):
 
        hg_model = ScmModel()
 
        c.repo = hg_model.get_repo(c.repo_name)
 

	
 
        try:
 
            c.cs = c.repo.get_changeset(revision)
 
            c.file = c.cs.get_node(f_path)
 
        except RepositoryError, e:
 
            h.flash(str(e), category='warning')
 
            redirect(h.url('files_home', repo_name=repo_name, revision=revision))
 

	
 
        c.file_history = self._get_history(c.repo, c.file, f_path)
 

	
 
        c.f_path = f_path
 

	
 
        return render('files/files_annotate.html')
 

	
 
    def archivefile(self, repo_name, fname):
 
        info = fname.split('.')
 
        revision, fileformat = info[0], '.' + '.'.join(info[1:])
 
        archive_specs = {
 
          '.tar.bz2': ('application/x-tar', 'tbz2'),
 
          '.tar.gz': ('application/x-tar', 'tgz'),
 
          '.zip': ('application/zip', 'zip'),
 
        }
 
        if not archive_specs.has_key(fileformat):
 
            return _('Unknown archive type %s') % fileformat
 

	
 
        repo = ScmModel().get_repo(repo_name)
 

	
 
        try:
 
            repo.get_changeset(revision)
 
        except ChangesetDoesNotExistError:
 
            return _('Unknown revision %s') % revision
 

	
 
        archive = tempfile.TemporaryFile()
 
        localrepo = repo.repo
 
        fname = '%s-%s%s' % (repo_name, revision, fileformat)
 
        archival.archive(localrepo, archive, revision, archive_specs[fileformat][1],
 
                         prefix='%s-%s' % (repo_name, revision))
 
        response.content_type = archive_specs[fileformat][0]
 
        response.content_disposition = 'attachment; filename=%s' % fname
 
        archive.seek(0)
 

	
 
        def read_in_chunks(file_object, chunk_size=1024 * 40):
 
            """Lazy function (generator) to read a file piece by piece.
 
            Default chunk size: 40k."""
 
            while True:
 
                data = file_object.read(chunk_size)
 
                if not data:
 
                    break
 
                yield data
 

	
 
        return read_in_chunks(archive)
 

	
 
    def diff(self, repo_name, f_path):
 
        hg_model = ScmModel()
 
        diff1 = request.GET.get('diff1')
 
        diff2 = request.GET.get('diff2')
 
        c.action = request.GET.get('diff')
 
        c.no_changes = diff1 == diff2
 
        c.f_path = f_path
 
        c.repo = hg_model.get_repo(c.repo_name)
 

	
 
        try:
 
            if diff1 not in ['', None, 'None', '0' * 12, '0' * 40]:
 
                c.changeset_1 = c.repo.get_changeset(diff1)
 
                node1 = c.changeset_1.get_node(f_path)
 
            else:
 
                c.changeset_1 = EmptyChangeset()
 
                node1 = FileNode('.', '', changeset=c.changeset_1)
 

	
 
            if diff2 not in ['', None, 'None', '0' * 12, '0' * 40]:
 
                c.changeset_2 = c.repo.get_changeset(diff2)
 
                node2 = c.changeset_2.get_node(f_path)
 
            else:
 
                c.changeset_2 = EmptyChangeset()
 
                node2 = FileNode('.', '', changeset=c.changeset_2)
 
        except RepositoryError:
 
            return redirect(url('files_home',
 
                                repo_name=c.repo_name, f_path=f_path))
 

	
 
        f_udiff = differ.get_udiff(node1, node2)
 
        diff = differ.DiffProcessor(f_udiff)
 

	
 
        if c.action == 'download':
 
            diff_name = '%s_vs_%s.diff' % (diff1, diff2)
 
            response.content_type = 'text/plain'
 
            response.content_disposition = 'attachment; filename=%s' \
 
                                                    % diff_name
 
            return diff.raw_diff()
 

	
 
        elif c.action == 'raw':
 
            response.content_type = 'text/plain'
 
            return diff.raw_diff()
 

	
 
        elif c.action == 'diff':
 
            if node1.size > self.cut_off_limit or node2.size > self.cut_off_limit:
 
                c.cur_diff = _('Diff is to big to display')
 
            else:
 
                c.cur_diff = diff.as_html()
 
        else:
 
            #default option
 
            if node1.size > self.cut_off_limit or node2.size > self.cut_off_limit:
 
                c.cur_diff = _('Diff is to big to display')
 
            else:
 
                c.cur_diff = diff.as_html()
 

	
 
        if not c.cur_diff: c.no_changes = True
 
        return render('files/file_diff.html')
 

	
 
    def _get_history(self, repo, node, f_path):
 
        from vcs.nodes import NodeKind
 
        if not node.kind is NodeKind.FILE:
 
            return []
 
        changesets = node.history
 
        hist_l = []
 

	
 
        changesets_group = ([], _("Changesets"))
 
        branches_group = ([], _("Branches"))
 
        tags_group = ([], _("Tags"))
 

	
 
        for chs in changesets:
 
            n_desc = 'r%s:%s' % (chs.revision, chs.short_id)
 
            changesets_group[0].append((chs.raw_id, n_desc,))
 

	
 
        hist_l.append(changesets_group)
 

	
 
        for name, chs in c.repository_branches.items():
 
            #chs = chs.split(':')[-1]
 
            branches_group[0].append((chs, name),)
 
        hist_l.append(branches_group)
 

	
 
        for name, chs in c.repository_tags.items():
 
            #chs = chs.split(':')[-1]
 
            tags_group[0].append((chs, name),)
 
        hist_l.append(tags_group)
 

	
 
        return hist_l
 

	
 
#                [
 
#                 ([("u1", "User1"), ("u2", "User2")], "Users"),
 
#                 ([("g1", "Group1"), ("g2", "Group2")], "Groups")
 
#                 ]
 

	
rhodecode/public/css/style.css
Show inline comments
 
@@ -1233,781 +1233,790 @@ text-decoration:none;
 
 
#content div.box div.traffic div.legend {
 
clear:both;
 
overflow:hidden;
 
border-bottom:1px solid #ddd;
 
margin:0 0 10px;
 
padding:0 0 10px;
 
}
 
 
#content div.box div.traffic div.legend h6 {
 
float:left;
 
border:none;
 
margin:0;
 
padding:0;
 
}
 
 
#content div.box div.traffic div.legend li {
 
list-style:none;
 
float:left;
 
font-size:11px;
 
margin:0;
 
padding:0 8px 0 4px;
 
}
 
 
#content div.box div.traffic div.legend li.visits {
 
border-left:12px solid #edc240;
 
}
 
 
#content div.box div.traffic div.legend li.pageviews {
 
border-left:12px solid #afd8f8;
 
}
 
 
#content div.box div.traffic table {
 
width:auto;
 
}
 
 
#content div.box div.traffic table td {
 
background:transparent;
 
border:none;
 
padding:2px 3px 3px;
 
}
 
 
#content div.box div.traffic table td.legendLabel {
 
padding:0 3px 2px;
 
}
 
 
#footer {
 
clear:both;
 
overflow:hidden;
 
text-align:right;
 
margin:0;
 
padding:0 30px 4px;
 
margin:-10px 0 0;
 
}
 
 
#footer div#footer-inner {
 
background:url("../images/header_inner.png") repeat-x scroll 0 0 #003367;
 
border-top:2px solid #FFFFFF;
 
}
 
 
#footer div#footer-inner p {
 
padding:15px 25px 15px 0;
 
color:#FFF;
 
font-weight:700;
 
}
 
#footer div#footer-inner .footer-link {
 
float:left;
 
padding-left:10px;
 
}
 
#footer div#footer-inner .footer-link a {
 
color:#FFF; 
 
}
 
 
#login div.title {
 
width:420px;
 
clear:both;
 
overflow:hidden;
 
position:relative;
 
background:#003367 url("../../images/header_inner.png") repeat-x;
 
margin:0 auto;
 
padding:0;
 
}
 
 
#login div.inner {
 
width:380px;
 
background:#FFF url("../images/login.png") no-repeat top left;
 
border-top:none;
 
border-bottom:none;
 
margin:0 auto;
 
padding:20px;
 
}
 
 
#login div.form div.fields div.field div.label {
 
width:173px;
 
float:left;
 
text-align:right;
 
margin:2px 10px 0 0;
 
padding:5px 0 0 5px;
 
}
 
 
#login div.form div.fields div.field div.input input {
 
width:176px;
 
background:#FFF;
 
border-top:1px solid #b3b3b3;
 
border-left:1px solid #b3b3b3;
 
border-right:1px solid #eaeaea;
 
border-bottom:1px solid #eaeaea;
 
color:#000;
 
font-family:Lucida Grande, Verdana, Lucida Sans Regular, Lucida Sans Unicode, Arial, sans-serif;
 
font-size:11px;
 
margin:0;
 
padding:7px 7px 6px;
 
}
 
 
#login div.form div.fields div.buttons {
 
clear:both;
 
overflow:hidden;
 
border-top:1px solid #DDD;
 
text-align:right;
 
margin:0;
 
padding:10px 0 0;
 
}
 
 
#login div.form div.links {
 
clear:both;
 
overflow:hidden;
 
margin:10px 0 0;
 
padding:0 0 2px;
 
}
 
 
#register div.title {
 
clear:both;
 
overflow:hidden;
 
position:relative;
 
background:#003367 url("../images/header_inner.png") repeat-x;
 
margin:0 auto;
 
padding:0;
 
}
 
 
#register div.inner {
 
background:#FFF;
 
border-top:none;
 
border-bottom:none;
 
margin:0 auto;
 
padding:20px;
 
}
 
 
#register div.form div.fields div.field div.label {
 
width:135px;
 
float:left;
 
text-align:right;
 
margin:2px 10px 0 0;
 
padding:5px 0 0 5px;
 
}
 
 
#register div.form div.fields div.field div.input input {
 
width:300px;
 
background:#FFF;
 
border-top:1px solid #b3b3b3;
 
border-left:1px solid #b3b3b3;
 
border-right:1px solid #eaeaea;
 
border-bottom:1px solid #eaeaea;
 
color:#000;
 
font-family:Lucida Grande, Verdana, Lucida Sans Regular, Lucida Sans Unicode, Arial, sans-serif;
 
font-size:11px;
 
margin:0;
 
padding:7px 7px 6px;
 
}
 
 
#register div.form div.fields div.buttons {
 
clear:both;
 
overflow:hidden;
 
border-top:1px solid #DDD;
 
text-align:left;
 
margin:0;
 
padding:10px 0 0 150px;
 
}
 
 
#register div.form div.fields div.buttons div.highlight input.ui-state-default {
 
background:url("../images/button_highlight.png") repeat-x scroll 0 0 #4E85BB;
 
color:#FFF;
 
border-color:#5C91A4 #2B7089 #1A6480 #2A6F89;
 
border-style:solid;
 
border-width:1px;
 
}
 
 
#register div.form div.activation_msg {
 
padding-top:4px;
 
padding-bottom:4px;
 
}
 
 
.trending_language_tbl,.trending_language_tbl td {
 
border:0 !important;
 
margin:0 !important;
 
padding:0 !important;
 
}
 
 
.trending_language {
 
background-color:#003367;
 
color:#FFF;
 
display:block;
 
min-width:20px;
 
text-decoration:none;
 
height:12px;
 
margin-bottom:4px;
 
margin-left:5px;
 
white-space:pre;
 
padding:3px;
 
}
 
 
h3.files_location {
 
font-size:1.8em;
 
font-weight:700;
 
border-bottom:none !important;
 
margin:10px 0 !important;
 
}
 
 
#files_data dl dt {
 
float:left;
 
width:115px;
 
margin:0 !important;
 
padding:5px;
 
}
 
 
#files_data dl dd {
 
margin:0 !important;
 
padding:5px !important;
 
}
 
 
#changeset_content {
 
border:1px solid #CCC;
 
padding:5px;
 
}
 
 
#changeset_content .container {
 
min-height:120px;
 
font-size:1.2em;
 
overflow:hidden;
 
}
 
 
#changeset_content .container .right {
 
float:right;
 
width:25%;
 
text-align:right;
 
}
 
 
#changeset_content .container .left .message {
 
font-style:italic;
 
color:#556CB5;
 
white-space:pre-wrap;
 
}
 
 
.cs_files .cs_added {
 
background:url("../images/icons/page_white_add.png") no-repeat scroll 3px;
 
height:16px;
 
padding-left:20px;
 
margin-top:7px;
 
text-align:left;
 
}
 
 
.cs_files .cs_changed {
 
background:url("../images/icons/page_white_edit.png") no-repeat scroll 3px;
 
height:16px;
 
padding-left:20px;
 
margin-top:7px;
 
text-align:left;
 
}
 
 
.cs_files .cs_removed {
 
background:url("../images/icons/page_white_delete.png") no-repeat scroll 3px;
 
height:16px;
 
padding-left:20px;
 
margin-top:7px;
 
text-align:left;
 
}
 
 
#graph {
 
overflow:hidden;
 
}
 
 
#graph_nodes {
 
width:160px;
 
float:left;
 
margin-left:-50px;
 
margin-top:5px;
 
}
 
 
#graph_content {
 
width:800px;
 
float:left;
 
}
 
 
#graph_content .container_header {
 
border:1px solid #CCC;
 
padding:10px;
 
}
 
 
#graph_content .container {
 
border-bottom:1px solid #CCC;
 
border-left:1px solid #CCC;
 
border-right:1px solid #CCC;
 
min-height:80px;
 
overflow:hidden;
 
font-size:1.2em;
 
}
 
 
#graph_content .container .right {
 
float:right;
 
width:28%;
 
text-align:right;
 
padding-bottom:5px;
 
}
 
 
#graph_content .container .left .date {
 
font-weight:700;
 
padding-bottom:5px;
 
}
 
 
#graph_content .container .left .message {
 
font-size:100%;
 
padding-top:3px;
 
white-space:pre-wrap;
 
}
 
 
.right div {
 
clear:both;
 
}
 
 
.right .changes .added,.changed,.removed {
 
border:1px solid #DDD;
 
display:block;
 
float:right;
 
text-align:center;
 
min-width:15px;
 
cursor: help;
 
}
 
 
.right .changes .added {
 
background:#BFB;
 
}
 
 
.right .changes .changed {
 
background:#FD8;
 
}
 
 
.right .changes .removed {
 
background:#F88;
 
}
 
 
.right .merge {
 
vertical-align:top;
 
font-size:0.75em;
 
font-weight:700;
 
}
 
 
.right .parent {
 
font-size:90%;
 
font-family:monospace;
 
}
 
 
.right .logtags .branchtag {
 
background:#FFF url("../images/icons/arrow_branch.png") no-repeat right 6px;
 
display:block;
 
font-size:0.8em;
 
padding:11px 16px 0 0;
 
}
 
 
.right .logtags .tagtag {
 
background:#FFF url("../images/icons/tag_blue.png") no-repeat right 6px;
 
display:block;
 
font-size:0.8em;
 
padding:11px 16px 0 0;
 
}
 
 
div.browserblock {
 
overflow:hidden;
 
border:1px solid #ccc;
 
background:#f8f8f8;
 
font-size:100%;
 
line-height:125%;
 
padding:0;
 
}
 
 
div.browserblock .browser-header {
 
border-bottom:1px solid #CCC;
 
background:#FFF;
 
color:blue;
 
padding:10px 0;
 
float:left;
 
}
 
 
div.browserblock .browser-branch {
 
background:#FFF;
 
padding:20px 0 0 0;
 
float:left;
 
}
 
div.browserblock .browser-branch label {
 
color:#4A4A4A;	
 
}
 
 
div.browserblock .browser-header span {
 
margin-left:25px;
 
font-weight:700;
 
}
 
 
div.browserblock .browser-body {
 
background:#EEE;
 
border-top:1px solid #CCC;
 
}
 
 
table.code-browser {
 
border-collapse:collapse;
 
width:100%;
 
}
 
 
table.code-browser tr {
 
margin:3px;
 
}
 
 
table.code-browser thead th {
 
background-color:#EEE;
 
height:20px;
 
font-size:1.1em;
 
font-weight:700;
 
text-align:left;
 
padding-left:10px;
 
}
 
 
table.code-browser tbody td {
 
padding-left:10px;
 
height:20px;
 
}
 
 
table.code-browser .browser-file {
 
background:url("../images/icons/document_16.png") no-repeat scroll 3px;
 
height:16px;
 
padding-left:20px;
 
text-align:left;
 
}
 
.diffblock .changeset_file{
 
background:url("../images/icons/file.png") no-repeat scroll 3px;
 
height:16px;
 
padding-left:22px;
 
text-align:left;
 
font-size: 14px;
 
}
 
 
.diffblock .changeset_header{
 
margin-left: 6px !important;
 
}
 
 
table.code-browser .browser-dir {
 
background:url("../images/icons/folder_16.png") no-repeat scroll 3px;
 
height:16px;
 
padding-left:20px;
 
text-align:left;
 
}
 
 
.box .search {
 
clear:both;
 
overflow:hidden;
 
margin:0;
 
padding:0 20px 10px;
 
}
 
 
.box .search div.search_path {
 
background:none repeat scroll 0 0 #EEE;
 
border:1px solid #CCC;
 
color:blue;
 
margin-bottom:10px;
 
padding:10px 0;
 
}
 
 
.box .search div.search_path div.link {
 
font-weight:700;
 
margin-left:25px;
 
}
 
 
.box .search div.search_path div.link a {
 
color:#003367;
 
cursor:pointer;
 
text-decoration:none;
 
}
 
 
#path_unlock {
 
color:red;
 
font-size:1.2em;
 
padding-left:4px;
 
}
 
 
.info_box * {
 
background:url("../../images/pager.png") repeat-x scroll 0 0 #EBEBEB;
 
color:#4A4A4A;
 
font-weight:700;
 
height:1%;
 
display:inline;
 
border-color:#DEDEDE #C4C4C4 #C4C4C4 #CFCFCF;
 
border-style:solid;
 
border-width:1px;
 
padding:4px 6px;
 
}
 
 
.info_box span {
 
margin-left:3px;
 
margin-right:3px;
 
}
 
 
.info_box input#at_rev {
 
text-align:center;
 
padding:5px 3px 3px 2px;
 
}
 
 
.info_box input#view {
 
text-align:center;
 
padding:4px 3px 2px 2px;
 
}
 
 
.yui-overlay,.yui-panel-container {
 
visibility:hidden;
 
position:absolute;
 
z-index:2;
 
}
 
 
.yui-tt {
 
visibility:hidden;
 
position:absolute;
 
color:#666;
 
background-color:#FFF;
 
font-family:arial, helvetica, verdana, sans-serif;
 
border:2px solid #003367;
 
font:100% sans-serif;
 
width:auto;
 
opacity:1px;
 
padding:8px;
 
white-space: pre;
 
}
 
 
.ac {
 
vertical-align:top;
 
}
 
 
.ac .yui-ac {
 
position:relative;
 
font-family:arial;
 
font-size:100%;
 
}
 
 
.ac .perm_ac {
 
width:15em;
 
}
 
 
.ac .yui-ac-input {
 
width:100%;
 
}
 
 
.ac .yui-ac-container {
 
position:absolute;
 
top:1.6em;
 
width:100%;
 
}
 
 
.ac .yui-ac-content {
 
position:absolute;
 
width:100%;
 
border:1px solid gray;
 
background:#fff;
 
overflow:hidden;
 
z-index:9050;
 
}
 
 
.ac .yui-ac-shadow {
 
position:absolute;
 
width:100%;
 
background:#000;
 
-moz-opacity:0.1px;
 
opacity:.10;
 
filter:alpha(opacity =   10);
 
z-index:9049;
 
margin:.3em;
 
}
 
 
.ac .yui-ac-content ul {
 
width:100%;
 
margin:0;
 
padding:0;
 
}
 
 
.ac .yui-ac-content li {
 
cursor:default;
 
white-space:nowrap;
 
margin:0;
 
padding:2px 5px;
 
}
 
 
.ac .yui-ac-content li.yui-ac-prehighlight {
 
background:#B3D4FF;
 
}
 
 
.ac .yui-ac-content li.yui-ac-highlight {
 
background:#556CB5;
 
color:#FFF;
 
}
 
 
.follow{
 
background:url("../images/icons/heart_add.png") no-repeat scroll 3px;
 
height: 16px;
 
width: 20px;
 
cursor: pointer;
 
display: block;
 
float: right;
 
margin-top: 2px;
 
}
 
 
.following{
 
background:url("../images/icons/heart_delete.png") no-repeat scroll 3px;
 
height: 16px;
 
width: 20px;
 
cursor: pointer;
 
display: block;
 
float: right;
 
margin-top: 2px;
 
}
 
 
.currently_following{
 
padding-left: 10px;
 
padding-bottom:5px;
 
}
 
 
.journal_highlight{
 
font-weight: bold;
 
text-decoration: underline;
 
}
 
 
.add_icon {
 
background:url("../images/icons/add.png") no-repeat scroll 3px;
 
height:16px;
 
padding-left:20px;
 
padding-top:1px;
 
text-align:left;
 
}
 
 
.edit_icon {
 
background:url("../images/icons/folder_edit.png") no-repeat scroll 3px;
 
height:16px;
 
padding-left:20px;
 
padding-top:1px;
 
text-align:left;
 
}
 
 
.delete_icon {
 
background:url("../images/icons/delete.png") no-repeat scroll 3px;
 
height:16px;
 
padding-left:20px;
 
padding-top:1px;
 
text-align:left;
 
}
 
 
.refresh_icon {
 
background:url("../images/icons/arrow_refresh.png") no-repeat scroll 3px;
 
height:16px;
 
padding-left:20px;
 
padding-top:1px;
 
text-align:left;
 
}
 
 
.rss_icon {
 
background:url("../images/icons/rss_16.png") no-repeat scroll 3px;
 
height:16px;
 
padding-left:20px;
 
padding-top:1px;
 
text-align:left;
 
}
 
 
.atom_icon {
 
background:url("../images/icons/atom.png") no-repeat scroll 3px;
 
height:16px;
 
padding-left:20px;
 
padding-top:1px;
 
text-align:left;
 
}
 
 
.archive_icon {
 
background:url("../images/icons/compress.png") no-repeat scroll 3px;
 
height:16px;
 
padding-left:20px;
 
text-align:left;
 
padding-top:1px;
 
}
 
 
.action_button {
 
border:0;
 
display:block;
 
}
 
 
.action_button:hover {
 
border:0;
 
text-decoration:underline;
 
cursor:pointer;
 
}
 
 
#switch_repos {
 
position:absolute;
 
height:25px;
 
z-index:1;
 
}
 
 
#switch_repos select {
 
min-width:150px;
 
max-height:250px;
 
z-index:1;
 
}
 
 
.breadcrumbs {
 
border:medium none;
 
color:#FFF;
 
float:left;
 
text-transform:uppercase;
 
font-weight:700;
 
font-size:14px;
 
margin:0;
 
padding:11px 0 11px 10px;
 
}
 
 
.breadcrumbs a {
 
color:#FFF;
 
}
 
 
.flash_msg ul {
 
margin:0;
 
padding:0 0 10px;
 
}
 
 
.error_msg {
 
background-color:#FFCFCF;
 
background-image:url("../../images/icons/error_msg.png");
 
border:1px solid #FF9595;
 
color:#C30;
 
}
 
 
.warning_msg {
 
background-color:#FFFBCC;
 
background-image:url("../../images/icons/warning_msg.png");
 
border:1px solid #FFF35E;
 
color:#C69E00;
 
}
 
 
.success_msg {
 
background-color:#D5FFCF;
 
background-image:url("../../images/icons/success_msg.png");
 
border:1px solid #97FF88;
 
color:#090;
 
}
 
 
.notice_msg {
 
background-color:#DCE3FF;
 
background-image:url("../../images/icons/notice_msg.png");
 
border:1px solid #93A8FF;
 
color:#556CB5;
 
}
 
 
.success_msg,.error_msg,.notice_msg,.warning_msg {
 
background-position:10px center;
 
background-repeat:no-repeat;
 
font-size:12px;
 
font-weight:700;
 
min-height:14px;
 
line-height:14px;
 
margin-bottom:0;
 
margin-top:0;
 
display:block;
 
overflow:auto;
 
padding:6px 10px 6px 40px;
 
}
 
 
#msg_close {
 
background:transparent url("../../icons/cross_grey_small.png") no-repeat scroll 0 0;
 
cursor:pointer;
 
height:16px;
 
position:absolute;
 
right:5px;
 
top:5px;
 
width:16px;
 
}
 
 
div#legend_container table,div#legend_choices table {
 
width:auto !important;
 
}
 
 
table#permissions_manage {
 
width:0 !important;
 
}
 
rhodecode/templates/files/files_browser.html
Show inline comments
 
<%def name="file_class(node)">
 
	%if node.is_file():
 
		<%return "browser-file" %>
 
	%else:
 
		<%return "browser-dir"%>
 
	%endif
 
</%def>
 
<div id="body" class="browserblock">
 
	<div class="browser-header">
 
		${h.form(h.url.current())}
 
		<div class="info_box">
 
          <span >${_('view')}@rev</span> 
 
          <a href="${c.url_prev}" title="${_('previous revision')}">&laquo;</a>
 
          ${h.text('at_rev',value=c.changeset.revision,size=3)}
 
          <a href="${c.url_next}" title="${_('next revision')}">&raquo;</a>
 
          ${h.submit('view','view')}
 
	    </div>           
 
		${h.end_form()}
 
	</div>
 
    <div class="browser-branch">
 
       ${h.checkbox('stay_at_branch',c.changeset.branch,c.changeset.branch==c.branch)}
 
       <label>${_('follow current branch')}</label>
 
       <script type="text/javascript">
 
        YUE.on('stay_at_branch','click',function(e){
 
        	if(e.target.checked){
 
        		var uri = "${h.url.current(branch='__BRANCH__')}"
 
        		uri = uri.replace('__BRANCH__',e.target.value);
 
        		window.location = uri;
 
        	}
 
        	else{
 
        		window.location = "${h.url.current()}";
 
        	}
 
        	
 
        })
 
       </script>
 
    </div>
 
    <div style="clear:both"></div>
 
	<div class="browser-body">
 
		<table class="code-browser">
 
		         <thead>
 
		             <tr>
 
		                 <th>${_('Name')}</th>
 
		                 <th>${_('Size')}</th>
 
		                 <th>${_('Mimetype')}</th>
 
		                 <th>${_('Revision')}</th>
 
		                 <th>${_('Last modified')}</th>
 
		                 <th>${_('Last commiter')}</th>
 
		             </tr>
 
		         </thead>
 

	
 
          		%if c.files_list.parent:
 
         		<tr class="parity0">
 
	          		<td>		          		
 
	          			${h.link_to('..',h.url('files_home',repo_name=c.repo_name,revision=c.changeset.raw_id,f_path=c.files_list.parent.path),class_="browser-dir")}
 
	          		</td>
 
	          		<td></td>
 
	          		<td></td>
 
	          		<td></td>
 
	          		<td></td>
 
	          		<td></td>
 
				</tr>
 
          		%endif
 
		         	
 
		    %for cnt,node in enumerate(c.files_list):
 
				<tr class="parity${cnt+1%2}">
 
		             <td>
 
						${h.link_to(node.name,h.url('files_home',repo_name=c.repo_name,revision=c.changeset.raw_id,f_path=node.path),class_=file_class(node))}
 
		             </td>
 
		             <td>
 
		             %if node.is_file():
 
		             	${h.format_byte_size(node.size,binary=True)}
 
		             %endif	
 
		             </td>
 
		             <td>
 
		              %if node.is_file():
 
		                  ${node.mimetype}
 
		              %endif
 
		             </td>
 
		             <td>
 
		             	%if node.is_file():
 
		             		<span class="tooltip" tooltip_title="${node.last_changeset.raw_id}">${node.last_changeset.revision}</span>
 
		             	%endif
 
		             </td>
 
		             <td>
 
		             	%if node.is_file():
 
		             		${node.last_changeset.date} - ${h.age(node.last_changeset.date)}
 
		             	%endif
 
		             </td>
 
		             <td>
 
		             	%if node.is_file():
 
		             		${node.last_changeset.author}
 
		             	%endif                    
 
		             </td>
 
				</tr>
 
			%endfor
 
		</table>
 
	</div>
 
</div>
 
\ No newline at end of file
0 comments (0 inline, 0 general)