From b1b92284f496800a4dfd2cea72cb9be07ba8661c Mon Sep 17 00:00:00 2001 From: Paul Everitt Date: Fri, 13 Sep 2013 16:52:14 -0400 Subject: First cut at import of quick tutorial. --- docs/quick_tutorial/databases/development.ini | 49 +++++++++++ docs/quick_tutorial/databases/setup.py | 20 +++++ docs/quick_tutorial/databases/sqltutorial.sqlite | Bin 0 -> 12288 bytes docs/quick_tutorial/databases/tutorial/__init__.py | 20 +++++ .../databases/tutorial/initialize_db.py | 37 ++++++++ docs/quick_tutorial/databases/tutorial/models.py | 35 ++++++++ docs/quick_tutorial/databases/tutorial/tests.py | 58 +++++++++++++ docs/quick_tutorial/databases/tutorial/views.py | 96 +++++++++++++++++++++ .../quick_tutorial/databases/tutorial/wiki_view.pt | 19 ++++ .../databases/tutorial/wikipage_addedit.pt | 22 +++++ .../databases/tutorial/wikipage_view.pt | 17 ++++ 11 files changed, 373 insertions(+) create mode 100644 docs/quick_tutorial/databases/development.ini create mode 100644 docs/quick_tutorial/databases/setup.py create mode 100644 docs/quick_tutorial/databases/sqltutorial.sqlite create mode 100644 docs/quick_tutorial/databases/tutorial/__init__.py create mode 100644 docs/quick_tutorial/databases/tutorial/initialize_db.py create mode 100644 docs/quick_tutorial/databases/tutorial/models.py create mode 100644 docs/quick_tutorial/databases/tutorial/tests.py create mode 100644 docs/quick_tutorial/databases/tutorial/views.py create mode 100644 docs/quick_tutorial/databases/tutorial/wiki_view.pt create mode 100644 docs/quick_tutorial/databases/tutorial/wikipage_addedit.pt create mode 100644 docs/quick_tutorial/databases/tutorial/wikipage_view.pt (limited to 'docs/quick_tutorial/databases') diff --git a/docs/quick_tutorial/databases/development.ini b/docs/quick_tutorial/databases/development.ini new file mode 100644 index 000000000..270da960f --- /dev/null +++ b/docs/quick_tutorial/databases/development.ini @@ -0,0 +1,49 @@ +[app:main] +use = egg:tutorial +pyramid.reload_templates = true +pyramid.includes = + pyramid_debugtoolbar + pyramid_tm + +sqlalchemy.url = sqlite:///%(here)s/sqltutorial.sqlite + +[server:main] +use = egg:pyramid#wsgiref +host = 0.0.0.0 +port = 6543 + +# Begin logging configuration + +[loggers] +keys = root, tutorial, sqlalchemy + +[logger_tutorial] +level = DEBUG +handlers = +qualname = tutorial + +[logger_sqlalchemy] +level = INFO +handlers = +qualname = sqlalchemy.engine + +[handlers] +keys = console + +[formatters] +keys = generic + +[logger_root] +level = INFO +handlers = console + +[handler_console] +class = StreamHandler +args = (sys.stderr,) +level = NOTSET +formatter = generic + +[formatter_generic] +format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s + +# End logging configuration diff --git a/docs/quick_tutorial/databases/setup.py b/docs/quick_tutorial/databases/setup.py new file mode 100644 index 000000000..5cb197c39 --- /dev/null +++ b/docs/quick_tutorial/databases/setup.py @@ -0,0 +1,20 @@ +from setuptools import setup + +requires = [ + 'pyramid', + 'deform', + 'sqlalchemy', + 'pyramid_tm', + 'zope.sqlalchemy', + 'pysqlite' +] + +setup(name='tutorial', + install_requires=requires, + entry_points="""\ + [paste.app_factory] + main = tutorial:main + [console_scripts] + initialize_tutorial_db = tutorial.initialize_db:main + """, +) \ No newline at end of file diff --git a/docs/quick_tutorial/databases/sqltutorial.sqlite b/docs/quick_tutorial/databases/sqltutorial.sqlite new file mode 100644 index 000000000..b8bd856fd Binary files /dev/null and b/docs/quick_tutorial/databases/sqltutorial.sqlite differ diff --git a/docs/quick_tutorial/databases/tutorial/__init__.py b/docs/quick_tutorial/databases/tutorial/__init__.py new file mode 100644 index 000000000..47e8fefa6 --- /dev/null +++ b/docs/quick_tutorial/databases/tutorial/__init__.py @@ -0,0 +1,20 @@ +from pyramid.config import Configurator + +from sqlalchemy import engine_from_config + +from .models import DBSession, Base + +def main(global_config, **settings): + engine = engine_from_config(settings, 'sqlalchemy.') + DBSession.configure(bind=engine) + Base.metadata.bind = engine + + config = Configurator(settings=settings, + root_factory='tutorial.models.Root') + config.add_route('wiki_view', '/') + config.add_route('wikipage_add', '/add') + config.add_route('wikipage_view', '/{uid}') + config.add_route('wikipage_edit', '/{uid}/edit') + config.add_static_view('deform_static', 'deform:static/') + config.scan('.views') + return config.make_wsgi_app() \ No newline at end of file diff --git a/docs/quick_tutorial/databases/tutorial/initialize_db.py b/docs/quick_tutorial/databases/tutorial/initialize_db.py new file mode 100644 index 000000000..98be524a1 --- /dev/null +++ b/docs/quick_tutorial/databases/tutorial/initialize_db.py @@ -0,0 +1,37 @@ +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, + Base, + ) + + +def usage(argv): + cmd = os.path.basename(argv[0]) + print('usage: %s \n' + '(example: "%s development.ini")' % (cmd, cmd)) + sys.exit(1) + + +def main(argv=sys.argv): + 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) + Base.metadata.create_all(engine) + with transaction.manager: + model = Page(title='Root', body='

