Changeset - 3e55d9981c0e
[Not reviewed]
default
0 5 0
Marcin Kuzminski - 15 years ago 2010-07-28 23:38:06
marcin@python-works.com
templating fixes
5 files changed with 13 insertions and 8 deletions:
0 comments (0 inline, 0 general)
pylons_app/controllers/files.py
Show inline comments
 
#!/usr/bin/env python
 
# encoding: utf-8
 
# files controller for pylons
 
# Copyright (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com>
 

	
 
# 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.
 
"""
 
Created on April 21, 2010
 
files controller for pylons
 
@author: marcink
 
"""
 
from mercurial import archival
 
from pylons import request, response, session, tmpl_context as c, url
 
from pylons.controllers.util import redirect
 
from pylons_app.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
 
from pylons_app.lib.base import BaseController, render
 
from pylons_app.lib.utils import EmptyChangeset, get_repo_slug
 
from pylons_app.model.hg_model import HgModel
 
from vcs.exceptions import RepositoryError, ChangesetError
 
from vcs.nodes import FileNode
 
from vcs.utils import diffs as differ
 
import logging
 
import pylons_app.lib.helpers as h
 
import tempfile
 
        
 
log = logging.getLogger(__name__)
 

	
 
class FilesController(BaseController):
 
    
 
    @LoginRequired()
 
    @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
 
                                   'repository.admin')       
 
    def __before__(self):
 
        super(FilesController, self).__before__()
 

	
 
    def index(self, repo_name, revision, f_path):
 
        hg_model = HgModel()
 
        c.repo = repo = hg_model.get_repo(c.repo_name)
 
        revision = request.POST.get('at_rev', None) or revision
 
        
 
        def get_next_rev(cur):
 
            max_rev = len(c.repo.revisions) - 1
 
            r = cur + 1
 
            if r > max_rev:
 
                r = max_rev
 
            return r
 
            
 
        def get_prev_rev(cur):
 
            r = cur - 1
 
            return r
 

	
 
        c.f_path = f_path
 
     
 
        
 
        try:
 
            cur_rev = repo.get_changeset(revision).revision
 
            prev_rev = repo.get_changeset(get_prev_rev(cur_rev)).raw_id
 
            next_rev = repo.get_changeset(get_next_rev(cur_rev)).raw_id
 
                    
 
            c.url_prev = url('files_home', repo_name=c.repo_name,
 
                             revision=prev_rev, f_path=f_path) 
 
            c.url_next = url('files_home', repo_name=c.repo_name,
 
                             revision=next_rev, f_path=f_path)   
 
                    
 
            c.changeset = repo.get_changeset(revision)
 

	
 
                        
 
            c.cur_rev = c.changeset.raw_id
 
            c.rev_nr = c.changeset.revision
 
            c.files_list = c.changeset.get_node(f_path)
 
            c.file_history = self._get_history(repo, c.files_list, f_path)
 
            
 
        except (RepositoryError, ChangesetError):
 
            c.files_list = None
 
        
 
        return render('files/files.html')
 

	
 
    def rawfile(self, repo_name, revision, f_path):
 
        hg_model = HgModel()
 
        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 annotate(self, repo_name, revision, f_path):
 
        hg_model = HgModel()
 
        c.repo = hg_model.get_repo(c.repo_name)
 
        cs = c.repo.get_changeset(revision)
 
        c.file = cs.get_node(f_path)
 
        c.file_msg = cs.get_file_message(f_path)
 
        c.cur_rev = cs.raw_id
 
        c.rev_nr = cs.revision        
 
        c.f_path = f_path
 

	
 
        return render('files/files_annotate.html')
 
      
 
    def archivefile(self, repo_name, revision, fileformat):
 
        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
 
                        
 
        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        
 
            
 
        archive = tempfile.TemporaryFile()
 
        repo = HgModel().get_repo(repo_name).repo
 
        fname = '%s-%s%s' % (repo_name, revision, fileformat)
 
        archival.archive(repo, 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)
 
        return read_in_chunks(archive)
 
    
 
    def diff(self, repo_name, f_path):
 
        hg_model = HgModel()
 
        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]:
 
                c.changeset_1 = c.repo.get_changeset(diff1)
 
                node1 = c.changeset_1.get_node(f_path)
 
            else:
 
                c.changeset_1 = EmptyChangeset()
 
                node1 = FileNode('.', '')
 
            if diff2 not in ['', None, 'None', '0' * 12]:
 
                c.changeset_2 = c.repo.get_changeset(diff2)
 
                node2 = c.changeset_2.get_node(f_path)
 
            else:
 
                c.changeset_2 = EmptyChangeset()
 
                node2 = FileNode('.', '') 
 
        except RepositoryError:
 
            return redirect(url('files_home',
 
                                repo_name=c.repo_name, f_path=f_path))
 

	
 
        c.diff1 = 'r%s:%s' % (c.changeset_1.revision, c.changeset_1.raw_id)
 
        c.diff2 = 'r%s:%s' % (c.changeset_2.revision, c.changeset_2.raw_id)
 
        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':
 
            c.cur_diff = '<pre class="raw">%s</pre>' % h.escape(diff.raw_diff())
 
        elif c.action == 'diff':
 
            c.cur_diff = diff.as_html()
 
        else:
 
            #default option
 
            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 = []
 
        for chs in changesets:
 
            n_desc = 'r%s:%s' % (chs.revision, chs._short)
 
            hist_l.append((chs._short, n_desc,))
 
        return hist_l
