Permalink
Browse files

fix merge conflicts

  • Loading branch information...
2 parents ea0da83 + 9e78f5e commit 5ad8e92418a3ed27d87d292d044e98a1d075c9f4 @mcdonc mcdonc committed Feb 15, 2012
@@ -1,13 +1,15 @@
shootout
========
-shootout is a demo app for the Pyramid web framework. The concepts
+Shootout is a demo app for the Pyramid web framework. The concepts
demonstrated in the code include:
- Urldispatch mechanism (similar to routes).
- Built-in authentication and authorization mechanism.
+- Beaker encrypted sessions using pyramid_beaker.
+
- Integration with pyramid_simpleform for form handling.
- SQLAlchemy based models.
@@ -22,17 +24,17 @@ On a Debian system, these imply: build-essentials, libsqlite3-dev.
Installing and Running
----------------------
-#. virtualenv --no-site-packages env
+- virtualenv --no-site-packages env
-#. cd env
+- cd env
-#. . bin/activate
+- . bin/activate
-#. git clone git@github.com:Pylons/shootout.git
+- git clone git@github.com:Pylons/shootout.git
-#. cd shootout
+- cd shootout
-#. python setup.py develop
+- python setup.py develop
-#. paster serve development.ini
+- paster serve development.ini
View
@@ -1,14 +1,20 @@
[app:main]
use = egg:shootout
+
reload_templates = true
debug_authorization = false
debug_notfound = false
debug_routematch = false
debug_templates = true
default_locale_name = en
-sqlalchemy.url = sqlite:///%(here)s/shootout.db
+session.type = cookie
+session.key = shootout
+session.encrypt_key = mysecretencryptionkey
+session.validate_key = mysecretvalidationkey
+session.cookie_on_exception = true
pyramid.includes = pyramid_debugtoolbar
pyramid_tm
+sqlalchemy.url = sqlite:///%(here)s/shootout.db
[server:main]
use = egg:waitress#main
View
@@ -1,14 +1,15 @@
[app:main]
use = egg:shootout
-reload_templates = true
+reload_templates = false
debug_authorization = false
debug_notfound = false
debug_routematch = false
debug_templates = true
default_locale_name = en
+pyramid.includes = pyramid_tm
+ pyramid_exclog
+
sqlalchemy.url = sqlite:///%(here)s/shootout.db
-pyramid.includes = pyramid_exclog
- pyramid_tm
[server:main]
use = egg:waitress#main
@@ -35,6 +36,11 @@ level = DEBUG
handlers =
qualname = shootout
+[logger_exc_logger]
+level = ERROR
+handlers = exc_handler
+qualname = exc_logger
+
[logger_sqlalchemy]
level = INFO
handlers =
View
@@ -4,7 +4,7 @@
from setuptools import setup, find_packages
here = os.path.abspath(os.path.dirname(__file__))
-README = open(os.path.join(here, 'README.txt')).read()
+README = open(os.path.join(here, 'README.rst')).read()
CHANGES = open(os.path.join(here, 'CHANGES.txt')).read()
requires = [
@@ -19,15 +19,17 @@
'pyramid_simpleform',
'cryptacular',
'waitress',
+ 'pyramid_beaker',
+ 'pycrypto',
]
if sys.version_info[:3] < (2,5,0):
raise RuntimeError('This application requires Python 2.6+')
setup(name='shootout',
- version='0.2',
+ version='0.2.2',
description='A generic idea discussion and rating app (Pyramid sample)',
- long_description=README + '\n\n' + CHANGES,
+ long_description=README + '\n\n' + CHANGES,
classifiers=[
"Framework :: Pylons",
"Framework :: BFG",
@@ -42,13 +44,13 @@
author_email="cguardia@yahoo.com, virhilo@gmail.com",
url='http://pylons-devel@googlegroups.com',
license="BSD-derived (http://www.repoze.org/LICENSE.txt)",
- keywords='web wsgi pyramid pylons example',
+ keywords='web wsgi bfg pyramid pylons example',
packages=find_packages(),
include_package_data=True,
zip_safe=False,
test_suite='shootout.tests',
- install_requires = requires,
- entry_points = """\
+ install_requires=requires,
+ entry_points="""\
[paste.app_factory]
main = shootout:main
""",
@@ -1,20 +1,21 @@
from pyramid.config import Configurator
from pyramid.authentication import AuthTktAuthenticationPolicy
from pyramid.authorization import ACLAuthorizationPolicy
-from pyramid.session import UnencryptedCookieSessionFactoryConfig
+
+from pyramid_beaker import session_factory_from_settings
from sqlalchemy import engine_from_config
from shootout.models import initialize_sql
-def main(global_config, **settings):
+def main(global_config, **settings): # pragma: no cover
""" This function returns a Pyramid WSGI application.
"""
engine = engine_from_config(settings, 'sqlalchemy.')
initialize_sql(engine)
- session_factory = UnencryptedCookieSessionFactoryConfig('secret')
+ session_factory = session_factory_from_settings(settings)
authn_policy = AuthTktAuthenticationPolicy('s0secret')
authz_policy = ACLAuthorizationPolicy()
View
@@ -9,6 +9,7 @@
from sqlalchemy.orm import backref
from sqlalchemy.orm import column_property
from sqlalchemy.orm import synonym
+from sqlalchemy.orm import joinedload
from sqlalchemy.types import Integer
from sqlalchemy.types import Unicode
from sqlalchemy.types import UnicodeText
@@ -27,9 +28,11 @@
crypt = cryptacular.bcrypt.BCRYPTPasswordManager()
+
def hash_password(password):
return unicode(crypt.encode(password))
+
class User(Base):
"""
Application's user model.
@@ -63,7 +66,7 @@ def __init__(self, username, password, name, email):
@classmethod
def get_by_username(cls, username):
- return DBSession.query(cls).filter(cls.username==username).first()
+ return DBSession.query(cls).filter(cls.username == username).first()
@classmethod
def check_password(cls, username, password):
@@ -100,7 +103,7 @@ def extract_tags(tags_string):
@classmethod
def get_by_name(cls, tag_name):
- tag = DBSession.query(cls).filter(cls.name==tag_name)
+ tag = DBSession.query(cls).filter(cls.name == tag_name)
return tag.first()
@classmethod
@@ -116,7 +119,7 @@ def create_tags(cls, tags_string):
tags.append(tag)
return tags
-
+
@classmethod
def tag_counts(cls):
query = DBSession.query(Tag.name, func.count('*'))
@@ -154,32 +157,54 @@ class Idea(Base):
)
@classmethod
- def get_by_id(cls, idea_id):
- return DBSession.query(cls).filter(cls.idea_id==idea_id).first()
+ def get_query(cls, with_joinedload=True):
+ query = DBSession.query(cls)
+ if with_joinedload:
+ query = query.options(joinedload('tags'), joinedload('author'))
+ return query
+
+ @classmethod
+ def get_by_id(cls, idea_id, with_joinedload=True):
+ query = cls.get_query(with_joinedload)
+ return query.filter(cls.idea_id == idea_id).first()
@classmethod
- def get_by_tagname(cls, tag_name):
- return DBSession.query(Idea).filter(Idea.tags.any(name=tag_name))
+ def get_by_tagname(cls, tag_name, with_joinedload=True):
+ query = cls.get_query(with_joinedload)
+ return query.filter(Idea.tags.any(name=tag_name))
@classmethod
- def ideas_bunch(cls, order_by, how_many=10):
- q = DBSession.query(cls).join('author').filter(cls.target==None)
- return q.order_by(order_by)[:how_many]
+ def ideas_bunch(cls, order_by, how_many=10, with_joinedload=True):
+ query = cls.get_query(with_joinedload).join('author')
+ return query.filter(cls.target == None).order_by(order_by)[:how_many]
def user_voted(self, username):
return bool(self.voted_users.filter_by(username=username).first())
+ def vote(self, user, positive):
+ if positive:
+ self.hits += 1
+ self.author.hits += 1
+ user.delivered_hits += 1
+ else:
+ self.misses += 1
+ self.author.misses += 1
+ user.delivered_misses += 1
+
+ self.voted_users.append(user)
+
class RootFactory(object):
__acl__ = [
(Allow, Everyone, 'view'),
(Allow, Authenticated, 'post')
]
+
def __init__(self, request):
- pass
+ pass # pragma: no cover
-def initialize_sql(engine):
+def initialize_sql(engine): # pragma: no cover
DBSession.configure(bind=engine)
Base.metadata.bind = engine
Base.metadata.create_all(engine)
@@ -14,6 +14,7 @@
<li>Urldispatch mechanism (similar to routes).</li>
<li>Built-in authentication and authorization mechanism.</li>
<li>Integration with pyramid_simpleform for form handling.</li>
+ <li>Beaker encrypted sessions using pyramid_beaker.</li>
<li>SQLAlchemy based models.</li>
</ul>
<p>The code can be checked out from the version control repository at:</p>
@@ -1,5 +1,7 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
+<html xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:tal="http://xml.zope.org/namespaces/tal"
+ xmlns:metal="http://xml.zope.org/namespaces/metal">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<link href="${request.static_url('shootout:static/default.css')}" rel="stylesheet" type="text/css" />
@@ -25,7 +25,7 @@
<div tal:condition="voted">
<p>You already voted for this idea.</p>
</div>
- <div tal:condition="not voted and viewer_username">
+ <div tal:condition="not voted and viewer_username and idea.author.username != viewer_username">
<form action="${request.route_url('idea_vote')}" method="post">
<input name="_csrf" type="hidden"
value="${request.session.get_csrf_token()}">
@@ -67,7 +67,6 @@ def test_doesnt_exitst(self):
self.assertRaises(NoResultFound, query.one)
def test_arleady_exist(self):
- from shootout.models import User
from sqlalchemy.exc import IntegrityError
self._addUser()
self.assertRaises(IntegrityError, self._addUser)
@@ -80,7 +79,7 @@ def test_password_hashing(self):
def test_password_checking(self):
from shootout.models import User
- user = self._addUser()
+ self._addUser()
self.assertTrue(User.check_password(u'username', u'password'))
self.assertFalse(User.check_password(u'username', u'wrong'))
self.assertFalse(User.check_password(u'nobody', u'password'))
@@ -89,7 +88,7 @@ def test_getting_by_username(self):
from shootout.models import User
user = self._addUser()
self.assertEqual(user, User.get_by_username(u'username'))
-
+
class TestTag(ModelsTestCase):
def test_extracting_tags(self):
@@ -110,7 +109,7 @@ def test_creating_tags(self):
self.assertEqual(tags[2].name, tags_names.pop())
def test_tags_counts(self):
- from shootout.models import Tag, Idea
+ from shootout.models import Tag
user = self._addUser()
@@ -233,11 +232,10 @@ def test_ideas_bunch(self):
[idea1, idea4, idea2, idea3])
def test_user_voted(self):
- from shootout.models import Idea
idea = self._addIdea()
voting_user = self._addUser(u'voter')
idea.voted_users.append(voting_user)
self.session.flush()
self.assertTrue(idea.user_voted(u'voter'))
self.assertFalse(idea.user_voted(u'xxx'))
-
+
Oops, something went wrong.

0 comments on commit 5ad8e92

Please sign in to comment.