Changeset - 935dddee7422
[Not reviewed]
Merge celery
0 7 1
Marcin Kuzminski - 15 years ago 2010-09-11 03:42:57
marcin@python-works.com
merged with default
6 files changed:
0 comments (0 inline, 0 general)
pylons_app/config/environment.py
Show inline comments
 
"""Pylons environment configuration"""
 
from mako.lookup import TemplateLookup
 
from pylons.configuration import PylonsConfig
 
from pylons.error import handle_mako_error
 
from pylons_app.config.routing import make_map
 
from pylons_app.lib.auth import set_available_permissions, set_base_path
 
from pylons_app.lib.utils import repo2db_mapper, make_ui, set_hg_app_config
 
from pylons_app.model import init_model
 
from pylons_app.model.hg_model import _get_repos_cached_initial
 
from sqlalchemy import engine_from_config
 
import logging
 
import os
 
import pylons_app.lib.app_globals as app_globals
 
import pylons_app.lib.helpers
 

	
 
log = logging.getLogger(__name__)
 

	
 
def load_environment(global_conf, app_conf, initial=False):
 
    """Configure the Pylons environment via the ``pylons.config``
 
    object
 
    """
 
    config = PylonsConfig()
 
    
 
    # Pylons paths
 
    root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
 
    paths = dict(root=root,
 
                 controllers=os.path.join(root, 'controllers'),
 
                 static_files=os.path.join(root, 'public'),
 
                 templates=[os.path.join(root, 'templates')])
 

	
 
    # Initialize config with the basic options
 
    config.init_app(global_conf, app_conf, package='pylons_app', paths=paths)
 

	
 
    config['routes.map'] = make_map(config)
 
    config['pylons.app_globals'] = app_globals.Globals(config)
 
    config['pylons.h'] = pylons_app.lib.helpers
 
    
 
    # Setup cache object as early as possible
 
    import pylons
 
    pylons.cache._push_object(config['pylons.app_globals'].cache)
 
    
 
    # Create the Mako TemplateLookup, with the default auto-escaping
 
    config['pylons.app_globals'].mako_lookup = TemplateLookup(
 
        directories=paths['templates'],
 
        error_handler=handle_mako_error,
 
        module_directory=os.path.join(app_conf['cache_dir'], 'templates'),
 
        input_encoding='utf-8', default_filters=['escape'],
 
        imports=['from webhelpers.html import escape'])
 

	
 
    #sets the c attribute access when don't existing attribute are accessed
 
    config['pylons.strict_tmpl_context'] = True
 
    
 
    test = os.path.split(config['__file__'])[-1] == 'tests.ini'
 
    #MULTIPLE DB configs
 
    # Setup the SQLAlchemy database engine
 
    if config['debug'] and os.path.split(config['__file__'])[-1] != 'tests.ini':
 
    if config['debug'] and not test:
 
        #use query time debugging.
 
        from pylons_app.lib.timerproxy import TimerProxy
 
        sa_engine_db1 = engine_from_config(config, 'sqlalchemy.db1.',
 
                                                            proxy=TimerProxy())
 
    else:
 
        sa_engine_db1 = engine_from_config(config, 'sqlalchemy.db1.')
 

	
 
    init_model(sa_engine_db1)
 
    #init baseui
 
    config['pylons.app_globals'].baseui = make_ui('db')
 
    
 
    repo2db_mapper(_get_repos_cached_initial(config['pylons.app_globals'], initial))
 
    set_available_permissions(config)
 
    set_base_path(config)
 
    set_hg_app_config(config)
 
    # CONFIGURATION OPTIONS HERE (note: all config options will override
 
    # any Pylons config options)
 
    
 
    return config
pylons_app/controllers/changeset.py
Show inline comments
 
#!/usr/bin/env python
 
# encoding: utf-8
 
# changeset 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 25, 2010
 
changeset controller for pylons
 
@author: marcink
 