pylons_app/public/css/style.css
Show inline comments
 
@@ -2638,772 +2638,776 @@ div.options a:hover
 
 
#register div.form div.fields div.field div.input
 
{
 
	margin: 0;
 
	padding: 0;
 
	float: left;
 
}
 
 
#register div.form div.fields div.field div.input input
 
{
 
    margin: 0;
 
    padding: 7px 7px 6px 7px;
 
    width: 245px;
 
    background: #FFFFFF;
 
    border-top: 1px solid #b3b3b3;
 
    border-left: 1px solid #b3b3b3;
 
    border-right: 1px solid #eaeaea;
 
    border-bottom: 1px solid #eaeaea;
 
    color: #000000;
 
	font-family: Lucida Grande, Verdana, Lucida Sans Regular, Lucida Sans Unicode, Arial, sans-serif;
 
	font-size: 11px;
 
}
 
 
#register div.form div.fields div.field div.input  input.error
 
{
 
	background: #FBE3E4;
 
	border-top: 1px solid #e1b2b3;
 
	border-left: 1px solid #e1b2b3;
 
	border-right: 1px solid #FBC2C4;
 
	border-bottom: 1px solid #FBC2C4;
 
}
 
 
#register div.form div.fields div.field div.input  input.success
 
{
 
	background: #E6EFC2;
 
	border-top: 1px solid #cebb98;
 
	border-left: 1px solid #cebb98;
 
	border-right: 1px solid #c6d880;
 
	border-bottom: 1px solid #c6d880;
 
}
 
 
#register div.form div.fields div.field div.input div.link
 
{
 
	margin: 6px 0 0 0;
 
	padding: 0;
 
	text-align: right;
 
}
 
 
#register div.form div.fields div.field div.checkbox
 
{
 
	margin: 0 0 0 184px;
 
	padding: 0;
 
}
 
 
#register div.form div.fields div.field div.checkbox label
 
{
 
    color: #565656;
 
    font-weight: bold;
 
}
 
 
#register div.form div.fields div.buttons
 
{
 
	margin: 0;
 
	padding: 10px 0 0 97px;
 
	clear: both;
 
	overflow: hidden;
 
	border-top: 1px solid #DDDDDD;
 
	text-align: left;
 
}
 
 
#register div.form div.fields div.buttons input
 
{
 
	margin: 0;
 
    color: #000000;
 
	font-size: 1.0em; 
 
    font-weight: bold;
 
	font-family: Verdana, Helvetica, Sans-Serif; 
 
}
 
 
#register div.form div.fields div.buttons input.ui-state-default
 
{
 
    margin: 0;
 
    padding: 6px 12px 6px 12px;
 
    background: #e5e3e3 url("../images/button.png") repeat-x;
 
    border-top: 1px solid #DDDDDD;
 
    border-left: 1px solid #c6c6c6;
 
    border-right: 1px solid #DDDDDD;
 
    border-bottom: 1px solid #c6c6c6;
 
    color: #515151;
 
}
 
#register div.form div.fields div.buttons div.highlight input.ui-state-default
 
