From f10fb24a3663cb070b28b8020fde957d16563400 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Wed, 2 Dec 2015 04:18:10 -0800 Subject: - rewrite wiki2/tests.rst (removed an obsolete reference to testing models, per 2885a7b96545c037109d7999319f74869a640050) - add wiki2/src/tests/ files. special thanks to @ppaez --- docs/tutorials/wiki2/src/tests/development.ini | 4 +- docs/tutorials/wiki2/src/tests/production.ini | 14 +- docs/tutorials/wiki2/src/tests/setup.py | 4 +- .../tutorials/wiki2/src/tests/tutorial/__init__.py | 18 +- docs/tutorials/wiki2/src/tests/tutorial/models.py | 37 ---- .../wiki2/src/tests/tutorial/models/__init__.py | 7 + .../wiki2/src/tests/tutorial/models/meta.py | 46 ++++ .../wiki2/src/tests/tutorial/models/mymodel.py | 26 +++ .../src/tests/tutorial/scripts/initializedb.py | 25 ++- .../tutorials/wiki2/src/tests/tutorial/security.py | 7 - .../wiki2/src/tests/tutorial/security/__init__.py | 1 + .../wiki2/src/tests/tutorial/security/default.py | 7 + .../wiki2/src/tests/tutorial/static/theme.min.css | 2 +- .../wiki2/src/tests/tutorial/templates/edit.jinja2 | 73 +++++++ .../wiki2/src/tests/tutorial/templates/edit.pt | 74 ------- .../src/tests/tutorial/templates/layout.jinja2 | 66 ++++++ .../src/tests/tutorial/templates/login.jinja2 | 74 +++++++ .../wiki2/src/tests/tutorial/templates/login.pt | 54 ----- .../src/tests/tutorial/templates/mytemplate.jinja2 | 8 + .../src/tests/tutorial/templates/mytemplate.pt | 66 ------ .../wiki2/src/tests/tutorial/templates/view.jinja2 | 71 +++++++ .../wiki2/src/tests/tutorial/templates/view.pt | 74 ------- docs/tutorials/wiki2/src/tests/tutorial/tests.py | 235 --------------------- .../wiki2/src/tests/tutorial/tests/__init__.py | 1 + .../src/tests/tutorial/tests/test_functional.py | 141 +++++++++++++ .../wiki2/src/tests/tutorial/tests/test_views.py | 168 +++++++++++++++ docs/tutorials/wiki2/src/tests/tutorial/views.py | 123 ----------- .../wiki2/src/tests/tutorial/views/__init__.py | 0 .../wiki2/src/tests/tutorial/views/default.py | 120 +++++++++++ 29 files changed, 843 insertions(+), 703 deletions(-) delete mode 100644 docs/tutorials/wiki2/src/tests/tutorial/models.py create mode 100644 docs/tutorials/wiki2/src/tests/tutorial/models/__init__.py create mode 100644 docs/tutorials/wiki2/src/tests/tutorial/models/meta.py create mode 100644 docs/tutorials/wiki2/src/tests/tutorial/models/mymodel.py delete mode 100644 docs/tutorials/wiki2/src/tests/tutorial/security.py create mode 100644 docs/tutorials/wiki2/src/tests/tutorial/security/__init__.py create mode 100644 docs/tutorials/wiki2/src/tests/tutorial/security/default.py create mode 100644 docs/tutorials/wiki2/src/tests/tutorial/templates/edit.jinja2 delete mode 100644 docs/tutorials/wiki2/src/tests/tutorial/templates/edit.pt create mode 100644 docs/tutorials/wiki2/src/tests/tutorial/templates/layout.jinja2 create mode 100644 docs/tutorials/wiki2/src/tests/tutorial/templates/login.jinja2 delete mode 100644 docs/tutorials/wiki2/src/tests/tutorial/templates/login.pt create mode 100644 docs/tutorials/wiki2/src/tests/tutorial/templates/mytemplate.jinja2 delete mode 100644 docs/tutorials/wiki2/src/tests/tutorial/templates/mytemplate.pt create mode 100644 docs/tutorials/wiki2/src/tests/tutorial/templates/view.jinja2 delete mode 100644 docs/tutorials/wiki2/src/tests/tutorial/templates/view.pt delete mode 100644 docs/tutorials/wiki2/src/tests/tutorial/tests.py create mode 100644 docs/tutorials/wiki2/src/tests/tutorial/tests/__init__.py create mode 100644 docs/tutorials/wiki2/src/tests/tutorial/tests/test_functional.py create mode 100644 docs/tutorials/wiki2/src/tests/tutorial/tests/test_views.py delete mode 100644 docs/tutorials/wiki2/src/tests/tutorial/views.py create mode 100644 docs/tutorials/wiki2/src/tests/tutorial/views/__init__.py create mode 100644 docs/tutorials/wiki2/src/tests/tutorial/views/default.py (limited to 'docs/tutorials/wiki2/src/tests') diff --git a/docs/tutorials/wiki2/src/tests/development.ini b/docs/tutorials/wiki2/src/tests/development.ini index a9d53b296..99c4ff0fe 100644 --- a/docs/tutorials/wiki2/src/tests/development.ini +++ b/docs/tutorials/wiki2/src/tests/development.ini @@ -27,7 +27,7 @@ sqlalchemy.url = sqlite:///%(here)s/tutorial.sqlite [server:main] use = egg:waitress#main -host = 0.0.0.0 +host = 127.0.0.1 port = 6543 ### @@ -68,4 +68,4 @@ level = NOTSET formatter = generic [formatter_generic] -format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s +format = %(asctime)s %(levelname)-5.5s [%(name)s:%(lineno)s][%(threadName)s] %(message)s diff --git a/docs/tutorials/wiki2/src/tests/production.ini b/docs/tutorials/wiki2/src/tests/production.ini index 4684d2f7a..97acfbd7d 100644 --- a/docs/tutorials/wiki2/src/tests/production.ini +++ b/docs/tutorials/wiki2/src/tests/production.ini @@ -1,3 +1,8 @@ +### +# app configuration +# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html +### + [app:main] use = egg:tutorial @@ -16,7 +21,10 @@ use = egg:waitress#main host = 0.0.0.0 port = 6543 -# Begin logging configuration +### +# logging configuration +# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html +### [loggers] keys = root, tutorial, sqlalchemy @@ -51,6 +59,4 @@ level = NOTSET formatter = generic [formatter_generic] -format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s - -# End logging configuration +format = %(asctime)s %(levelname)-5.5s [%(name)s:%(lineno)s][%(threadName)s] %(message)s diff --git a/docs/tutorials/wiki2/src/tests/setup.py b/docs/tutorials/wiki2/src/tests/setup.py index d8486e462..f640b4399 100644 --- a/docs/tutorials/wiki2/src/tests/setup.py +++ b/docs/tutorials/wiki2/src/tests/setup.py @@ -10,7 +10,7 @@ with open(os.path.join(here, 'CHANGES.txt')) as f: requires = [ 'pyramid', - 'pyramid_chameleon', + 'pyramid_jinja2', 'pyramid_debugtoolbar', 'pyramid_tm', 'SQLAlchemy', @@ -18,7 +18,7 @@ requires = [ 'zope.sqlalchemy', 'waitress', 'docutils', - 'WebTest', # add this + 'WebTest', ] setup(name='tutorial', diff --git a/docs/tutorials/wiki2/src/tests/tutorial/__init__.py b/docs/tutorials/wiki2/src/tests/tutorial/__init__.py index cee89184b..084fee19f 100644 --- a/docs/tutorials/wiki2/src/tests/tutorial/__init__.py +++ b/docs/tutorials/wiki2/src/tests/tutorial/__init__.py @@ -2,30 +2,20 @@ from pyramid.config import Configurator from pyramid.authentication import AuthTktAuthenticationPolicy from pyramid.authorization import ACLAuthorizationPolicy -from sqlalchemy import engine_from_config - -from tutorial.security import groupfinder - -from .models import ( - DBSession, - Base, - ) - +from security.default import groupfinder def main(global_config, **settings): """ This function returns a Pyramid WSGI application. """ - engine = engine_from_config(settings, 'sqlalchemy.') - DBSession.configure(bind=engine) - Base.metadata.bind = engine authn_policy = AuthTktAuthenticationPolicy( 'sosecret', callback=groupfinder, hashalg='sha512') authz_policy = ACLAuthorizationPolicy() config = Configurator(settings=settings, - root_factory='tutorial.models.RootFactory') - config.include('pyramid_chameleon') + root_factory='tutorial.models.mymodel.RootFactory') config.set_authentication_policy(authn_policy) config.set_authorization_policy(authz_policy) + config.include('pyramid_jinja2') + config.include('.models.meta') config.add_static_view('static', 'static', cache_max_age=3600) config.add_route('view_wiki', '/') config.add_route('login', '/login') diff --git a/docs/tutorials/wiki2/src/tests/tutorial/models.py b/docs/tutorials/wiki2/src/tests/tutorial/models.py deleted file mode 100644 index 4f7e1e024..000000000 --- a/docs/tutorials/wiki2/src/tests/tutorial/models.py +++ /dev/null @@ -1,37 +0,0 @@ -from pyramid.security import ( - Allow, - Everyone, - ) - -from sqlalchemy import ( - Column, - Integer, - Text, - ) - -from sqlalchemy.ext.declarative import declarative_base - -from sqlalchemy.orm import ( - scoped_session, - sessionmaker, - ) - -from zope.sqlalchemy import ZopeTransactionExtension - -DBSession = scoped_session(sessionmaker(extension=ZopeTransactionExtension())) -Base = declarative_base() - - -class Page(Base): - """ The SQLAlchemy declarative model class for a Page object. """ - __tablename__ = 'pages' - id = Column(Integer, primary_key=True) - name = Column(Text, unique=True) - data = Column(Text) - - -class RootFactory(object): - __acl__ = [ (Allow, Everyone, 'view'), - (Allow, 'group:editors', 'edit') ] - def __init__(self, request): - pass diff --git a/docs/tutorials/wiki2/src/tests/tutorial/models/__init__.py b/docs/tutorials/wiki2/src/tests/tutorial/models/__init__.py new file mode 100644 index 000000000..7b1c62867 --- /dev/null +++ b/docs/tutorials/wiki2/src/tests/tutorial/models/__init__.py @@ -0,0 +1,7 @@ +from sqlalchemy.orm import configure_mappers +# import all models classes here for sqlalchemy mappers +# to pick up +from .mymodel import Page # flake8: noqa + +# run configure mappers to ensure we avoid any race conditions +configure_mappers() diff --git a/docs/tutorials/wiki2/src/tests/tutorial/models/meta.py b/docs/tutorials/wiki2/src/tests/tutorial/models/meta.py new file mode 100644 index 000000000..b72b45f9f --- /dev/null +++ b/docs/tutorials/wiki2/src/tests/tutorial/models/meta.py @@ -0,0 +1,46 @@ +from sqlalchemy import engine_from_config +from sqlalchemy.ext.declarative import declarative_base +from sqlalchemy.orm import sessionmaker +from sqlalchemy.schema import MetaData +import zope.sqlalchemy + +NAMING_CONVENTION = { + "ix": 'ix_%(column_0_label)s', + "uq": "uq_%(table_name)s_%(column_0_name)s", + "ck": "ck_%(table_name)s_%(constraint_name)s", + "fk": "fk_%(table_name)s_%(column_0_name)s_%(referred_table_name)s", + "pk": "pk_%(table_name)s" +} + +metadata = MetaData(naming_convention=NAMING_CONVENTION) +Base = declarative_base(metadata=metadata) + + +def includeme(config): + settings = config.get_settings() + dbmaker = get_dbmaker(get_engine(settings)) + + config.add_request_method( + lambda r: get_session(r.tm, dbmaker), + 'dbsession', + reify=True + ) + + config.include('pyramid_tm') + + +def get_session(transaction_manager, dbmaker): + dbsession = dbmaker() + zope.sqlalchemy.register(dbsession, + transaction_manager=transaction_manager) + return dbsession + + +def get_engine(settings, prefix='sqlalchemy.'): + return engine_from_config(settings, prefix) + + +def get_dbmaker(engine): + dbmaker = sessionmaker() + dbmaker.configure(bind=engine) + return dbmaker diff --git a/docs/tutorials/wiki2/src/tests/tutorial/models/mymodel.py b/docs/tutorials/wiki2/src/tests/tutorial/models/mymodel.py new file mode 100644 index 000000000..03e2f90ca --- /dev/null +++ b/docs/tutorials/wiki2/src/tests/tutorial/models/mymodel.py @@ -0,0 +1,26 @@ +from .meta import Base + +from pyramid.security import ( + Allow, + Everyone, + ) + +from sqlalchemy import ( + Column, + Integer, + Text, + ) + + +class Page(Base): + """ The SQLAlchemy declarative model class for a Page object. """ + __tablename__ = 'pages' + id = Column(Integer, primary_key=True) + name = Column(Text, unique=True) + data = Column(Integer) + +class RootFactory(object): + __acl__ = [ (Allow, Everyone, 'view'), + (Allow, 'group:editors', 'edit') ] + def __init__(self, request): + pass \ No newline at end of file diff --git a/docs/tutorials/wiki2/src/tests/tutorial/scripts/initializedb.py b/docs/tutorials/wiki2/src/tests/tutorial/scripts/initializedb.py index 23a5f13f4..4aac4a848 100644 --- a/docs/tutorials/wiki2/src/tests/tutorial/scripts/initializedb.py +++ b/docs/tutorials/wiki2/src/tests/tutorial/scripts/initializedb.py @@ -2,36 +2,41 @@ import os import sys import transaction -from sqlalchemy import engine_from_config - from pyramid.paster import ( get_appsettings, setup_logging, ) -from ..models import ( - DBSession, - Page, +from ..models.meta import ( Base, + get_session, + get_engine, + get_dbmaker, ) +from ..models.mymodel import Page def usage(argv): cmd = os.path.basename(argv[0]) - print('usage: %s \n' + print('usage: %s [var=value]\n' '(example: "%s development.ini")' % (cmd, cmd)) sys.exit(1) def main(argv=sys.argv): - if len(argv) != 2: + if len(argv) < 2: usage(argv) config_uri = argv[1] setup_logging(config_uri) settings = get_appsettings(config_uri) - engine = engine_from_config(settings, 'sqlalchemy.') - DBSession.configure(bind=engine) + + engine = get_engine(settings) + dbmaker = get_dbmaker(engine) + + dbsession = get_session(transaction.manager, dbmaker) + Base.metadata.create_all(engine) + with transaction.manager: model = Page(name='FrontPage', data='This is the front page') - DBSession.add(model) + dbsession.add(model) diff --git a/docs/tutorials/wiki2/src/tests/tutorial/security.py b/docs/tutorials/wiki2/src/tests/tutorial/security.py deleted file mode 100644 index d88c9c71f..000000000 --- a/docs/tutorials/wiki2/src/tests/tutorial/security.py +++ /dev/null @@ -1,7 +0,0 @@ -USERS = {'editor':'editor', - 'viewer':'viewer'} -GROUPS = {'editor':['group:editors']} - -def groupfinder(userid, request): - if userid in USERS: - return GROUPS.get(userid, []) diff --git a/docs/tutorials/wiki2/src/tests/tutorial/security/__init__.py b/docs/tutorials/wiki2/src/tests/tutorial/security/__init__.py new file mode 100644 index 000000000..5bb534f79 --- /dev/null +++ b/docs/tutorials/wiki2/src/tests/tutorial/security/__init__.py @@ -0,0 +1 @@ +# package diff --git a/docs/tutorials/wiki2/src/tests/tutorial/security/default.py b/docs/tutorials/wiki2/src/tests/tutorial/security/default.py new file mode 100644 index 000000000..d88c9c71f --- /dev/null +++ b/docs/tutorials/wiki2/src/tests/tutorial/security/default.py @@ -0,0 +1,7 @@ +USERS = {'editor':'editor', + 'viewer':'viewer'} +GROUPS = {'editor':['group:editors']} + +def groupfinder(userid, request): + if userid in USERS: + return GROUPS.get(userid, []) diff --git a/docs/tutorials/wiki2/src/tests/tutorial/static/theme.min.css b/docs/tutorials/wiki2/src/tests/tutorial/static/theme.min.css index 2f924bcc5..0d25de5b6 100644 --- a/docs/tutorials/wiki2/src/tests/tutorial/static/theme.min.css +++ b/docs/tutorials/wiki2/src/tests/tutorial/static/theme.min.css @@ -1 +1 @@ -@import url(//fonts.googleapis.com/css?family=Open+Sans:300,400,600,700);body{font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-weight:300;color:#fff;background:#bc2131}h1,h2,h3,h4,h5,h6{font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-weight:300}p{font-weight:300}.font-normal{font-weight:400}.font-semi-bold{font-weight:600}.font-bold{font-weight:700}.starter-template{margin-top:250px}.starter-template .content{margin-left:10px}.starter-template .content h1{margin-top:10px;font-size:60px}.starter-template .content h1 .smaller{font-size:40px;color:#f2b7bd}.starter-template .content .lead{font-size:25px;color:#f2b7bd}.starter-template .content .lead .font-normal{color:#fff}.starter-template .links{float:right;right:0;margin-top:125px}.starter-template .links ul{display:block;padding:0;margin:0}.starter-template .links ul li{list-style:none;display:inline;margin:0 10px}.starter-template .links ul li:first-child{margin-left:0}.starter-template .links ul li:last-child{margin-right:0}.starter-template .links ul li.current-version{color:#f2b7bd;font-weight:400}.starter-template .links ul li a{color:#fff}.starter-template .links ul li a:hover{text-decoration:underline}.starter-template .links ul li .icon-muted{color:#eb8b95;margin-right:5px}.starter-template .links ul li:hover .icon-muted{color:#fff}.starter-template .copyright{margin-top:10px;font-size:.9em;color:#f2b7bd;text-transform:lowercase;float:right;right:0}@media (max-width:1199px){.starter-template .content h1{font-size:45px}.starter-template .content h1 .smaller{font-size:30px}.starter-template .content .lead{font-size:20px}}@media (max-width:991px){.starter-template{margin-top:0}.starter-template .logo{margin:40px auto}.starter-template .content{margin-left:0;text-align:center}.starter-template .content h1{margin-bottom:20px}.starter-template .links{float:none;text-align:center;margin-top:60px}.starter-template .copyright{float:none;text-align:center}}@media (max-width:767px){.starter-template .content h1 .smaller{font-size:25px;display:block}.starter-template .content .lead{font-size:16px}.starter-template .links{margin-top:40px}.starter-template .links ul li{display:block;margin:0}.starter-template .links ul li .icon-muted{display:none}.starter-template .copyright{margin-top:20px}} \ No newline at end of file +@import url(//fonts.googleapis.com/css?family=Open+Sans:300,400,600,700);body{font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-weight:300;color:#fff;background:#bc2131}h1,h2,h3,h4,h5,h6{font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-weight:300}p{font-weight:300}.font-normal{font-weight:400}.font-semi-bold{font-weight:600}.font-bold{font-weight:700}.starter-template{margin-top:250px}.starter-template .content{margin-left:10px}.starter-template .content h1{margin-top:10px;font-size:60px}.starter-template .content h1 .smaller{font-size:40px;color:#f2b7bd}.starter-template .content .lead{font-size:25px;color:#f2b7bd}.starter-template .content .lead .font-normal{color:#fff}.starter-template .links{float:right;right:0;margin-top:125px}.starter-template .links ul{display:block;padding:0;margin:0}.starter-template .links ul li{list-style:none;display:inline;margin:0 10px}.starter-template .links ul li:first-child{margin-left:0}.starter-template .links ul li:last-child{margin-right:0}.starter-template .links ul li.current-version{color:#f2b7bd;font-weight:400}.starter-template .links ul li a,a{color:#f2b7bd;text-decoration:underline}.starter-template .links ul li a:hover,a:hover{color:#fff;text-decoration:underline}.starter-template .links ul li .icon-muted{color:#eb8b95;margin-right:5px}.starter-template .links ul li:hover .icon-muted{color:#fff}.starter-template .copyright{margin-top:10px;font-size:.9em;color:#f2b7bd;text-transform:lowercase;float:right;right:0}@media (max-width:1199px){.starter-template .content h1{font-size:45px}.starter-template .content h1 .smaller{font-size:30px}.starter-template .content .lead{font-size:20px}}@media (max-width:991px){.starter-template{margin-top:0}.starter-template .logo{margin:40px auto}.starter-template .content{margin-left:0;text-align:center}.starter-template .content h1{margin-bottom:20px}.starter-template .links{float:none;text-align:center;margin-top:60px}.starter-template .copyright{float:none;text-align:center}}@media (max-width:767px){.starter-template .content h1 .smaller{font-size:25px;display:block}.starter-template .content .lead{font-size:16px}.starter-template .links{margin-top:40px}.starter-template .links ul li{display:block;margin:0}.starter-template .links ul li .icon-muted{display:none}.starter-template .copyright{margin-top:20px}} diff --git a/docs/tutorials/wiki2/src/tests/tutorial/templates/edit.jinja2 b/docs/tutorials/wiki2/src/tests/tutorial/templates/edit.jinja2 new file mode 100644 index 000000000..c4f3a2c93 --- /dev/null +++ b/docs/tutorials/wiki2/src/tests/tutorial/templates/edit.jinja2 @@ -0,0 +1,73 @@ + + + + + + + + + + + Edit{% if page.name %} {{page.name}}{% endif %} - Pyramid tutorial wiki (based on TurboGears 20-Minute Wiki) + + + + + + + + + + + + + +
+
+
+
+ +
+
+
+ {% if logged_in %} +