"""
 
from pylons import tmpl_context as c, url, request, response
 
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.model.hg_model import HgModel
 
from vcs.exceptions import RepositoryError
 
from vcs.nodes import FileNode
 
from vcs.utils import diffs as differ
 
import logging
 
import traceback
 

	
 
log = logging.getLogger(__name__)
 

	
 
class ChangesetController(BaseController):
 
    
 
    @LoginRequired()
 
    @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
 
                                   'repository.admin')       
 
    def __before__(self):
 
        super(ChangesetController, self).__before__()
 
        
 
    def index(self, revision):
 
        hg_model = HgModel()
 
        try:
 
            c.changeset = hg_model.get_repo(c.repo_name).get_changeset(revision)
 
        except RepositoryError:
 
            log.error(traceback.format_exc())
 
            return redirect(url('hg_home'))
 
        else:
 
            try:
 
                c.changeset_old = c.changeset.parents[0]
 
            except IndexError:
 
                c.changeset_old = None
 
            c.changes = []
 
            
 
            for node in c.changeset.added:
 
                filenode_old = FileNode(node.path, '')
 
                if filenode_old.is_binary or node.is_binary:
 
                    diff = 'binary file'
 
                else:    
 
                    f_udiff = differ.get_udiff(filenode_old, node)
 
                    diff = differ.DiffProcessor(f_udiff).as_html()
 

	
 
                cs1 = None
 
                cs2 = node.last_changeset.raw_id                                        
 
                c.changes.append(('added', node, diff, cs1, cs2))
 
                
 
            for node in c.changeset.changed:
 
                filenode_old = c.changeset_old.get_node(node.path)
 
                if filenode_old.is_binary or node.is_binary:
 
                    diff = 'binary file'
 
                else:    
 
                    f_udiff = differ.get_udiff(filenode_old, node)
 
                    diff = differ.DiffProcessor(f_udiff).as_html()
 

	
 
                cs1 = filenode_old.last_changeset.raw_id
 
                cs2 = node.last_changeset.raw_id                    
 
                c.changes.append(('changed', node, diff, cs1, cs2))
 
                
 
            for node in c.changeset.removed:
 
                c.changes.append(('removed', node, None, None, None))            
 
            
 
        return render('changeset/changeset.html')
 

	
 
    def raw_changeset(self,revision):
 
        
 
        hg_model = HgModel()
 
        method = request.GET.get('diff','show')
 
        try:
 
            c.changeset = hg_model.get_repo(c.repo_name).get_changeset(revision)
 
        except RepositoryError:
 
            log.error(traceback.format_exc())
 
            return redirect(url('hg_home'))
 
        else:
 
            try:
 
                c.changeset_old = c.changeset.parents[0]
 
            except IndexError:
 
                c.changeset_old = None
 
            c.changes = []
 
            
 
            for node in c.changeset.added:
 
                filenode_old = FileNode(node.path, '')
 
                if filenode_old.is_binary or node.is_binary:
 
                    diff = 'binary file'
 
                else:    
 
                    f_udiff = differ.get_udiff(filenode_old, node)
 
                    diff = differ.DiffProcessor(f_udiff).raw_diff()
 

	
 
                cs1 = None
 
                cs2 = node.last_changeset.raw_id                                        
 
                c.changes.append(('added', node, diff, cs1, cs2))
 
                
 
            for node in c.changeset.changed:
 
                filenode_old = c.changeset_old.get_node(node.path)
 
                if filenode_old.is_binary or node.is_binary:
 
                    diff = 'binary file'
 
                else:    
 
                    f_udiff = differ.get_udiff(filenode_old, node)
 
                    diff = differ.DiffProcessor(f_udiff).raw_diff()
 

	
 
                cs1 = filenode_old.last_changeset.raw_id
 
                cs2 = node.last_changeset.raw_id                    
 
                c.changes.append(('changed', node, diff, cs1, cs2))      
 
        
 
        response.content_type = 'text/plain'
 

	
 
        if method == 'download':
 
            response.content_disposition = 'attachment; filename=%s.patch' % revision 
 
        parent = True if len(c.changeset.parents) > 0 else False
 
        c.parent_tmpl = 'Parent  %s' % c.changeset.parents[0]._hex if parent else ''
 
    
 
        c.diffs = ''
 
        for x in c.changes:
 
            c.diffs += x[2]
 
            
 
        return render('changeset/raw_changeset.html')
pylons_app/templates/changeset/changeset.html
Show inline comments
 
<%inherit file="/base/base.html"/>
 

	
 
<%def name="title()">
 
    ${_('Changeset')}
 
</%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;
 
    ${_('Changeset')} - r${c.changeset.revision}:${c.changeset.raw_id}
 
</%def>
 

	
 
<%def name="page_nav()">
 
    ${self.menu('changelog')}     
 
</%def>
 

	
 
<%def name="main()">
 
<div class="box">
 
    <!-- box / title -->
 
    <div class="title">
 
        ${self.breadcrumbs()}
 
    </div>
 
    <div class="table">
 
		<div id="body" class="diffblock">
 
			<div class="code-header">
 
				<div>
 
				${_('Changeset')} - r${c.changeset.revision}:${c.changeset.raw_id}
 
				 &raquo; <span>${h.link_to(_('raw diff'),
 
				h.url('raw_changeset_home',repo_name=c.repo_name,revision=c.changeset.raw_id,diff='show'))}</span>
 
				 &raquo; <span>${h.link_to(_('download diff'),
 
				h.url('raw_changeset_home',repo_name=c.repo_name,revision=c.changeset.raw_id,diff='download'))}</span>
 
				</div>
 
			</div>
 
		</div>
 
		    
 
    <div id="changeset_content">
 
		<div class="container">
 
			<div class="left">
 
				<div class="date">${_('Date')}: ${c.changeset.date}</div>
 
				<div class="author">${_('Author')}: ${c.changeset.author}</div>
 
				<div class="message">${h.wrap_paragraphs(c.changeset.message)}</div>
 
			</div>	
 
			<div class="right">
 
				<span class="logtags">
 
					<span class="branchtag">${c.changeset.branch}</span>
 
					%for tag in c.changeset.tags:
 
						<span class="tagtag">${tag}</span>
 
					%endfor
 
				</span>					
 
				%if len(c.changeset.parents)>1:
 
				<div class="merge">		
 
				${_('merge')}
 
				<img alt="merge" src="/images/icons/arrow_join.png">
 
				</div>
 
				%endif						
 
				%for p_cs in reversed(c.changeset.parents):
 
					<div class="parent">${_('Parent')} ${p_cs.revision}: ${h.link_to(p_cs.raw_id,
 
						h.url('changeset_home',repo_name=c.repo_name,revision=p_cs.raw_id),title=p_cs.message)}
 
					</div>
 
				%endfor								
 
			</div>		
 
		</div>
 
		<span style="font-size:1.1em;font-weight: bold">${_('Files affected')}</span>
 
	    <div class="cs_files">
 
				%for change,filenode,diff,cs1,cs2 in c.changes:
 
					<div class="cs_${change}">${h.link_to(filenode.path,h.url.current(anchor='CHANGE-%s'%filenode.path))}</div>
 
				%endfor
 
		</div>		    
 
    </div>
 
    	
 
	%for change,filenode,diff,cs1,cs2 in c.changes:
 
		%if change !='removed':
 
		<div style="clear:both;height:10px"></div>
 
		<div id="body" class="diffblock">
 
			<div id="${'CHANGE-%s'%filenode.path}" class="code-header">
 
				<div>
 
					<span>
 
						${h.link_to_if(change!='removed',filenode.path,h.url('files_home',repo_name=c.repo_name,
 
						revision=filenode.changeset.raw_id,f_path=filenode.path))}
 
					</span>
 
					%if 1:
 
					&raquo; <span>${h.link_to(_('diff'),
 
					h.url('files_diff_home',repo_name=c.repo_name,f_path=filenode.path,diff2=cs2,diff1=cs1,diff='diff'))}</span>
 
					&raquo; <span>${h.link_to(_('raw diff'),
 
					h.url('files_diff_home',repo_name=c.repo_name,f_path=filenode.path,diff2=cs2,diff1=cs1,diff='raw'))}</span>
 
					&raquo; <span>${h.link_to(_('download diff'),
 
					h.url('files_diff_home',repo_name=c.repo_name,f_path=filenode.path,diff2=cs2,diff1=cs1,diff='download'))}</span>
 
					%endif
 
				</div>
 
			</div>
 
			<div class="code-body">        
 
					%if diff:
 
						${diff|n}
 
					%else:
 
						${_('No changes in this file')}
 
					%endif
 
			</div>
 
		</div>
 
		%endif
 
	%endfor 
 
    </div>
 
</div>    
 
	
 
</%def>
 
\ No newline at end of file
pylons_app/templates/changeset/raw_changeset.html
Show inline comments
 
# HG changeset patch
 
# User ${c.changeset.author}
 
# User ${c.changeset.author|n}
 
# Date ${"%d %d" % c.changeset._ctx.date()}
 
# Node ID ${c.changeset._hex}
 
# ${c.parent_tmpl}
 
${c.changeset.message}
 

	
 
${c.diffs|n}
 
\ No newline at end of file
pylons_app/tests/__init__.py
Show inline comments
 
"""Pylons application test package
 

	
 