{
 
	background:url("../images/colors/blue/button_highlight.png") repeat-x scroll 0 0 #4E85BB;
 
	border-color:#5C91A4 #2B7089 #1A6480 #2A6F89;
 
	border-style:solid;
 
	border-width:1px;
 
	color:#FFFFFF;
 
}
 
 
 
 
#register div.form div.fields div.buttons input.ui-state-hover
 
{
 
    margin: 0;
 
    padding: 6px 12px 6px 12px;
 
    background: #b4b4b4 url("../images/button_selected.png") repeat-x;
 
    border-top: 1px solid #cccccc;
 
    border-left: 1px solid #bebebe;
 
    border-right: 1px solid #b1b1b1;
 
    border-bottom: 1px solid #afafaf;
 
    color: #515151;
 
}
 
 
 
/* -----------------------------------------------------------
 
	CHANGESETS
 
----------------------------------------------------------- */
 
#changeset_content {
 
	border:1px solid #CCCCCC;
 
	padding:5px;
 
}
 
 
#changeset_content .container .wrapper {
 
	width: 600px;
 
}
 
 
#changeset_content .container {
 
	height: 120px;
 
}
 
 
#changeset_content .container .left {
 
	float: left;
 
	width: 70%;
 
	padding-left: 5px;
 
}
 
 
#changeset_content .container .right {
 
	float: right;
 
	width: 25%;
 
	text-align: right;
 
}
 
 
#changeset_content .container .left .date {
 
	font-weight: bold;
 
}
 
 
#changeset_content .container .left .author {
 
	
 
}
 
 
#changeset_content .container .left .message {
 
	font-style: italic;
 
	color: #556CB5;
 
}
 
 
.cs_files {
 
 
}
 
 
.cs_files .cs_added {
 
	background: url("/images/icons/page_white_add.png") no-repeat scroll 3px;
 
	/*background-color:#BBFFBB;*/
 
	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;
 
	/*background-color: #FFDD88;*/
 
	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;
 
	/*background-color: #FF8888;*/
 
	height: 16px;
 
	padding-left: 20px;
 
	margin-top: 7px;
 
	text-align: left;
 
}
 
 
 
 
/* -----------------------------------------------------------
 
	CHANGESETS - CANVAS
 
----------------------------------------------------------- */
 
 
#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 #CCCCCC;
 
	padding:10px;
 
}
 
 
#graph_content .container .wrapper {
 
	width: 600px;
 
}
 
 
#graph_content .container {
 
	border-bottom: 1px solid #CCCCCC;
 
	border-left: 1px solid #CCCCCC;
 
	border-right: 1px solid #CCCCCC;
 
	min-height: 80px;
 
	overflow: hidden;
 
}
 
 
#graph_content .container .left {
 
	float: left;
 
	width: 70%;
 
	padding-left: 5px;
 
}
 
 
#graph_content .container .right {
 
	float: right;
 
	width: 25%;
 
	text-align: right;
 
}
 
 
#graph_content .container .left .date {
 
	font-weight: bold;
 
}
 
 
#graph_content .container .left .author {
 
	
 
}
 
 
#graph_content .container .left .message {
 
	font-size: 80%;
 
}
 
 
.right div {
 
	clear: both;
 
}
 
 
.right .changes .added,.changed,.removed {
 
	border: 1px solid #DDDDDD;
 
	display: block;
 
	float: right;
 
	font-size: 0.75em;
 
	text-align: center;
 
	min-width: 15px;
 
}
 
 
.right .changes .added {
 
	background: #BBFFBB;
 
}
 
 
.right .changes .changed {
 
	background: #FFDD88;
 
}
 
 
.right .changes .removed {
 
	background: #FF8888;
 
}
 
 
.right .merge {
 
	vertical-align: top;
 
	font-size: 60%;
 
	font-weight: bold;
 
}
 
 
.right .merge img {
 
	vertical-align: bottom;
 
}
 
 
.right .parent {
 
	font-size: 90%;
 
	font-family: monospace;
 
}
 
 
 
 
/* -----------------------------------------------------------
 
	FILE BROWSER
 
----------------------------------------------------------- */
 