+ Logout +

+ {% endif %} +

+ Editing {% if page.name %}{{page.name}}{% else %}Page Name Goes Here{% endif %} +

+

You can return to the + FrontPage. +

+
+
+ +
+
+ +
+
+
+
+
+
+ +
+
+
+ + + + + + + + diff --git a/docs/tutorials/wiki2/src/tests/tutorial/templates/edit.pt b/docs/tutorials/wiki2/src/tests/tutorial/templates/edit.pt deleted file mode 100644 index 50e55c850..000000000 --- a/docs/tutorials/wiki2/src/tests/tutorial/templates/edit.pt +++ /dev/null @@ -1,74 +0,0 @@ - - - - - - - - - - - ${page.name} - Pyramid tutorial wiki (based on - TurboGears 20-Minute Wiki) - - - - - - - - - - - - -
-
-
-
- -
-
-
-

- Editing Page Name Goes - Here -

-

You can return to the - FrontPage. -

-

- - Logout - -

-
-
- -
-
- -
-
-
-
-
-
- -
-
-
- - - - - - - - diff --git a/docs/tutorials/wiki2/src/tests/tutorial/templates/layout.jinja2 b/docs/tutorials/wiki2/src/tests/tutorial/templates/layout.jinja2 new file mode 100644 index 000000000..ff624c65b --- /dev/null +++ b/docs/tutorials/wiki2/src/tests/tutorial/templates/layout.jinja2 @@ -0,0 +1,66 @@ + + + + + + + + + + + Alchemy Scaffold for The Pyramid Web Framework + + + + + + + + + + + + + +
+
+
+
+ +
+
+ {% block content %} +

