Changeset - 25ab66a26975
[Not reviewed]
default
0 5 0
Marcin Kuzminski - 15 years ago 2010-08-20 18:43:08
marcin@python-works.com
fix for new bcrypt password.
Some templating updates, added "time ago" to file browser
changed whoosh dep.
5 files changed with 10 insertions and 4 deletions:
0 comments (0 inline, 0 general)
pylons_app/model/forms.py
Show inline comments
 
""" this is forms validation classes
 
http://formencode.org/module-formencode.validators.html
 
for list off all availible validators
 

	
 
we can create our own validators
 

	
 
The table below outlines the options which can be used in a schema in addition to the validators themselves
 
pre_validators          []     These validators will be applied before the schema
 
chained_validators      []     These validators will be applied after the schema
 
allow_extra_fields      False     If True, then it is not an error when keys that aren't associated with a validator are present
 
filter_extra_fields     False     If True, then keys that aren't associated with a validator are removed
 
if_key_missing          NoDefault If this is given, then any keys that aren't available but are expected will be replaced with this value (and then validated). This does not override a present .if_missing attribute on validators. NoDefault is a special FormEncode class to mean that no default values has been specified and therefore missing keys shouldn't take a default value.
 
ignore_key_missing      False     If True, then missing keys will be missing in the result, if the validator doesn't have .if_missing on it already    
 
  
 
  
 
<name> = formencode.validators.<name of validator>
 
<name> must equal form name
 
list=[1,2,3,4,5]
 
for SELECT use formencode.All(OneOf(list), Int())
 
    
 
"""
 
from formencode import All
 
from formencode.validators import UnicodeString, OneOf, Int, Number, Regex, \
 
    Email, Bool, StringBoolean
 
from pylons import session
 
from pylons.i18n.translation import _
 
from pylons_app.lib.auth import check_password
 
from pylons_app.lib.auth import check_password, get_crypt_password
 
from pylons_app.model import meta
 
from pylons_app.model.db import User, Repository
 
from sqlalchemy.exc import OperationalError
 
from sqlalchemy.orm.exc import NoResultFound, MultipleResultsFound
 
from webhelpers.pylonslib.secure_form import authentication_token
 
import datetime
 
import formencode
 
import logging
 
import os
 
import pylons_app.lib.helpers as h
 
log = logging.getLogger(__name__)
 

	
 

	
 
#this is needed to translate the messages using _() in validators
 
class State_obj(object):
 
    _ = staticmethod(_)
 
    
 
#===============================================================================
 
# VALIDATORS
 
#===============================================================================
 
class ValidAuthToken(formencode.validators.FancyValidator):
 
    messages = {'invalid_token':_('Token mismatch')}
 

	
 
    def validate_python(self, value, state):
 

	
 
        if value != authentication_token():
 
            raise formencode.Invalid(self.message('invalid_token', state,
 
                                            search_number=value), value, state)
 
            
 
def ValidUsername(edit, old_data):             
 
    class _ValidUsername(formencode.validators.FancyValidator):
 
    
 
        def validate_python(self, value, state):
 
            if value in ['default', 'new_user']:
 
                raise formencode.Invalid(_('Invalid username'), value, state)
 
            #check if user is uniq
 
            sa = meta.Session
 
            old_un = None
 
            if edit:
 
                old_un = sa.query(User).get(old_data.get('user_id')).username
 
                
 
            if old_un != value or not edit:    
 
                if sa.query(User).filter(User.username == value).scalar():
 
                    raise formencode.Invalid(_('This username already exists') ,
 
                                             value, state)
 
            meta.Session.remove()
 
                            
 
    return _ValidUsername   
pylons_app/public/css/style.css
Show inline comments
 