div.browserblock {
 
	overflow: hidden;
 
	padding: 0px;
 
	border: 1px solid #ccc;
 
	background: #f8f8f8;
 
	font-size: 100%;
 
	line-height: 100%;
 
	/* new */
 
	line-height: 125%;
 
}
 
 
div.browserblock .browser-header {
 
	border-bottom: 1px solid #CCCCCC;
 
	background: #FFFFFF;
 
	color: blue;
 
	padding: 10px 0 10px 0;
 
}
 
 
div.browserblock .browser-header span {
 
	margin-left: 25px;
 
	font-weight: bold;
 
}
 
 
div.browserblock .browser-body {
 
	background: #EEEEEE;
 
}
 
 
table.code-browser {
 
	border-collapse: collapse;
 
	width: 100%;
 
}
 
 
table.code-browser tr {
 
	margin: 3px;
 
}
 
 
table.code-browser thead th {
 
	background-color: #EEEEEE;
 
	height: 20px;
 
	font-size: 1.1em;
 
	font-weight: bold;
 
	text-align: center;
 
	text-align: left;
 
	padding-left: 10px;
 
}
 
 
table.code-browser tbody tr {
 
	
 
}
 
 
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;
 
}
 
 
table.code-browser .browser-dir {
 
	background: url("/images/icons/folder_16.png") no-repeat scroll 3px;
 
	height: 16px;
 
	padding-left: 20px;
 
	text-align: left;
 
}
 
 
 
/* -----------------------------------------------------------
 
    INFOBOX
 
----------------------------------------------------------- */
 
.info_box *{
 
	background:url("../../images/pager.png") repeat-x scroll 0 0 #EBEBEB;
 
	border-color:#DEDEDE #C4C4C4 #C4C4C4 #CFCFCF;
 
	border-style:solid;
 
	border-width:1px;
 
	color:#4A4A4A;
 
	display:block;
 
	font-weight:bold;
 
	height:1%;
 
	padding:4px 6px;
 
	display: inline;
 
}
 
.info_box span{
 
    margin-left:3px;
 
    margin-righ:3px;
 
}
 
.info_box input {
 
    padding:3px 6px;
 
}
 
 
.info_box input#at_rev {
 
	padding:1px 3px 3px 2px;
 
	text-align:center;
 
}
 
.info_box input#view {
 
	padding:0px 3px 2px 2px;
 
	text-align:center;
 
}
 
/* -----------------------------------------------------------
 
    TOOLTIP
 
----------------------------------------------------------- */
 
.yui-overlay,.yui-panel-container {
 
    visibility: hidden;
 
    position: absolute;
 
    z-index: 2;
 
}
 
 
.yui-tt {
 
    visibility: hidden;
 
    position: absolute;
 
    color: #666666;
 
    background-color: #FFFFFF;
 
    font-family: arial, helvetica, verdana, sans-serif;
 
    padding: 8px;
 
    border: 2px solid #556CB5;
 
    font: 100% sans-serif;
 
    width: auto;
 
    opacity: 1.0;
 
}
 
 
.yui-tt-shadow {
 
    display: none;
 
}
 
 
/* -----------------------------------------------------------
 
    AUTOCOMPLETE 
 
----------------------------------------------------------- */
 
 
.ac{
 
    vertical-align: top;
 
 
}
 
.ac .match {
 
    font-weight:bold;
 
}
 
 
.ac .yui-ac {
 
    position: relative;
 
    font-family: arial;
 
    font-size: 100%;
 
}
 
 
.ac .perm_ac{
 
    width:15em;
 
}
 
/* styles for input field */
 
.ac .yui-ac-input {
 
    width: 100%;
 
}
 
 
/* styles for results container */
 
.ac .yui-ac-container {
 
    position: absolute;
 
    top: 1.6em;
 
    width: 100%;
 
}
 
 
/* styles for header/body/footer wrapper within container */
 
.ac .yui-ac-content {
 
    position: absolute;
 
    width: 100%;
 
    border: 1px solid #808080;
 
    background: #fff;
 
    overflow: hidden;
 
    z-index: 9050;
 
}
 
 
/* styles for container shadow */
 
.ac .yui-ac-shadow {
 
    position: absolute;
 
    margin: .3em;
 
    width: 100%;
 
    background: #000;
 
    -moz-opacity: 0.10;
 
    opacity: .10;
 
    filter: alpha(opacity = 10);
 
    z-index: 9049;
 
}
 
 
/* styles for results list */
 
.ac .yui-ac-content ul {
 
    margin: 0;
 
    padding: 0;
 
    width: 100%;
 
}
 
 
/* styles for result item */
 