This package assumes the Pylons environment is already loaded, such as
 
when this script is imported from the `nosetests --with-pylons=test.ini`
 
command.
 

	
 
This module initializes the application via ``websetup`` (`paster
 
setup-app`) and provides the base testing objects.
 
"""
 
from unittest import TestCase
 

	
 
from paste.deploy import loadapp
 
from paste.script.appinstall import SetupCommand
 
from pylons import config, url
 
from routes.util import URLGenerator
 
from webtest import TestApp
 
import os
 
from pylons_app.model import meta
 
import pylons.test
 

	
 
__all__ = ['environ', 'url', 'TestController']
 

	
 
# Invoke websetup with the current config file
 
SetupCommand('setup-app').run([pylons.test.pylonsapp.config['__file__']])
 

	
 
environ = {}
 

	
 
class TestController(TestCase):
 

	
 
    def __init__(self, *args, **kwargs):
 
        wsgiapp = pylons.test.pylonsapp
 
        config = wsgiapp.config
 
        self.app = TestApp(wsgiapp)
 
        self.session = session
 
        url._push_object(URLGenerator(config['routes.map'], environ))
 
        self.sa = meta.Session
 
        TestCase.__init__(self, *args, **kwargs)
 

	
 
    
 
    def log_user(self):
 
        response = self.app.post(url(controller='login', action='index'),
 
                                 {'username':'test_admin',
 
                                  'password':'test'})
 
        assert response.status == '302 Found', 'Wrong response code from login got %s' % response.status
 
        assert response.session['hg_app_user'].username == 'test_admin', 'wrong logged in user'
 
        return response.follow()        
 
\ No newline at end of file
pylons_app/tests/functional/test_search.py
Show inline comments
 
from pylons_app.tests import *
 
from pylons_app.lib.indexers import IDX_LOCATION
 
import os
 
from nose.plugins.skip import SkipTest
 

	
 
class TestSearchController(TestController):
 

	
 
    def test_index(self):
 
        self.log_user()
 
        response = self.app.get(url(controller='search', action='index'))
 
        print response.body
 
        assert 'class="small" id="q" name="q" type="text"' in response.body,'Search box content error'
 
        # Test response...
 

	
 
    def test_empty_search(self):
 
        
 
        if os.path.isdir(IDX_LOCATION):
 
            raise SkipTest('skipped due to existing index')
 
        else:
 
        self.log_user()
 
        response = self.app.get(url(controller='search', action='index'),{'q':'vcs_test'})
 
        assert 'There is no index to search in. Please run whoosh indexer' in response.body,'No error message about empty index'
 
\ No newline at end of file
 
            assert 'There is no index to search in. Please run whoosh indexer' in response.body,'No error message about empty index'
 
        
 
    def test_normal_search(self):
 
        self.log_user()
 
        response = self.app.get(url(controller='search', action='index'),{'q':'def+repo'})
 
        print response.body
 
        assert '9 results' in response.body,'no message about proper search results'
 
        

Changeset was too big and was cut off... Show full diff anyway

0 comments (0 inline, 0 general)