No content

+ {% endblock content %} +
+
+
+ +
+
+ +
+
+
+ + + + + + + + diff --git a/docs/tutorials/wiki2/src/tests/tutorial/templates/login.jinja2 b/docs/tutorials/wiki2/src/tests/tutorial/templates/login.jinja2 new file mode 100644 index 000000000..a80a2a165 --- /dev/null +++ b/docs/tutorials/wiki2/src/tests/tutorial/templates/login.jinja2 @@ -0,0 +1,74 @@ + + + + + + + + + + + Login - Pyramid tutorial wiki (based on TurboGears 20-Minute Wiki) + + + + + + + + + + + + + +
+
+
+
+ +
+
+
+

+ + Login +
+ {{ message }} +

+
+ +
+ + +
+
+ + +
+
+ +
+
+
+
+
+
+ +
+
+
+ + + + + + + + diff --git a/docs/tutorials/wiki2/src/tests/tutorial/templates/login.pt b/docs/tutorials/wiki2/src/tests/tutorial/templates/login.pt deleted file mode 100644 index 5f8e9b98c..000000000 --- a/docs/tutorials/wiki2/src/tests/tutorial/templates/login.pt +++ /dev/null @@ -1,54 +0,0 @@ - - - - Login - Pyramid tutorial wiki (based on TurboGears - 20-Minute Wiki) - - - - - - - - -
-
-
-
- pyramid -
-
-
-
-
-
- Login
- -
- -
-
-
-
-
- -
-
- -
-
-
-
- - diff --git a/docs/tutorials/wiki2/src/tests/tutorial/templates/mytemplate.jinja2 b/docs/tutorials/wiki2/src/tests/tutorial/templates/mytemplate.jinja2 new file mode 100644 index 000000000..bb622bf5a --- /dev/null +++ b/docs/tutorials/wiki2/src/tests/tutorial/templates/mytemplate.jinja2 @@ -0,0 +1,8 @@ +{% extends "layout.jinja2" %} + +{% block content %} +
+