.ac .yui-ac-content li {
 
    margin: 0;
 
    padding: 2px 5px;
 
    cursor: default;
 
    white-space: nowrap;
 
}
 
 
/* styles for prehighlighted result item */
 
.ac .yui-ac-content li.yui-ac-prehighlight {
 
    background: #B3D4FF;
 
}
 
 
/* styles for highlighted result item */
 
.ac .yui-ac-content li.yui-ac-highlight {
 
    background: #556CB5;
 
    color: #FFF;
 
}
 
 
 
/* -----------------------------------------------------------
 
    ACTION ICONS
 
----------------------------------------------------------- */
 
.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;
 
}
 
 
.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: 0px;
 
    display: block;
 
}
 
 
.action_button:hover {
 
    border: 0px;
 
    font-style: italic;
 
    cursor: pointer;
 
}
 
 
/* -----------------------------------------------------------
 
    REPO SWITCHER
 
----------------------------------------------------------- */
 
 
#switch_repos{
 
	position: absolute;
 
	height: 25px;
 
	z-index: 1;
 
}
 
/* -----------------------------------------------------------
 
    BREADCRUMBS
 
----------------------------------------------------------- */
 
 
.breadcrumbs{
 
	border:medium none;
 
	color:#FFFFFF;
 
	float:left;
 
	margin:0;
 
	padding:11px 0 11px 10px;
 
	text-transform:uppercase;
 
    font-weight: bold;
 
    font-size: 14px;
 
}
 
.breadcrumbs a{
 
 color: #FFFFFF;
 
}
 
 
 
/* -----------------------------------------------------------
 
    FLASH MSG
 
----------------------------------------------------------- */
 
.flash_msg ul {
 
    margin: 0;
 
    padding: 0px 0px 10px 0px;
 
}
 
 
.error_msg {
 
    background-color: #FFCFCF;
 
    background-image: url("/images/icons/error_msg.png");
 
    border: 1px solid #FF9595;
 
    color: #CC3300;
 
}
 
 
.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: #009900;
 
}
 
 
.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: bold;
 
    min-height: 14px;
 
    line-height: 14px;
 
    margin-bottom: 0px;
 
    margin-top: 0px;
 
    padding: 6px 10px 6px 40px;
 
    display: block;
 
    overflow: auto;
 
}
 
 
#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;
 
}
 
/* -----------------------------------------------------------
 
	YUI FLOT
 
----------------------------------------------------------- */
 
 
div#commit_history{
 
	float: left;
 
}
 
div#legend_data{
 
	float:left;
 
	
 
}
 
div#legend_container {
 
	float: left;
 
}
 
 
div#legend_container table,div#legend_choices table{
 
	width:auto !important;
 
}
 
 
div#legend_container table td{
 
	border: none !important;
 
	padding: 2px !important;
 
}
 
 
div#legend_choices table td{
 
	border: none !important;
 
	padding: 0px !important;
 
}
 
 
div#legend_choices{
 
	float:left;
 
}
 
 
/* -----------------------------------------------------------
 
    PERMISSIONS TABLE
 
----------------------------------------------------------- */
 
table#permissions_manage{
 
    width: 0 !important;
 
 
}
 
table#permissions_manage span.private_repo_msg{
 
    font-size: 0.8em;
 
    opacity:0.6;
 
    
 
}
 
table#permissions_manage td.private_repo_msg{
 
    font-size: 0.8em;
 
    
 
}
 
table#permissions_manage tr#add_perm_input td{
 
    vertical-align:middle;
 
 
}
 
 
 
/* -----------------------------------------------------------
 
	jquery ui
 
----------------------------------------------------------- */
 
 
.ui-helper-hidden { display: none; }
 
.ui-helper-hidden-accessible { position: absolute; left: -99999999px; }
 
.ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; }
 
 
/* -----------------------------------------------------------
 
	jquery ui -> icons
 
----------------------------------------------------------- */
 
 
.ui-icon { width: 16px; height: 16px; background-image: url(../images/ui/ui-icons_222222_256x240.png); }
 
.ui-widget-content .ui-icon {background-image: url(../images/ui/ui-icons_222222_256x240.png); }
 
.ui-widget-header .ui-icon {background-image: url(../images/ui/ui-icons_222222_256x240.png); }
 
.ui-state-default .ui-icon { background-image: url(../images/ui/ui-icons_ef8c08_256x240.png); }
 
