Changeset - d79f3505549e
[Not reviewed]
beta
0 7 0
Marcin Kuzminski - 13 years ago 2013-02-27 02:17:52
marcin@python-works.com
whitespace cleanup
7 files changed with 14 insertions and 16 deletions:
0 comments (0 inline, 0 general)
docs/installation_win.rst
Show inline comments
 
@@ -2,140 +2,140 @@
 

	
 

	
 
Step by step Installation for Windows
 
=====================================
 

	
 

	
 
RhodeCode step-by-step install Guide for Windows
 

	
 
Target OS: Windows XP SP3 32bit English (Clean installation)
 
+ All Windows Updates until 24-may-2012
 

	
 
.. note::
 

	
 
   This installation is for 32bit systems, for 64bit windows you might need
 
   to download proper 64bit versions of the different packages(Windows Installer, Win32py extensions)
 
   plus some extra tweaks.
 
   These extra steps haven been marked as "64bit".
 
   Tested on Windows Server 2008 R2 SP1, 9-feb-2013.
 
   If you run into any 64bit related problems, please check these pages:
 
   - http://blog.victorjabur.com/2011/06/05/compiling-python-2-7-modules-on-windows-32-and-64-using-msvc-2008-express/
 
   - http://bugs.python.org/issue7511
 

	
 
Step1 - Install Visual Studio 2008 Express
 
------------------------------------------
 

	
 

	
 
Optional: You can also install MingW, but VS2008 installation is easier
 

	
 
Download "Visual C++ 2008 Express Edition with SP1" from:
 
http://www.microsoft.com/visualstudio/en-us/products/2008-editions/express
 
(if not found or relocated, google for "visual studio 2008 express" for
 
updated link)
 

	
 
You can also download full ISO file for offline installation, just
 
choose "All - Offline Install ISO image file" in the previous page and
 
choose "Visual C++ 2008 Express" when installing.
 

	
 
.. note::
 

	
 
   Using other versions of Visual Studio will lead to random crashes.
 
   You must use Visual Studio 2008!"
 

	
 
.. note::
 

	
 
   Silverlight Runtime and SQL Server 2008 Express Edition are not
 
   required, you can uncheck them
 

	
 