Pyramid Alchemy scaffold

+

Welcome to {{project}}, an application generated by
the Pyramid Web Framework 1.7.dev0.

+
+{% endblock content %} diff --git a/docs/tutorials/wiki2/src/tests/tutorial/templates/mytemplate.pt b/docs/tutorials/wiki2/src/tests/tutorial/templates/mytemplate.pt deleted file mode 100644 index c9b0cec21..000000000 --- a/docs/tutorials/wiki2/src/tests/tutorial/templates/mytemplate.pt +++ /dev/null @@ -1,66 +0,0 @@ - - - - - - - - - - - Alchemy Scaffold for The Pyramid Web Framework - - - - - - - - - - - - - -
-
-
-
- -
-
-
-

Pyramid Alchemy scaffold

-

Welcome to ${project}, an application generated by
the Pyramid Web Framework.

-
-
-
- -
- -
-
-
- - - - - - - - diff --git a/docs/tutorials/wiki2/src/tests/tutorial/templates/view.jinja2 b/docs/tutorials/wiki2/src/tests/tutorial/templates/view.jinja2 new file mode 100644 index 000000000..a7afc66fc --- /dev/null +++ b/docs/tutorials/wiki2/src/tests/tutorial/templates/view.jinja2 @@ -0,0 +1,71 @@ + + + + + + + + + + + {{page.name}} - Pyramid tutorial wiki (based on TurboGears 20-Minute Wiki) + + + + + + + + + + + + + +
+
+
+
+ +
+
+
+ {% if logged_in %} +