.ui-state-hover .ui-icon, .ui-state-focus .ui-icon { background-image: url(../images/ui/ui-icons_ef8c08_256x240.png); }
 
.ui-state-active .ui-icon {background-image: url(../images/ui/ui-icons_ef8c08_256x240.png); }
 
.ui-state-highlight .ui-icon {background-image: url(../images/ui/ui-icons_228ef1_256x240.png); }
 
.ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(../images/ui/ui-icons_ffd27a_256x240.png); }
 
 
/* -----------------------------------------------------------
 
	jquery ui -> icon positioning
 
----------------------------------------------------------- */
 
.ui-icon-carat-1-n { background-position: 0 0; }
 
.ui-icon-carat-1-ne { background-position: -16px 0; }
 
.ui-icon-carat-1-e { background-position: -32px 0; }
 
.ui-icon-carat-1-se { background-position: -48px 0; }
 
.ui-icon-carat-1-s { background-position: -64px 0; }
 
.ui-icon-carat-1-sw { background-position: -80px 0; }
 
.ui-icon-carat-1-w { background-position: -96px 0; }
 
.ui-icon-carat-1-nw { background-position: -112px 0; }
 
.ui-icon-carat-2-n-s { background-position: -128px 0; }
 
.ui-icon-carat-2-e-w { background-position: -144px 0; }
 
.ui-icon-triangle-1-n { background-position: 0 -16px; }
 
.ui-icon-triangle-1-ne { background-position: -16px -16px; }
 
.ui-icon-triangle-1-e { background-position: -32px -16px; }
 
.ui-icon-triangle-1-se { background-position: -48px -16px; }
 
.ui-icon-triangle-1-s { background-position: -64px -16px; }
 
.ui-icon-triangle-1-sw { background-position: -80px -16px; }
 
.ui-icon-triangle-1-w { background-position: -96px -16px; }
 
.ui-icon-triangle-1-nw { background-position: -112px -16px; }
 
.ui-icon-triangle-2-n-s { background-position: -128px -16px; }
 
.ui-icon-triangle-2-e-w { background-position: -144px -16px; }
 
.ui-icon-arrow-1-n { background-position: 0 -32px; }
 
.ui-icon-arrow-1-ne { background-position: -16px -32px; }
 
.ui-icon-arrow-1-e { background-position: -32px -32px; }
 
.ui-icon-arrow-1-se { background-position: -48px -32px; }
 
.ui-icon-arrow-1-s { background-position: -64px -32px; }
 
.ui-icon-arrow-1-sw { background-position: -80px -32px; }
 
.ui-icon-arrow-1-w { background-position: -96px -32px; }
 
.ui-icon-arrow-1-nw { background-position: -112px -32px; }
 
.ui-icon-arrow-2-n-s { background-position: -128px -32px; }
 
.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; }
 
.ui-icon-arrow-2-e-w { background-position: -160px -32px; }
 
.ui-icon-arrow-2-se-nw { background-position: -176px -32px; }
 
.ui-icon-arrowstop-1-n { background-position: -192px -32px; }
 
.ui-icon-arrowstop-1-e { background-position: -208px -32px; }
 
.ui-icon-arrowstop-1-s { background-position: -224px -32px; }
 
.ui-icon-arrowstop-1-w { background-position: -240px -32px; }
 
.ui-icon-arrowthick-1-n { background-position: 0 -48px; }
 
.ui-icon-arrowthick-1-ne { background-position: -16px -48px; }
 
.ui-icon-arrowthick-1-e { background-position: -32px -48px; }
 
.ui-icon-arrowthick-1-se { background-position: -48px -48px; }
 
.ui-icon-arrowthick-1-s { background-position: -64px -48px; }
 
.ui-icon-arrowthick-1-sw { background-position: -80px -48px; }
 
.ui-icon-arrowthick-1-w { background-position: -96px -48px; }
 
.ui-icon-arrowthick-1-nw { background-position: -112px -48px; }
pylons_app/templates/admin/repos/repos.html
Show inline comments
 
## -*- coding: utf-8 -*-
 
<%inherit file="/base/base.html"/>
 

	
 
<%def name="title()">
 
    ${_('Repositories administration')}
 
</%def>
 

	
 

	
 