.. note::
 
   
 

	
 
   64bit: You also need to install the Microsoft Windows SDK for .NET 3.5 SP1 (.NET 4.0 won't work).
 
   Download from: http://www.microsoft.com/en-us/download/details.aspx?id=3138
 

	
 
.. note::
 

	
 
   64bit: You also need to copy and rename a .bat file to make the Visual C++ compiler work.
 
   I am not sure why this is not necessary for 32bit.
 
   Copy C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\bin\vcvars64.bat to C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\bin\amd64\vcvarsamd64.bat
 

	
 

	
 
Step2 - Install Python
 
----------------------
 

	
 
Install Python 2.x.y (x >= 5) x86 version (32bit). DO NOT USE A 3.x version.
 
Download Python 2.x.y from:
 
http://www.python.org/download/
 

	
 
Choose "Windows Installer" (32bit version) not "Windows X86-64
 
Installer". While writing this guide, the latest version was v2.7.3.
 
Remember the specific major and minor version installed, because it will
 
be needed in the next step. In this case, it is "2.7".
 

	
 
.. note::
 

	
 
   64bit: Just download and install the 64bit version of python.
 

	
 
Step3 - Install Win32py extensions
 
----------------------------------
 

	
 
Download pywin32 from:
 
http://sourceforge.net/projects/pywin32/files/
 

	
 
- Click on "pywin32" folder
 
- Click on the first folder (in this case, Build 217, maybe newer when you try)
 
- Choose the file ending with ".win32-py2.x.exe" -> x being the minor
 
  version of Python you installed (in this case, 7)
 
  When writing this guide, the file was:
 
  http://sourceforge.net/projects/pywin32/files/pywin32/Build%20217/pywin32-217.win32-py2.7.exe/download
 

	
 
  .. note::
 

	
 
     64bit: Download and install the 64bit version.
 
     At the time of writing you can find this at: 
 
     At the time of writing you can find this at:
 
     http://sourceforge.net/projects/pywin32/files/pywin32/Build%20218/pywin32-218.win-amd64-py2.7.exe/download
 

	
 
Step4 - Python BIN
 
------------------
 

	
 
Add Python BIN folder to the path
 

	
 
You have to add the Python folder to the path, you can do it manually
 
(editing "PATH" environment variable) or using Windows Support Tools
 
that came preinstalled in Vista/7 and can be installed in Windows XP.
 

	
 
- Using support tools on WINDOWS XP:
 
  If you use Windows XP you can install them using Windows XP CD and
 
  navigating to \SUPPORT\TOOLS. There, execute Setup.EXE (not MSI).
 
  Afterwards, open a CMD and type::
 

	
 
    SETX PATH "%PATH%;[your-python-path]" -M
 

	
 
  Close CMD (the path variable will be updated then)
 

	
 
- Using support tools on WINDOWS Vista/7:
 

	
 
  Open a CMD and type::
 

	
 
    SETX PATH "%PATH%;[your-python-path]" /M
 

	
 
  Please substitute [your-python-path] with your Python installation path.
 
  Typically: C:\\Python27
 

	
 

	
 
Step5 - RhodeCode folder structure
 
----------------------------------
 

	
 
Create a RhodeCode folder structure
 

	
 
This is only a example to install RhodeCode, you can of course change
 
it. However, this guide will follow the proposed structure, so please
 
later adapt the paths if you change them. My recommendation is to use
 
folders with NO SPACES. But you can try if you are brave...
 

	
 
Create the following folder structure::
 

	
 
  C:\RhodeCode
 
  C:\RhodeCode\Bin
 
  C:\RhodeCode\Env
 
  C:\RhodeCode\Repos
 

	
 

	
docs/theme/nature/static/pygments.css
Show inline comments
 
@@ -6,49 +6,49 @@
 
.c1 { color: #999988; font-style: italic } /* Comment.Single */
 
.gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
 
.ge { font-style: italic } /* Generic.Emph */
 
.gr { color: #aa0000 } /* Generic.Error */
 
.gh { color: #999999 } /* Generic.Heading */
 
.gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
 
.go { color: #111 } /* Generic.Output */
 
.gp { color: #555555 } /* Generic.Prompt */
 
.gs { font-weight: bold } /* Generic.Strong */
 
.gu { color: #aaaaaa } /* Generic.Subheading */
 
.gt { color: #aa0000 } /* Generic.Traceback */
 
.kc { font-weight: bold } /* Keyword.Constant */
 
.kd { font-weight: bold } /* Keyword.Declaration */
 
.kp { font-weight: bold } /* Keyword.Pseudo */
 
.kr { font-weight: bold } /* Keyword.Reserved */
 
.kt { color: #445588; font-weight: bold } /* Keyword.Type */
 
.m { color: #009999 } /* Literal.Number */
 
.s { color: #bb8844 } /* Literal.String */
 
.na { color: #008080 } /* Name.Attribute */
 
.nb { color: #999999 } /* Name.Builtin */
 
.nc { color: #445588; font-weight: bold } /* Name.Class */
 
.no { color: #ff99ff } /* Name.Constant */
 
.ni { color: #800080 } /* Name.Entity */
 
.ne { color: #990000; font-weight: bold } /* Name.Exception */
 
.nf { color: #990000; font-weight: bold } /* Name.Function */
 
.nn { color: #555555 } /* Name.Namespace */
 
.nt { color: #000080 } /* Name.Tag */
 
.nv { color: purple } /* Name.Variable */
 
.ow { font-weight: bold } /* Operator.Word */
 
.mf { color: #009999 } /* Literal.Number.Float */
 
.mh { color: #009999 } /* Literal.Number.Hex */
 
.mi { color: #009999 } /* Literal.Number.Integer */
 
.mo { color: #009999 } /* Literal.Number.Oct */
 
.sb { color: #bb8844 } /* Literal.String.Backtick */
 
.sc { color: #bb8844 } /* Literal.String.Char */
 
.sd { color: #bb8844 } /* Literal.String.Doc */
 
.s2 { color: #bb8844 } /* Literal.String.Double */
 
.se { color: #bb8844 } /* Literal.String.Escape */
 
.sh { color: #bb8844 } /* Literal.String.Heredoc */
 
.si { color: #bb8844 } /* Literal.String.Interpol */
 
.sx { color: #bb8844 } /* Literal.String.Other */
 
.sr { color: #808000 } /* Literal.String.Regex */
 
.s1 { color: #bb8844 } /* Literal.String.Single */
 
.ss { color: #bb8844 } /* Literal.String.Symbol */
 
.bp { color: #999999 } /* Name.Builtin.Pseudo */
 
.vc { color: #ff99ff } /* Name.Variable.Class */
 
.vg { color: #ff99ff } /* Name.Variable.Global */
 
.vi { color: #ff99ff } /* Name.Variable.Instance */
 
.il { color: #009999 } /* Literal.Number.Integer.Long */
 
\ No newline at end of file
 
.il { color: #009999 } /* Literal.Number.Integer.Long */
docs/usage/performance.rst
Show inline comments
 
.. _performance:
 

	
 
================================
 
Optimizing RhodeCode Performance
 
================================
 

	
 
When serving large amount of big repositories RhodeCode can start
 
performing slower than expected. Because of demanding nature of handling large
 
amount of data from version control systems here are some tips how to get
 
the best performance.
 

	
 
* RhodeCode will perform better on machines with faster disks (SSD/SAN). It's
 
  more important to have faster disk than faster CPU.
 

	
 
* Slowness on initial page can be easily fixed by grouping repositories, and/or
 
  increasing cache size (see below), that includes using lightweight dashboard
 
  option and vcs_full_cache setting in .ini file
 

	
 

	
 
Follow these few steps to improve performance of RhodeCode system.
 

	
 

	
 
1. Increase cache
 

	
 
    in the .ini file::
 

	
 
     beaker.cache.sql_cache_long.expire=3600 <-- set this to higher number
 

	
 
    This option affects the cache expiration time for main page. Having
 
    few hundreds of repositories on main page can sometimes make the system
 
    to behave slow when cache expires for all of them. Increasing `expire`
 
    option to day (86400) or a week (604800) will improve general response
 
    times for the main page. RhodeCode has an intelligent cache expiration
 
    system and it will expire cache for repositories that had been changed.
 

	
 
2. Switch from sqlite to postgres or mysql
 

	
 
    sqlite is a good option when having small load on the system. But due to
 
    locking issues with sqlite, it's not recommended to use it for larger
 
    setup. Switching to mysql or postgres will result in a immediate
 
    performance increase.
 

	
 
3. Scale RhodeCode horizontally
 

	
 
    Scaling horizontally can give huge performance increase when dealing with
 
    large traffic (large amount of users, CI servers etc). RhodeCode can be
 
    scaled horizontally on one (recommended) or multiple machines. In order
 
    to scale horizontally you need to do the following:
 
    
 

	
 
    - each instance needs it's own .ini file and unique `instance_id` set in them
 
    - each instance `data` storage needs to be configured to be stored on a 
 
    - each instance `data` storage needs to be configured to be stored on a
 
      shared disk storage, preferably together with repositories. This `data`
 
      dir contains template caches, sessions, whoosh index and it's used for
 
      tasks locking (so it's safe across multiple instances). Set the
 
      `cache_dir`, `index_dir`, `beaker.cache.data_dir`, `beaker.cache.lock_dir`
 
      variables in each .ini file to shared location across RhodeCode instances 
 
      variables in each .ini file to shared location across RhodeCode instances
 
    - if celery is used each instance should run separate celery instance, but
 
      the message broken should be common to all of them (ex one rabbitmq
 
      shared server)    
 
      shared server)
 
    - load balance using round robin or ip hash, recommended is writing LB rules
 
      that will separate regular user traffic from automated processes like CI
 
      servers or build bots.
 

	
 

	
requires.txt
Show inline comments
 
waitress==0.8.1
 
webob==1.0.8
 
Pylons==1.0.0
 
Beaker==1.6.4
 
WebHelpers==1.3
 
formencode==1.2.4
 
SQLAlchemy==0.7.8
 
Mako==0.7.2
 
pygments>=1.5
 
whoosh>=2.4.0,<2.5
 
celery>=2.2.5,<2.3
 
babel
 
python-dateutil>=1.5.0,<2.0.0
 
dulwich>=0.8.5,<0.9.0
 
markdown==2.1.1
 
docutils==0.8.1
 
simplejson==2.5.2
 
mock
 
py-bcrypt
 
mercurial==2.3.0
 
\ No newline at end of file
 
mercurial==2.3.0
rhodecode/public/css/style.css
Show inline comments
 
@@ -269,142 +269,142 @@ div:hover > a.permalink {
 
    list-style: none;
 
    float: left;
 
    margin: 8px 0 0;
 
    padding: 4px 12px;
 
    border-left: 1px solid #316293;
 
}
 

	
 
#header ul#logged-user li.first {
 
    border-left: none;
 
    margin: 4px;
 
}
 

	
 
#header ul#logged-user li.first div.gravatar {
 
    margin-top: -2px;
 
}
 

	
 
#header ul#logged-user li.first div.account {
 
    padding-top: 4px;
 
    float: left;
 
}
 

	
 
#header ul#logged-user li.last {
 
    border-right: none;
 
}
 

	
 
#header ul#logged-user li a {
 
    color: #fff;
 
    font-weight: 700;
 
    text-decoration: none;
 
}
 

	
 
#header ul#logged-user li a:hover {
 
    text-decoration: underline;
 
}
 

	
 
#header ul#logged-user li.highlight a {
 
    color: #fff;
 
}
 

	
 
#header ul#logged-user li.highlight a:hover {
 
    color: #FFF;
 
}
 
#header-dd {
 
    clear: both;
 
    position: fixed !important;
 
    background-color: #003B76;
 
    opacity: 0.01;
 
    cursor: pointer;
 
    min-height: 10px;	
 
    min-height: 10px;
 
    width: 100% !important;
 
    -webkit-border-radius: 0px 0px 4px 4px;
 
    -khtml-border-radius: 0px 0px 4px 4px;
 
    -moz-border-radius: 0px 0px 4px 4px;
 
    border-radius: 0px 0px 4px 4px;
 
}
 

	
 
#header-dd:hover{
 
	opacity: 0.2;
 
    -webkit-transition: opacity 0.5s ease-in-out;
 
    -moz-transition: opacity 0.5s ease-in-out;
 
    transition: opacity 0.5s ease-in-out;	
 
    transition: opacity 0.5s ease-in-out;
 
}
 

	
 
#header #header-inner {
 
    min-height: 44px;
 
    clear: both;
 
    position: relative;
 
    background-color: #003B76;
 
    background-repeat: repeat-x;
 
    background-image: -khtml-gradient(linear, left top, left bottom, from(#003B76), to(#00376E) );
 
    background-image: -moz-linear-gradient(top, #003b76, #00376e);
 
    background-image: -ms-linear-gradient(top, #003b76, #00376e);
 
    background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #003b76),color-stop(100%, #00376e) );
 
    background-image: -webkit-linear-gradient(top, #003b76, #00376e);
 
    background-image: -o-linear-gradient(top, #003b76, #00376e);
 
    background-image: linear-gradient(top, #003b76, #00376e);
 
    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#003b76',endColorstr='#00376e', GradientType=0 );
 
    margin: 0;
 
    padding: 0;
 
    display: block;
 
    box-shadow: 0 2px 2px rgba(0, 0, 0, 0.6);
 
    -webkit-border-radius: 0px 0px 4px 4px;
 
    -khtml-border-radius: 0px 0px 4px 4px;
 
    -moz-border-radius: 0px 0px 4px 4px;
 
    border-radius: 0px 0px 4px 4px;
 
}
 
#header #header-inner.hover {
 
    width: 100% !important;
 
    -webkit-border-radius: 0px 0px 0px 0px;
 
    -khtml-border-radius: 0px 0px 0px 0px;
 
    -moz-border-radius: 0px 0px 0px 0px;
 
    border-radius: 0px 0px 0px 0px;
 
    position: fixed !important;
 
    z-index: 10000;    
 
    z-index: 10000;
 
}
 

	
 
.ie7 #header #header-inner.hover,
 
.ie8 #header #header-inner.hover,
 
.ie9 #header #header-inner.hover
 
{
 
    z-index: auto !important;
 
}
 

	
 
.header-pos-fix, .anchor {
 
    margin-top: -46px;
 
    padding-top: 46px;
 
}
 

	
 
#header #header-inner #home a {
 
    height: 40px;
 
    width: 46px;
 
    display: block;
 
    background: url("../images/button_home.png");
 
    background-position: 0 0;
 
    margin: 0;
 
    padding: 0;
 
}
 

	
 
#header #header-inner #home a:hover {
 
    background-position: 0 -40px;
 
}
 

	
 
#header #header-inner #logo {
 
    float: left;
 
    position: absolute;
 
}
 

	
 
#header #header-inner #logo h1 {
 
    color: #FFF;
 
    font-size: 20px;
 
    margin: 12px 0 0 13px;
 
    padding: 0;
 
}
 

	
 
#header #header-inner #logo a {
 
    color: #fff;
 
    text-decoration: none;
 
}
 

	
 
#header #header-inner #logo a:hover {
 
    color: #bfe3ff;
 
}
 
@@ -2109,97 +2109,97 @@ a.metatag[tag="license"]:hover {
 
    text-align: left;
 
}
 

	
 
#quick_login .password_forgoten a {
 
    font-size: 10px;
 
    color: #fff;
 
}
 

	
 
#quick_login .register {
 
    padding-right: 10px;
 
    padding-top: 5px;
 
    text-align: left;
 
}
 

	
 
#quick_login .register a {
 
    font-size: 10px;
 
    color: #fff;
 
}
 

	
 
#quick_login .submit {
 
    margin: -20px 0 0 0px;
 
    position: absolute;
 
    right: 15px;
 
}
 

	
 
#quick_login .links_left {
 
    float: left;
 
}
 
#quick_login .links_right {
 
    float: right;
 
}
 
#quick_login .full_name {
 
    color: #FFFFFF;
 
    font-weight: bold;
 
    padding: 3px 3px 3px 6px;
 
}
 
#quick_login .big_gravatar {
 
    padding:4px 0px 0px 6px;
 
}
 
#quick_login .notifications {
 
    padding:4px 0px 0px 6px;
 
    color: #FFFFFF;
 
    font-weight: bold;
 
}
 
#quick_login .notifications a,
 
#quick_login .unread a {
 
    color: #FFFFFF;
 
    display: block;
 
    padding: 2px;    
 
    padding: 2px;
 
}
 
#quick_login .notifications a:hover,
 
#quick_login .unread a:hover {
 
    background-color: inherit !important;
 
}
 
#quick_login .email, #quick_login .unread {
 
    color: #FFFFFF;
 
    padding: 3px 3px 3px 6px;
 
}
 
#quick_login .links .logout {
 
}
 

	
 
#quick_login div.form div.fields {
 
    padding-top: 2px;
 
    padding-left: 10px;
 
}
 

	
 
#quick_login div.form div.fields div.field {
 
    padding: 5px;
 
}
 

	
 
#quick_login div.form div.fields div.field div.label label {
 
    color: #fff;
 
    padding-bottom: 3px;
 
}
 

	
 
#quick_login div.form div.fields div.field div.input input {
 
    width: 236px;
 
    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-size: 11px;
 
    margin: 0;
 
    padding: 5px 7px 4px;
 
}
 

	
 
#quick_login div.form div.fields div.buttons {
 
    clear: both;
 
    overflow: hidden;
 
    text-align: right;
 
    margin: 0;
 
    padding: 5px 14px 0px 5px;
 
}
 

	
 
#quick_login div.form div.links {
rhodecode/templates/admin/users/user_edit_my_account.html
Show inline comments
 
@@ -108,97 +108,97 @@ var show_perms = function(e){
 
    YUD.addClass('show_perms', 'current');
 
    YUD.removeClass('show_my','current');
 
    YUD.removeClass('show_pullrequests','current');
 

	
 
    YUD.setStyle('my_container','display','none');
 
    YUD.setStyle('pullrequests_container','display','none');
 
    YUD.setStyle('perms_container','display','');
 
    YUD.setStyle('q_filter','display','none');
 
}
 
YUE.on('show_perms','click',function(e){
 
    show_perms();
 
})
 

	
 
var show_my = function(e){
 
    YUD.addClass('show_my', 'current');
 
    YUD.removeClass('show_perms','current');
 
    YUD.removeClass('show_pullrequests','current');
 

	
 
    YUD.setStyle('perms_container','display','none');
 
    YUD.setStyle('pullrequests_container','display','none');
 
    YUD.setStyle('my_container','display','');
 
    YUD.setStyle('q_filter','display','');
 
    if(!YUD.hasClass('show_my', 'loaded')){
 
        table_renderer(${c.data |n});
 
        YUD.addClass('show_my', 'loaded');
 
    }
 
}
 
YUE.on('show_my','click',function(e){
 
    show_my(e);
 
})
 

	
 
var show_pullrequests = function(e){
 
    YUD.addClass('show_pullrequests', 'current');
 
    YUD.removeClass('show_my','current');
 
    YUD.removeClass('show_perms','current');
 

	
 
    YUD.setStyle('my_container','display','none');
 
    YUD.setStyle('perms_container','display','none');
 
    YUD.setStyle('pullrequests_container','display','');
 
    YUD.setStyle('q_filter','display','none');
 

	
 
    var url = pyroutes.url('admin_settings_my_pullrequests');
 
    if(YUD.get('show_closed') && YUD.get('show_closed').checked) {
 
    	var url = pyroutes.url('admin_settings_my_pullrequests', {'pr_show_closed': '1'});
 
    }
 
    ypjax(url, 'pullrequests_container', function(){
 
        YUE.on('show_closed','change',function (e) {
 
            show_pullrequests(e);
 
        });    	
 
        });
 
    });
 
}
 
YUE.on('show_pullrequests','click',function(e){
 
    show_pullrequests(e)
 
})
 

	
 
var tabs = {
 
    'perms': show_perms,
 
    'my': show_my,
 
    'pullrequests': show_pullrequests
 
}
 
var url = location.href.split('#');
 
if (url[1]) {
 
    //We have a hash
 
    var tabHash = url[1];
 
    var func = tabs[tabHash]
 
    if (func){
 
        func();
 
    }
 
}
 

	
 
function table_renderer(data){
 
    var myDataSource = new YAHOO.util.DataSource(data);
 
    myDataSource.responseType = YAHOO.util.DataSource.TYPE_JSON;
 

	
 
    myDataSource.responseSchema = {
 
        resultsList: "records",
 
        fields: [
 
            {key:"menu"},
 
            {key:"raw_name"},
 
            {key:"name"},
 
            {key:"last_changeset"},
 
            {key:"action"},
 
            ]
 
        };
 
    myDataSource.doBeforeCallback = function(req,raw,res,cb) {
 
        // This is the filter function
 
        var data     = res.results || [],
 
            filtered = [],
 
            i,l;
 

	
 
        if (req) {
 
            req = req.toLowerCase();
 
            for (i = 0; i<data.length; i++) {
 
                var pos = data[i].raw_name.toLowerCase().indexOf(req)
 
                if (pos != -1) {
 
                    filtered.push(data[i]);
 
                }
rhodecode/templates/pullrequests/pullrequest_show.html
Show inline comments
 
<%inherit file="/base/base.html"/>
 

	
 
<%def name="title()">
 
    ${c.repo_name} ${_('Pull request #%s') % c.pull_request.pull_request_id}
 
</%def>
 

	
 
<%def name="breadcrumbs_links()">
 
    ${h.link_to(_(u'Home'),h.url('/'))}
 
    &raquo;
 
    ${h.repo_link(c.rhodecode_db_repo.groups_and_repo)}
 
    &raquo;
 
    ${_('Pull request #%s') % c.pull_request.pull_request_id}
 
</%def>
 

	
 
<%def name="main()">
 

	
 
<div class="box">
 
    <!-- box / title -->
 
    <div class="title">
 
        ${self.breadcrumbs()}
 
    </div>
 
        %if c.pull_request.is_closed():
 
        <div style="padding:10px; font-size:22px;width:100%;text-align: center; color:#88D882">${_('Closed %s') % (h.age(c.pull_request.updated_on))} ${_('with status %s') % h.changeset_status_lbl(c.current_changeset_status)}</div>
 
        %endif
 
    <h3>
 
    %if c.pull_request.is_closed():
 
        <img src="${h.url('/images/icons/lock_go.png')}" title="${_('Closed')}"/>
 
    %endif
 
    <img src="${h.url('/images/icons/flag_status_%s.png' % str(c.pull_request.last_review_status))}" />    
 
    <img src="${h.url('/images/icons/flag_status_%s.png' % str(c.pull_request.last_review_status))}" />
 
    ${_('Title')}: ${c.pull_request.title}</h3>
 

	
 
    <div class="form">
 
      <div id="summary" class="fields">
 
         <div class="field">
 
          <div class="label-summary">
 
              <label>${_('Review status')}:</label>
 
          </div>
 
          <div class="input">
 
            <div class="changeset-status-container" style="float:none;clear:both">
 
            %if c.current_changeset_status:
 
              <div title="${_('Pull request status')}" class="changeset-status-lbl">${h.changeset_status_lbl(c.current_changeset_status)}</div>
 
              <div class="changeset-status-ico" style="padding:1px 4px"><img src="${h.url('/images/icons/flag_status_%s.png' % c.current_changeset_status)}" /></div>
 
            %endif
 
            </div>
 
          </div>
 
         </div>
 
         <div class="field">
 
          <div class="label-summary">
 
              <label>${_('Still not reviewed by')}:</label>
 
          </div>
 
          <div class="input">
 
            % if len(c.pull_request_pending_reviewers) > 0:
 
                <div class="tooltip" title="${h.tooltip(','.join([x.username for x in c.pull_request_pending_reviewers]))}">${ungettext('%d reviewer', '%d reviewers',len(c.pull_request_pending_reviewers)) % len(c.pull_request_pending_reviewers)}</div>
 
            %else:
 
                <div>${_('pull request was reviewed by all reviewers')}</div>
 
            %endif
 
          </div>
 
         </div>
 
         <div class="field">
 
          <div class="label-summary">
 
              <label>${_('Origin repository')}:</label>
 
          </div>
 
          <div class="input">
 
              <div>
 
             ##%if h.is_hg(c.pull_request.org_repo):
 
             ##  <img class="icon" title="${_('Mercurial repository')}" alt="${_('Mercurial repository')}" src="${h.url('/images/icons/hgicon.png')}"/>
 
             ##%elif h.is_git(c.pull_request.org_repo):
 
             ##  <img class="icon" title="${_('Git repository')}" alt="${_('Git repository')}" src="${h.url('/images/icons/giticon.png')}"/>
 
             ##%endif
 
              <span class="spantag">${c.pull_request.org_ref_parts[0]}: ${c.pull_request.org_ref_parts[1]}</span>
 
              <span><a href="${h.url('summary_home', repo_name=c.pull_request.org_repo.repo_name)}">${c.pull_request.org_repo.clone_url()}</a></span>
 
              </div>
 
          </div>
 
         </div>
 
         <div class="field">
 
          <div class="label-summary">
 
              <label>${_('Summary')}:</label>
0 comments (0 inline, 0 general)