Root

') + DBSession.add(model) diff --git a/docs/quick_tutorial/databases/tutorial/models.py b/docs/quick_tutorial/databases/tutorial/models.py new file mode 100644 index 000000000..b27c38417 --- /dev/null +++ b/docs/quick_tutorial/databases/tutorial/models.py @@ -0,0 +1,35 @@ +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): + __tablename__ = 'wikipages' + uid = Column(Integer, primary_key=True) + title = Column(Text, unique=True) + body = Column(Text) + + +class Root(object): + __acl__ = [(Allow, Everyone, 'view'), + (Allow, 'group:editors', 'edit')] + + def __init__(self, request): + pass \ No newline at end of file diff --git a/docs/quick_tutorial/databases/tutorial/tests.py b/docs/quick_tutorial/databases/tutorial/tests.py new file mode 100644 index 000000000..e18e70c8c --- /dev/null +++ b/docs/quick_tutorial/databases/tutorial/tests.py @@ -0,0 +1,58 @@ +import unittest +import transaction + +from pyramid import testing + + +def _initTestingDB(): + from sqlalchemy import create_engine + from .models import ( + DBSession, + Page, + Base + ) + engine = create_engine('sqlite://') + Base.metadata.create_all(engine) + DBSession.configure(bind=engine) + with transaction.manager: + model = Page(title='FrontPage', body='This is the front page') + DBSession.add(model) + return DBSession + + +class WikiViewTests(unittest.TestCase): + def setUp(self): + self.session = _initTestingDB() + self.config = testing.setUp() + + def tearDown(self): + self.session.remove() + testing.tearDown() + + def test_wiki_view(self): + from tutorial.views import WikiViews + + request = testing.DummyRequest() + inst = WikiViews(request) + response = inst.wiki_view() + self.assertEqual(response['title'], 'Wiki View') + + +class WikiFunctionalTests(unittest.TestCase): + def setUp(self): + self.session = _initTestingDB() + self.config = testing.setUp() + from pyramid.paster import get_app + app = get_app('development.ini') + from webtest import TestApp + self.testapp = TestApp(app) + + def tearDown(self): + self.session.remove() + testing.tearDown() + + def test_it(self): + res = self.testapp.get('/', status=200) + self.assertIn(b'Wiki: View', res.body) + res = self.testapp.get('/add', status=200) + self.assertIn(b'Add/Edit', res.body) diff --git a/docs/quick_tutorial/databases/tutorial/views.py b/docs/quick_tutorial/databases/tutorial/views.py new file mode 100644 index 000000000..4608c6d43 --- /dev/null +++ b/docs/quick_tutorial/databases/tutorial/views.py @@ -0,0 +1,96 @@ +import colander +import deform.widget + +from pyramid.httpexceptions import HTTPFound +from pyramid.view import view_config + +from .models import DBSession, Page + + +class WikiPage(colander.MappingSchema): + title = colander.SchemaNode(colander.String()) + body = colander.SchemaNode( + colander.String(), + widget=deform.widget.RichTextWidget() + ) + + +class WikiViews(object): + def __init__(self, request): + self.request = request + + @property + def wiki_form(self): + schema = WikiPage() + return deform.Form(schema, buttons=('submit',)) + + @property + def reqts(self): + return self.wiki_form.get_widget_resources() + + @view_config(route_name='wiki_view', renderer='wiki_view.pt') + def wiki_view(self): + pages = DBSession.query(Page).order_by(Page.title) + return dict(title='Wiki View', pages=pages) + + @view_config(route_name='wikipage_add', + renderer='wikipage_addedit.pt') + def wikipage_add(self): + form = self.wiki_form.render() + + if 'submit' in self.request.params: + controls = self.request.POST.items() + try: + appstruct = self.wiki_form.validate(controls) + except deform.ValidationFailure as e: + # Form is NOT valid + return dict(form=e.render()) + + # Add a new page to the database + new_title = appstruct['title'] + new_body = appstruct['body'] + DBSession.add(Page(title=new_title, body=new_body)) + + # Get the new ID and redirect + page = DBSession.query(Page).filter_by(title=new_title).one() + new_uid = page.uid + + url = self.request.route_url('wikipage_view', uid=new_uid) + return HTTPFound(url) + + return dict(form=form) + + + @view_config(route_name='wikipage_view', renderer='wikipage_view.pt') + def wikipage_view(self): + uid = int(self.request.matchdict['uid']) + page = DBSession.query(Page).filter_by(uid=uid).one() + return dict(page=page) + + + @view_config(route_name='wikipage_edit', + renderer='wikipage_addedit.pt') + def wikipage_edit(self): + uid = int(self.request.matchdict['uid']) + page = DBSession.query(Page).filter_by(uid=uid).one() + + wiki_form = self.wiki_form + + if 'submit' in self.request.params: + controls = self.request.POST.items() + try: + appstruct = wiki_form.validate(controls) + except deform.ValidationFailure as e: + return dict(page=page, form=e.render()) + + # Change the content and redirect to the view + page.title = appstruct['title'] + page.body = appstruct['body'] + url = self.request.route_url('wikipage_view', uid=uid) + return HTTPFound(url) + + form = self.wiki_form.render(dict( + uid=page.uid, title=page.title, body=page.body) + ) + + return dict(page=page, form=form) diff --git a/docs/quick_tutorial/databases/tutorial/wiki_view.pt b/docs/quick_tutorial/databases/tutorial/wiki_view.pt new file mode 100644 index 000000000..9e3afe495 --- /dev/null +++ b/docs/quick_tutorial/databases/tutorial/wiki_view.pt @@ -0,0 +1,19 @@ + + + + Wiki: View + + +