@@ -2811,96 +2811,102 @@ div.form div.fields div.buttons input
 
	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;
 
}
 
 
#register div.form div.activation_msg {
 
	padding-top:4px;
 
	padding-bottom:4px;
 
	
 
}
 
 
/* -----------------------------------------------------------
 
	SUMMARY
 
----------------------------------------------------------- */
 
 
#clone_url{
 
	border: none;
 
}
 
 
/* -----------------------------------------------------------
 
	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;
 
}
pylons_app/templates/admin/users/users.html
Show inline comments
 
## -*- coding: utf-8 -*-
 
<%inherit file="/base/base.html"/>
 

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

	
 
<%def name="breadcrumbs_links()">
 
    ${h.link_to(_('Admin'),h.url('admin_home'))} &raquo; ${_('Users')}
 
</%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 USER',h.url('new_user'),class_="add_icon")}</span>
 
          </li>
 
          
 
        </ul>        
 
    </div>
 
    <!-- end box / title -->
 
    <div class="table">
 
        <table class="table_disp">
 
        <tr class="header">
 
        	<th></th>
 
            <th class="left">${_('username')}</th>
 
            <th class="left">${_('name')}</th>
 
            <th class="left">${_('lastname')}</th>
 
            <th class="left">${_('active')}</th>
 
            <th class="left">${_('admin')}</th>
 
            <th class="left">${_('action')}</th>
 
        </tr>
 
            %for cnt,user in enumerate(c.users_list):
 
             %if user.name !='default':
 
                <tr class="parity${cnt%2}">
 
                	<td><div class="gravatar"><img alt="gravatar" src="${h.gravatar_url(user.email)}"> </div></td>
 
                	<td><div class="gravatar"><img alt="gravatar" src="${h.gravatar_url(user.email,24)}"> </div></td>
 
                    <td>${h.link_to(user.username,h.url('edit_user', id=user.user_id))}</td>
 
                    <td>${user.name}</td>
 
                    <td>${user.lastname}</td>
 
                    <td>${user.active}</td>
 
                    <td>${user.admin}</td>
 
                    <td>
 
                        ${h.form(url('user', id=user.user_id),method='delete')}
 
                            ${h.submit('remove','delete',class_="delete_icon action_button")}
 
                        ${h.end_form()}
 
                    </td>
 
                </tr>
 
             %endif
 
            %endfor
 
        </table>
 
    </div>
 
</div>
 
</%def>
pylons_app/templates/files/files_browser.html
Show inline comments
 
@@ -11,61 +11,61 @@
 
		<div class="info_box">
 
          <span >${_('view')}@rev</span> 
 
          <a href="${c.url_prev}">&laquo;</a>
 
          ${h.text('at_rev',value=c.rev_nr,size=3)}
 
          <a href="${c.url_next}">&raquo;</a>
 
          ${h.submit('view','view')}
 
	    </div>           
 
		${h.end_form()}
 
	</div>
 
	<div class="browser-body">
 
		<table class="code-browser">
 
		         <thead>
 
		             <tr>
 
		                 <th>${_('Name')}</th>
 
		                 <th>${_('Size')}</th>
 
		                 <th>${_('Revision')}</th>
 
		                 <th>${_('Last modified')}</th>
 
		                 <th>${_('Last commiter')}</th>
 
		             </tr>
 
		         </thead>
 
		         	<tr class="parity0">
 
		          		<td>
 
		          		% if c.files_list.parent:
 
		          			${h.link_to('..',h.url('files_home',repo_name=c.repo_name,revision=c.cur_rev,f_path=c.files_list.parent.path),class_="browser-dir")}
 
		          		%endif
 
		          		</td>
 
		          		<td></td>
 
		          		<td></td>
 
		          		<td></td>
 
		          		<td></td>
 
		         	</tr>
 
		    %for cnt,node in enumerate(c.files_list,1):
 
				<tr class="parity${cnt%2}">
 
		             <td>
 
						${h.link_to(node.name,h.url('files_home',repo_name=c.repo_name,revision=c.cur_rev,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.last_changeset.revision}
 
		             	%endif
 
		             </td>
 
		             <td>
 
		             	%if node.is_file():
 
		             		${node.last_changeset.date}
 
		             		${h.age(node.last_changeset._ctx.date())} - ${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
setup.py
Show inline comments
 
from pylons_app import get_version
 
try:
 
    from setuptools import setup, find_packages
 
except ImportError:
 
    from ez_setup import use_setuptools
 
    use_setuptools()
 
    from setuptools import setup, find_packages
 

	
 
setup(
 
    name='hg_app',
 
    version=get_version(),
 
    description='Mercurial repository serving and browsing app',
 
    keywords='mercurial web hgwebdir replacement serving hgweb',
 
    license='BSD',
 
    author='marcin kuzminski',
 
    author_email='marcin@python-works.com',
 
    url='http://hg.python-works.com',
 
    install_requires=[
 
        "Pylons>=1.0.0",
 
        "SQLAlchemy>=0.6",
 
        "Mako>=0.3.2",
 
        "vcs>=0.1.4",
 
        "pygments>=1.3.0",
 
        "mercurial>=1.6",
 
        "pysqlite",
 
        "whoosh>=1.0.0b5",
 
        "whoosh==1.0.0b9",
 
        "py-bcrypt",
 
    ],
 
    setup_requires=["PasteScript>=1.6.3"],
 
    packages=find_packages(exclude=['ez_setup']),
 
    include_package_data=True,
 
    test_suite='nose.collector',
 
    package_data={'pylons_app': ['i18n/*/LC_MESSAGES/*.mo']},
 
    message_extractors={'pylons_app': [
 
            ('**.py', 'python', None),
 
            ('templates/**.mako', 'mako', {'input_encoding': 'utf-8'}),
 
            ('public/**', 'ignore', None)]},
 
    zip_safe=False,
 
    paster_plugins=['PasteScript', 'Pylons'],
 
    entry_points="""
 
    [paste.app_factory]
 
    main = pylons_app.config.middleware:make_app
 

	
 
    [paste.app_install]
 
    main = pylons.util:PylonsInstaller
 
    """,
 
)
0 comments (0 inline, 0 general)