<%def name="breadcrumbs_links()">
 
    ${h.link_to(_('Admin'),h.url('admin_home'))} &raquo; ${_('Repositories')}
 
</%def>
 
<%def name="page_nav()">
 
	${self.menu('admin')}
 
</%def>
 
<%def name="main()">
 
<div class="box">
 
    <!-- box / title -->
 
    <div class="title">
 
        ${self.breadcrumbs()}
 
        <ul class="links">
 
          <li>
 
            <span>${h.link_to(u'ADD NEW REPO',h.url('new_repo'),class_="add_icon")}</span>
 
            <span>${h.link_to(u'ADD NEW REPOSITORY',h.url('new_repo'),class_="add_icon")}</span>
 
          </li>          
 
        </ul>        
 
    </div>
 
    <!-- end box / title -->
 
    <div class="table">
 
        <table class="table_disp">
 
        <tr class="header">
 
            <th class="left">${_('name')}</th>
 
            <th class="left">${_('owner')}</th>
 
            <th class="left">${_('last revision')}</th>
 
            <th class="left">${_('action')}</th>
 
        </tr>
 
            %for cnt,repo in enumerate(c.repos_list):
 
            <tr class="parity${cnt%2}">
 
                 <td>
 
                 %if repo['repo'].dbrepo.private:
 
                    <img alt="${_('private')}" src="/images/icons/lock.png"/>
 
                 %else:
 
                    <img alt="${_('public')}" src="/images/icons/lock_open.png"/>
 
                 %endif         
 
                ${h.link_to(repo['name'],h.url('edit_repo',repo_name=repo['name']))}</td>
 
                <td>${repo['contact']}</td>
 
                <td>r${repo['rev']}:${repo['tip']}</td>
 
                <td>
 
                  ${h.form(url('repo', repo_name=repo['name']),method='delete')}
 
                    ${h.submit('remove','delete',class_="delete_icon action_button",onclick="return confirm('Confirm to delete this repository');")}
 
                  ${h.end_form()}
 
                </td>
 
            </tr>
 
            %endfor
 
        </table>
 
    </div>
 
</div> 
 
		   
 
</%def>    
pylons_app/templates/files/files_annotate.html
Show inline comments
 
<%inherit file="/base/base.html"/>
 

	
 
<%def name="title()">
 
    ${_('File annotate')}
 
</%def>
 

	
 
<%def name="breadcrumbs_links()">
 
    ${h.link_to(u'Home',h.url('/'))}
 
    &raquo;
 
    ${h.link_to(c.repo_name,h.url('summary_home',repo_name=c.repo_name))}
 
    &raquo;
 
    ${_('annotate')}  
 
    ${_('annotate')} @ R${c.rev_nr}:${c.cur_rev}
 
</%def>
 

	
 
<%def name="page_nav()">
 
		${self.menu('files')}     
 
</%def>
 
<%def name="main()">
 
<div class="box">
 
    <!-- box / title -->
 
    <div class="title">
 
        ${self.breadcrumbs()}
 
    </div>
 
    <div class="table">
 
		<div id="files_data">
 
			<h2>${_('Location')}: ${h.files_breadcrumbs(c.repo_name,c.cur_rev,c.file.path)}</h2>
 
			<dl class="overview">
 
				<dt>${_('Revision')}</dt>
 
				<dt>${_('Last revision')}</dt>
 
				<dd>r${c.file.last_changeset.revision}:${c.file.last_changeset._short}</dd>
 
				<dt>${_('Size')}</dt>
 
				<dd>${h.format_byte_size(c.file.size,binary=True)}</dd>
 
				<dt>${_('Options')}</dt>
 
				<dd>${h.link_to(_('show source'),
 
						h.url('files_home',repo_name=c.repo_name,revision=c.cur_rev,f_path=c.f_path))}  
 
					/ ${h.link_to(_('download as raw'),
 
						h.url('files_raw_home',repo_name=c.repo_name,revision=c.cur_rev,f_path=c.f_path))}
 
				</dd>				
 
			</dl>
 
			<div id="body" class="codeblock">
 
				<div class="code-header">
 
					<div class="revision">${c.file.name}@r${c.file.last_changeset.revision}:${c.file.last_changeset._short}</div>
 
					<div class="commit" style="font-size:70%">"${c.file_msg}"</div>
 
				</div>
 
				<div class="code-body">
 
					${h.pygmentize_annotation(c.file,linenos=True,anchorlinenos=True,lineanchors='S',cssclass="code-highlight")}
 
				</div>
 
			</div>
 
		</div>    
 
    </div>
 