Wiki

+ +Add + WikiPage + + + \ No newline at end of file diff --git a/docs/quick_tutorial/databases/tutorial/wikipage_addedit.pt b/docs/quick_tutorial/databases/tutorial/wikipage_addedit.pt new file mode 100644 index 000000000..d1fea0d7f --- /dev/null +++ b/docs/quick_tutorial/databases/tutorial/wikipage_addedit.pt @@ -0,0 +1,22 @@ + + + + WikiPage: Add/Edit + + + + + + + + +

Wiki

+ +

${structure: form}

+ + + diff --git a/docs/quick_tutorial/databases/tutorial/wikipage_view.pt b/docs/quick_tutorial/databases/tutorial/wikipage_view.pt new file mode 100644 index 000000000..cb9ff526e --- /dev/null +++ b/docs/quick_tutorial/databases/tutorial/wikipage_view.pt @@ -0,0 +1,17 @@ + + + + WikiPage: View + + + + Up + | + + Edit + + +

${page.title}

+

${structure: page.body}

+ + \ No newline at end of file -- cgit v1.2.3 From 34e974e360184baef873da55f31379697e367f32 Mon Sep 17 00:00:00 2001 From: Paul Everitt Date: Wed, 25 Sep 2013 12:08:33 -0400 Subject: Get pyramid_chameleon added to the quick tutorial, plus some other fixes for Python 3. --- docs/quick_tutorial/databases/setup.py | 4 ++-- docs/quick_tutorial/databases/tutorial/__init__.py | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'docs/quick_tutorial/databases') diff --git a/docs/quick_tutorial/databases/setup.py b/docs/quick_tutorial/databases/setup.py index 5cb197c39..238358fe4 100644 --- a/docs/quick_tutorial/databases/setup.py +++ b/docs/quick_tutorial/databases/setup.py @@ -2,11 +2,11 @@ from setuptools import setup requires = [ 'pyramid', + 'pyramid_chameleon', 'deform', 'sqlalchemy', 'pyramid_tm', - 'zope.sqlalchemy', - 'pysqlite' + 'zope.sqlalchemy' ] setup(name='tutorial', diff --git a/docs/quick_tutorial/databases/tutorial/__init__.py b/docs/quick_tutorial/databases/tutorial/__init__.py index 47e8fefa6..74aa25740 100644 --- a/docs/quick_tutorial/databases/tutorial/__init__.py +++ b/docs/quick_tutorial/databases/tutorial/__init__.py @@ -11,6 +11,7 @@ def main(global_config, **settings): config = Configurator(settings=settings, root_factory='tutorial.models.Root') + config.include('pyramid_chameleon') config.add_route('wiki_view', '/') config.add_route('wikipage_add', '/add') config.add_route('wikipage_view', '/{uid}') -- cgit v1.2.3 From ba85e591d563ed654f492f7cab5ca492a32a86d7 Mon Sep 17 00:00:00 2001 From: Tres Seaver Date: Thu, 13 Mar 2014 18:17:43 -0400 Subject: Strip redundant logging config from tutorial INI files. Leave it for the 'logging' and 'scaffolds' sections, where it is germane. --- docs/quick_tutorial/databases/development.ini | 36 --------------------------- 1 file changed, 36 deletions(-) (limited to 'docs/quick_tutorial/databases') diff --git a/docs/quick_tutorial/databases/development.ini b/docs/quick_tutorial/databases/development.ini index 270da960f..04c249a62 100644 --- a/docs/quick_tutorial/databases/development.ini +++ b/docs/quick_tutorial/databases/development.ini @@ -11,39 +11,3 @@ sqlalchemy.url = sqlite:///%(here)s/sqltutorial.sqlite use = egg:pyramid#wsgiref host = 0.0.0.0 port = 6543 - -# Begin logging configuration - -[loggers] -keys = root, tutorial, sqlalchemy - -[logger_tutorial] -level = DEBUG -handlers = -qualname = tutorial - -[logger_sqlalchemy] -level = INFO -handlers = -qualname = sqlalchemy.engine - -[handlers] -keys = console - -[formatters] -keys = generic - -[logger_root] -level = INFO -handlers = console - -[handler_console] -class = StreamHandler -args = (sys.stderr,) -level = NOTSET -formatter = generic - -[formatter_generic] -format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s - -# End logging configuration -- cgit v1.2.3 From c8e23eca583e1e3dd770951e820004a1477c4e11 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sat, 23 May 2015 12:05:56 -0700 Subject: fix template static asset URLs; grammar; line numbers --- docs/quick_tutorial/databases/tutorial/wikipage_addedit.pt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'docs/quick_tutorial/databases') diff --git a/docs/quick_tutorial/databases/tutorial/wikipage_addedit.pt b/docs/quick_tutorial/databases/tutorial/wikipage_addedit.pt index d1fea0d7f..01955ef72 100644 --- a/docs/quick_tutorial/databases/tutorial/wikipage_addedit.pt +++ b/docs/quick_tutorial/databases/tutorial/wikipage_addedit.pt @@ -4,10 +4,12 @@ WikiPage: Add/Edit + href="${request.static_url(reqt)}"> + - -- cgit v1.2.3 From 608f955e20723723f33750211bb12debf613819b Mon Sep 17 00:00:00 2001 From: Karen Dalton Date: Mon, 1 Jun 2015 12:54:43 -0700 Subject: Add additional logging configs necessary for db script output and update tests.py to fix the 'At least one scoped session' warning --- docs/quick_tutorial/databases/development.ini | 36 +++++++++++++++++++++++++ docs/quick_tutorial/databases/tutorial/tests.py | 4 +-- 2 files changed, 38 insertions(+), 2 deletions(-) (limited to 'docs/quick_tutorial/databases') diff --git a/docs/quick_tutorial/databases/development.ini b/docs/quick_tutorial/databases/development.ini index 04c249a62..5da87d602 100644 --- a/docs/quick_tutorial/databases/development.ini +++ b/docs/quick_tutorial/databases/development.ini @@ -11,3 +11,39 @@ sqlalchemy.url = sqlite:///%(here)s/sqltutorial.sqlite use = egg:pyramid#wsgiref host = 0.0.0.0 port = 6543 + +# Begin logging configuration + +[loggers] +keys = root, tutorial, sqlalchemy.engine.base.Engine + +[logger_tutorial] +level = DEBUG +handlers = +qualname = tutorial + +[handlers] +keys = console + +[formatters] +keys = generic + +[logger_root] +level = INFO +handlers = console + +[logger_sqlalchemy.engine.base.Engine] +level = INFO +handlers = +qualname = sqlalchemy.engine.base.Engine + +[handler_console] +class = StreamHandler +args = (sys.stderr,) +level = NOTSET +formatter = generic + +[formatter_generic] +format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s + +# End logging configuration diff --git a/docs/quick_tutorial/databases/tutorial/tests.py b/docs/quick_tutorial/databases/tutorial/tests.py index e18e70c8c..1e08ef760 100644 --- a/docs/quick_tutorial/databases/tutorial/tests.py +++ b/docs/quick_tutorial/databases/tutorial/tests.py @@ -40,7 +40,6 @@ class WikiViewTests(unittest.TestCase): class WikiFunctionalTests(unittest.TestCase): def setUp(self): - self.session = _initTestingDB() self.config = testing.setUp() from pyramid.paster import get_app app = get_app('development.ini') @@ -48,7 +47,8 @@ class WikiFunctionalTests(unittest.TestCase): self.testapp = TestApp(app) def tearDown(self): - self.session.remove() + from .models import DBSession + DBSession.remove() testing.tearDown() def test_it(self): -- cgit v1.2.3 From cd979b7d0e8a9e17d07fd76dd09ad9ea60cd2c9b Mon Sep 17 00:00:00 2001 From: Karen Dalton Date: Mon, 1 Jun 2015 14:05:51 -0700 Subject: remove some calls to the testing module and self.config as they are not used --- docs/quick_tutorial/databases/tutorial/tests.py | 4 ---- 1 file changed, 4 deletions(-) (limited to 'docs/quick_tutorial/databases') diff --git a/docs/quick_tutorial/databases/tutorial/tests.py b/docs/quick_tutorial/databases/tutorial/tests.py index 1e08ef760..4aeb718e6 100644 --- a/docs/quick_tutorial/databases/tutorial/tests.py +++ b/docs/quick_tutorial/databases/tutorial/tests.py @@ -23,11 +23,9 @@ def _initTestingDB(): class WikiViewTests(unittest.TestCase): def setUp(self): self.session = _initTestingDB() - self.config = testing.setUp() def tearDown(self): self.session.remove() - testing.tearDown() def test_wiki_view(self): from tutorial.views import WikiViews @@ -40,7 +38,6 @@ class WikiViewTests(unittest.TestCase): class WikiFunctionalTests(unittest.TestCase): def setUp(self): - self.config = testing.setUp() from pyramid.paster import get_app app = get_app('development.ini') from webtest import TestApp @@ -49,7 +46,6 @@ class WikiFunctionalTests(unittest.TestCase): def tearDown(self): from .models import DBSession DBSession.remove() - testing.tearDown() def test_it(self): res = self.testapp.get('/', status=200) -- cgit v1.2.3 From 3da8dd06f1f5ac41b548755f68906d4a0934e3b2 Mon Sep 17 00:00:00 2001 From: Karen Dalton Date: Mon, 1 Jun 2015 14:22:01 -0700 Subject: add self.config = testing.setUp and testing.tearDown back to WikiViewTests as it is a standard pattern for view tests --- docs/quick_tutorial/databases/tutorial/tests.py | 2 ++ 1 file changed, 2 insertions(+) (limited to 'docs/quick_tutorial/databases') diff --git a/docs/quick_tutorial/databases/tutorial/tests.py b/docs/quick_tutorial/databases/tutorial/tests.py index 4aeb718e6..11e747d15 100644 --- a/docs/quick_tutorial/databases/tutorial/tests.py +++ b/docs/quick_tutorial/databases/tutorial/tests.py @@ -23,9 +23,11 @@ def _initTestingDB(): class WikiViewTests(unittest.TestCase): def setUp(self): self.session = _initTestingDB() + self.config = testing.setUp() def tearDown(self): self.session.remove() + testing.tearDown() def test_wiki_view(self): from tutorial.views import WikiViews -- cgit v1.2.3 From 122a5164c7f0f279580a6c291de5c0a8adee1ac3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arian=20Maykon=20de=20Arau=CC=81jo=20Dio=CC=81genes?= Date: Thu, 14 Apr 2016 10:50:40 -0300 Subject: Issue #2493: Fixing Quick Tutorial Step 18 - CSS/JS Paths, also on Step 19 - Database --- docs/quick_tutorial/databases/tutorial/wikipage_addedit.pt | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'docs/quick_tutorial/databases') diff --git a/docs/quick_tutorial/databases/tutorial/wikipage_addedit.pt b/docs/quick_tutorial/databases/tutorial/wikipage_addedit.pt index 01955ef72..d1fea0d7f 100644 --- a/docs/quick_tutorial/databases/tutorial/wikipage_addedit.pt +++ b/docs/quick_tutorial/databases/tutorial/wikipage_addedit.pt @@ -4,12 +4,10 @@ WikiPage: Add/Edit + href="${request.static_url('deform:static/' + reqt)}"/> - - -- cgit v1.2.3 From 8bca48a37f5a0f79976d975aa3afd5760688a89c Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sat, 16 Apr 2016 13:22:31 -0700 Subject: quick_tutorial cleanup - replace nose with pytest - cleanup databases.rst --- docs/quick_tutorial/databases/sqltutorial.sqlite | Bin 12288 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 docs/quick_tutorial/databases/sqltutorial.sqlite (limited to 'docs/quick_tutorial/databases') diff --git a/docs/quick_tutorial/databases/sqltutorial.sqlite b/docs/quick_tutorial/databases/sqltutorial.sqlite deleted file mode 100644 index b8bd856fd..000000000 Binary files a/docs/quick_tutorial/databases/sqltutorial.sqlite and /dev/null differ -- cgit v1.2.3