+ Logout +

+ {% endif %} +

{{ content|safe }}

+

+ + Edit this page + +

+

+ Viewing {% if page.name %}{{page.name}}{% else %}Page Name Goes Here{% endif %} +

+

You can return to the + FrontPage. +

+
+
+
+
+ +
+
+
+ + + + + + + + diff --git a/docs/tutorials/wiki2/src/tests/tutorial/templates/view.pt b/docs/tutorials/wiki2/src/tests/tutorial/templates/view.pt deleted file mode 100644 index 4e5772de0..000000000 --- a/docs/tutorials/wiki2/src/tests/tutorial/templates/view.pt +++ /dev/null @@ -1,74 +0,0 @@ - - - - - - - - - - - ${page.name} - Pyramid tutorial wiki (based on - TurboGears 20-Minute Wiki) - - - - - - - - - - - - -
-
-
-
- -
-
-
-
- Page text goes here. -
-

- - Edit this page - -

-

- Viewing - Page Name Goes Here -

-

You can return to the - FrontPage. -

-

- - Logout - -

-
-
-
-
- -
-
-
- - - - - - - - diff --git a/docs/tutorials/wiki2/src/tests/tutorial/tests.py b/docs/tutorials/wiki2/src/tests/tutorial/tests.py deleted file mode 100644 index c50e05b6d..000000000 --- a/docs/tutorials/wiki2/src/tests/tutorial/tests.py +++ /dev/null @@ -1,235 +0,0 @@ -import unittest -import transaction - -from pyramid import testing - - -def _initTestingDB(): - from sqlalchemy import create_engine - from tutorial.models import ( - DBSession, - Page, - Base - ) - engine = create_engine('sqlite://') - Base.metadata.create_all(engine) - DBSession.configure(bind=engine) - with transaction.manager: - model = Page(name='FrontPage', data='This is the front page') - DBSession.add(model) - return DBSession - - -def _registerRoutes(config): - config.add_route('view_page', '{pagename}') - config.add_route('edit_page', '{pagename}/edit_page') - config.add_route('add_page', 'add_page/{pagename}') - - -class ViewWikiTests(unittest.TestCase): - def setUp(self): - self.config = testing.setUp() - - def tearDown(self): - testing.tearDown() - - def _callFUT(self, request): - from tutorial.views import view_wiki - return view_wiki(request) - - def test_it(self): - _registerRoutes(self.config) - request = testing.DummyRequest() - response = self._callFUT(request) - self.assertEqual(response.location, 'http://example.com/FrontPage') - - -class ViewPageTests(unittest.TestCase): - def setUp(self): - self.session = _initTestingDB() - self.config = testing.setUp() - - def tearDown(self): - self.session.remove() - testing.tearDown() - - def _callFUT(self, request): - from tutorial.views import view_page - return view_page(request) - - def test_it(self): - from tutorial.models import Page - request = testing.DummyRequest() - request.matchdict['pagename'] = 'IDoExist' - page = Page(name='IDoExist', data='Hello CruelWorld IDoExist') - self.session.add(page) - _registerRoutes(self.config) - info = self._callFUT(request) - self.assertEqual(info['page'], page) - self.assertEqual( - info['content'], - '
\n' - '

Hello ' - 'CruelWorld ' - '' - 'IDoExist' - '

\n
\n') - self.assertEqual(info['edit_url'], - 'http://example.com/IDoExist/edit_page') - - -class AddPageTests(unittest.TestCase): - def setUp(self): - self.session = _initTestingDB() - self.config = testing.setUp() - - def tearDown(self): - self.session.remove() - testing.tearDown() - - def _callFUT(self, request): - from tutorial.views import add_page - return add_page(request) - - def test_it_notsubmitted(self): - _registerRoutes(self.config) - request = testing.DummyRequest() - request.matchdict = {'pagename':'AnotherPage'} - info = self._callFUT(request) - self.assertEqual(info['page'].data,'') - self.assertEqual(info['save_url'], - 'http://example.com/add_page/AnotherPage') - - def test_it_submitted(self): - from tutorial.models import Page - _registerRoutes(self.config) - request = testing.DummyRequest({'form.submitted':True, - 'body':'Hello yo!'}) - request.matchdict = {'pagename':'AnotherPage'} - self._callFUT(request) - page = self.session.query(Page).filter_by(name='AnotherPage').one() - self.assertEqual(page.data, 'Hello yo!') - - -class EditPageTests(unittest.TestCase): - def setUp(self): - self.session = _initTestingDB() - self.config = testing.setUp() - - def tearDown(self): - self.session.remove() - testing.tearDown() - - def _callFUT(self, request): - from tutorial.views import edit_page - return edit_page(request) - - def test_it_notsubmitted(self): - from tutorial.models import Page - _registerRoutes(self.config) - request = testing.DummyRequest() - request.matchdict = {'pagename':'abc'} - page = Page(name='abc', data='hello') - self.session.add(page) - info = self._callFUT(request) - self.assertEqual(info['page'], page) - self.assertEqual(info['save_url'], - 'http://example.com/abc/edit_page') - - def test_it_submitted(self): - from tutorial.models import Page - _registerRoutes(self.config) - request = testing.DummyRequest({'form.submitted':True, - 'body':'Hello yo!'}) - request.matchdict = {'pagename':'abc'} - page = Page(name='abc', data='hello') - self.session.add(page) - response = self._callFUT(request) - self.assertEqual(response.location, 'http://example.com/abc') - self.assertEqual(page.data, 'Hello yo!') - - -class FunctionalTests(unittest.TestCase): - - viewer_login = '/login?login=viewer&password=viewer' \ - '&came_from=FrontPage&form.submitted=Login' - viewer_wrong_login = '/login?login=viewer&password=incorrect' \ - '&came_from=FrontPage&form.submitted=Login' - editor_login = '/login?login=editor&password=editor' \ - '&came_from=FrontPage&form.submitted=Login' - - def setUp(self): - from tutorial import main - settings = { 'sqlalchemy.url': 'sqlite://'} - app = main({}, **settings) - from webtest import TestApp - self.testapp = TestApp(app) - _initTestingDB() - - def tearDown(self): - del self.testapp - from tutorial.models import DBSession - DBSession.remove() - - def test_root(self): - res = self.testapp.get('/', status=302) - self.assertEqual(res.location, 'http://localhost/FrontPage') - - def test_FrontPage(self): - res = self.testapp.get('/FrontPage', status=200) - self.assertTrue(b'FrontPage' in res.body) - - def test_unexisting_page(self): - self.testapp.get('/SomePage', status=404) - - def test_successful_log_in(self): - res = self.testapp.get(self.viewer_login, status=302) - self.assertEqual(res.location, 'http://localhost/FrontPage') - - def test_failed_log_in(self): - res = self.testapp.get(self.viewer_wrong_login, status=200) - self.assertTrue(b'login' in res.body) - - def test_logout_link_present_when_logged_in(self): - self.testapp.get(self.viewer_login, status=302) - res = self.testapp.get('/FrontPage', status=200) - self.assertTrue(b'Logout' in res.body) - - def test_logout_link_not_present_after_logged_out(self): - self.testapp.get(self.viewer_login, status=302) - self.testapp.get('/FrontPage', status=200) - res = self.testapp.get('/logout', status=302) - self.assertTrue(b'Logout' not in res.body) - - def test_anonymous_user_cannot_edit(self): - res = self.testapp.get('/FrontPage/edit_page', status=200) - self.assertTrue(b'Login' in res.body) - - def test_anonymous_user_cannot_add(self): - res = self.testapp.get('/add_page/NewPage', status=200) - self.assertTrue(b'Login' in res.body) - - def test_viewer_user_cannot_edit(self): - self.testapp.get(self.viewer_login, status=302) - res = self.testapp.get('/FrontPage/edit_page', status=200) - self.assertTrue(b'Login' in res.body) - - def test_viewer_user_cannot_add(self): - self.testapp.get(self.viewer_login, status=302) - res = self.testapp.get('/add_page/NewPage', status=200) - self.assertTrue(b'Login' in res.body) - - def test_editors_member_user_can_edit(self): - self.testapp.get(self.editor_login, status=302) - res = self.testapp.get('/FrontPage/edit_page', status=200) - self.assertTrue(b'Editing' in res.body) - - def test_editors_member_user_can_add(self): - self.testapp.get(self.editor_login, status=302) - res = self.testapp.get('/add_page/NewPage', status=200) - self.assertTrue(b'Editing' in res.body) - - def test_editors_member_user_can_view(self): - self.testapp.get(self.editor_login, status=302) - res = self.testapp.get('/FrontPage', status=200) - self.assertTrue(b'FrontPage' in res.body) diff --git a/docs/tutorials/wiki2/src/tests/tutorial/tests/__init__.py b/docs/tutorials/wiki2/src/tests/tutorial/tests/__init__.py new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/docs/tutorials/wiki2/src/tests/tutorial/tests/__init__.py @@ -0,0 +1 @@ + diff --git a/docs/tutorials/wiki2/src/tests/tutorial/tests/test_functional.py b/docs/tutorials/wiki2/src/tests/tutorial/tests/test_functional.py new file mode 100644 index 000000000..339c60bc2 --- /dev/null +++ b/docs/tutorials/wiki2/src/tests/tutorial/tests/test_functional.py @@ -0,0 +1,141 @@ +import unittest + +from pyramid import testing + + +def dummy_request(dbsession): + return testing.DummyRequest(dbsession=dbsession) + + +def _register_routes(config): + config.add_route('view_page', '{pagename}') + config.add_route('edit_page', '{pagename}/edit_page') + config.add_route('add_page', 'add_page/{pagename}') + + +class FunctionalTests(unittest.TestCase): + + viewer_login = '/login?login=viewer&password=viewer' \ + '&came_from=FrontPage&form.submitted=Login' + viewer_wrong_login = '/login?login=viewer&password=incorrect' \ + '&came_from=FrontPage&form.submitted=Login' + editor_login = '/login?login=editor&password=editor' \ + '&came_from=FrontPage&form.submitted=Login' + + engine = None + + @staticmethod + def setup_database(): + import transaction + from tutorial.models.mymodel import Page + from tutorial.models.meta import ( + Base, + ) + import tutorial.models.meta + + + def initialize_db(dbsession, engine): + Base.metadata.create_all(engine) + with transaction.manager: + model = Page(name='FrontPage', data='This is the front page') + dbsession.add(model) + + def wrap_get_session(transaction_manager, dbmaker): + dbsession = get_session(transaction_manager, dbmaker) + initialize_db(dbsession, engine) + tutorial.models.meta.get_session = get_session + tutorial.models.meta.get_engine = get_engine + return dbsession + + def wrap_get_engine(settings): + global engine + engine = get_engine(settings) + return engine + + get_session = tutorial.models.meta.get_session + tutorial.models.meta.get_session = wrap_get_session + + get_engine = tutorial.models.meta.get_engine + tutorial.models.meta.get_engine = wrap_get_engine + + @classmethod + def setUpClass(cls): + cls.setup_database() + + from webtest import TestApp + from tutorial import main + settings = {'sqlalchemy.url': 'sqlite://'} + app = main({}, **settings) + cls.testapp = TestApp(app) + + @classmethod + def tearDownClass(cls): + from tutorial.models.meta import Base + Base.metadata.drop_all(engine) + + def tearDown(self): + import transaction + transaction.abort() + + def test_root(self): + res = self.testapp.get('/', status=302) + self.assertEqual(res.location, 'http://localhost/FrontPage') + + def test_FrontPage(self): + res = self.testapp.get('/FrontPage', status=200) + self.assertTrue(b'FrontPage' in res.body) + + def test_unexisting_page(self): + self.testapp.get('/SomePage', status=404) + + def test_successful_log_in(self): + res = self.testapp.get(self.viewer_login, status=302) + self.assertEqual(res.location, 'http://localhost/FrontPage') + + def test_failed_log_in(self): + res = self.testapp.get(self.viewer_wrong_login, status=200) + self.assertTrue(b'login' in res.body) + + def test_logout_link_present_when_logged_in(self): + self.testapp.get(self.viewer_login, status=302) + res = self.testapp.get('/FrontPage', status=200) + self.assertTrue(b'Logout' in res.body) + + def test_logout_link_not_present_after_logged_out(self): + self.testapp.get(self.viewer_login, status=302) + self.testapp.get('/FrontPage', status=200) + res = self.testapp.get('/logout', status=302) + self.assertTrue(b'Logout' not in res.body) + + def test_anonymous_user_cannot_edit(self): + res = self.testapp.get('/FrontPage/edit_page', status=200) + self.assertTrue(b'Login' in res.body) + + def test_anonymous_user_cannot_add(self): + res = self.testapp.get('/add_page/NewPage', status=200) + self.assertTrue(b'Login' in res.body) + + def test_viewer_user_cannot_edit(self): + self.testapp.get(self.viewer_login, status=302) + res = self.testapp.get('/FrontPage/edit_page', status=200) + self.assertTrue(b'Login' in res.body) + + def test_viewer_user_cannot_add(self): + self.testapp.get(self.viewer_login, status=302) + res = self.testapp.get('/add_page/NewPage', status=200) + self.assertTrue(b'Login' in res.body) + + def test_editors_member_user_can_edit(self): + self.testapp.get(self.editor_login, status=302) + res = self.testapp.get('/FrontPage/edit_page', status=200) + self.assertTrue(b'Editing' in res.body) + + def test_editors_member_user_can_add(self): + self.testapp.get(self.editor_login, status=302) + res = self.testapp.get('/add_page/NewPage', status=200) + self.assertTrue(b'Editing' in res.body) + + def test_editors_member_user_can_view(self): + self.testapp.get(self.editor_login, status=302) + res = self.testapp.get('/FrontPage', status=200) + self.assertTrue(b'FrontPage' in res.body) diff --git a/docs/tutorials/wiki2/src/tests/tutorial/tests/test_views.py b/docs/tutorials/wiki2/src/tests/tutorial/tests/test_views.py new file mode 100644 index 000000000..d70311e38 --- /dev/null +++ b/docs/tutorials/wiki2/src/tests/tutorial/tests/test_views.py @@ -0,0 +1,168 @@ +import unittest +import transaction + +from pyramid import testing + + +def dummy_request(dbsession): + return testing.DummyRequest(dbsession=dbsession) + + +def _register_routes(config): + config.add_route('view_page', '{pagename}') + config.add_route('edit_page', '{pagename}/edit_page') + config.add_route('add_page', 'add_page/{pagename}') + + +class BaseTest(unittest.TestCase): + def setUp(self): + self.config = testing.setUp(settings={ + 'sqlalchemy.url': 'sqlite:///:memory:' + }) + self.config.include('..models.meta') + _register_routes(self.config) + settings = self.config.get_settings() + + from ..models.meta import ( + get_session, + get_engine, + get_dbmaker, + ) + + self.engine = get_engine(settings) + dbmaker = get_dbmaker(self.engine) + + self.session = get_session(transaction.manager, dbmaker) + + self.init_database() + + def init_database(self): + from ..models.meta import Base + Base.metadata.create_all(self.engine) + + def tearDown(self): + testing.tearDown() + transaction.abort() + + +class ViewWikiTests(unittest.TestCase): + + def setUp(self): + self.config = testing.setUp() + _register_routes(self.config) + + def tearDown(self): + testing.tearDown() + + def _callFUT(self, request): + from tutorial.views.default import view_wiki + return view_wiki(request) + + def test_it(self): + request = testing.DummyRequest() + response = self._callFUT(request) + self.assertEqual(response.location, 'http://example.com/FrontPage') + + +class ViewPageTests(BaseTest): + def setUp(self): + super(ViewPageTests, self).setUp() + + def tearDown(self): + transaction.abort() + testing.tearDown() + + def _callFUT(self, request): + from tutorial.views.default import view_page + return view_page(request) + + def test_it(self): + # add a page to the db + from ..models.mymodel import Page + page = Page(name='IDoExist', data='Hello CruelWorld IDoExist') + self.session.add(page) + + # create a request asking for the page we've created + request = dummy_request(self.session) + request.matchdict['pagename'] = 'IDoExist' + + # call the view we're testing and check its behavior + info = self._callFUT(request) + self.assertEqual(info['page'], page) + self.assertEqual( + info['content'], + '
\n' + '

Hello ' + 'CruelWorld ' + '' + 'IDoExist' + '

\n
\n') + self.assertEqual(info['edit_url'], + 'http://example.com/IDoExist/edit_page') + + +class AddPageTests(BaseTest): + def setUp(self): + super(AddPageTests, self).setUp() + + def tearDown(self): + transaction.abort() + testing.tearDown() + + def _callFUT(self, request): + from tutorial.views.default import add_page + return add_page(request) + + def test_it_notsubmitted(self): + request = dummy_request(self.session) + request.matchdict = {'pagename': 'AnotherPage'} + info = self._callFUT(request) + self.assertEqual(info['page'].data, '') + self.assertEqual(info['save_url'], + 'http://example.com/add_page/AnotherPage') + + def test_it_submitted(self): + from ..models.mymodel import Page + request = testing.DummyRequest({'form.submitted': True, + 'body': 'Hello yo!'}, + dbsession=self.session) + request.matchdict = {'pagename': 'AnotherPage'} + self._callFUT(request) + page = self.session.query(Page).filter_by(name='AnotherPage').one() + self.assertEqual(page.data, 'Hello yo!') + + +class EditPageTests(BaseTest): + def setUp(self): + super(EditPageTests, self).setUp() + + def tearDown(self): + transaction.abort() + testing.tearDown() + + def _callFUT(self, request): + from tutorial.views.default import edit_page + return edit_page(request) + + def test_it_notsubmitted(self): + from ..models.mymodel import Page + request = dummy_request(self.session) + request.matchdict = {'pagename': 'abc'} + page = Page(name='abc', data='hello') + self.session.add(page) + info = self._callFUT(request) + self.assertEqual(info['page'], page) + self.assertEqual(info['save_url'], + 'http://example.com/abc/edit_page') + + def test_it_submitted(self): + from ..models.mymodel import Page + request = testing.DummyRequest({'form.submitted': True, + 'body': 'Hello yo!'}, + dbsession=self.session) + request.matchdict = {'pagename': 'abc'} + page = Page(name='abc', data='hello') + self.session.add(page) + response = self._callFUT(request) + self.assertEqual(response.location, 'http://example.com/abc') + self.assertEqual(page.data, 'Hello yo!') diff --git a/docs/tutorials/wiki2/src/tests/tutorial/views.py b/docs/tutorials/wiki2/src/tests/tutorial/views.py deleted file mode 100644 index 41bea4785..000000000 --- a/docs/tutorials/wiki2/src/tests/tutorial/views.py +++ /dev/null @@ -1,123 +0,0 @@ -import re -from docutils.core import publish_parts - -from pyramid.httpexceptions import ( - HTTPFound, - HTTPNotFound, - ) - -from pyramid.view import ( - view_config, - forbidden_view_config, - ) - -from pyramid.security import ( - remember, - forget, - ) - -from .security import USERS - -from .models import ( - DBSession, - Page, - ) - - -# regular expression used to find WikiWords -wikiwords = re.compile(r"\b([A-Z]\w+[A-Z]+\w+)") - -@view_config(route_name='view_wiki', - permission='view') -def view_wiki(request): - return HTTPFound(location = request.route_url('view_page', - pagename='FrontPage')) - -@view_config(route_name='view_page', renderer='templates/view.pt', - permission='view') -def view_page(request): - pagename = request.matchdict['pagename'] - page = DBSession.query(Page).filter_by(name=pagename).first() - if page is None: - return HTTPNotFound('No such page') - - def check(match): - word = match.group(1) - exists = DBSession.query(Page).filter_by(name=word).all() - if exists: - view_url = request.route_url('view_page', pagename=word) - return '%s' % (view_url, word) - else: - add_url = request.route_url('add_page', pagename=word) - return '%s' % (add_url, word) - - content = publish_parts(page.data, writer_name='html')['html_body'] - content = wikiwords.sub(check, content) - edit_url = request.route_url('edit_page', pagename=pagename) - return dict(page=page, content=content, edit_url=edit_url, - logged_in=request.authenticated_userid) - -@view_config(route_name='add_page', renderer='templates/edit.pt', - permission='edit') -def add_page(request): - pagename = request.matchdict['pagename'] - if 'form.submitted' in request.params: - body = request.params['body'] - page = Page(name=pagename, data=body) - DBSession.add(page) - return HTTPFound(location = request.route_url('view_page', - pagename=pagename)) - save_url = request.route_url('add_page', pagename=pagename) - page = Page(name='', data='') - return dict(page=page, save_url=save_url, - logged_in=request.authenticated_userid) - -@view_config(route_name='edit_page', renderer='templates/edit.pt', - permission='edit') -def edit_page(request): - pagename = request.matchdict['pagename'] - page = DBSession.query(Page).filter_by(name=pagename).one() - if 'form.submitted' in request.params: - page.data = request.params['body'] - DBSession.add(page) - return HTTPFound(location = request.route_url('view_page', - pagename=pagename)) - return dict( - page=page, - save_url=request.route_url('edit_page', pagename=pagename), - logged_in=request.authenticated_userid - ) - -@view_config(route_name='login', renderer='templates/login.pt') -@forbidden_view_config(renderer='templates/login.pt') -def login(request): - login_url = request.route_url('login') - referrer = request.url - if referrer == login_url: - referrer = '/' # never use the login form itself as came_from - came_from = request.params.get('came_from', referrer) - message = '' - login = '' - password = '' - if 'form.submitted' in request.params: - login = request.params['login'] - password = request.params['password'] - if USERS.get(login) == password: - headers = remember(request, login) - return HTTPFound(location = came_from, - headers = headers) - message = 'Failed login' - - return dict( - message = message, - url = request.application_url + '/login', - came_from = came_from, - login = login, - password = password, - ) - -@view_config(route_name='logout') -def logout(request): - headers = forget(request) - return HTTPFound(location = request.route_url('view_wiki'), - headers = headers) diff --git a/docs/tutorials/wiki2/src/tests/tutorial/views/__init__.py b/docs/tutorials/wiki2/src/tests/tutorial/views/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/docs/tutorials/wiki2/src/tests/tutorial/views/default.py b/docs/tutorials/wiki2/src/tests/tutorial/views/default.py new file mode 100644 index 000000000..f35f041a4 --- /dev/null +++ b/docs/tutorials/wiki2/src/tests/tutorial/views/default.py @@ -0,0 +1,120 @@ +import cgi +import re +from docutils.core import publish_parts + +from pyramid.httpexceptions import ( + HTTPFound, + HTTPNotFound, + ) + +from pyramid.view import ( + view_config, + forbidden_view_config, + ) + +from pyramid.security import ( + remember, + forget, + ) + +from ..security.default import USERS + +from ..models.mymodel import Page + +# regular expression used to find WikiWords +wikiwords = re.compile(r"\b([A-Z]\w+[A-Z]+\w+)") + +@view_config(route_name='view_wiki', + permission='view') +def view_wiki(request): + return HTTPFound(location=request.route_url('view_page', + pagename='FrontPage')) + +@view_config(route_name='view_page', renderer='templates/view.jinja2', + permission='view') +def view_page(request): + pagename = request.matchdict['pagename'] + page = request.dbsession.query(Page).filter_by(name=pagename).first() + if page is None: + return HTTPNotFound('No such page') + + def check(match): + word = match.group(1) + exists = request.dbsession.query(Page).filter_by(name=word).all() + if exists: + view_url = request.route_url('view_page', pagename=word) + return '%s' % (view_url, cgi.escape(word)) + else: + add_url = request.route_url('add_page', pagename=word) + return '%s' % (add_url, cgi.escape(word)) + + content = publish_parts(page.data, writer_name='html')['html_body'] + content = wikiwords.sub(check, content) + edit_url = request.route_url('edit_page', pagename=pagename) + return dict(page=page, content=content, edit_url=edit_url, + logged_in=request.authenticated_userid) + +@view_config(route_name='add_page', renderer='templates/edit.jinja2', + permission='edit') +def add_page(request): + pagename = request.matchdict['pagename'] + if 'form.submitted' in request.params: + body = request.params['body'] + page = Page(name=pagename, data=body) + request.dbsession.add(page) + return HTTPFound(location = request.route_url('view_page', + pagename=pagename)) + save_url = request.route_url('add_page', pagename=pagename) + page = Page(name='', data='') + return dict(page=page, save_url=save_url, + logged_in=request.authenticated_userid) + +@view_config(route_name='edit_page', renderer='templates/edit.jinja2', + permission='edit') +def edit_page(request): + pagename = request.matchdict['pagename'] + page = request.dbsession.query(Page).filter_by(name=pagename).one() + if 'form.submitted' in request.params: + page.data = request.params['body'] + request.dbsession.add(page) + return HTTPFound(location = request.route_url('view_page', + pagename=pagename)) + return dict( + page=page, + save_url = request.route_url('edit_page', pagename=pagename), + logged_in=request.authenticated_userid + ) + +@view_config(route_name='login', renderer='templates/login.jinja2') +@forbidden_view_config(renderer='templates/login.jinja2') +def login(request): + login_url = request.route_url('login') + referrer = request.url + if referrer == login_url: + referrer = '/' # never use the login form itself as came_from + came_from = request.params.get('came_from', referrer) + message = '' + login = '' + password = '' + if 'form.submitted' in request.params: + login = request.params['login'] + password = request.params['password'] + if USERS.get(login) == password: + headers = remember(request, login) + return HTTPFound(location = came_from, + headers = headers) + message = 'Failed login' + + return dict( + message = message, + url = request.application_url + '/login', + came_from = came_from, + login = login, + password = password, + ) + +@view_config(route_name='logout') +def logout(request): + headers = forget(request) + return HTTPFound(location = request.route_url('view_wiki'), + headers = headers) -- cgit v1.2.3