</div>    
 
</%def>   
 
\ No newline at end of file
pylons_app/templates/index.html
Show inline comments
 
## -*- coding: utf-8 -*-
 
<%inherit file="base/base.html"/>
 
<%def name="title()">
 
    ${c.hg_app_name}
 
</%def>
 
<%def name="breadcrumbs()">
 
	${c.hg_app_name}
 
</%def>
 
<%def name="page_nav()">
 
	${self.menu('home')}
 
</%def>
 
<%def name="main()">
 
	<%def name="get_sort(name)">
 
		<%name_slug = name.lower().replace(' ','_') %>
 
		%if name_slug == c.cs_slug:
 
			<span style="font-weight: bold;text-decoration: underline;">${name}</span>
 
		%else:
 
			<span style="font-weight: bold">${name}</span>
 
		%endif
 
		<a href="?sort=${name_slug}">&darr;</a>
 
		<a href="?sort=-${name_slug}">&uarr;</a>
 
	</%def>
 
	
 
	
 
	
 
    <div class="box">
 
	    <!-- box / title -->
 
	    <div class="title">
 
	        <h5>${_('Dashboard')}</h5>
 
	        ##%if h.HasPermissionAll('repository.create')():
 
	        <ul class="links">
 
	          <li>
 
	            <span>${h.link_to(u'ADD NEW REPO',h.url('new_repo'),class_="add_icon")}</span>
 
	            <span>${h.link_to(u'ADD NEW REPOSITORY',h.url('new_repo'),class_="add_icon")}</span>
 
	          </li>          
 
	        </ul>  	        
 
	        ##%endif
 
	    </div>
 
	    <!-- end box / title -->
 
        <div class="table">
 
                    <table>
 
            <thead>
 
	            <tr>
 
			        <th class="left">${get_sort(_('Name'))}</th>
 
			        <th class="left">${get_sort(_('Description'))}</th>
 
			        <th class="left">${get_sort(_('Last change'))}</th>
 
			        <th class="left">${get_sort(_('Tip'))}</th>
 
			        <th class="left">${get_sort(_('Contact'))}</th>
 
			        <th class="left">${_('RSS')}</th>
 
			        <th class="left">${_('Atom')}</th>
 
	            </tr>
 
            </thead>
 
                        <tbody>
 
					    %for cnt,repo in enumerate(c.repos_list):
 
					        %if h.HasRepoPermissionAny('repository.write','repository.read','repository.admin')(repo['name'],'main page check'):
 
					        <tr class="parity${cnt%2}">
 
					            <td>
 
					             %if repo['repo'].dbrepo.private:
 
					                <img alt="${_('private')}" src="/images/icons/lock.png"/>
 
					             %else:
 
					                <img alt="${_('public')}" src="/images/icons/lock_open.png"/>
 
					             %endif  
 
					            ${h.link_to(repo['name'],
 
					                h.url('summary_home',repo_name=repo['name']))}</td>
 
					            <td title="${repo['description']}">${h.truncate(repo['description'],60)}</td>
 
					            <td>${h.age(repo['last_change'])}</td>
 
					            <td>${h.link_to_if(repo['rev']>=0,'r%s:%s' % (repo['rev'],repo['tip']),
 
					                h.url('changeset_home',repo_name=repo['name'],revision=repo['tip']),
 
					                class_="tooltip",
 
					                tooltip_title=h.tooltip(repo['last_msg']))}</td>
 
					            <td title="${repo['contact']}">${h.person(repo['contact'])}</td>
 
					            <td>
 
					                <a title="${_('Subscribe to %s rss feed')%repo['name']}" class="rss_icon"  href="${h.url('rss_feed_home',repo_name=repo['name'])}"></a>
 
					            </td>        
 
					            <td>
 
					                <a title="${_('Subscribe to %s atom feed')%repo['name']}"  class="atom_icon" href="${h.url('atom_feed_home',repo_name=repo['name'])}"></a>
 
					            </td>
 
					        </tr>
 
					        %endif
 
					    %endfor
 
                        </tbody>
 
                    </table>
 
            </div>
 
    </div>	
 
</%def>    
0 comments (0 inline, 0 general)