diff options
Diffstat (limited to 'docs/tutorials/bfgwiki2')
93 files changed, 0 insertions, 5902 deletions
diff --git a/docs/tutorials/bfgwiki2/authorization.rst b/docs/tutorials/bfgwiki2/authorization.rst deleted file mode 100644 index 709d0ba8e..000000000 --- a/docs/tutorials/bfgwiki2/authorization.rst +++ /dev/null @@ -1,280 +0,0 @@ -.. _wiki2_adding_authorization: - -==================== -Adding Authorization -==================== - -Our application currently allows anyone with access to the server to -view, edit, and add pages to our wiki. For purposes of demonstration -we'll change our application to allow only people whom possess a -specific username (`editor`) to add and edit wiki pages but we'll -continue allowing anyone with access to the server to view pages. -:mod:`repoze.bfg` provides facilities for *authorization* and -*authentication*. We'll make use of both features to provide security -to our application. - -The source code for this tutorial stage can be browsed at -`docs.repoze.org -<http://docs.repoze.org/bfgwiki2-1.3/authorization>`_. - -Adding A Root Factory ---------------------- - -We're going to start to use a custom :term:`root factory` within our -``run.py`` file. The objects generated by the root factory will be -used as the :term:`context` of each request to our application. In -order for :mod:`repoze.bfg` declarative security to work properly, the -context object generated during a request must be decorated with -security declarations; when we begin to use a custom root factory to -generate our contexts, we can begin to make use of the declarative -security features of :mod:`repoze.bfg`. - -Let's modify our ``run.py``, passing in a :term:`root factory` to our -:term:`Configurator` constructor. We'll point it at a new class we -create inside our ``models.py`` file. Add the following statements to -your ``models.py`` file: - -.. code-block:: python - - from repoze.bfg.security import Allow - from repoze.bfg.security import Everyone - - class RootFactory(object): - __acl__ = [ (Allow, Everyone, 'view'), - (Allow, 'group:editors', 'edit') ] - def __init__(self, request): - self.__dict__.update(request.matchdict) - -The ``RootFactory`` class we've just added will be used by -:mod:`repoze.bfg` to construct a ``context`` object. The context is -attached to the request object passed to our view callables as the -``context`` attribute. - -All of our context objects will possess an ``__acl__`` attribute that -allows :data:`repoze.bfg.security.Everyone` (a special principal) to -view all pages, while allowing only a :term:`principal` named -``group:editors`` to edit and add pages. The ``__acl__`` attribute -attached to a context is interpreted specially by :mod:`repoze.bfg` as -an access control list during view callable execution. See -:ref:`assigning_acls` for more information about what an :term:`ACL` -represents. - -.. note: Although we don't use the functionality here, the ``factory`` - used to create route contexts may differ per-route as opposed to - globally. See the ``factory`` attribute in - :ref:`route_zcml_directive` for more info. - -We'll pass the ``RootFactory`` we created in the step above in as the -``root_factory`` argument to a :term:`Configurator`. When we're done, -your application's ``run.py`` will look like this. - -.. literalinclude:: src/authorization/tutorial/run.py - :linenos: - :language: python - -Configuring a ``repoze.bfg`` Authorization Policy -------------------------------------------------- - -For any :mod:`repoze.bfg` application to perform authorization, we -need to add a ``security.py`` module and we'll need to change our -``configure.zcml`` file to add an :term:`authentication policy` and an -:term:`authorization policy`. - -Changing ``configure.zcml`` -~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -We'll change our ``configure.zcml`` file to enable an -``AuthTktAuthenticationPolicy`` and an ``ACLAuthorizationPolicy`` to -enable declarative security checking. We'll also change -``configure.zcml`` to add a view stanza which points at our ``login`` -:term:`view callable`, also known as a :term:`forbidden view`. This -configures our newly created login view to show up when -:mod:`repoze.bfg` detects that a view invocation can not be -authorized. Also, we'll add ``view_permission`` attributes with the -value ``edit`` to the ``edit_page`` and ``add_page`` route -declarations. This indicates that the view callables which these -routes reference cannot be invoked without the authenticated user -possessing the ``edit`` permission with respect to the current -context. - -This makes the assertion that only users who possess the effective -``edit`` permission at the time of the request may invoke those two -views. We've granted the ``group:editors`` principal the ``edit`` -permission at the root model via its ACL, so only the a user whom is a -member of the group named ``group:editors`` will able to invoke the -views associated with the ``add_page`` or ``edit_page`` routes. - -When you're done, your ``configure.zcml`` will look like so - -.. literalinclude:: src/authorization/tutorial/configure.zcml - :linenos: - :language: xml - -Note that the ``authtktauthenticationpolicy`` tag has two attributes: -``secret`` and ``callback``. ``secret`` is a string representing an -encryption key used by the "authentication ticket" machinery -represented by this policy: it is required. The ``callback`` is a -string, representing a :term:`dotted Python name`, which points at the -``groupfinder`` function in the current directory's ``security.py`` -file. We haven't added that module yet, but we're about to. - -Adding ``security.py`` -~~~~~~~~~~~~~~~~~~~~~~ - -Add a ``security.py`` module within your package (in the same -directory as "run.py", "views.py", etc) with the following content: - -.. literalinclude:: src/authorization/tutorial/security.py - :linenos: - :language: python - -The groupfinder defined here is an :term:`authentication policy` -"callback"; it is a callable that accepts a userid and a request. If -the userid exists in the system, the callback will return a sequence -of group identifiers (or an empty sequence if the user isn't a member -of any groups). If the userid *does not* exist in the system, the -callback will return ``None``. In a production system, user and group -data will most often come from a database, but here we use "dummy" -data to represent user and groups sources. Note that the ``editor`` -user is a member of the ``group:editors`` group in our dummy group -data (the ``GROUPS`` data structure). - -We've given the ``editor`` user membership to the ``group:editors`` by -mapping him to this group in the ``GROUPS`` data structure (``GROUPS = -{'editor':['group:editors']}``). Since the ``groupfinder`` function -consults the ``GROUPS`` data structure, this will mean that, as a -result of the ACL attached to the root returned by the root factory, -and the permission associated with the ``add_page`` and ``edit_page`` -views, the ``editor`` user should be able to add and edit pages. - -Adding Login and Logout Views -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -We'll add a ``login`` view callable which renders a login form and -processes the post from the login form, checking credentials. - -We'll also add a ``logout`` view callable to our application and -provide a link to it. This view will clear the credentials of the -logged in user and redirect back to the front page. - -We'll add a different file (for presentation convenience) to add login -and logout view callables. Add a file named ``login.py`` to your -application (in the same directory as ``views.py``) with the following -content: - -.. literalinclude:: src/authorization/tutorial/login.py - :linenos: - :language: python - -Changing Existing Views -~~~~~~~~~~~~~~~~~~~~~~~ - -Then we need to change each of our ``view_page``, ``edit_page`` and -``add_page`` views in ``views.py`` to pass a "logged in" parameter to -its template. We'll add something like this to each view body: - -.. ignore-next-block -.. code-block:: python - :linenos: - - from repoze.bfg.security import authenticated_userid - logged_in = authenticated_userid(request) - -We'll then change the return value of these views to pass the -`resulting `logged_in`` value to the template, e.g.: - -.. ignore-next-block -.. code-block:: python - :linenos: - - return dict(page = context, - content = content, - logged_in = logged_in, - edit_url = edit_url) - -Adding the ``login.pt`` Template -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Add a ``login.pt`` template to your templates directory. It's -referred to within the login view we just added to ``login.py``. - -.. literalinclude:: src/authorization/tutorial/templates/login.pt - :linenos: - :language: xml - -Change ``view.pt`` and ``edit.pt`` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -We'll also need to change our ``edit.pt`` and ``view.pt`` templates to -display a "Logout" link if someone is logged in. This link will -invoke the logout view. - -To do so we'll add this to both templates within the ``<div -class="main_content">`` div: - -.. code-block:: xml - :linenos: - - <span tal:condition="logged_in"> - <a href="${request.application_url}/logout">Logout</a> - </span> - -Viewing the Application in a Browser ------------------------------------- - -We can finally examine our application in a browser. The views we'll -try are as follows: - -- Visiting ``http://localhost:6543/`` in a browser invokes the - ``view_wiki`` view. This always redirects to the ``view_page`` view - of the FrontPage page object. It is executable by any user. - -- Visiting ``http://localhost:6543/FrontPage`` in a browser invokes - the ``view_page`` view of the FrontPage page object. - -- Visiting ``http://localhost:6543/FrontPage/edit_page`` in a browser - invokes the edit view for the FrontPage object. It is executable by - only the ``editor`` user. If a different user (or the anonymous - user) invokes it, a login form will be displayed. Supplying the - credentials with the username ``editor``, password ``editor`` will - display the edit page form. - -- Visiting ``http://localhost:6543/add_page/SomePageName`` in a - browser invokes the add view for a page. It is executable by only - the ``editor`` user. If a different user (or the anonymous user) - invokes it, a login form will be displayed. Supplying the - credentials with the username ``editor``, password ``editor`` will - display the edit page form. - -Seeing Our Changes To ``views.py`` and our Templates ----------------------------------------------------- - -Our ``views.py`` module will look something like this when we're done: - -.. literalinclude:: src/authorization/tutorial/views.py - :linenos: - :language: python - -Our ``edit.pt`` template will look something like this when we're done: - -.. literalinclude:: src/authorization/tutorial/templates/edit.pt - :linenos: - :language: xml - -Our ``view.pt`` template will look something like this when we're done: - -.. literalinclude:: src/authorization/tutorial/templates/view.pt - :linenos: - :language: xml - -Revisiting the Application ---------------------------- - -When we revisit the application in a browser, and log in (as a result -of hitting an edit or add page and submitting the login form with the -``editor`` credentials), we'll see a Logout link in the upper right -hand corner. When we click it, we're logged out, and redirected back -to the front page. - - - diff --git a/docs/tutorials/bfgwiki2/background.rst b/docs/tutorials/bfgwiki2/background.rst deleted file mode 100644 index aed9b875d..000000000 --- a/docs/tutorials/bfgwiki2/background.rst +++ /dev/null @@ -1,17 +0,0 @@ -========== -Background -========== - -This tutorial presents a :mod:`repoze.bfg` application that uses -technologies which will be familiar to someone with :term:`Pylons` -experience. It uses :term:`SQLAlchemy` as a persistence mechanism and -:term:`url dispatch` to map URLs to code. It can also be followed by -people without any prior Python web framework experience. - -To code along with this tutorial, the developer will need a UNIX -machine with development tools (Mac OS X with XCode, any Linux or BSD -variant, etc) *or* he will need a Windows system of any kind. - -This tutorial is targeted at :mod:`repoze.bfg` version 1.3. - -Have fun! diff --git a/docs/tutorials/bfgwiki2/basiclayout.rst b/docs/tutorials/bfgwiki2/basiclayout.rst deleted file mode 100644 index bf458c844..000000000 --- a/docs/tutorials/bfgwiki2/basiclayout.rst +++ /dev/null @@ -1,147 +0,0 @@ -============ -Basic Layout -============ - -The starter files generated by the ``bfg_routesalchemy`` template are -basic, but they provide a good orientation for the high-level patterns -common to most :term:`url dispatch` -based :mod:`repoze.bfg` projects. - -The source code for this tutorial stage can be browsed at -`docs.repoze.org <http://docs.repoze.org/bfgwiki2-1.3/basiclayout>`_. - -``__init__.py`` ---------------- - -A directory on disk can be turned into a Python :term:`package` by -containing an ``__init__.py`` file. Even if empty, this marks a -directory as a Python package. - -Configuration With ``configure.zcml`` --------------------------------------- - -:mod:`repoze.bfg` uses a configuration markup language syntactically -the same as Zope's implementation of :term:`ZCML`, but using a -different default XML namespace. Our sample ZCML file looks like the -following: - - .. literalinclude:: src/basiclayout/tutorial/configure.zcml - :linenos: - :language: xml - -#. *Line 1*. The root ``<configure>`` element, using the - ``http://namespaces.repoze.org/bfg`` namespace. - -#. *Lines 3-4*. Boilerplate, the comment explains. - -#. *Lines 6-11*. Register a ``<route>`` :term:`route configuration` - that will be used when the URL is ``/``. Since this ``<route>`` - has an empty ``pattern`` attribute, it is the "default" route. The - attribute named ``view`` with the value ``.views.my_view`` is the - dotted name to a *function* we write (generated by the - ``bfg_routesalchemy`` template) that is given a ``request`` object - and which returns a response or a dictionary. You will use mostly - ``<route>`` statements in a :term:`URL dispatch` based application - to map URLs to code. This ``route`` also names a - ``view_renderer``, which is a template which lives in the - ``templates`` subdirectory of the package. When the - ``.views.my_view`` view returns a dictionary, a :term:`renderer` - will use this template to create a response. - -#. *Lines 13-16*. Register a ``<static>`` directive that will match - any URL that starts with ``/static/``. This will serve up static - resources for us, in this case, at - ``http://localhost:6543/static/`` and below. With this - declaration, we're saying that any URL that starts with ``/static`` - should go to the static view; any remainder of its path (e.g. the - ``/foo`` in ``/static/foo``) will be used to compose a path to a - static file resource, such as a CSS file. - -#. *Line 18*. The closing ``</configure>`` tag. - -Content Models with ``models.py`` ---------------------------------- - -In a SQLAlchemy-based application, a *model* object is an object -composed by querying the SQL database which backs an application. -SQLAlchemy is an "object relational mapper" (an ORM). The -``models.py`` file is where the ``bfg_routesalchemy`` Paster template -put the classes that implement our models. - -Here is the source for ``models.py``: - - .. literalinclude:: src/basiclayout/tutorial/models.py - :linenos: - :language: py - -#. *Lines 1-14*. Imports to support later code. - -#. *Line 16*. We set up a SQLAlchemy "DBSession" object here. We - specify that we'd like to use the "ZopeTransactionExtension". This - extension is an extension which allows us to use a *transaction - manager* instead of controlling commits and aborts to database - operations by hand. - -#. *Line 17*. We create a declarative ``Base`` object to use as a - base class for our model. - -#. *Lines 19-27*. A model class named ``MyModel``. It has an - ``__init__`` that takes a two arguments (``name``, and ``value``). - It stores these values as ``self.name`` and ``self.value`` within - the ``__init__`` function itself. The ``MyModel`` class also has a - ``__tablename__`` attribute. This informs SQLAlchemy which table - to use to store the data representing instances of this class. - -#. *Lines 29-34*. A function named ``populate`` which adds a single - model instance into our SQL storage and commits a transaction. - -#. *Lines 36-44*. A function named ``initialize_sql`` which sets up - an actual SQL database and binds it to our SQLAlchemy DBSession - object. It also calls the ``populate`` function, to do initial - database population. - -App Startup with ``run.py`` ---------------------------- - -When you run the application using the ``paster`` command using the -``tutorial.ini`` generated config file, the application configuration -points at an Setuptools *entry point* described as -``egg:tutorial#app``. In our application, because the application's -``setup.py`` file says so, this entry point happens to be the ``app`` -function within the file named ``run.py``: - - .. literalinclude:: src/basiclayout/tutorial/run.py - :linenos: - :language: py - -#. *Lines 1-3*. Imports to support later code. - -#. *Line 12*. Obtain the ``configure_zcml`` setting from a value in - the ``tutorial.ini`` file's ``[app:sqlalchemy]`` section. If it - doesn't exist in the configuration file, default to - ``configure.zcml``. - -#. *Lines 13-15*. Get the database configuration string from the - ``tutorial.ini`` file's ``[app:sqlalchemy]`` section. This will be a URI - (something like ``sqlite://``). - -#. *Line 16*. Get the database echo settingf rom ``tutorial.ini`` - file's ``[app:sqlalchemy]`` section. This will either be ``true`` - or ``false``. If ``true``, the application will print SQL to the - console as it is generated and run by SQLAlchemy. By default, it - is false. - -#. Line *17*. We initialize our SQL database using SQLAlchemy, passing - it the db string and a variant of the db_echo value. - -#. *Line 18*. We construct a :term:`Configurator`. ``settings`` is - passed as a keyword argument with the dictionary values passed by - PasteDeploy as the ``settings`` argument. This will be a - dictionary of settings parsed by PasteDeploy, which contains - deployment-related values such as ``reload_templates``, - ``db_string``, etc. - -#. *Lines 19-22*. We then load a ZCML file to do application - configuration, and use the - :meth:`repoze.bfg.configuration.Configurator.make_wsgi_app` method - to return a :term:`WSGI` application. - diff --git a/docs/tutorials/bfgwiki2/definingmodels.rst b/docs/tutorials/bfgwiki2/definingmodels.rst deleted file mode 100644 index 378f7beda..000000000 --- a/docs/tutorials/bfgwiki2/definingmodels.rst +++ /dev/null @@ -1,78 +0,0 @@ -=============== -Defining Models -=============== - -The first change we'll make to our stock paster-generated application -will be to define a :term:`model` constructor representing a wiki -page. We'll do this inside our ``models.py`` file. - -The source code for this tutorial stage can be browsed at -`docs.repoze.org <http://docs.repoze.org/bfgwiki2-1.3/models>`_. - -Making Edits to ``models.py`` ------------------------------ - -.. note:: - - There is nothing automagically special about the filename - ``models.py``. A project may have many models throughout its - codebase in arbitrarily-named files. Files implementing models - often have ``model`` in their filenames (or they may live in a - Python subpackage of your application package named ``models``) , - but this is only by convention. - -The first thing we want to do is remove the stock ``Model`` class from -the generated ``models.py`` file. The ``Model`` class is only a -sample and we're not going to use it. - -Then, we'll add a ``Page`` class. Because this is a SQLAlchemy -application, this class should inherit from an instance of -:class:`sqlalchemy.ext.declarative.declarative_base`. Declarative -SQLAlchemy models are easier to use than directly-mapped ones. The -code generated by our ``routesalchemy`` paster template does not use -declarative SQLAlchemy syntax, so we'll need to change various things -to begin to use declarative syntax. - -Our ``Page`` class will have a class level attribute ``__tablename__`` -which equals the string ``pages``. This means that SQLAlchemy will -store our wiki data in a SQL table named ``pages``. Our Page class -will also have class-level attributes named ``id``, ``pagename`` and -``data`` (all instances of :class:`sqlalchemy.Column`). These will -map to columns in the ``pages`` table. The ``id`` attribute will be -the primary key in the table. The ``name`` attribute will be a text -attribute, each value of which needs to be unique within the column. -The ``data`` attribute is a text attribute that will hold the body of -each page. - -We'll also remove our ``populate`` function. We'll inline the -populate step into ``initialize_sql``, changing our ``initialize_sql`` -function to add a FrontPage object to our database at startup time. -We're also going to use slightly different binding syntax. It will -will otherwise largely be the same as the ``initialize_sql`` in the -paster-generated ``models.py``. - -Our DBSession assignment stays the same as the original generated -``models.py``. - -Looking at the Result of Our Edits to ``models.py`` ---------------------------------------------------- - -The result of all of our edits to ``models.py`` will end up looking -something like this: - -.. literalinclude:: src/models/tutorial/models.py - :linenos: - :language: python - -Viewing the Application in a Browser ------------------------------------- - -We can't. At this point, our system is in a "non-runnable" state; -we'll need to change view-related files in the next chapter to be able -to start the application successfully. If you try to start the -application, you'll wind up with a Python traceback on your console -that ends with this exception: - -.. code-block:: text - - ImportError: cannot import name MyModel diff --git a/docs/tutorials/bfgwiki2/definingviews.rst b/docs/tutorials/bfgwiki2/definingviews.rst deleted file mode 100644 index c33795883..000000000 --- a/docs/tutorials/bfgwiki2/definingviews.rst +++ /dev/null @@ -1,402 +0,0 @@ -============== -Defining Views -============== - -A :term:`view callable` in a :term:`url dispatch` -based -:mod:`repoze.bfg` application is typically a simple Python function -that accepts a single parameter named :term:`request`. A view -callable is assumed to return a :term:`response` object. - -.. note:: A :mod:`repoze.bfg` view can also be defined as callable - which accepts *two* arguments: a :term:`context` and a - :term:`request`. You'll see this two-argument pattern used in - other :mod:`repoze.bfg` tutorials and applications. Either calling - convention will work in any :mod:`repoze.bfg` application; the - calling conventions can be used interchangeably as necessary. In - :term:`url dispatch` based applications, however, the context - object is rarely used in the view body itself, so within this - tutorial we define views as callables that accept only a request to - avoid the visual "noise". If you do need the ``context`` within a - view function that only takes the request as a single argument, you - can obtain it via ``request.context``. - -The request passed to every view that is called as the result of a -route match has an attribute named ``matchdict`` that contains the -elements placed into the URL by the ``pattern`` of a ``route`` -statement. For instance, if a route statement in ``configure.zcml`` -had the pattern ``:one/:two``, and the URL at -``http://example.com/foo/bar`` was invoked, matching this pattern, the -matchdict dictionary attached to the request passed to the view would -have a ``one`` key with the value ``foo`` and a ``two`` key with the -value ``bar``. - -The source code for this tutorial stage can be browsed at -`docs.repoze.org <http://docs.repoze.org/bfgwiki2-1.3/views>`_. - -Declaring Dependencies in Our ``setup.py`` File -=============================================== - -The view code in our application will depend on a package which is not -a dependency of the original "tutorial" application. The original -"tutorial" application was generated by the ``paster create`` command; -it doesn't know about our custom application requirements. We need to -add a dependency on the ``docutils`` package to our ``tutorial`` -package's ``setup.py`` file by assigning this dependency to the -``install_requires`` parameter in the ``setup`` function. - -Our resulting ``setup.py`` should look like so: - -.. literalinclude:: src/views/setup.py - :linenos: - :language: python - -.. note:: After these new dependencies are added, you will need to - rerun ``python setup.py develop`` inside the root of the - ``tutorial`` package to obtain and register the newly added - dependency package. - -Adding View Functions -===================== - -We'll get rid of our ``my_view`` view function in our ``views.py`` -file. It's only an example and isn't relevant to our application. - -Then we're going to add four :term:`view callable` functions to our -``views.py`` module. One view callable (named ``view_wiki``) will -display the wiki itself (it will answer on the root URL), another -named ``view_page`` will display an individual page, another named -``add_page`` will allow a page to be added, and a final view callable -named ``edit_page`` will allow a page to be edited. We'll describe -each one briefly and show the resulting ``views.py`` file afterward. - -.. note:: - - There is nothing special about the filename ``views.py``. A project - may have many view callables throughout its codebase in - arbitrarily-named files. Files implementing view callables often - have ``view`` in their filenames (or may live in a Python subpackage - of your application package named ``views``), but this is only by - convention. - -The ``view_wiki`` view function -------------------------------- - -The ``view_wiki`` function will respond as the :term:`default view` of -a ``Wiki`` model object. It always redirects to a URL which -represents the path to our "FrontPage". It returns an instance of the -:class:`webob.exc.HTTPFound` class (instances of which implement the -WebOb :term:`response` interface), It will use the -:func:`repoze.bfg.url.route_url` API to construct a URL to the -``FrontPage`` page (e.g. ``http://localhost:6543/FrontPage``), and -will use it as the "location" of the HTTPFound response, forming an -HTTP redirect. - -The ``view_page`` view function -------------------------------- - -The ``view_page`` function will respond as the :term:`default view` of -a ``Page`` object. The ``view_page`` function renders the -:term:`ReStructuredText` body of a page (stored as the ``data`` -attribute of a Page object) as HTML. Then it substitutes an HTML -anchor for each *WikiWord* reference in the rendered HTML using a -compiled regular expression. - -The curried function named ``check`` is used as the first argument to -``wikiwords.sub``, indicating that it should be called to provide a -value for each WikiWord match found in the content. If the wiki -already contains a page with the matched WikiWord name, the ``check`` -function generates a view link to be used as the substitution value -and returns it. If the wiki does not already contain a page with with -the matched WikiWord name, the function generates an "add" link as the -substitution value and returns it. - -As a result, the ``content`` variable is now a fully formed bit of -HTML containing various view and add links for WikiWords based on the -content of our current page object. - -We then generate an edit URL (because it's easier to do here than in -the template), and we return a dictionary with a number of arguments. -The fact that this view returns a dictionary (as opposed to a -:term:`response` object) is a cue to :mod:`repoze.bfg` that it should -try to use a :term:`renderer` associated with the view configuration -to render a template. In our case, the template which will be -rendered will be the ``templates/view.pt`` template, as per the -configuration put into effect in ``configure.zcml``. - -The ``add_page`` view function ------------------------------- - -The ``add_page`` function will be invoked when a user clicks on a -*WikiWord* which isn't yet represented as a page in the system. The -``check`` function within the ``view_page`` view generates URLs to -this view. It also acts as a handler for the form that is generated -when we want to add a page object. The ``matchdict`` attribute of the -request passed to the ``add_page`` view will have the values we need -to construct URLs and find model objects. - -The matchdict will have a ``pagename`` key that matches the name of -the page we'd like to add. If our add view is invoked via, -e.g. ``http://localhost:6543/add_page/SomeName``, the ``pagename`` -value in the matchdict will be ``SomeName``. - -If the view execution is *not* a result of a form submission (if the -expression ``'form.submitted' in request.params`` is ``False``), the -view callable renders a template. To do so, it generates a "save url" -which the template use as the form post URL during rendering. We're -lazy here, so we're trying to use the same template -(``templates/edit.pt``) for the add view as well as the page edit -view, so we create a dummy Page object in order to satisfy the edit -form's desire to have *some* page object exposed as ``page``, and -:mod:`repoze.bfg` will render the template associated with this view -to a response. - -If the view execution *is* a result of a form submission (if the -expression ``'form.submitted' in request.params`` is ``True``), we -scrape the page body from the form data, create a Page object using -the name in the matchdict ``pagename``, and obtain the page body from -the request, and save it into the database using ``session.add``. We -then redirect back to the ``view_page`` view (the :term:`default view` -for a Page) for the newly created page. - -The ``edit_page`` view function -------------------------------- - -The ``edit_page`` function will be invoked when a user clicks the -"Edit this Page" button on the view form. It renders an edit form but -it also acts as the handler for the form it renders. The -``matchdict`` attribute of the request passed to the ``add_page`` view -will have a ``pagename`` key matching the name of the page the user -wants to edit. - -If the view execution is *not* a result of a form submission (if the -expression ``'form.submitted' in request.params`` is ``False``), the -view simply renders the edit form, passing the request, the page -object, and a save_url which will be used as the action of the -generated form. - -If the view execution *is* a result of a form submission (if the -expression ``'form.submitted' in request.params`` is ``True``), the -view grabs the ``body`` element of the request parameter and sets it -as the ``data`` key in the matchdict. It then redirects to the -default view of the wiki page, which will always be the ``view_page`` -view. - -Viewing the Result of Our Edits to ``views.py`` -=============================================== - -The result of all of our edits to ``views.py`` will leave it looking -like this: - -.. literalinclude:: src/views/tutorial/views.py - :linenos: - :language: python - -Adding Templates -================ - -The views we've added all reference a :term:`template`. Each template -is a :term:`Chameleon` template. The default templating system in -:mod:`repoze.bfg` is a variant of :term:`ZPT` provided by -:term:`Chameleon`. These templates will live in the ``templates`` -directory of our tutorial package. - -The ``view.pt`` Template ------------------------- - -The ``view.pt`` template is used for viewing a single wiki page. It -is used by the ``view_page`` view function. It should have a div that -is "structure replaced" with the ``content`` value provided by the -view. It should also have a link on the rendered page that points at -the "edit" URL (the URL which invokes the ``edit_page`` view for the -page being viewed). - -Once we're done with the ``view.pt`` template, it will look a lot like -the below: - -.. literalinclude:: src/views/tutorial/templates/view.pt - :linenos: - :language: xml - -.. note:: The names available for our use in a template are always - those that are present in the dictionary returned by the view - callable. But our templates make use of a ``request`` object that - none of our tutorial views return in their dictionary. This value - appears as if "by magic". However, ``request`` is one of several - names that are available "by default" in a template when a template - renderer is used. See :ref:`chameleon_template_renderers` for more - information about other names that are available by default in a - template when a Chameleon template is used as a renderer. - -The ``edit.pt`` Template ------------------------- - -The ``edit.pt`` template is used for adding and editing a wiki page. -It is used by the ``add_page`` and ``edit_page`` view functions. It -should display a page containing a form that POSTs back to the -"save_url" argument supplied by the view. The form should have a -"body" textarea field (the page data), and a submit button that has -the name "form.submitted". The textarea in the form should be filled -with any existing page data when it is rendered. - -Once we're done with the ``edit.pt`` template, it will look a lot like -the below: - -.. literalinclude:: src/views/tutorial/templates/edit.pt - :linenos: - :language: xml - -Static Resources ----------------- - -Our templates name a single static resource named ``style.css``. We -need to create this and place it in a file named ``style.css`` within -our package's ``templates/static`` directory. This file is a little -too long to replicate within the body of this guide, however it is -available `online -<http://docs.repoze.org/bfgwiki2-1.2/views/tutorial/templates/static/style.css>`_. - -This CSS file will be accessed via -e.g. ``http://localhost:6543/static/style.css`` by virtue of the -``<static>`` directive we've defined in the ``configure.zcml`` file. -Any number and type of static resources can be placed in this -directory (or subdirectories) and are just referred to by URL within -templates. - -Mapping Views to URLs in ``configure.zcml`` -=========================================== - -The ``configure.zcml`` file contains ``route`` declarations (and a -lone ``view`` declaration) which serve to map URLs via :term:`url -dispatch` to view functions. First, we’ll get rid of the existing -``route`` created by the template using the name ``home``. It’s only -an example and isn’t relevant to our application. - -We then need to add four ``route`` declarations to ``configure.zcml``. -Note that the *ordering* of these declarations is very important. -``route`` declarations are matched in the order they're found in the -``configure.zcml`` file. - -#. Add a declaration which maps the empty pattern (signifying the root - URL) to the view named ``view_wiki`` in our ``views.py`` file with - the name ``view_wiki``. This is the :term:`default view` for the - wiki. - -#. Add a declaration which maps the pattern ``:pagename`` to the - view named ``view_page`` in our ``views.py`` file with the view - name ``view_page``. This is the regular view for a page. - -#. Add a declaration which maps the pattern - ``:pagename/edit_page`` to the view named ``edit_page`` in our - ``views.py`` file with the name ``edit_page``. This is the edit view - for a page. - -#. Add a declaration which maps the pattern - ``add_page/:pagename`` to the view named ``add_page`` in our - ``views.py`` file with the name ``add_page``. This is the add view - for a new page. - -As a result of our edits, the ``configure.zcml`` file should look -something like so: - -.. literalinclude:: src/views/tutorial/configure.zcml - :linenos: - :language: xml - -The WSGI Pipeline ------------------ - -Within ``tutorial.ini``, note the existence of a ``[pipeline:main]`` -section which specifies our WSGI pipeline. This "pipeline" will be -served up as our WSGI application. As far as the WSGI server is -concerned the pipeline *is* our application. Simpler configurations -don't use a pipeline: instead they expose a single WSGI application as -"main". Our setup is more complicated, so we use a pipeline. - -``egg:repoze.tm2#tm`` is at the "top" of the pipeline. This is a -piece of middleware which commits a transaction if no exception -occurs; if an exception occurs, the transaction will be aborted. This -is the piece of software that allows us to forget about needing to do -manual commits and aborts of our database connection in view code. - -Adding an Element to the Pipeline ---------------------------------- - -Let's add a piece of middleware to the WSGI pipeline. We'll add -``egg:Paste#evalerror`` middleware which displays debuggable errors in -the browser while you're developing (this is *not* recommended for -deployment as it is a security risk). Let's insert evalerror into the -pipeline right above ``egg:repoze.tm2#tm``, making our resulting -``tutorial.ini`` file look like so: - -.. literalinclude:: src/views/tutorial.ini - :linenos: - :language: ini - -Viewing the Application in a Browser -==================================== - -Once we've set up the WSGI pipeline properly, we can finally examine -our application in a browser. The views we'll try are as follows: - -- Visiting ``http://localhost:6543`` in a browser invokes the - ``view_wiki`` view. This always redirects to the ``view_page`` view - of the FrontPage page object. - -- Visiting ``http://localhost:6543/FrontPage`` in a browser invokes - the ``view_page`` view of the front page page object. - -- Visiting ``http://localhost:6543/FrontPage/edit_page`` in a browser - invokes the edit view for the front page object. - -- Visiting ``http://localhost:6543/add_page/SomePageName`` in a - browser invokes the add view for a page. - -Try generating an error within the body of a view by adding code to -the top of it that generates an exception (e.g. ``raise -Exception('Forced Exception')``). Then visit the error-raising view -in a browser. You should see an interactive exception handler in the -browser which allows you to examine values in a post-mortem mode. - -Adding Tests -============ - -Since we've added a good bit of imperative code here, it's useful to -define tests for the views we've created. We'll change our tests.py -module to look like this: - -.. literalinclude:: src/views/tutorial/tests.py - :linenos: - :language: python - -We can then run the tests using something like: - -.. code-block:: text - :linenos: - - $ python setup.py test -q - -The expected output is something like: - -.. code-block:: text - :linenos: - - running test - running egg_info - writing requirements to tutorial.egg-info/requires.txt - writing tutorial.egg-info/PKG-INFO - writing top-level names to tutorial.egg-info/top_level.txt - writing dependency_links to tutorial.egg-info/dependency_links.txt - writing entry points to tutorial.egg-info/entry_points.txt - unrecognized .svn/entries format in - reading manifest file 'tutorial.egg-info/SOURCES.txt' - writing manifest file 'tutorial.egg-info/SOURCES.txt' - running build_ext - ...... - ---------------------------------------------------------------------- - Ran 6 tests in 0.181s - - OK - - - - diff --git a/docs/tutorials/bfgwiki2/distributing.rst b/docs/tutorials/bfgwiki2/distributing.rst deleted file mode 100644 index 22013a0fb..000000000 --- a/docs/tutorials/bfgwiki2/distributing.rst +++ /dev/null @@ -1,49 +0,0 @@ -============================= -Distributing Your Application -============================= - -Once your application works properly, you can create a "tarball" from -it by using the ``setup.py sdist`` command. The following commands -assume your current working directory is the ``tutorial`` package -we've created and that the parent directory of the ``tutorial`` -package is a virtualenv representing a :mod:`repoze.bfg` environment. - -On UNIX: - -.. code-block:: text - - $ ../bin/python setup.py sdist - -On Windows: - -.. code-block:: text - - c:\bigfntut> ..\Scripts\python setup.py sdist - -.. warning:: If your project files are not checked in to a version - control repository (such as Subversion), the dist tarball will - *not* contain all the files it needs to. In particular, it will - not contain non-Python-source files (such as templates and static - files). To ensure that these are included, check your files into a - version control repository before running ``setup.py sdist``. - -The output of such a command will be something like: - -.. code-block:: text - - running sdist - # ... more output ... - creating dist - tar -cf dist/tutorial-0.1.tar tutorial-0.1 - gzip -f9 dist/tutorial-0.1.tar - removing 'tutorial-0.1' (and everything under it) - -Note that this command creates a tarball in the "dist" subdirectory -named ``tutorial-0.1.tar.gz``. You can send this file to your friends -to show them your cool new application. They should be able to -install it by pointing the ``easy_install`` command directly at it. -Or you can upload it to `PyPI <http://pypi.python.org>`_ and share it -with the rest of the world, where it can be downloaded via -``easy_install`` remotely like any other package people download from -PyPI. - diff --git a/docs/tutorials/bfgwiki2/index.rst b/docs/tutorials/bfgwiki2/index.rst deleted file mode 100644 index 34b56ff82..000000000 --- a/docs/tutorials/bfgwiki2/index.rst +++ /dev/null @@ -1,26 +0,0 @@ -.. _bfg_sql_wiki_tutorial: - -SQLAlchemy + URL Dispatch Wiki Tutorial -======================================= - -This tutorial introduces a :term:`SQLAlchemy` and :term:`url dispatch` --based :mod:`repoze.bfg` application to a developer familiar with -Python. When the tutorial is finished, the developer will have -created a basic Wiki application with authentication. - -For cut and paste purposes, the source code for all stages of this -tutorial can be browsed at `docs.repoze.org -<http://docs.repoze.org/bfgwiki2-1.3>`_. - -.. toctree:: - :maxdepth: 2 - - background - installation - basiclayout - definingmodels - definingviews - authorization - distributing - - diff --git a/docs/tutorials/bfgwiki2/installation.rst b/docs/tutorials/bfgwiki2/installation.rst deleted file mode 100644 index 6fd31ce65..000000000 --- a/docs/tutorials/bfgwiki2/installation.rst +++ /dev/null @@ -1,276 +0,0 @@ -============ -Installation -============ - -For the most part, the installation process for this tutorial -duplicates the steps described in :ref:`installing_chapter` and -:ref:`project_narr`, however it also explains how to install -additional libraries for tutorial purposes. - -Preparation -=========== - -Please take the following steps to prepare for the tutorial. The -steps are slightly different depending on whether you're using UNIX or -Windows. - -Preparation, UNIX ------------------ - -#. Install SQLite3 and its development packages if you don't already - have them installed. Usually this is via your system's package - manager. For example, on a Debian Linux system, do ``sudo apt-get - install libsqlite3-dev``. - -#. If you don't already have a Python 2.6 interpreter installed on - your system, obtain, install, or find `Python 2.6 - <http://www.python.org/download/releases/2.6.6/>`_ for your system. - -#. Install the latest `setuptools` into the Python you - obtained/installed/found in the step above: download `ez_setup.py - <http://peak.telecommunity.com/dist/ez_setup.py>`_ and run it using - the ``python`` interpreter of your Python 2.6 installation: - - .. code-block:: text - - $ /path/to/my/Python-2.6/bin/python ez_setup.py - -#. Use that Python's `bin/easy_install` to install `virtualenv`: - - .. code-block:: text - - $ /path/to/my/Python-2.6/bin/easy_install virtualenv - -#. Use that Python's virtualenv to make a workspace: - - .. code-block:: text - - $ path/to/my/Python-2.6/bin/virtualenv --no-site-packages bigfntut - -#. Switch to the ``bigfntut`` directory: - - .. code-block:: text - - $ cd bigfntut - -#. (Optional) Consider using ``source bin/activate`` to make your - shell environment wired to use the virtualenv. - -#. Use ``easy_install`` to get :mod:`repoze.bfg` and its direct - dependencies installed: - - .. code-block:: text - - $ bin/easy_install repoze.bfg - -#. Use ``easy_install`` to install various packages from PyPI. - - .. code-block:: text - - $ bin/easy_install docutils nose coverage zope.sqlalchemy \ - SQLAlchemy repoze.tm2 - -Preparation, Windows --------------------- - -#. Install, or find `Python 2.6.6 - <http://python.org/download/releases/2.6.6/>`_ for your system. - -#. Install the latest `setuptools` into the Python you - obtained/installed/found in the step above: download `ez_setup.py - <http://peak.telecommunity.com/dist/ez_setup.py>`_ and run it using - the ``python`` interpreter of your Python 2.6 installation using a - command prompt: - - .. code-block:: text - - c:\> c:\Python26\python ez_setup.py - -#. Use that Python's `bin/easy_install` to install `virtualenv`: - - .. code-block:: text - - c:\> c:\Python26\Scripts\easy_install virtualenv - -#. Use that Python's virtualenv to make a workspace: - - .. code-block:: text - - c:\> c:\Python26\Scripts\virtualenv --no-site-packages bigfntut - -#. Switch to the ``bigfntut`` directory: - - .. code-block:: text - - c:\> cd bigfntut - -#. (Optional) Consider using ``bin\activate.bat`` to make your shell - environment wired to use the virtualenv. - -#. Use ``easy_install`` to get :mod:`repoze.bfg` and its direct - dependencies installed: - - .. code-block:: text - - c:\bigfntut> Scripts\easy_install repoze.bfg - -#. Use ``easy_install`` to install various packages from PyPI. - - .. code-block:: text - - c:\bigfntut> Scripts\easy_install -i docutils \ - nose coverage zope.sqlalchemy SQLAlchemy repoze.tm2 - - -.. _sql_making_a_project: - -Making a Project -================ - -Your next step is to create a project. :mod:`repoze.bfg` supplies a -variety of templates to generate sample projects. We will use the -``bfg_routesalchemy`` template, which generates an application that -uses :term:`SQLAlchemy` and :term:`URL dispatch`. - -The below instructions assume your current working directory is the -"virtualenv" named "bigfntut". - -On UNIX: - -.. code-block:: text - - $ bin/paster create -t bfg_routesalchemy tutorial - -On Windows: - -.. code-block:: text - - c:\bigfntut> Scripts\paster create -t bfg_routesalchemy tutorial - -.. note:: If you are using Windows, the ``bfg_routesalchemy`` Paster - template may not deal gracefully with installation into a location - that contains spaces in the path. If you experience startup - problems, try putting both the virtualenv and the project into - directories that do not contain spaces in their paths. - -Installing the Project in "Development Mode" -============================================ - -In order to do development on the project easily, you must "register" -the project as a development egg in your workspace using the -``setup.py develop`` command. In order to do so, cd to the "tutorial" -directory you created in :ref:`sql_making_a_project`, and run the -"setup.py develop" command using virtualenv Python interpreter. - -On UNIX: - -.. code-block:: text - - $ cd tutorial - $ ../bin/python setup.py develop - -On Windows: - -.. code-block:: text - - c:\bigfntut> cd tutorial - c:\bigfntut\tutorial> ..\Scripts\python setup.py develop - -.. _sql_running_tests: - -Running the Tests -================= - -After you've installed the project in development mode, you may run -the tests for the project. - -On UNIX: - -.. code-block:: text - - $ ../bin/python setup.py test -q - -On Windows: - -.. code-block:: text - - c:\bigfntut\tutorial> ..\Scripts\python setup.py test -q - -Starting the Application -======================== - -Start the application. - -On UNIX: - -.. code-block:: text - - $ ../bin/paster serve tutorial.ini --reload - -On Windows: - -.. code-block:: text - - c:\bifgfntut\tutorial> ..\Scripts\paster serve tutorial.ini --reload - -Exposing Test Coverage Information -================================== - -You can run the ``nosetests`` command to see test coverage -information. This runs the tests in the same way that ``setup.py -test`` does but provides additional "coverage" information, exposing -which lines of your project are "covered" (or not covered) by the -tests. - -To get this functionality working, we'll need to install a couple of -other packages into our ``virtualenv``: ``nose`` and ``coverage``: - -On UNIX: - -.. code-block:: text - - $ ../bin/easy_install nose coverage - -On Windows: - -.. code-block:: text - - c:\bfgfntut\tutorial> ..\Scripts\easy_install nose coverage - -Once ``nose`` and ``coverage`` are installed, we can actually run the -coverage tests. - -On UNIX: - -.. code-block:: text - - $ ../bin/nosetests --cover-package=tutorial --cover-erase --with-coverage - -On Windows: - -.. code-block:: text - - c:\bigfntut\tutorial> ..\Scripts\nosetests --cover-package=tutorial \ - --cover-erase --with-coverage - -Looks like our package's ``models`` module doesn't quite have 100% -test coverage. - -Visit the Application in a Browser -================================== - -In a browser, visit ``http://localhost:6543/``. You will see the -generated application's default page. - -Decisions the ``bfg_routesalchemy`` Template Has Made For You -============================================================= - -Creating a project using the ``bfg_routesalchemy`` template makes the -assumption that you are willing to use :term:`SQLAlchemy` as a -database access tool and :term:`url dispatch` to map URLs to code. -:mod:`repoze.bfg` supports any persistent storage mechanism -(e.g. object database or filesystem files, etc). It also supports an -additional mechanism to map URLs to code (:term:`traversal`). -However, for the purposes of this tutorial, we'll only be using url -dispatch and SQLAlchemy. - diff --git a/docs/tutorials/bfgwiki2/src/authorization/CHANGES.txt b/docs/tutorials/bfgwiki2/src/authorization/CHANGES.txt deleted file mode 100644 index 35a34f332..000000000 --- a/docs/tutorials/bfgwiki2/src/authorization/CHANGES.txt +++ /dev/null @@ -1,4 +0,0 @@ -0.0 ---- - -- Initial version diff --git a/docs/tutorials/bfgwiki2/src/authorization/README.txt b/docs/tutorials/bfgwiki2/src/authorization/README.txt deleted file mode 100644 index d41f7f90f..000000000 --- a/docs/tutorials/bfgwiki2/src/authorization/README.txt +++ /dev/null @@ -1,4 +0,0 @@ -tutorial README - - - diff --git a/docs/tutorials/bfgwiki2/src/authorization/setup.cfg b/docs/tutorials/bfgwiki2/src/authorization/setup.cfg deleted file mode 100644 index 23b2ad983..000000000 --- a/docs/tutorials/bfgwiki2/src/authorization/setup.cfg +++ /dev/null @@ -1,27 +0,0 @@ -[nosetests] -match=^test -nocapture=1 -cover-package=tutorial -with-coverage=1 -cover-erase=1 - -[compile_catalog] -directory = tutorial/locale -domain = tutorial -statistics = true - -[extract_messages] -add_comments = TRANSLATORS: -output_file = tutorial/locale/tutorial.pot -width = 80 - -[init_catalog] -domain = tutorial -input_file = tutorial/locale/tutorial.pot -output_dir = tutorial/locale - -[update_catalog] -domain = tutorial -input_file = tutorial/locale/tutorial.pot -output_dir = tutorial/locale -previous = true diff --git a/docs/tutorials/bfgwiki2/src/authorization/setup.py b/docs/tutorials/bfgwiki2/src/authorization/setup.py deleted file mode 100644 index 764e8c0ea..000000000 --- a/docs/tutorials/bfgwiki2/src/authorization/setup.py +++ /dev/null @@ -1,46 +0,0 @@ -import os -import sys - -from setuptools import setup, find_packages - -here = os.path.abspath(os.path.dirname(__file__)) -README = open(os.path.join(here, 'README.txt')).read() -CHANGES = open(os.path.join(here, 'CHANGES.txt')).read() - -requires = [ - 'repoze.bfg', - 'SQLAlchemy', - 'transaction', - 'repoze.tm2', - 'zope.sqlalchemy', - 'docutils' - ] - -if sys.version_info[:3] < (2,5,0): - requires.append('pysqlite') - -setup(name='tutorial', - version='0.0', - description='tutorial', - long_description=README + '\n\n' + CHANGES, - classifiers=[ - "Programming Language :: Python", - "Framework :: BFG", - "Topic :: Internet :: WWW/HTTP", - "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", - ], - author='', - author_email='', - url='', - keywords='web wsgi bfg', - packages=find_packages(), - include_package_data=True, - zip_safe=False, - test_suite='tutorial', - install_requires = requires, - entry_points = """\ - [paste.app_factory] - app = tutorial.run:app - """ - ) - diff --git a/docs/tutorials/bfgwiki2/src/authorization/tutorial.ini b/docs/tutorials/bfgwiki2/src/authorization/tutorial.ini deleted file mode 100644 index 85f131c2e..000000000 --- a/docs/tutorials/bfgwiki2/src/authorization/tutorial.ini +++ /dev/null @@ -1,23 +0,0 @@ -[DEFAULT] -debug = true - -[app:sqlalchemy] -use = egg:tutorial#app -reload_templates = true -debug_authorization = false -debug_notfound = false -debug_templates = true -default_locale_name = en -db_string = sqlite:///%(here)s/tutorial.db -db_echo = false - -[pipeline:main] -pipeline = - egg:Paste#evalerror - egg:repoze.tm2#tm - sqlalchemy - -[server:main] -use = egg:Paste#http -host = 0.0.0.0 -port = 6543 diff --git a/docs/tutorials/bfgwiki2/src/authorization/tutorial/__init__.py b/docs/tutorials/bfgwiki2/src/authorization/tutorial/__init__.py deleted file mode 100644 index cbdfd3ac6..000000000 --- a/docs/tutorials/bfgwiki2/src/authorization/tutorial/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -# A package - diff --git a/docs/tutorials/bfgwiki2/src/authorization/tutorial/configure.zcml b/docs/tutorials/bfgwiki2/src/authorization/tutorial/configure.zcml deleted file mode 100644 index 0fd79b4e3..000000000 --- a/docs/tutorials/bfgwiki2/src/authorization/tutorial/configure.zcml +++ /dev/null @@ -1,65 +0,0 @@ -<configure xmlns="http://namespaces.repoze.org/bfg"> - - <!-- this must be included for the view declarations to work --> - <include package="repoze.bfg.includes" /> - - <static - path="templates/static" - name="static" - /> - - <route - pattern="login" - name="login" - view=".login.login" - view_renderer="templates/login.pt" - /> - - <route - pattern="logout" - name="logout" - view=".login.logout" - /> - - <route - pattern="" - name="view_wiki" - view=".views.view_wiki" - /> - - <route - pattern=":pagename" - name="view_page" - view=".views.view_page" - view_renderer="templates/view.pt" - /> - - <route - pattern="add_page/:pagename" - name="add_page" - view=".views.add_page" - view_renderer="templates/edit.pt" - view_permission="edit" - /> - - <route - pattern=":pagename/edit_page" - name="edit_page" - view=".views.edit_page" - view_renderer="templates/edit.pt" - view_permission="edit" - /> - - <view - view=".login.login" - renderer="templates/login.pt" - for="repoze.bfg.exceptions.Forbidden"/> - - <authtktauthenticationpolicy - secret="sosecret" - callback=".security.groupfinder" - /> - - <aclauthorizationpolicy/> - -</configure> diff --git a/docs/tutorials/bfgwiki2/src/authorization/tutorial/login.py b/docs/tutorials/bfgwiki2/src/authorization/tutorial/login.py deleted file mode 100644 index 1a54d575c..000000000 --- a/docs/tutorials/bfgwiki2/src/authorization/tutorial/login.py +++ /dev/null @@ -1,39 +0,0 @@ -from webob.exc import HTTPFound - -from pyramid.security import remember -from pyramid.security import forget -from pyramid.url import route_url - -from tutorial.security import USERS - -def login(request): - login_url = route_url('login', request) - 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, - ) - -def logout(request): - headers = forget(request) - return HTTPFound(location = route_url('view_wiki', request), - headers = headers) - diff --git a/docs/tutorials/bfgwiki2/src/authorization/tutorial/models.py b/docs/tutorials/bfgwiki2/src/authorization/tutorial/models.py deleted file mode 100644 index a77b4964c..000000000 --- a/docs/tutorials/bfgwiki2/src/authorization/tutorial/models.py +++ /dev/null @@ -1,52 +0,0 @@ -import transaction - -from pyramid.security import Allow -from pyramid.security import Everyone - -from sqlalchemy import create_engine -from sqlalchemy import Column -from sqlalchemy import Integer -from sqlalchemy import Text - -from sqlalchemy.exc import IntegrityError -from sqlalchemy.ext.declarative import declarative_base - -from sqlalchemy.orm import scoped_session -from sqlalchemy.orm import 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) - - def __init__(self, name, data): - self.name = name - self.data = data - -def initialize_sql(db_string, echo=False): - engine = create_engine(db_string, echo=echo) - DBSession.configure(bind=engine) - Base.metadata.bind = engine - Base.metadata.create_all(engine) - try: - session = DBSession() - page = Page('FrontPage', 'initial data') - session.add(page) - transaction.commit() - except IntegrityError: - # already created - pass - -class RootFactory(object): - __acl__ = [ (Allow, Everyone, 'view'), - (Allow, 'group:editors', 'edit') ] - def __init__(self, request): - self.__dict__.update(request.matchdict) diff --git a/docs/tutorials/bfgwiki2/src/authorization/tutorial/run.py b/docs/tutorials/bfgwiki2/src/authorization/tutorial/run.py deleted file mode 100644 index 82ce37490..000000000 --- a/docs/tutorials/bfgwiki2/src/authorization/tutorial/run.py +++ /dev/null @@ -1,25 +0,0 @@ -from pyramid.configuration import Configurator -from paste.deploy.converters import asbool - -from tutorial.models import initialize_sql -from tutorial.models import RootFactory - -def app(global_config, **settings): - """ This function returns a WSGI application. - - It is usually called by the PasteDeploy framework during - ``paster serve``. - """ - zcml_file = settings.get('configure_zcml', 'configure.zcml') - db_string = settings.get('db_string') - if db_string is None: - raise ValueError( - "No 'db_string' value in application configuration.") - db_echo = settings.get('db_echo', 'false') - initialize_sql(db_string, asbool(db_echo)) - config = Configurator(settings=settings, root_factory=RootFactory) - config.begin() - config.load_zcml(zcml_file) - config.end() - return config.make_wsgi_app() - diff --git a/docs/tutorials/bfgwiki2/src/authorization/tutorial/security.py b/docs/tutorials/bfgwiki2/src/authorization/tutorial/security.py deleted file mode 100644 index cfd13071e..000000000 --- a/docs/tutorials/bfgwiki2/src/authorization/tutorial/security.py +++ /dev/null @@ -1,8 +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/bfgwiki2/src/authorization/tutorial/templates/edit.pt b/docs/tutorials/bfgwiki2/src/authorization/tutorial/templates/edit.pt deleted file mode 100644 index dd4e0691e..000000000 --- a/docs/tutorials/bfgwiki2/src/authorization/tutorial/templates/edit.pt +++ /dev/null @@ -1,35 +0,0 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" - "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> -<html - xmlns="http://www.w3.org/1999/xhtml" - xmlns:tal="http://xml.zope.org/namespaces/tal"> - -<head> - <meta content="text/html; charset=utf-8" http-equiv="Content-Type"/> - <title>bfg tutorial wiki (based on TurboGears 20-Minute Wiki) - Editing: ${page.name}</title> - <link rel="stylesheet" type="text/css" - href="${request.application_url}/static/style.css" /> -</head> - -<body> - -<div class="main_content"> - <div style="float:right; width: 10em;"> Viewing - <span tal:replace="page.name">Page Name Goes Here</span> <br/> - You can return to the <a href="${request.application_url}" - >FrontPage</a>. - <span tal:condition="logged_in"> - <a href="${request.application_url}/logout">Logout</a> - </span> - </div> - - <div> - <form action="${save_url}" method="post"> - <textarea name="body" tal:content="page.data" rows="10" cols="60"/> - <input type="submit" name="form.submitted" value="Save"/> - </form> - </div> -</div> -</body> -</html> diff --git a/docs/tutorials/bfgwiki2/src/authorization/tutorial/templates/login.pt b/docs/tutorials/bfgwiki2/src/authorization/tutorial/templates/login.pt deleted file mode 100644 index a9e086461..000000000 --- a/docs/tutorials/bfgwiki2/src/authorization/tutorial/templates/login.pt +++ /dev/null @@ -1,32 +0,0 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" - "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> -<html - xmlns="http://www.w3.org/1999/xhtml" - xmlns:tal="http://xml.zope.org/namespaces/tal"> - -<head> - <meta content="text/html; charset=utf-8" http-equiv="Content-Type"/> - <title>bfg tutorial wiki (based on TurboGears 20-Minute Wiki)</title> - <link rel="stylesheet" type="text/css" - href="${request.application_url}/static/style.css" /> -</head> - -<body> - -<h1>Log In</h1> - -<div tal:replace="message"/> - -<div class="main_content"> - <form action="${url}" method="post"> - <input type="hidden" name="came_from" value="${came_from}"/> - <input type="text" name="login" value="${login}"/> - <br/> - <input type="password" name="password" value="${password}"/> - <br/> - <input type="submit" name="form.submitted" value="Log In"/> - </form> -</div> - -</body> -</html> diff --git a/docs/tutorials/bfgwiki2/src/authorization/tutorial/templates/mytemplate.pt b/docs/tutorials/bfgwiki2/src/authorization/tutorial/templates/mytemplate.pt deleted file mode 100644 index 2aedcad9f..000000000 --- a/docs/tutorials/bfgwiki2/src/authorization/tutorial/templates/mytemplate.pt +++ /dev/null @@ -1,99 +0,0 @@ -<!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" - xmlns:tal="http://xml.zope.org/namespaces/tal"> -<head> -<meta http-equiv="content-type" content="text/html; charset=utf-8" /> -<title>${project} Application</title> -<meta name="keywords" content="python web application" /> -<meta name="description" content="repoze.bfg web application" /> -<link href="${request.application_url}/static/default.css" rel="stylesheet" type="text/css" /> -</head> -<body> -<!-- start header --> -<div id="logo"> - <h2><code>${project}</code>, a <code>repoze.bfg</code> application</h2> -</div> -<div id="header"> - <div id="menu"> - </div> -</div> -<!-- end header --> -<div id="wrapper"> - <!-- start page --> - <div id="page"> - <!-- start content --> - <div id="content"> - <div class="post"> - <h1 class="title">Welcome to <code>${project}</code>, an - application generated by the <a - href="http://bfg.repoze.org">repoze.bfg</a> web - application framework.</h1> - </div> - </div> - <!-- end content --> - <!-- start sidebar --> - <div id="sidebar"> - <ul> - <li id="search"> - <h2>Search<br/> <code>repoze.bfg</code> Documentation</h2> - <form method="get" - action="http://bfg.repoze.org/searchresults"> - <fieldset> - <input type="text" id="q" name="text" value="" /> - <input type="submit" id="x" value="Search" /> - </fieldset> - </form> - </li> - <li> - <h2><code>repoze.bfg</code> links</h2> - <ul> - <li><a - href="http://docs.repoze.org/bfg/current/#narrative-documentation">Narrative - Documentation</a> - </li> - <li> - <a - href="http://docs.repoze.org/bfg/current/#api-documentation">API - Documentation</a> - </li> - <li> - <a - href="http://docs.repoze.org/bfg/current/#tutorials">Tutorials</a> - </li> - <li> - <a - href="http://docs.repoze.org/bfg/current/#change-history">Change - History</a> - </li> - <li> - <a - href="http://docs.repoze.org/bfg/current/#sample-applications">Sample - Applications</a> - </li> - <li> - <a - href="http://docs.repoze.org/bfg/current/#support-and-development">Support - and Development</a> - </li> - <li> - <a - href="irc://irc.freenode.net#repoze">IRC Channel</a> - </li> - </ul> - </li> - </ul> - </div> - <!-- end sidebar --> - <div style="clear: both;"> </div> - </div> -</div> -<!-- end page --> -<!-- start footer --> -<div id="footer"> - <p id="legal">( c ) 2008. All Rights Reserved. Template design - by <a href="http://www.freecsstemplates.org/">Free CSS - Templates</a>.</p> -</div> -<!-- end footer --> -</body> -</html> diff --git a/docs/tutorials/bfgwiki2/src/authorization/tutorial/templates/static/default.css b/docs/tutorials/bfgwiki2/src/authorization/tutorial/templates/static/default.css deleted file mode 100644 index 41b3debde..000000000 --- a/docs/tutorials/bfgwiki2/src/authorization/tutorial/templates/static/default.css +++ /dev/null @@ -1,380 +0,0 @@ -/* -Design by Free CSS Templates -http://www.freecsstemplates.org -Released for free under a Creative Commons Attribution 2.5 License -*/ - -body { - margin: 0; - padding: 0; - background: url(images/img01.gif) repeat-x left top; - font-size: 13px; - font-family: "Trebuchet MS", Georgia, "Times New Roman", Times, serif; - text-align: justify; - color: #FFFFFF; -} - -h1, h2, h3 { - margin: 0; - text-transform: lowercase; - font-weight: normal; - color: #FFFFFF; -} - -h1 { - letter-spacing: -1px; - font-size: 32px; -} - -h2 { - font-size: 23px; -} - -p, ul, ol { - margin: 0 0 2em 0; - text-align: justify; - line-height: 26px; -} - -a:link { - color: #8BD80E; -} - -a:hover, a:active { - text-decoration: none; - color: #8BD80E; -} - -a:visited { - color: #8BD80E; -} - -img { - border: none; -} - -img.left { - float: left; - margin-right: 15px; -} - -img.right { - float: right; - margin-left: 15px; -} - -/* Form */ - -form { - margin: 0; - padding: 0; -} - -fieldset { - margin: 0; - padding: 0; - border: none; -} - -legend { - display: none; -} - -input, textarea, select { - font-family: "Trebuchet MS", Arial, Helvetica, sans-serif; - font-size: 13px; - color: #333333; -} - -#wrapper { - margin: 0; - padding: 0; - background: #000000; -} - -/* Header */ - -#header { - width: 713px; - margin: 0 auto; - height: 42px; -} - -/* Menu */ - -#menu { - float: left; - width: 713px; - height: 50px; - background: url(images/img02.gif) no-repeat left top; -} - -#menu ul { - margin: 0; - padding: 0px 0 0 10px; - list-style: none; - line-height: normal; -} - -#menu li { - display: block; - float: left; -} - -#menu a { - display: block; - float: left; - background: url(images/img04.gif) no-repeat right 55%; - margin-top: 5px; - margin-right: 3px; - padding: 8px 17px; - text-decoration: none; - font-size: 13px; - color: #000000; -} - -#menu a:hover { - color: #000000; -} - -#menu .current_page_item a { - color: #000000; -} - -/** LOGO */ - -#logo { - width: 713px; - height: 80px; - margin: 0 auto; -} - -#logo h1, #logo h2 { - float: left; - margin: 0; - padding: 30px 0 0 0px; - line-height: normal; -} - -#logo h1 { - font-family: Georgia, "Times New Roman", Times, serif; - font-size:40px; -} - -#logo h1 a { - text-decoration: none; - color: #4C4C4C; -} - -#logo h1 a:hover { text-decoration: underline; } - -#logo h2 { - float: left; - padding: 45px 0 0 18px; - font: 18px Georgia, "Times New Roman", Times, serif; - color: #8BD80E; -} - -#logo p a { - text-decoration: none; - color: #8BD80E; -} - -#logo p a:hover { text-decoration: underline; } - - - -/* Page */ - -#page { - width: 663px; - margin: 0 auto; - background: #4C4C4C url(images/img03.gif) no-repeat left bottom; - padding: 0 25px; -} - -/* Content */ - -#content { - float: left; - width: 410px; - -} - -/* Post */ - -.post { - padding: 15px 0px; - margin-bottom: 20px; -} - -.post .title { - margin-bottom: 20px; - padding-bottom: 5px; -} - -.post h1 { - padding: 0px 0 0 0px; - background: url(images/img08.jpg) no-repeat left top; - font-size: 24px; - color: #FFFFFF; -} - -.post h2 { - padding: 0px 0 0 0px; - font-size: 22px; - color: #FFFFFF; -} - -.post .entry { -} - -.post .meta { - padding: 15px 15px 30px 0px; - font-family: Arial, Helvetica, sans-serif; - font-size: 11px; -} - -.post .meta p { - margin: 0; - padding-top: 15px; - line-height: normal; - color: #FFFFFF; -} - -.post .meta .byline { - float: left; -} - -.post .meta .links { - float: right; -} - -.post .meta .more { - padding: 0 10px 0 18px; -} - -.post .meta .comments { -} - -.post .meta b { - display: none; -} - - -/* Sidebar */ - -#sidebar { - width: 210px; - float: right; - margin: 0; - padding: 0; -} - -#sidebar ul { - margin: 0; - padding: 0; - list-style: none; -} - -#sidebar li { - margin-bottom: 40px; -} - -#sidebar li ul { -} - -#sidebar li li { - margin: 0; -} - -#sidebar h2 { - width: 250px; - padding: 8px 0 0 0px; - margin-bottom: 10px; - background: url(images/img07.jpg) no-repeat left top; - font-size: 20px; - color: #FFFFFF; -} - -/* Search */ - -#search { - -} - -#search h2 { - margin-bottom: 20px; -} - -#s { - width: 140px; - margin-right: 5px; - padding: 3px; - border: 1px solid #BED99C; -} - -#x { - padding: 3px; - border: none; - background: #8BD80E; - text-transform: lowercase; - font-size: 11px; - color: #FFFFFF; -} - -/* Boxes */ - -.box1 { - padding: 20px; -} - -.box2 { - color: #BABABA; -} - -.box2 h2 { - margin-bottom: 15px; - font-size: 16px; - color: #FFFFFF; -} - -.box2 ul { - margin: 0; - padding: 0; - list-style: none; -} - -.box2 a:link, .box2 a:hover, .box2 a:active, .box2 a:visited { - color: #EDEDED; -} - -/* Footer */ -#footer-wrap { -} - -#footer { - margin: 0 auto; - padding: 20px 0 10px 0; - background: #000000; -} - -html>body #footer { - height: auto; -} - -#footer p { - font-size: 11px; -} - -#legal { - clear: both; - padding-top: 17px; - text-align: center; - color: #FFFFFF; -} - -#legal a { - font-weight: normal; - color: #FFFFFF; -} diff --git a/docs/tutorials/bfgwiki2/src/authorization/tutorial/templates/static/images/img01.gif b/docs/tutorials/bfgwiki2/src/authorization/tutorial/templates/static/images/img01.gif Binary files differdeleted file mode 100644 index 5f082bd99..000000000 --- a/docs/tutorials/bfgwiki2/src/authorization/tutorial/templates/static/images/img01.gif +++ /dev/null diff --git a/docs/tutorials/bfgwiki2/src/authorization/tutorial/templates/static/images/img02.gif b/docs/tutorials/bfgwiki2/src/authorization/tutorial/templates/static/images/img02.gif Binary files differdeleted file mode 100644 index 45a3ae976..000000000 --- a/docs/tutorials/bfgwiki2/src/authorization/tutorial/templates/static/images/img02.gif +++ /dev/null diff --git a/docs/tutorials/bfgwiki2/src/authorization/tutorial/templates/static/images/img03.gif b/docs/tutorials/bfgwiki2/src/authorization/tutorial/templates/static/images/img03.gif Binary files differdeleted file mode 100644 index d92ea38f9..000000000 --- a/docs/tutorials/bfgwiki2/src/authorization/tutorial/templates/static/images/img03.gif +++ /dev/null diff --git a/docs/tutorials/bfgwiki2/src/authorization/tutorial/templates/static/images/img04.gif b/docs/tutorials/bfgwiki2/src/authorization/tutorial/templates/static/images/img04.gif Binary files differdeleted file mode 100644 index 950c4af9d..000000000 --- a/docs/tutorials/bfgwiki2/src/authorization/tutorial/templates/static/images/img04.gif +++ /dev/null diff --git a/docs/tutorials/bfgwiki2/src/authorization/tutorial/templates/static/images/spacer.gif b/docs/tutorials/bfgwiki2/src/authorization/tutorial/templates/static/images/spacer.gif Binary files differdeleted file mode 100644 index 5bfd67a2d..000000000 --- a/docs/tutorials/bfgwiki2/src/authorization/tutorial/templates/static/images/spacer.gif +++ /dev/null diff --git a/docs/tutorials/bfgwiki2/src/authorization/tutorial/templates/static/style.css b/docs/tutorials/bfgwiki2/src/authorization/tutorial/templates/static/style.css deleted file mode 100644 index cad87e0d4..000000000 --- a/docs/tutorials/bfgwiki2/src/authorization/tutorial/templates/static/style.css +++ /dev/null @@ -1,109 +0,0 @@ -html, body { - color: black; - background-color: #ddd; - font: x-small "Lucida Grande", "Lucida Sans Unicode", geneva, sans-serif; - margin: 0; - padding: 0; -} - -td, th {padding:3px;border:none;} -tr th {text-align:left;background-color:#f0f0f0;color:#333;} -tr.odd td {background-color:#edf3fe;} -tr.even td {background-color:#fff;} - -#header { - height: 80px; - width: 777px; - background: blue URL('../images/header_inner.png') no-repeat; - border-left: 1px solid #aaa; - border-right: 1px solid #aaa; - margin: 0 auto 0 auto; -} - -a.link, a, a.active { - color: #369; -} - - -#main_content { - color: black; - font-size: 127%; - background-color: white; - width: 757px; - margin: 0 auto 0 auto; - border-left: 1px solid #aaa; - border-right: 1px solid #aaa; - padding: 10px; -} - -#sidebar { - border: 1px solid #aaa; - background-color: #eee; - margin: 0.5em; - padding: 1em; - float: right; - width: 200px; - font-size: 88%; -} - -#sidebar h2 { - margin-top: 0; -} - -#sidebar ul { - margin-left: 1.5em; - padding-left: 0; -} - -h1,h2,h3,h4,h5,h6,#getting_started_steps { - font-family: "Century Schoolbook L", Georgia, serif; - font-weight: bold; -} - -h2 { - font-size: 150%; -} - -#footer { - border: 1px solid #aaa; - border-top: 0px none; - color: #999; - background-color: white; - padding: 10px; - font-size: 80%; - text-align: center; - width: 757px; - margin: 0 auto 1em auto; -} - -.code { - font-family: monospace; -} - -span.code { - font-weight: bold; - background: #eee; -} - -#status_block { - margin: 0 auto 0.5em auto; - padding: 15px 10px 15px 55px; - background: #cec URL('../images/ok.png') left center no-repeat; - border: 1px solid #9c9; - width: 450px; - font-size: 120%; - font-weight: bolder; -} - -.notice { - margin: 0.5em auto 0.5em auto; - padding: 15px 10px 15px 55px; - width: 450px; - background: #eef URL('../images/info.png') left center no-repeat; - border: 1px solid #cce; -} - -.fielderror { - color: red; - font-weight: bold; -} diff --git a/docs/tutorials/bfgwiki2/src/authorization/tutorial/templates/static/templatelicense.txt b/docs/tutorials/bfgwiki2/src/authorization/tutorial/templates/static/templatelicense.txt deleted file mode 100644 index ccb6b06ab..000000000 --- a/docs/tutorials/bfgwiki2/src/authorization/tutorial/templates/static/templatelicense.txt +++ /dev/null @@ -1,243 +0,0 @@ -Creative Commons </> - -Creative Commons Legal Code - -*Attribution 2.5* - -CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE -LEGAL SERVICES. DISTRIBUTION OF THIS LICENSE DOES NOT CREATE AN -ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS INFORMATION -ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES REGARDING THE -INFORMATION PROVIDED, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM -ITS USE. - -/License/ - -THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE -COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). THE WORK IS PROTECTED BY -COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS -AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED. - -BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE -TO BE BOUND BY THE TERMS OF THIS LICENSE. THE LICENSOR GRANTS YOU THE -RIGHTS CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS -AND CONDITIONS. - -*1. Definitions* - - 1. *"Collective Work"* means a work, such as a periodical issue, - anthology or encyclopedia, in which the Work in its entirety in - unmodified form, along with a number of other contributions, - constituting separate and independent works in themselves, are - assembled into a collective whole. A work that constitutes a - Collective Work will not be considered a Derivative Work (as - defined below) for the purposes of this License. - 2. *"Derivative Work"* means a work based upon the Work or upon the - Work and other pre-existing works, such as a translation, musical - arrangement, dramatization, fictionalization, motion picture - version, sound recording, art reproduction, abridgment, - condensation, or any other form in which the Work may be recast, - transformed, or adapted, except that a work that constitutes a - Collective Work will not be considered a Derivative Work for the - purpose of this License. For the avoidance of doubt, where the - Work is a musical composition or sound recording, the - synchronization of the Work in timed-relation with a moving image - ("synching") will be considered a Derivative Work for the purpose - of this License. - 3. *"Licensor"* means the individual or entity that offers the Work - under the terms of this License. - 4. *"Original Author"* means the individual or entity who created the - Work. - 5. *"Work"* means the copyrightable work of authorship offered under - the terms of this License. - 6. *"You"* means an individual or entity exercising rights under this - License who has not previously violated the terms of this License - with respect to the Work, or who has received express permission - from the Licensor to exercise rights under this License despite a - previous violation. - -*2. Fair Use Rights.* Nothing in this license is intended to reduce, -limit, or restrict any rights arising from fair use, first sale or other -limitations on the exclusive rights of the copyright owner under -copyright law or other applicable laws. - -*3. License Grant.* Subject to the terms and conditions of this License, -Licensor hereby grants You a worldwide, royalty-free, non-exclusive, -perpetual (for the duration of the applicable copyright) license to -exercise the rights in the Work as stated below: - - 1. to reproduce the Work, to incorporate the Work into one or more - Collective Works, and to reproduce the Work as incorporated in the - Collective Works; - 2. to create and reproduce Derivative Works; - 3. to distribute copies or phonorecords of, display publicly, perform - publicly, and perform publicly by means of a digital audio - transmission the Work including as incorporated in Collective Works; - 4. to distribute copies or phonorecords of, display publicly, perform - publicly, and perform publicly by means of a digital audio - transmission Derivative Works. - 5. - - For the avoidance of doubt, where the work is a musical composition: - - 1. *Performance Royalties Under Blanket Licenses*. Licensor - waives the exclusive right to collect, whether individually - or via a performance rights society (e.g. ASCAP, BMI, - SESAC), royalties for the public performance or public - digital performance (e.g. webcast) of the Work. - 2. *Mechanical Rights and Statutory Royalties*. Licensor waives - the exclusive right to collect, whether individually or via - a music rights agency or designated agent (e.g. Harry Fox - Agency), royalties for any phonorecord You create from the - Work ("cover version") and distribute, subject to the - compulsory license created by 17 USC Section 115 of the US - Copyright Act (or the equivalent in other jurisdictions). - 6. *Webcasting Rights and Statutory Royalties*. For the avoidance of - doubt, where the Work is a sound recording, Licensor waives the - exclusive right to collect, whether individually or via a - performance-rights society (e.g. SoundExchange), royalties for the - public digital performance (e.g. webcast) of the Work, subject to - the compulsory license created by 17 USC Section 114 of the US - Copyright Act (or the equivalent in other jurisdictions). - -The above rights may be exercised in all media and formats whether now -known or hereafter devised. The above rights include the right to make -such modifications as are technically necessary to exercise the rights -in other media and formats. All rights not expressly granted by Licensor -are hereby reserved. - -*4. Restrictions.*The license granted in Section 3 above is expressly -made subject to and limited by the following restrictions: - - 1. You may distribute, publicly display, publicly perform, or - publicly digitally perform the Work only under the terms of this - License, and You must include a copy of, or the Uniform Resource - Identifier for, this License with every copy or phonorecord of the - Work You distribute, publicly display, publicly perform, or - publicly digitally perform. You may not offer or impose any terms - on the Work that alter or restrict the terms of this License or - the recipients' exercise of the rights granted hereunder. You may - not sublicense the Work. You must keep intact all notices that - refer to this License and to the disclaimer of warranties. You may - not distribute, publicly display, publicly perform, or publicly - digitally perform the Work with any technological measures that - control access or use of the Work in a manner inconsistent with - the terms of this License Agreement. The above applies to the Work - as incorporated in a Collective Work, but this does not require - the Collective Work apart from the Work itself to be made subject - to the terms of this License. If You create a Collective Work, - upon notice from any Licensor You must, to the extent practicable, - remove from the Collective Work any credit as required by clause - 4(b), as requested. If You create a Derivative Work, upon notice - from any Licensor You must, to the extent practicable, remove from - the Derivative Work any credit as required by clause 4(b), as - requested. - 2. If you distribute, publicly display, publicly perform, or publicly - digitally perform the Work or any Derivative Works or Collective - Works, You must keep intact all copyright notices for the Work and - provide, reasonable to the medium or means You are utilizing: (i) - the name of the Original Author (or pseudonym, if applicable) if - supplied, and/or (ii) if the Original Author and/or Licensor - designate another party or parties (e.g. a sponsor institute, - publishing entity, journal) for attribution in Licensor's - copyright notice, terms of service or by other reasonable means, - the name of such party or parties; the title of the Work if - supplied; to the extent reasonably practicable, the Uniform - Resource Identifier, if any, that Licensor specifies to be - associated with the Work, unless such URI does not refer to the - copyright notice or licensing information for the Work; and in the - case of a Derivative Work, a credit identifying the use of the - Work in the Derivative Work (e.g., "French translation of the Work - by Original Author," or "Screenplay based on original Work by - Original Author"). Such credit may be implemented in any - reasonable manner; provided, however, that in the case of a - Derivative Work or Collective Work, at a minimum such credit will - appear where any other comparable authorship credit appears and in - a manner at least as prominent as such other comparable authorship - credit. - -*5. Representations, Warranties and Disclaimer* - -UNLESS OTHERWISE MUTUALLY AGREED TO BY THE PARTIES IN WRITING, LICENSOR -OFFERS THE WORK AS-IS AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY -KIND CONCERNING THE WORK, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE, -INCLUDING, WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTIBILITY, -FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF -LATENT OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE OF ABSENCE OF ERRORS, -WHETHER OR NOT DISCOVERABLE. SOME JURISDICTIONS DO NOT ALLOW THE -EXCLUSION OF IMPLIED WARRANTIES, SO SUCH EXCLUSION MAY NOT APPLY TO YOU. - -*6. Limitation on Liability.* EXCEPT TO THE EXTENT REQUIRED BY -APPLICABLE LAW, IN NO EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY LEGAL -THEORY FOR ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY -DAMAGES ARISING OUT OF THIS LICENSE OR THE USE OF THE WORK, EVEN IF -LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - -*7. Termination* - - 1. This License and the rights granted hereunder will terminate - automatically upon any breach by You of the terms of this License. - Individuals or entities who have received Derivative Works or - Collective Works from You under this License, however, will not - have their licenses terminated provided such individuals or - entities remain in full compliance with those licenses. Sections - 1, 2, 5, 6, 7, and 8 will survive any termination of this License. - 2. Subject to the above terms and conditions, the license granted - here is perpetual (for the duration of the applicable copyright in - the Work). Notwithstanding the above, Licensor reserves the right - to release the Work under different license terms or to stop - distributing the Work at any time; provided, however that any such - election will not serve to withdraw this License (or any other - license that has been, or is required to be, granted under the - terms of this License), and this License will continue in full - force and effect unless terminated as stated above. - -*8. Miscellaneous* - - 1. Each time You distribute or publicly digitally perform the Work or - a Collective Work, the Licensor offers to the recipient a license - to the Work on the same terms and conditions as the license - granted to You under this License. - 2. Each time You distribute or publicly digitally perform a - Derivative Work, Licensor offers to the recipient a license to the - original Work on the same terms and conditions as the license - granted to You under this License. - 3. If any provision of this License is invalid or unenforceable under - applicable law, it shall not affect the validity or enforceability - of the remainder of the terms of this License, and without further - action by the parties to this agreement, such provision shall be - reformed to the minimum extent necessary to make such provision - valid and enforceable. - 4. No term or provision of this License shall be deemed waived and no - breach consented to unless such waiver or consent shall be in - writing and signed by the party to be charged with such waiver or - consent. - 5. This License constitutes the entire agreement between the parties - with respect to the Work licensed here. There are no - understandings, agreements or representations with respect to the - Work not specified here. Licensor shall not be bound by any - additional provisions that may appear in any communication from - You. This License may not be modified without the mutual written - agreement of the Licensor and You. - -Creative Commons is not a party to this License, and makes no warranty -whatsoever in connection with the Work. Creative Commons will not be -liable to You or any party on any legal theory for any damages -whatsoever, including without limitation any general, special, -incidental or consequential damages arising in connection to this -license. Notwithstanding the foregoing two (2) sentences, if Creative -Commons has expressly identified itself as the Licensor hereunder, it -shall have all rights and obligations of Licensor. - -Except for the limited purpose of indicating to the public that the Work -is licensed under the CCPL, neither party will use the trademark -"Creative Commons" or any related trademark or logo of Creative Commons -without the prior written consent of Creative Commons. Any permitted use -will be in compliance with Creative Commons' then-current trademark -usage guidelines, as may be published on its website or otherwise made -available upon request from time to time. - -Creative Commons may be contacted at http://creativecommons.org/ -<http://creativecommons.org>. - -« Back to Commons Deed <./> diff --git a/docs/tutorials/bfgwiki2/src/authorization/tutorial/templates/view.pt b/docs/tutorials/bfgwiki2/src/authorization/tutorial/templates/view.pt deleted file mode 100644 index 6c066f557..000000000 --- a/docs/tutorials/bfgwiki2/src/authorization/tutorial/templates/view.pt +++ /dev/null @@ -1,31 +0,0 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" - "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> -<html - xmlns="http://www.w3.org/1999/xhtml" - xmlns:tal="http://xml.zope.org/namespaces/tal"> - -<head> - <meta content="text/html; charset=utf-8" http-equiv="Content-Type"/> - <title>${page.name} - bfg tutorial wiki - (based on TurboGears 20-Minute Wiki)</title> - <link rel="stylesheet" type="text/css" - href="${request.application_url}/static/style.css" /> -</head> - -<body> - -<div class="main_content"> -<div style="float:right; width: 10em;"> Viewing -<span tal:replace="page.name">Page Name Goes Here</span> <br/> -You can return to the <a href="${request.application_url}">FrontPage</a>. -<span tal:condition="logged_in"> - <a href="${request.application_url}/logout">Logout</a> -</span> -</div> - -<div tal:replace="structure content">Page text goes here.</div> -<p><a tal:attributes="href edit_url" href="">Edit this page</a></p> -</div> - -</body> -</html> diff --git a/docs/tutorials/bfgwiki2/src/authorization/tutorial/tests.py b/docs/tutorials/bfgwiki2/src/authorization/tutorial/tests.py deleted file mode 100644 index 65330ce17..000000000 --- a/docs/tutorials/bfgwiki2/src/authorization/tutorial/tests.py +++ /dev/null @@ -1,139 +0,0 @@ -import unittest - -from pyramid.configuration import Configurator -from pyramid import testing - -def _initTestingDB(): - from tutorial.models import DBSession - from tutorial.models import Base - from sqlalchemy import create_engine - engine = create_engine('sqlite://') - DBSession.configure(bind=engine) - Base.metadata.bind = engine - Base.metadata.create_all(engine) - 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 = Configurator() - self.config.begin() - - def tearDown(self): - self.config.end() - - def test_it(self): - from tutorial.views import view_wiki - self.config.add_route('view_page', ':pagename') - request = testing.DummyRequest() - response = view_wiki(request) - self.assertEqual(response.location, 'http://example.com/FrontPage') - -class ViewPageTests(unittest.TestCase): - def setUp(self): - self.session = _initTestingDB() - self.config = Configurator() - self.config.begin() - - def tearDown(self): - self.session.remove() - self.config.end() - - 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('IDoExist', 'Hello CruelWorld IDoExist') - self.session.add(page) - _registerRoutes(self.config) - info = self._callFUT(request) - self.assertEqual(info['page'], page) - self.assertEqual( - info['content'], - '<div class="document">\n' - '<p>Hello <a href="http://example.com/add_page/CruelWorld">' - 'CruelWorld</a> ' - '<a href="http://example.com/IDoExist">' - 'IDoExist</a>' - '</p>\n</div>\n') - self.assertEqual(info['edit_url'], - 'http://example.com/IDoExist/edit_page') - - -class AddPageTests(unittest.TestCase): - def setUp(self): - self.session = _initTestingDB() - self.config = Configurator() - self.config.begin() - - def tearDown(self): - self.session.remove() - self.config.end() - - 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 = Configurator() - self.config.begin() - - def tearDown(self): - self.session.remove() - self.config.end() - - 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('abc', '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('abc', '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/bfgwiki2/src/authorization/tutorial/views.py b/docs/tutorials/bfgwiki2/src/authorization/tutorial/views.py deleted file mode 100644 index a7e7a57c7..000000000 --- a/docs/tutorials/bfgwiki2/src/authorization/tutorial/views.py +++ /dev/null @@ -1,71 +0,0 @@ -import re - -from docutils.core import publish_parts - -from webob.exc import HTTPFound - -from pyramid.security import authenticated_userid -from pyramid.url import route_url - -from tutorial.models import DBSession -from tutorial.models import Page - -# regular expression used to find WikiWords -wikiwords = re.compile(r"\b([A-Z]\w+[A-Z]+\w+)") - -def view_wiki(request): - return HTTPFound(location = route_url('view_page', request, - pagename='FrontPage')) - -def view_page(request): - pagename = request.matchdict['pagename'] - session = DBSession() - page = session.query(Page).filter_by(name=pagename).one() - - def check(match): - word = match.group(1) - exists = session.query(Page).filter_by(name=word).all() - if exists: - view_url = route_url('view_page', request, pagename=word) - return '<a href="%s">%s</a>' % (view_url, word) - else: - add_url = route_url('add_page', request, pagename=word) - return '<a href="%s">%s</a>' % (add_url, word) - - content = publish_parts(page.data, writer_name='html')['html_body'] - content = wikiwords.sub(check, content) - edit_url = route_url('edit_page', request, pagename=pagename) - logged_in = authenticated_userid(request) - return dict(page=page, content=content, edit_url=edit_url, - logged_in=logged_in) - -def add_page(request): - name = request.matchdict['pagename'] - if 'form.submitted' in request.params: - session = DBSession() - body = request.params['body'] - page = Page(name, body) - session.add(page) - return HTTPFound(location = route_url('view_page', request, - pagename=name)) - save_url = route_url('add_page', request, pagename=name) - page = Page('', '') - logged_in = authenticated_userid(request) - return dict(page=page, save_url=save_url, logged_in=logged_in) - -def edit_page(request): - name = request.matchdict['pagename'] - session = DBSession() - page = session.query(Page).filter_by(name=name).one() - if 'form.submitted' in request.params: - page.data = request.params['body'] - session.add(page) - return HTTPFound(location = route_url('view_page', request, - pagename=name)) - - logged_in = authenticated_userid(request) - return dict( - page=page, - save_url = route_url('edit_page', request, pagename=name), - logged_in = logged_in, - ) diff --git a/docs/tutorials/bfgwiki2/src/basiclayout/CHANGES.txt b/docs/tutorials/bfgwiki2/src/basiclayout/CHANGES.txt deleted file mode 100644 index 35a34f332..000000000 --- a/docs/tutorials/bfgwiki2/src/basiclayout/CHANGES.txt +++ /dev/null @@ -1,4 +0,0 @@ -0.0 ---- - -- Initial version diff --git a/docs/tutorials/bfgwiki2/src/basiclayout/README.txt b/docs/tutorials/bfgwiki2/src/basiclayout/README.txt deleted file mode 100644 index d41f7f90f..000000000 --- a/docs/tutorials/bfgwiki2/src/basiclayout/README.txt +++ /dev/null @@ -1,4 +0,0 @@ -tutorial README - - - diff --git a/docs/tutorials/bfgwiki2/src/basiclayout/setup.cfg b/docs/tutorials/bfgwiki2/src/basiclayout/setup.cfg deleted file mode 100644 index 23b2ad983..000000000 --- a/docs/tutorials/bfgwiki2/src/basiclayout/setup.cfg +++ /dev/null @@ -1,27 +0,0 @@ -[nosetests] -match=^test -nocapture=1 -cover-package=tutorial -with-coverage=1 -cover-erase=1 - -[compile_catalog] -directory = tutorial/locale -domain = tutorial -statistics = true - -[extract_messages] -add_comments = TRANSLATORS: -output_file = tutorial/locale/tutorial.pot -width = 80 - -[init_catalog] -domain = tutorial -input_file = tutorial/locale/tutorial.pot -output_dir = tutorial/locale - -[update_catalog] -domain = tutorial -input_file = tutorial/locale/tutorial.pot -output_dir = tutorial/locale -previous = true diff --git a/docs/tutorials/bfgwiki2/src/basiclayout/setup.py b/docs/tutorials/bfgwiki2/src/basiclayout/setup.py deleted file mode 100644 index fae50a1ee..000000000 --- a/docs/tutorials/bfgwiki2/src/basiclayout/setup.py +++ /dev/null @@ -1,45 +0,0 @@ -import os -import sys - -from setuptools import setup, find_packages - -here = os.path.abspath(os.path.dirname(__file__)) -README = open(os.path.join(here, 'README.txt')).read() -CHANGES = open(os.path.join(here, 'CHANGES.txt')).read() - -requires = [ - 'repoze.bfg', - 'SQLAlchemy', - 'transaction', - 'repoze.tm2', - 'zope.sqlalchemy', - ] - -if sys.version_info[:3] < (2,5,0): - requires.append('pysqlite') - -setup(name='tutorial', - version='0.0', - description='tutorial', - long_description=README + '\n\n' + CHANGES, - classifiers=[ - "Programming Language :: Python", - "Framework :: BFG", - "Topic :: Internet :: WWW/HTTP", - "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", - ], - author='', - author_email='', - url='', - keywords='web wsgi bfg', - packages=find_packages(), - include_package_data=True, - zip_safe=False, - test_suite='tutorial', - install_requires = requires, - entry_points = """\ - [paste.app_factory] - app = tutorial.run:app - """ - ) - diff --git a/docs/tutorials/bfgwiki2/src/basiclayout/tutorial.ini b/docs/tutorials/bfgwiki2/src/basiclayout/tutorial.ini deleted file mode 100644 index 73b5ed9a4..000000000 --- a/docs/tutorials/bfgwiki2/src/basiclayout/tutorial.ini +++ /dev/null @@ -1,22 +0,0 @@ -[DEFAULT] -debug = true - -[app:sqlalchemy] -use = egg:tutorial#app -reload_templates = true -debug_authorization = false -debug_notfound = false -debug_templates = true -default_locale_name = en -db_string = sqlite:///%(here)s/tutorial.db -db_echo = false - -[pipeline:main] -pipeline = - egg:repoze.tm2#tm - sqlalchemy - -[server:main] -use = egg:Paste#http -host = 0.0.0.0 -port = 6543 diff --git a/docs/tutorials/bfgwiki2/src/basiclayout/tutorial/__init__.py b/docs/tutorials/bfgwiki2/src/basiclayout/tutorial/__init__.py deleted file mode 100644 index cbdfd3ac6..000000000 --- a/docs/tutorials/bfgwiki2/src/basiclayout/tutorial/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -# A package - diff --git a/docs/tutorials/bfgwiki2/src/basiclayout/tutorial/configure.zcml b/docs/tutorials/bfgwiki2/src/basiclayout/tutorial/configure.zcml deleted file mode 100644 index 6d16bd089..000000000 --- a/docs/tutorials/bfgwiki2/src/basiclayout/tutorial/configure.zcml +++ /dev/null @@ -1,18 +0,0 @@ -<configure xmlns="http://namespaces.repoze.org/bfg"> - - <!-- this must be included for the view declarations to work --> - <include package="repoze.bfg.includes" /> - - <route - pattern="" - name="home" - view=".views.my_view" - view_renderer="templates/mytemplate.pt" - /> - - <static - name="static" - path="templates/static" - /> - -</configure> diff --git a/docs/tutorials/bfgwiki2/src/basiclayout/tutorial/models.py b/docs/tutorials/bfgwiki2/src/basiclayout/tutorial/models.py deleted file mode 100644 index ae71e7943..000000000 --- a/docs/tutorials/bfgwiki2/src/basiclayout/tutorial/models.py +++ /dev/null @@ -1,45 +0,0 @@ -import transaction - -from sqlalchemy import create_engine -from sqlalchemy import Column -from sqlalchemy import Integer -from sqlalchemy import Unicode - -from sqlalchemy.exc import IntegrityError -from sqlalchemy.ext.declarative import declarative_base - -from sqlalchemy.orm import scoped_session -from sqlalchemy.orm import sessionmaker - -from zope.sqlalchemy import ZopeTransactionExtension - -DBSession = scoped_session(sessionmaker( - extension=ZopeTransactionExtension())) -Base = declarative_base() - -class MyModel(Base): - __tablename__ = 'models' - id = Column(Integer, primary_key=True) - name = Column(Unicode(255), unique=True) - value = Column(Integer) - - def __init__(self, name, value): - self.name = name - self.value = value - -def populate(): - session = DBSession() - model = MyModel(name=u'root',value=55) - session.add(model) - session.flush() - transaction.commit() - -def initialize_sql(db_string, db_echo=False): - engine = create_engine(db_string, echo=db_echo) - DBSession.configure(bind=engine) - Base.metadata.bind = engine - Base.metadata.create_all(engine) - try: - populate() - except IntegrityError: - pass diff --git a/docs/tutorials/bfgwiki2/src/basiclayout/tutorial/run.py b/docs/tutorials/bfgwiki2/src/basiclayout/tutorial/run.py deleted file mode 100644 index 7225987ee..000000000 --- a/docs/tutorials/bfgwiki2/src/basiclayout/tutorial/run.py +++ /dev/null @@ -1,24 +0,0 @@ -from pyramid.configuration import Configurator -from paste.deploy.converters import asbool - -from tutorial.models import initialize_sql - -def app(global_config, **settings): - """ This function returns a WSGI application. - - It is usually called by the PasteDeploy framework during - ``paster serve``. - """ - zcml_file = settings.get('configure_zcml', 'configure.zcml') - db_string = settings.get('db_string') - if db_string is None: - raise ValueError( - "No 'db_string' value in application configuration.") - db_echo = settings.get('db_echo', 'false') - initialize_sql(db_string, asbool(db_echo)) - config = Configurator(settings=settings) - config.begin() - config.load_zcml(zcml_file) - config.end() - return config.make_wsgi_app() - diff --git a/docs/tutorials/bfgwiki2/src/basiclayout/tutorial/templates/mytemplate.pt b/docs/tutorials/bfgwiki2/src/basiclayout/tutorial/templates/mytemplate.pt deleted file mode 100644 index 2aedcad9f..000000000 --- a/docs/tutorials/bfgwiki2/src/basiclayout/tutorial/templates/mytemplate.pt +++ /dev/null @@ -1,99 +0,0 @@ -<!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" - xmlns:tal="http://xml.zope.org/namespaces/tal"> -<head> -<meta http-equiv="content-type" content="text/html; charset=utf-8" /> -<title>${project} Application</title> -<meta name="keywords" content="python web application" /> -<meta name="description" content="repoze.bfg web application" /> -<link href="${request.application_url}/static/default.css" rel="stylesheet" type="text/css" /> -</head> -<body> -<!-- start header --> -<div id="logo"> - <h2><code>${project}</code>, a <code>repoze.bfg</code> application</h2> -</div> -<div id="header"> - <div id="menu"> - </div> -</div> -<!-- end header --> -<div id="wrapper"> - <!-- start page --> - <div id="page"> - <!-- start content --> - <div id="content"> - <div class="post"> - <h1 class="title">Welcome to <code>${project}</code>, an - application generated by the <a - href="http://bfg.repoze.org">repoze.bfg</a> web - application framework.</h1> - </div> - </div> - <!-- end content --> - <!-- start sidebar --> - <div id="sidebar"> - <ul> - <li id="search"> - <h2>Search<br/> <code>repoze.bfg</code> Documentation</h2> - <form method="get" - action="http://bfg.repoze.org/searchresults"> - <fieldset> - <input type="text" id="q" name="text" value="" /> - <input type="submit" id="x" value="Search" /> - </fieldset> - </form> - </li> - <li> - <h2><code>repoze.bfg</code> links</h2> - <ul> - <li><a - href="http://docs.repoze.org/bfg/current/#narrative-documentation">Narrative - Documentation</a> - </li> - <li> - <a - href="http://docs.repoze.org/bfg/current/#api-documentation">API - Documentation</a> - </li> - <li> - <a - href="http://docs.repoze.org/bfg/current/#tutorials">Tutorials</a> - </li> - <li> - <a - href="http://docs.repoze.org/bfg/current/#change-history">Change - History</a> - </li> - <li> - <a - href="http://docs.repoze.org/bfg/current/#sample-applications">Sample - Applications</a> - </li> - <li> - <a - href="http://docs.repoze.org/bfg/current/#support-and-development">Support - and Development</a> - </li> - <li> - <a - href="irc://irc.freenode.net#repoze">IRC Channel</a> - </li> - </ul> - </li> - </ul> - </div> - <!-- end sidebar --> - <div style="clear: both;"> </div> - </div> -</div> -<!-- end page --> -<!-- start footer --> -<div id="footer"> - <p id="legal">( c ) 2008. All Rights Reserved. Template design - by <a href="http://www.freecsstemplates.org/">Free CSS - Templates</a>.</p> -</div> -<!-- end footer --> -</body> -</html> diff --git a/docs/tutorials/bfgwiki2/src/basiclayout/tutorial/templates/static/default.css b/docs/tutorials/bfgwiki2/src/basiclayout/tutorial/templates/static/default.css deleted file mode 100644 index 41b3debde..000000000 --- a/docs/tutorials/bfgwiki2/src/basiclayout/tutorial/templates/static/default.css +++ /dev/null @@ -1,380 +0,0 @@ -/* -Design by Free CSS Templates -http://www.freecsstemplates.org -Released for free under a Creative Commons Attribution 2.5 License -*/ - -body { - margin: 0; - padding: 0; - background: url(images/img01.gif) repeat-x left top; - font-size: 13px; - font-family: "Trebuchet MS", Georgia, "Times New Roman", Times, serif; - text-align: justify; - color: #FFFFFF; -} - -h1, h2, h3 { - margin: 0; - text-transform: lowercase; - font-weight: normal; - color: #FFFFFF; -} - -h1 { - letter-spacing: -1px; - font-size: 32px; -} - -h2 { - font-size: 23px; -} - -p, ul, ol { - margin: 0 0 2em 0; - text-align: justify; - line-height: 26px; -} - -a:link { - color: #8BD80E; -} - -a:hover, a:active { - text-decoration: none; - color: #8BD80E; -} - -a:visited { - color: #8BD80E; -} - -img { - border: none; -} - -img.left { - float: left; - margin-right: 15px; -} - -img.right { - float: right; - margin-left: 15px; -} - -/* Form */ - -form { - margin: 0; - padding: 0; -} - -fieldset { - margin: 0; - padding: 0; - border: none; -} - -legend { - display: none; -} - -input, textarea, select { - font-family: "Trebuchet MS", Arial, Helvetica, sans-serif; - font-size: 13px; - color: #333333; -} - -#wrapper { - margin: 0; - padding: 0; - background: #000000; -} - -/* Header */ - -#header { - width: 713px; - margin: 0 auto; - height: 42px; -} - -/* Menu */ - -#menu { - float: left; - width: 713px; - height: 50px; - background: url(images/img02.gif) no-repeat left top; -} - -#menu ul { - margin: 0; - padding: 0px 0 0 10px; - list-style: none; - line-height: normal; -} - -#menu li { - display: block; - float: left; -} - -#menu a { - display: block; - float: left; - background: url(images/img04.gif) no-repeat right 55%; - margin-top: 5px; - margin-right: 3px; - padding: 8px 17px; - text-decoration: none; - font-size: 13px; - color: #000000; -} - -#menu a:hover { - color: #000000; -} - -#menu .current_page_item a { - color: #000000; -} - -/** LOGO */ - -#logo { - width: 713px; - height: 80px; - margin: 0 auto; -} - -#logo h1, #logo h2 { - float: left; - margin: 0; - padding: 30px 0 0 0px; - line-height: normal; -} - -#logo h1 { - font-family: Georgia, "Times New Roman", Times, serif; - font-size:40px; -} - -#logo h1 a { - text-decoration: none; - color: #4C4C4C; -} - -#logo h1 a:hover { text-decoration: underline; } - -#logo h2 { - float: left; - padding: 45px 0 0 18px; - font: 18px Georgia, "Times New Roman", Times, serif; - color: #8BD80E; -} - -#logo p a { - text-decoration: none; - color: #8BD80E; -} - -#logo p a:hover { text-decoration: underline; } - - - -/* Page */ - -#page { - width: 663px; - margin: 0 auto; - background: #4C4C4C url(images/img03.gif) no-repeat left bottom; - padding: 0 25px; -} - -/* Content */ - -#content { - float: left; - width: 410px; - -} - -/* Post */ - -.post { - padding: 15px 0px; - margin-bottom: 20px; -} - -.post .title { - margin-bottom: 20px; - padding-bottom: 5px; -} - -.post h1 { - padding: 0px 0 0 0px; - background: url(images/img08.jpg) no-repeat left top; - font-size: 24px; - color: #FFFFFF; -} - -.post h2 { - padding: 0px 0 0 0px; - font-size: 22px; - color: #FFFFFF; -} - -.post .entry { -} - -.post .meta { - padding: 15px 15px 30px 0px; - font-family: Arial, Helvetica, sans-serif; - font-size: 11px; -} - -.post .meta p { - margin: 0; - padding-top: 15px; - line-height: normal; - color: #FFFFFF; -} - -.post .meta .byline { - float: left; -} - -.post .meta .links { - float: right; -} - -.post .meta .more { - padding: 0 10px 0 18px; -} - -.post .meta .comments { -} - -.post .meta b { - display: none; -} - - -/* Sidebar */ - -#sidebar { - width: 210px; - float: right; - margin: 0; - padding: 0; -} - -#sidebar ul { - margin: 0; - padding: 0; - list-style: none; -} - -#sidebar li { - margin-bottom: 40px; -} - -#sidebar li ul { -} - -#sidebar li li { - margin: 0; -} - -#sidebar h2 { - width: 250px; - padding: 8px 0 0 0px; - margin-bottom: 10px; - background: url(images/img07.jpg) no-repeat left top; - font-size: 20px; - color: #FFFFFF; -} - -/* Search */ - -#search { - -} - -#search h2 { - margin-bottom: 20px; -} - -#s { - width: 140px; - margin-right: 5px; - padding: 3px; - border: 1px solid #BED99C; -} - -#x { - padding: 3px; - border: none; - background: #8BD80E; - text-transform: lowercase; - font-size: 11px; - color: #FFFFFF; -} - -/* Boxes */ - -.box1 { - padding: 20px; -} - -.box2 { - color: #BABABA; -} - -.box2 h2 { - margin-bottom: 15px; - font-size: 16px; - color: #FFFFFF; -} - -.box2 ul { - margin: 0; - padding: 0; - list-style: none; -} - -.box2 a:link, .box2 a:hover, .box2 a:active, .box2 a:visited { - color: #EDEDED; -} - -/* Footer */ -#footer-wrap { -} - -#footer { - margin: 0 auto; - padding: 20px 0 10px 0; - background: #000000; -} - -html>body #footer { - height: auto; -} - -#footer p { - font-size: 11px; -} - -#legal { - clear: both; - padding-top: 17px; - text-align: center; - color: #FFFFFF; -} - -#legal a { - font-weight: normal; - color: #FFFFFF; -} diff --git a/docs/tutorials/bfgwiki2/src/basiclayout/tutorial/templates/static/images/img01.gif b/docs/tutorials/bfgwiki2/src/basiclayout/tutorial/templates/static/images/img01.gif Binary files differdeleted file mode 100644 index 5f082bd99..000000000 --- a/docs/tutorials/bfgwiki2/src/basiclayout/tutorial/templates/static/images/img01.gif +++ /dev/null diff --git a/docs/tutorials/bfgwiki2/src/basiclayout/tutorial/templates/static/images/img02.gif b/docs/tutorials/bfgwiki2/src/basiclayout/tutorial/templates/static/images/img02.gif Binary files differdeleted file mode 100644 index 45a3ae976..000000000 --- a/docs/tutorials/bfgwiki2/src/basiclayout/tutorial/templates/static/images/img02.gif +++ /dev/null diff --git a/docs/tutorials/bfgwiki2/src/basiclayout/tutorial/templates/static/images/img03.gif b/docs/tutorials/bfgwiki2/src/basiclayout/tutorial/templates/static/images/img03.gif Binary files differdeleted file mode 100644 index d92ea38f9..000000000 --- a/docs/tutorials/bfgwiki2/src/basiclayout/tutorial/templates/static/images/img03.gif +++ /dev/null diff --git a/docs/tutorials/bfgwiki2/src/basiclayout/tutorial/templates/static/images/img04.gif b/docs/tutorials/bfgwiki2/src/basiclayout/tutorial/templates/static/images/img04.gif Binary files differdeleted file mode 100644 index 950c4af9d..000000000 --- a/docs/tutorials/bfgwiki2/src/basiclayout/tutorial/templates/static/images/img04.gif +++ /dev/null diff --git a/docs/tutorials/bfgwiki2/src/basiclayout/tutorial/templates/static/images/spacer.gif b/docs/tutorials/bfgwiki2/src/basiclayout/tutorial/templates/static/images/spacer.gif Binary files differdeleted file mode 100644 index 5bfd67a2d..000000000 --- a/docs/tutorials/bfgwiki2/src/basiclayout/tutorial/templates/static/images/spacer.gif +++ /dev/null diff --git a/docs/tutorials/bfgwiki2/src/basiclayout/tutorial/templates/static/templatelicense.txt b/docs/tutorials/bfgwiki2/src/basiclayout/tutorial/templates/static/templatelicense.txt deleted file mode 100644 index ccb6b06ab..000000000 --- a/docs/tutorials/bfgwiki2/src/basiclayout/tutorial/templates/static/templatelicense.txt +++ /dev/null @@ -1,243 +0,0 @@ -Creative Commons </> - -Creative Commons Legal Code - -*Attribution 2.5* - -CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE -LEGAL SERVICES. DISTRIBUTION OF THIS LICENSE DOES NOT CREATE AN -ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS INFORMATION -ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES REGARDING THE -INFORMATION PROVIDED, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM -ITS USE. - -/License/ - -THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE -COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). THE WORK IS PROTECTED BY -COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS -AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED. - -BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE -TO BE BOUND BY THE TERMS OF THIS LICENSE. THE LICENSOR GRANTS YOU THE -RIGHTS CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS -AND CONDITIONS. - -*1. Definitions* - - 1. *"Collective Work"* means a work, such as a periodical issue, - anthology or encyclopedia, in which the Work in its entirety in - unmodified form, along with a number of other contributions, - constituting separate and independent works in themselves, are - assembled into a collective whole. A work that constitutes a - Collective Work will not be considered a Derivative Work (as - defined below) for the purposes of this License. - 2. *"Derivative Work"* means a work based upon the Work or upon the - Work and other pre-existing works, such as a translation, musical - arrangement, dramatization, fictionalization, motion picture - version, sound recording, art reproduction, abridgment, - condensation, or any other form in which the Work may be recast, - transformed, or adapted, except that a work that constitutes a - Collective Work will not be considered a Derivative Work for the - purpose of this License. For the avoidance of doubt, where the - Work is a musical composition or sound recording, the - synchronization of the Work in timed-relation with a moving image - ("synching") will be considered a Derivative Work for the purpose - of this License. - 3. *"Licensor"* means the individual or entity that offers the Work - under the terms of this License. - 4. *"Original Author"* means the individual or entity who created the - Work. - 5. *"Work"* means the copyrightable work of authorship offered under - the terms of this License. - 6. *"You"* means an individual or entity exercising rights under this - License who has not previously violated the terms of this License - with respect to the Work, or who has received express permission - from the Licensor to exercise rights under this License despite a - previous violation. - -*2. Fair Use Rights.* Nothing in this license is intended to reduce, -limit, or restrict any rights arising from fair use, first sale or other -limitations on the exclusive rights of the copyright owner under -copyright law or other applicable laws. - -*3. License Grant.* Subject to the terms and conditions of this License, -Licensor hereby grants You a worldwide, royalty-free, non-exclusive, -perpetual (for the duration of the applicable copyright) license to -exercise the rights in the Work as stated below: - - 1. to reproduce the Work, to incorporate the Work into one or more - Collective Works, and to reproduce the Work as incorporated in the - Collective Works; - 2. to create and reproduce Derivative Works; - 3. to distribute copies or phonorecords of, display publicly, perform - publicly, and perform publicly by means of a digital audio - transmission the Work including as incorporated in Collective Works; - 4. to distribute copies or phonorecords of, display publicly, perform - publicly, and perform publicly by means of a digital audio - transmission Derivative Works. - 5. - - For the avoidance of doubt, where the work is a musical composition: - - 1. *Performance Royalties Under Blanket Licenses*. Licensor - waives the exclusive right to collect, whether individually - or via a performance rights society (e.g. ASCAP, BMI, - SESAC), royalties for the public performance or public - digital performance (e.g. webcast) of the Work. - 2. *Mechanical Rights and Statutory Royalties*. Licensor waives - the exclusive right to collect, whether individually or via - a music rights agency or designated agent (e.g. Harry Fox - Agency), royalties for any phonorecord You create from the - Work ("cover version") and distribute, subject to the - compulsory license created by 17 USC Section 115 of the US - Copyright Act (or the equivalent in other jurisdictions). - 6. *Webcasting Rights and Statutory Royalties*. For the avoidance of - doubt, where the Work is a sound recording, Licensor waives the - exclusive right to collect, whether individually or via a - performance-rights society (e.g. SoundExchange), royalties for the - public digital performance (e.g. webcast) of the Work, subject to - the compulsory license created by 17 USC Section 114 of the US - Copyright Act (or the equivalent in other jurisdictions). - -The above rights may be exercised in all media and formats whether now -known or hereafter devised. The above rights include the right to make -such modifications as are technically necessary to exercise the rights -in other media and formats. All rights not expressly granted by Licensor -are hereby reserved. - -*4. Restrictions.*The license granted in Section 3 above is expressly -made subject to and limited by the following restrictions: - - 1. You may distribute, publicly display, publicly perform, or - publicly digitally perform the Work only under the terms of this - License, and You must include a copy of, or the Uniform Resource - Identifier for, this License with every copy or phonorecord of the - Work You distribute, publicly display, publicly perform, or - publicly digitally perform. You may not offer or impose any terms - on the Work that alter or restrict the terms of this License or - the recipients' exercise of the rights granted hereunder. You may - not sublicense the Work. You must keep intact all notices that - refer to this License and to the disclaimer of warranties. You may - not distribute, publicly display, publicly perform, or publicly - digitally perform the Work with any technological measures that - control access or use of the Work in a manner inconsistent with - the terms of this License Agreement. The above applies to the Work - as incorporated in a Collective Work, but this does not require - the Collective Work apart from the Work itself to be made subject - to the terms of this License. If You create a Collective Work, - upon notice from any Licensor You must, to the extent practicable, - remove from the Collective Work any credit as required by clause - 4(b), as requested. If You create a Derivative Work, upon notice - from any Licensor You must, to the extent practicable, remove from - the Derivative Work any credit as required by clause 4(b), as - requested. - 2. If you distribute, publicly display, publicly perform, or publicly - digitally perform the Work or any Derivative Works or Collective - Works, You must keep intact all copyright notices for the Work and - provide, reasonable to the medium or means You are utilizing: (i) - the name of the Original Author (or pseudonym, if applicable) if - supplied, and/or (ii) if the Original Author and/or Licensor - designate another party or parties (e.g. a sponsor institute, - publishing entity, journal) for attribution in Licensor's - copyright notice, terms of service or by other reasonable means, - the name of such party or parties; the title of the Work if - supplied; to the extent reasonably practicable, the Uniform - Resource Identifier, if any, that Licensor specifies to be - associated with the Work, unless such URI does not refer to the - copyright notice or licensing information for the Work; and in the - case of a Derivative Work, a credit identifying the use of the - Work in the Derivative Work (e.g., "French translation of the Work - by Original Author," or "Screenplay based on original Work by - Original Author"). Such credit may be implemented in any - reasonable manner; provided, however, that in the case of a - Derivative Work or Collective Work, at a minimum such credit will - appear where any other comparable authorship credit appears and in - a manner at least as prominent as such other comparable authorship - credit. - -*5. Representations, Warranties and Disclaimer* - -UNLESS OTHERWISE MUTUALLY AGREED TO BY THE PARTIES IN WRITING, LICENSOR -OFFERS THE WORK AS-IS AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY -KIND CONCERNING THE WORK, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE, -INCLUDING, WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTIBILITY, -FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF -LATENT OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE OF ABSENCE OF ERRORS, -WHETHER OR NOT DISCOVERABLE. SOME JURISDICTIONS DO NOT ALLOW THE -EXCLUSION OF IMPLIED WARRANTIES, SO SUCH EXCLUSION MAY NOT APPLY TO YOU. - -*6. Limitation on Liability.* EXCEPT TO THE EXTENT REQUIRED BY -APPLICABLE LAW, IN NO EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY LEGAL -THEORY FOR ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY -DAMAGES ARISING OUT OF THIS LICENSE OR THE USE OF THE WORK, EVEN IF -LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - -*7. Termination* - - 1. This License and the rights granted hereunder will terminate - automatically upon any breach by You of the terms of this License. - Individuals or entities who have received Derivative Works or - Collective Works from You under this License, however, will not - have their licenses terminated provided such individuals or - entities remain in full compliance with those licenses. Sections - 1, 2, 5, 6, 7, and 8 will survive any termination of this License. - 2. Subject to the above terms and conditions, the license granted - here is perpetual (for the duration of the applicable copyright in - the Work). Notwithstanding the above, Licensor reserves the right - to release the Work under different license terms or to stop - distributing the Work at any time; provided, however that any such - election will not serve to withdraw this License (or any other - license that has been, or is required to be, granted under the - terms of this License), and this License will continue in full - force and effect unless terminated as stated above. - -*8. Miscellaneous* - - 1. Each time You distribute or publicly digitally perform the Work or - a Collective Work, the Licensor offers to the recipient a license - to the Work on the same terms and conditions as the license - granted to You under this License. - 2. Each time You distribute or publicly digitally perform a - Derivative Work, Licensor offers to the recipient a license to the - original Work on the same terms and conditions as the license - granted to You under this License. - 3. If any provision of this License is invalid or unenforceable under - applicable law, it shall not affect the validity or enforceability - of the remainder of the terms of this License, and without further - action by the parties to this agreement, such provision shall be - reformed to the minimum extent necessary to make such provision - valid and enforceable. - 4. No term or provision of this License shall be deemed waived and no - breach consented to unless such waiver or consent shall be in - writing and signed by the party to be charged with such waiver or - consent. - 5. This License constitutes the entire agreement between the parties - with respect to the Work licensed here. There are no - understandings, agreements or representations with respect to the - Work not specified here. Licensor shall not be bound by any - additional provisions that may appear in any communication from - You. This License may not be modified without the mutual written - agreement of the Licensor and You. - -Creative Commons is not a party to this License, and makes no warranty -whatsoever in connection with the Work. Creative Commons will not be -liable to You or any party on any legal theory for any damages -whatsoever, including without limitation any general, special, -incidental or consequential damages arising in connection to this -license. Notwithstanding the foregoing two (2) sentences, if Creative -Commons has expressly identified itself as the Licensor hereunder, it -shall have all rights and obligations of Licensor. - -Except for the limited purpose of indicating to the public that the Work -is licensed under the CCPL, neither party will use the trademark -"Creative Commons" or any related trademark or logo of Creative Commons -without the prior written consent of Creative Commons. Any permitted use -will be in compliance with Creative Commons' then-current trademark -usage guidelines, as may be published on its website or otherwise made -available upon request from time to time. - -Creative Commons may be contacted at http://creativecommons.org/ -<http://creativecommons.org>. - -« Back to Commons Deed <./> diff --git a/docs/tutorials/bfgwiki2/src/basiclayout/tutorial/tests.py b/docs/tutorials/bfgwiki2/src/basiclayout/tutorial/tests.py deleted file mode 100644 index 72f0c89d8..000000000 --- a/docs/tutorials/bfgwiki2/src/basiclayout/tutorial/tests.py +++ /dev/null @@ -1,24 +0,0 @@ -import unittest -from pyramid.configuration import Configurator -from pyramid import testing - -def _initTestingDB(): - from tutorial.models import initialize_sql - session = initialize_sql('sqlite://') - return session - -class TestMyView(unittest.TestCase): - def setUp(self): - self.config = Configurator() - self.config.begin() - _initTestingDB() - - def tearDown(self): - self.config.end() - - def test_it(self): - from tutorial.views import my_view - request = testing.DummyRequest() - info = my_view(request) - self.assertEqual(info['root'].name, 'root') - self.assertEqual(info['project'], 'tutorial') diff --git a/docs/tutorials/bfgwiki2/src/basiclayout/tutorial/views.py b/docs/tutorials/bfgwiki2/src/basiclayout/tutorial/views.py deleted file mode 100644 index e550e3257..000000000 --- a/docs/tutorials/bfgwiki2/src/basiclayout/tutorial/views.py +++ /dev/null @@ -1,7 +0,0 @@ -from tutorial.models import DBSession -from tutorial.models import MyModel - -def my_view(request): - dbsession = DBSession() - root = dbsession.query(MyModel).filter(MyModel.name==u'root').first() - return {'root':root, 'project':'tutorial'} diff --git a/docs/tutorials/bfgwiki2/src/models/CHANGES.txt b/docs/tutorials/bfgwiki2/src/models/CHANGES.txt deleted file mode 100644 index 35a34f332..000000000 --- a/docs/tutorials/bfgwiki2/src/models/CHANGES.txt +++ /dev/null @@ -1,4 +0,0 @@ -0.0 ---- - -- Initial version diff --git a/docs/tutorials/bfgwiki2/src/models/README.txt b/docs/tutorials/bfgwiki2/src/models/README.txt deleted file mode 100644 index d41f7f90f..000000000 --- a/docs/tutorials/bfgwiki2/src/models/README.txt +++ /dev/null @@ -1,4 +0,0 @@ -tutorial README - - - diff --git a/docs/tutorials/bfgwiki2/src/models/setup.cfg b/docs/tutorials/bfgwiki2/src/models/setup.cfg deleted file mode 100644 index 23b2ad983..000000000 --- a/docs/tutorials/bfgwiki2/src/models/setup.cfg +++ /dev/null @@ -1,27 +0,0 @@ -[nosetests] -match=^test -nocapture=1 -cover-package=tutorial -with-coverage=1 -cover-erase=1 - -[compile_catalog] -directory = tutorial/locale -domain = tutorial -statistics = true - -[extract_messages] -add_comments = TRANSLATORS: -output_file = tutorial/locale/tutorial.pot -width = 80 - -[init_catalog] -domain = tutorial -input_file = tutorial/locale/tutorial.pot -output_dir = tutorial/locale - -[update_catalog] -domain = tutorial -input_file = tutorial/locale/tutorial.pot -output_dir = tutorial/locale -previous = true diff --git a/docs/tutorials/bfgwiki2/src/models/setup.py b/docs/tutorials/bfgwiki2/src/models/setup.py deleted file mode 100644 index fae50a1ee..000000000 --- a/docs/tutorials/bfgwiki2/src/models/setup.py +++ /dev/null @@ -1,45 +0,0 @@ -import os -import sys - -from setuptools import setup, find_packages - -here = os.path.abspath(os.path.dirname(__file__)) -README = open(os.path.join(here, 'README.txt')).read() -CHANGES = open(os.path.join(here, 'CHANGES.txt')).read() - -requires = [ - 'repoze.bfg', - 'SQLAlchemy', - 'transaction', - 'repoze.tm2', - 'zope.sqlalchemy', - ] - -if sys.version_info[:3] < (2,5,0): - requires.append('pysqlite') - -setup(name='tutorial', - version='0.0', - description='tutorial', - long_description=README + '\n\n' + CHANGES, - classifiers=[ - "Programming Language :: Python", - "Framework :: BFG", - "Topic :: Internet :: WWW/HTTP", - "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", - ], - author='', - author_email='', - url='', - keywords='web wsgi bfg', - packages=find_packages(), - include_package_data=True, - zip_safe=False, - test_suite='tutorial', - install_requires = requires, - entry_points = """\ - [paste.app_factory] - app = tutorial.run:app - """ - ) - diff --git a/docs/tutorials/bfgwiki2/src/models/tutorial.ini b/docs/tutorials/bfgwiki2/src/models/tutorial.ini deleted file mode 100644 index 73b5ed9a4..000000000 --- a/docs/tutorials/bfgwiki2/src/models/tutorial.ini +++ /dev/null @@ -1,22 +0,0 @@ -[DEFAULT] -debug = true - -[app:sqlalchemy] -use = egg:tutorial#app -reload_templates = true -debug_authorization = false -debug_notfound = false -debug_templates = true -default_locale_name = en -db_string = sqlite:///%(here)s/tutorial.db -db_echo = false - -[pipeline:main] -pipeline = - egg:repoze.tm2#tm - sqlalchemy - -[server:main] -use = egg:Paste#http -host = 0.0.0.0 -port = 6543 diff --git a/docs/tutorials/bfgwiki2/src/models/tutorial/__init__.py b/docs/tutorials/bfgwiki2/src/models/tutorial/__init__.py deleted file mode 100644 index cbdfd3ac6..000000000 --- a/docs/tutorials/bfgwiki2/src/models/tutorial/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -# A package - diff --git a/docs/tutorials/bfgwiki2/src/models/tutorial/configure.zcml b/docs/tutorials/bfgwiki2/src/models/tutorial/configure.zcml deleted file mode 100644 index 6d16bd089..000000000 --- a/docs/tutorials/bfgwiki2/src/models/tutorial/configure.zcml +++ /dev/null @@ -1,18 +0,0 @@ -<configure xmlns="http://namespaces.repoze.org/bfg"> - - <!-- this must be included for the view declarations to work --> - <include package="repoze.bfg.includes" /> - - <route - pattern="" - name="home" - view=".views.my_view" - view_renderer="templates/mytemplate.pt" - /> - - <static - name="static" - path="templates/static" - /> - -</configure> diff --git a/docs/tutorials/bfgwiki2/src/models/tutorial/models.py b/docs/tutorials/bfgwiki2/src/models/tutorial/models.py deleted file mode 100644 index 8c3f14915..000000000 --- a/docs/tutorials/bfgwiki2/src/models/tutorial/models.py +++ /dev/null @@ -1,43 +0,0 @@ -import transaction - -from sqlalchemy import create_engine -from sqlalchemy import Column -from sqlalchemy import Integer -from sqlalchemy import Text - -from sqlalchemy.exc import IntegrityError -from sqlalchemy.ext.declarative import declarative_base - -from sqlalchemy.orm import scoped_session -from sqlalchemy.orm import 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) - - def __init__(self, name, data): - self.name = name - self.data = data - -def initialize_sql(db_string, echo=False): - engine = create_engine(db_string, echo=echo) - DBSession.configure(bind=engine) - Base.metadata.bind = engine - Base.metadata.create_all(engine) - try: - session = DBSession() - page = Page('FrontPage', 'initial data') - session.add(page) - transaction.commit() - except IntegrityError: - # already created - pass diff --git a/docs/tutorials/bfgwiki2/src/models/tutorial/run.py b/docs/tutorials/bfgwiki2/src/models/tutorial/run.py deleted file mode 100644 index 7225987ee..000000000 --- a/docs/tutorials/bfgwiki2/src/models/tutorial/run.py +++ /dev/null @@ -1,24 +0,0 @@ -from pyramid.configuration import Configurator -from paste.deploy.converters import asbool - -from tutorial.models import initialize_sql - -def app(global_config, **settings): - """ This function returns a WSGI application. - - It is usually called by the PasteDeploy framework during - ``paster serve``. - """ - zcml_file = settings.get('configure_zcml', 'configure.zcml') - db_string = settings.get('db_string') - if db_string is None: - raise ValueError( - "No 'db_string' value in application configuration.") - db_echo = settings.get('db_echo', 'false') - initialize_sql(db_string, asbool(db_echo)) - config = Configurator(settings=settings) - config.begin() - config.load_zcml(zcml_file) - config.end() - return config.make_wsgi_app() - diff --git a/docs/tutorials/bfgwiki2/src/models/tutorial/templates/mytemplate.pt b/docs/tutorials/bfgwiki2/src/models/tutorial/templates/mytemplate.pt deleted file mode 100644 index 2aedcad9f..000000000 --- a/docs/tutorials/bfgwiki2/src/models/tutorial/templates/mytemplate.pt +++ /dev/null @@ -1,99 +0,0 @@ -<!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" - xmlns:tal="http://xml.zope.org/namespaces/tal"> -<head> -<meta http-equiv="content-type" content="text/html; charset=utf-8" /> -<title>${project} Application</title> -<meta name="keywords" content="python web application" /> -<meta name="description" content="repoze.bfg web application" /> -<link href="${request.application_url}/static/default.css" rel="stylesheet" type="text/css" /> -</head> -<body> -<!-- start header --> -<div id="logo"> - <h2><code>${project}</code>, a <code>repoze.bfg</code> application</h2> -</div> -<div id="header"> - <div id="menu"> - </div> -</div> -<!-- end header --> -<div id="wrapper"> - <!-- start page --> - <div id="page"> - <!-- start content --> - <div id="content"> - <div class="post"> - <h1 class="title">Welcome to <code>${project}</code>, an - application generated by the <a - href="http://bfg.repoze.org">repoze.bfg</a> web - application framework.</h1> - </div> - </div> - <!-- end content --> - <!-- start sidebar --> - <div id="sidebar"> - <ul> - <li id="search"> - <h2>Search<br/> <code>repoze.bfg</code> Documentation</h2> - <form method="get" - action="http://bfg.repoze.org/searchresults"> - <fieldset> - <input type="text" id="q" name="text" value="" /> - <input type="submit" id="x" value="Search" /> - </fieldset> - </form> - </li> - <li> - <h2><code>repoze.bfg</code> links</h2> - <ul> - <li><a - href="http://docs.repoze.org/bfg/current/#narrative-documentation">Narrative - Documentation</a> - </li> - <li> - <a - href="http://docs.repoze.org/bfg/current/#api-documentation">API - Documentation</a> - </li> - <li> - <a - href="http://docs.repoze.org/bfg/current/#tutorials">Tutorials</a> - </li> - <li> - <a - href="http://docs.repoze.org/bfg/current/#change-history">Change - History</a> - </li> - <li> - <a - href="http://docs.repoze.org/bfg/current/#sample-applications">Sample - Applications</a> - </li> - <li> - <a - href="http://docs.repoze.org/bfg/current/#support-and-development">Support - and Development</a> - </li> - <li> - <a - href="irc://irc.freenode.net#repoze">IRC Channel</a> - </li> - </ul> - </li> - </ul> - </div> - <!-- end sidebar --> - <div style="clear: both;"> </div> - </div> -</div> -<!-- end page --> -<!-- start footer --> -<div id="footer"> - <p id="legal">( c ) 2008. All Rights Reserved. Template design - by <a href="http://www.freecsstemplates.org/">Free CSS - Templates</a>.</p> -</div> -<!-- end footer --> -</body> -</html> diff --git a/docs/tutorials/bfgwiki2/src/models/tutorial/templates/static/default.css b/docs/tutorials/bfgwiki2/src/models/tutorial/templates/static/default.css deleted file mode 100644 index 41b3debde..000000000 --- a/docs/tutorials/bfgwiki2/src/models/tutorial/templates/static/default.css +++ /dev/null @@ -1,380 +0,0 @@ -/* -Design by Free CSS Templates -http://www.freecsstemplates.org -Released for free under a Creative Commons Attribution 2.5 License -*/ - -body { - margin: 0; - padding: 0; - background: url(images/img01.gif) repeat-x left top; - font-size: 13px; - font-family: "Trebuchet MS", Georgia, "Times New Roman", Times, serif; - text-align: justify; - color: #FFFFFF; -} - -h1, h2, h3 { - margin: 0; - text-transform: lowercase; - font-weight: normal; - color: #FFFFFF; -} - -h1 { - letter-spacing: -1px; - font-size: 32px; -} - -h2 { - font-size: 23px; -} - -p, ul, ol { - margin: 0 0 2em 0; - text-align: justify; - line-height: 26px; -} - -a:link { - color: #8BD80E; -} - -a:hover, a:active { - text-decoration: none; - color: #8BD80E; -} - -a:visited { - color: #8BD80E; -} - -img { - border: none; -} - -img.left { - float: left; - margin-right: 15px; -} - -img.right { - float: right; - margin-left: 15px; -} - -/* Form */ - -form { - margin: 0; - padding: 0; -} - -fieldset { - margin: 0; - padding: 0; - border: none; -} - -legend { - display: none; -} - -input, textarea, select { - font-family: "Trebuchet MS", Arial, Helvetica, sans-serif; - font-size: 13px; - color: #333333; -} - -#wrapper { - margin: 0; - padding: 0; - background: #000000; -} - -/* Header */ - -#header { - width: 713px; - margin: 0 auto; - height: 42px; -} - -/* Menu */ - -#menu { - float: left; - width: 713px; - height: 50px; - background: url(images/img02.gif) no-repeat left top; -} - -#menu ul { - margin: 0; - padding: 0px 0 0 10px; - list-style: none; - line-height: normal; -} - -#menu li { - display: block; - float: left; -} - -#menu a { - display: block; - float: left; - background: url(images/img04.gif) no-repeat right 55%; - margin-top: 5px; - margin-right: 3px; - padding: 8px 17px; - text-decoration: none; - font-size: 13px; - color: #000000; -} - -#menu a:hover { - color: #000000; -} - -#menu .current_page_item a { - color: #000000; -} - -/** LOGO */ - -#logo { - width: 713px; - height: 80px; - margin: 0 auto; -} - -#logo h1, #logo h2 { - float: left; - margin: 0; - padding: 30px 0 0 0px; - line-height: normal; -} - -#logo h1 { - font-family: Georgia, "Times New Roman", Times, serif; - font-size:40px; -} - -#logo h1 a { - text-decoration: none; - color: #4C4C4C; -} - -#logo h1 a:hover { text-decoration: underline; } - -#logo h2 { - float: left; - padding: 45px 0 0 18px; - font: 18px Georgia, "Times New Roman", Times, serif; - color: #8BD80E; -} - -#logo p a { - text-decoration: none; - color: #8BD80E; -} - -#logo p a:hover { text-decoration: underline; } - - - -/* Page */ - -#page { - width: 663px; - margin: 0 auto; - background: #4C4C4C url(images/img03.gif) no-repeat left bottom; - padding: 0 25px; -} - -/* Content */ - -#content { - float: left; - width: 410px; - -} - -/* Post */ - -.post { - padding: 15px 0px; - margin-bottom: 20px; -} - -.post .title { - margin-bottom: 20px; - padding-bottom: 5px; -} - -.post h1 { - padding: 0px 0 0 0px; - background: url(images/img08.jpg) no-repeat left top; - font-size: 24px; - color: #FFFFFF; -} - -.post h2 { - padding: 0px 0 0 0px; - font-size: 22px; - color: #FFFFFF; -} - -.post .entry { -} - -.post .meta { - padding: 15px 15px 30px 0px; - font-family: Arial, Helvetica, sans-serif; - font-size: 11px; -} - -.post .meta p { - margin: 0; - padding-top: 15px; - line-height: normal; - color: #FFFFFF; -} - -.post .meta .byline { - float: left; -} - -.post .meta .links { - float: right; -} - -.post .meta .more { - padding: 0 10px 0 18px; -} - -.post .meta .comments { -} - -.post .meta b { - display: none; -} - - -/* Sidebar */ - -#sidebar { - width: 210px; - float: right; - margin: 0; - padding: 0; -} - -#sidebar ul { - margin: 0; - padding: 0; - list-style: none; -} - -#sidebar li { - margin-bottom: 40px; -} - -#sidebar li ul { -} - -#sidebar li li { - margin: 0; -} - -#sidebar h2 { - width: 250px; - padding: 8px 0 0 0px; - margin-bottom: 10px; - background: url(images/img07.jpg) no-repeat left top; - font-size: 20px; - color: #FFFFFF; -} - -/* Search */ - -#search { - -} - -#search h2 { - margin-bottom: 20px; -} - -#s { - width: 140px; - margin-right: 5px; - padding: 3px; - border: 1px solid #BED99C; -} - -#x { - padding: 3px; - border: none; - background: #8BD80E; - text-transform: lowercase; - font-size: 11px; - color: #FFFFFF; -} - -/* Boxes */ - -.box1 { - padding: 20px; -} - -.box2 { - color: #BABABA; -} - -.box2 h2 { - margin-bottom: 15px; - font-size: 16px; - color: #FFFFFF; -} - -.box2 ul { - margin: 0; - padding: 0; - list-style: none; -} - -.box2 a:link, .box2 a:hover, .box2 a:active, .box2 a:visited { - color: #EDEDED; -} - -/* Footer */ -#footer-wrap { -} - -#footer { - margin: 0 auto; - padding: 20px 0 10px 0; - background: #000000; -} - -html>body #footer { - height: auto; -} - -#footer p { - font-size: 11px; -} - -#legal { - clear: both; - padding-top: 17px; - text-align: center; - color: #FFFFFF; -} - -#legal a { - font-weight: normal; - color: #FFFFFF; -} diff --git a/docs/tutorials/bfgwiki2/src/models/tutorial/templates/static/images/img01.gif b/docs/tutorials/bfgwiki2/src/models/tutorial/templates/static/images/img01.gif Binary files differdeleted file mode 100644 index 5f082bd99..000000000 --- a/docs/tutorials/bfgwiki2/src/models/tutorial/templates/static/images/img01.gif +++ /dev/null diff --git a/docs/tutorials/bfgwiki2/src/models/tutorial/templates/static/images/img02.gif b/docs/tutorials/bfgwiki2/src/models/tutorial/templates/static/images/img02.gif Binary files differdeleted file mode 100644 index 45a3ae976..000000000 --- a/docs/tutorials/bfgwiki2/src/models/tutorial/templates/static/images/img02.gif +++ /dev/null diff --git a/docs/tutorials/bfgwiki2/src/models/tutorial/templates/static/images/img03.gif b/docs/tutorials/bfgwiki2/src/models/tutorial/templates/static/images/img03.gif Binary files differdeleted file mode 100644 index d92ea38f9..000000000 --- a/docs/tutorials/bfgwiki2/src/models/tutorial/templates/static/images/img03.gif +++ /dev/null diff --git a/docs/tutorials/bfgwiki2/src/models/tutorial/templates/static/images/img04.gif b/docs/tutorials/bfgwiki2/src/models/tutorial/templates/static/images/img04.gif Binary files differdeleted file mode 100644 index 950c4af9d..000000000 --- a/docs/tutorials/bfgwiki2/src/models/tutorial/templates/static/images/img04.gif +++ /dev/null diff --git a/docs/tutorials/bfgwiki2/src/models/tutorial/templates/static/images/spacer.gif b/docs/tutorials/bfgwiki2/src/models/tutorial/templates/static/images/spacer.gif Binary files differdeleted file mode 100644 index 5bfd67a2d..000000000 --- a/docs/tutorials/bfgwiki2/src/models/tutorial/templates/static/images/spacer.gif +++ /dev/null diff --git a/docs/tutorials/bfgwiki2/src/models/tutorial/templates/static/templatelicense.txt b/docs/tutorials/bfgwiki2/src/models/tutorial/templates/static/templatelicense.txt deleted file mode 100644 index ccb6b06ab..000000000 --- a/docs/tutorials/bfgwiki2/src/models/tutorial/templates/static/templatelicense.txt +++ /dev/null @@ -1,243 +0,0 @@ -Creative Commons </> - -Creative Commons Legal Code - -*Attribution 2.5* - -CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE -LEGAL SERVICES. DISTRIBUTION OF THIS LICENSE DOES NOT CREATE AN -ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS INFORMATION -ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES REGARDING THE -INFORMATION PROVIDED, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM -ITS USE. - -/License/ - -THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE -COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). THE WORK IS PROTECTED BY -COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS -AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED. - -BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE -TO BE BOUND BY THE TERMS OF THIS LICENSE. THE LICENSOR GRANTS YOU THE -RIGHTS CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS -AND CONDITIONS. - -*1. Definitions* - - 1. *"Collective Work"* means a work, such as a periodical issue, - anthology or encyclopedia, in which the Work in its entirety in - unmodified form, along with a number of other contributions, - constituting separate and independent works in themselves, are - assembled into a collective whole. A work that constitutes a - Collective Work will not be considered a Derivative Work (as - defined below) for the purposes of this License. - 2. *"Derivative Work"* means a work based upon the Work or upon the - Work and other pre-existing works, such as a translation, musical - arrangement, dramatization, fictionalization, motion picture - version, sound recording, art reproduction, abridgment, - condensation, or any other form in which the Work may be recast, - transformed, or adapted, except that a work that constitutes a - Collective Work will not be considered a Derivative Work for the - purpose of this License. For the avoidance of doubt, where the - Work is a musical composition or sound recording, the - synchronization of the Work in timed-relation with a moving image - ("synching") will be considered a Derivative Work for the purpose - of this License. - 3. *"Licensor"* means the individual or entity that offers the Work - under the terms of this License. - 4. *"Original Author"* means the individual or entity who created the - Work. - 5. *"Work"* means the copyrightable work of authorship offered under - the terms of this License. - 6. *"You"* means an individual or entity exercising rights under this - License who has not previously violated the terms of this License - with respect to the Work, or who has received express permission - from the Licensor to exercise rights under this License despite a - previous violation. - -*2. Fair Use Rights.* Nothing in this license is intended to reduce, -limit, or restrict any rights arising from fair use, first sale or other -limitations on the exclusive rights of the copyright owner under -copyright law or other applicable laws. - -*3. License Grant.* Subject to the terms and conditions of this License, -Licensor hereby grants You a worldwide, royalty-free, non-exclusive, -perpetual (for the duration of the applicable copyright) license to -exercise the rights in the Work as stated below: - - 1. to reproduce the Work, to incorporate the Work into one or more - Collective Works, and to reproduce the Work as incorporated in the - Collective Works; - 2. to create and reproduce Derivative Works; - 3. to distribute copies or phonorecords of, display publicly, perform - publicly, and perform publicly by means of a digital audio - transmission the Work including as incorporated in Collective Works; - 4. to distribute copies or phonorecords of, display publicly, perform - publicly, and perform publicly by means of a digital audio - transmission Derivative Works. - 5. - - For the avoidance of doubt, where the work is a musical composition: - - 1. *Performance Royalties Under Blanket Licenses*. Licensor - waives the exclusive right to collect, whether individually - or via a performance rights society (e.g. ASCAP, BMI, - SESAC), royalties for the public performance or public - digital performance (e.g. webcast) of the Work. - 2. *Mechanical Rights and Statutory Royalties*. Licensor waives - the exclusive right to collect, whether individually or via - a music rights agency or designated agent (e.g. Harry Fox - Agency), royalties for any phonorecord You create from the - Work ("cover version") and distribute, subject to the - compulsory license created by 17 USC Section 115 of the US - Copyright Act (or the equivalent in other jurisdictions). - 6. *Webcasting Rights and Statutory Royalties*. For the avoidance of - doubt, where the Work is a sound recording, Licensor waives the - exclusive right to collect, whether individually or via a - performance-rights society (e.g. SoundExchange), royalties for the - public digital performance (e.g. webcast) of the Work, subject to - the compulsory license created by 17 USC Section 114 of the US - Copyright Act (or the equivalent in other jurisdictions). - -The above rights may be exercised in all media and formats whether now -known or hereafter devised. The above rights include the right to make -such modifications as are technically necessary to exercise the rights -in other media and formats. All rights not expressly granted by Licensor -are hereby reserved. - -*4. Restrictions.*The license granted in Section 3 above is expressly -made subject to and limited by the following restrictions: - - 1. You may distribute, publicly display, publicly perform, or - publicly digitally perform the Work only under the terms of this - License, and You must include a copy of, or the Uniform Resource - Identifier for, this License with every copy or phonorecord of the - Work You distribute, publicly display, publicly perform, or - publicly digitally perform. You may not offer or impose any terms - on the Work that alter or restrict the terms of this License or - the recipients' exercise of the rights granted hereunder. You may - not sublicense the Work. You must keep intact all notices that - refer to this License and to the disclaimer of warranties. You may - not distribute, publicly display, publicly perform, or publicly - digitally perform the Work with any technological measures that - control access or use of the Work in a manner inconsistent with - the terms of this License Agreement. The above applies to the Work - as incorporated in a Collective Work, but this does not require - the Collective Work apart from the Work itself to be made subject - to the terms of this License. If You create a Collective Work, - upon notice from any Licensor You must, to the extent practicable, - remove from the Collective Work any credit as required by clause - 4(b), as requested. If You create a Derivative Work, upon notice - from any Licensor You must, to the extent practicable, remove from - the Derivative Work any credit as required by clause 4(b), as - requested. - 2. If you distribute, publicly display, publicly perform, or publicly - digitally perform the Work or any Derivative Works or Collective - Works, You must keep intact all copyright notices for the Work and - provide, reasonable to the medium or means You are utilizing: (i) - the name of the Original Author (or pseudonym, if applicable) if - supplied, and/or (ii) if the Original Author and/or Licensor - designate another party or parties (e.g. a sponsor institute, - publishing entity, journal) for attribution in Licensor's - copyright notice, terms of service or by other reasonable means, - the name of such party or parties; the title of the Work if - supplied; to the extent reasonably practicable, the Uniform - Resource Identifier, if any, that Licensor specifies to be - associated with the Work, unless such URI does not refer to the - copyright notice or licensing information for the Work; and in the - case of a Derivative Work, a credit identifying the use of the - Work in the Derivative Work (e.g., "French translation of the Work - by Original Author," or "Screenplay based on original Work by - Original Author"). Such credit may be implemented in any - reasonable manner; provided, however, that in the case of a - Derivative Work or Collective Work, at a minimum such credit will - appear where any other comparable authorship credit appears and in - a manner at least as prominent as such other comparable authorship - credit. - -*5. Representations, Warranties and Disclaimer* - -UNLESS OTHERWISE MUTUALLY AGREED TO BY THE PARTIES IN WRITING, LICENSOR -OFFERS THE WORK AS-IS AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY -KIND CONCERNING THE WORK, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE, -INCLUDING, WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTIBILITY, -FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF -LATENT OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE OF ABSENCE OF ERRORS, -WHETHER OR NOT DISCOVERABLE. SOME JURISDICTIONS DO NOT ALLOW THE -EXCLUSION OF IMPLIED WARRANTIES, SO SUCH EXCLUSION MAY NOT APPLY TO YOU. - -*6. Limitation on Liability.* EXCEPT TO THE EXTENT REQUIRED BY -APPLICABLE LAW, IN NO EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY LEGAL -THEORY FOR ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY -DAMAGES ARISING OUT OF THIS LICENSE OR THE USE OF THE WORK, EVEN IF -LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - -*7. Termination* - - 1. This License and the rights granted hereunder will terminate - automatically upon any breach by You of the terms of this License. - Individuals or entities who have received Derivative Works or - Collective Works from You under this License, however, will not - have their licenses terminated provided such individuals or - entities remain in full compliance with those licenses. Sections - 1, 2, 5, 6, 7, and 8 will survive any termination of this License. - 2. Subject to the above terms and conditions, the license granted - here is perpetual (for the duration of the applicable copyright in - the Work). Notwithstanding the above, Licensor reserves the right - to release the Work under different license terms or to stop - distributing the Work at any time; provided, however that any such - election will not serve to withdraw this License (or any other - license that has been, or is required to be, granted under the - terms of this License), and this License will continue in full - force and effect unless terminated as stated above. - -*8. Miscellaneous* - - 1. Each time You distribute or publicly digitally perform the Work or - a Collective Work, the Licensor offers to the recipient a license - to the Work on the same terms and conditions as the license - granted to You under this License. - 2. Each time You distribute or publicly digitally perform a - Derivative Work, Licensor offers to the recipient a license to the - original Work on the same terms and conditions as the license - granted to You under this License. - 3. If any provision of this License is invalid or unenforceable under - applicable law, it shall not affect the validity or enforceability - of the remainder of the terms of this License, and without further - action by the parties to this agreement, such provision shall be - reformed to the minimum extent necessary to make such provision - valid and enforceable. - 4. No term or provision of this License shall be deemed waived and no - breach consented to unless such waiver or consent shall be in - writing and signed by the party to be charged with such waiver or - consent. - 5. This License constitutes the entire agreement between the parties - with respect to the Work licensed here. There are no - understandings, agreements or representations with respect to the - Work not specified here. Licensor shall not be bound by any - additional provisions that may appear in any communication from - You. This License may not be modified without the mutual written - agreement of the Licensor and You. - -Creative Commons is not a party to this License, and makes no warranty -whatsoever in connection with the Work. Creative Commons will not be -liable to You or any party on any legal theory for any damages -whatsoever, including without limitation any general, special, -incidental or consequential damages arising in connection to this -license. Notwithstanding the foregoing two (2) sentences, if Creative -Commons has expressly identified itself as the Licensor hereunder, it -shall have all rights and obligations of Licensor. - -Except for the limited purpose of indicating to the public that the Work -is licensed under the CCPL, neither party will use the trademark -"Creative Commons" or any related trademark or logo of Creative Commons -without the prior written consent of Creative Commons. Any permitted use -will be in compliance with Creative Commons' then-current trademark -usage guidelines, as may be published on its website or otherwise made -available upon request from time to time. - -Creative Commons may be contacted at http://creativecommons.org/ -<http://creativecommons.org>. - -« Back to Commons Deed <./> diff --git a/docs/tutorials/bfgwiki2/src/models/tutorial/tests.py b/docs/tutorials/bfgwiki2/src/models/tutorial/tests.py deleted file mode 100644 index 72f0c89d8..000000000 --- a/docs/tutorials/bfgwiki2/src/models/tutorial/tests.py +++ /dev/null @@ -1,24 +0,0 @@ -import unittest -from pyramid.configuration import Configurator -from pyramid import testing - -def _initTestingDB(): - from tutorial.models import initialize_sql - session = initialize_sql('sqlite://') - return session - -class TestMyView(unittest.TestCase): - def setUp(self): - self.config = Configurator() - self.config.begin() - _initTestingDB() - - def tearDown(self): - self.config.end() - - def test_it(self): - from tutorial.views import my_view - request = testing.DummyRequest() - info = my_view(request) - self.assertEqual(info['root'].name, 'root') - self.assertEqual(info['project'], 'tutorial') diff --git a/docs/tutorials/bfgwiki2/src/models/tutorial/views.py b/docs/tutorials/bfgwiki2/src/models/tutorial/views.py deleted file mode 100644 index e550e3257..000000000 --- a/docs/tutorials/bfgwiki2/src/models/tutorial/views.py +++ /dev/null @@ -1,7 +0,0 @@ -from tutorial.models import DBSession -from tutorial.models import MyModel - -def my_view(request): - dbsession = DBSession() - root = dbsession.query(MyModel).filter(MyModel.name==u'root').first() - return {'root':root, 'project':'tutorial'} diff --git a/docs/tutorials/bfgwiki2/src/views/CHANGES.txt b/docs/tutorials/bfgwiki2/src/views/CHANGES.txt deleted file mode 100644 index 35a34f332..000000000 --- a/docs/tutorials/bfgwiki2/src/views/CHANGES.txt +++ /dev/null @@ -1,4 +0,0 @@ -0.0 ---- - -- Initial version diff --git a/docs/tutorials/bfgwiki2/src/views/README.txt b/docs/tutorials/bfgwiki2/src/views/README.txt deleted file mode 100644 index d41f7f90f..000000000 --- a/docs/tutorials/bfgwiki2/src/views/README.txt +++ /dev/null @@ -1,4 +0,0 @@ -tutorial README - - - diff --git a/docs/tutorials/bfgwiki2/src/views/setup.cfg b/docs/tutorials/bfgwiki2/src/views/setup.cfg deleted file mode 100644 index 23b2ad983..000000000 --- a/docs/tutorials/bfgwiki2/src/views/setup.cfg +++ /dev/null @@ -1,27 +0,0 @@ -[nosetests] -match=^test -nocapture=1 -cover-package=tutorial -with-coverage=1 -cover-erase=1 - -[compile_catalog] -directory = tutorial/locale -domain = tutorial -statistics = true - -[extract_messages] -add_comments = TRANSLATORS: -output_file = tutorial/locale/tutorial.pot -width = 80 - -[init_catalog] -domain = tutorial -input_file = tutorial/locale/tutorial.pot -output_dir = tutorial/locale - -[update_catalog] -domain = tutorial -input_file = tutorial/locale/tutorial.pot -output_dir = tutorial/locale -previous = true diff --git a/docs/tutorials/bfgwiki2/src/views/setup.py b/docs/tutorials/bfgwiki2/src/views/setup.py deleted file mode 100644 index 764e8c0ea..000000000 --- a/docs/tutorials/bfgwiki2/src/views/setup.py +++ /dev/null @@ -1,46 +0,0 @@ -import os -import sys - -from setuptools import setup, find_packages - -here = os.path.abspath(os.path.dirname(__file__)) -README = open(os.path.join(here, 'README.txt')).read() -CHANGES = open(os.path.join(here, 'CHANGES.txt')).read() - -requires = [ - 'repoze.bfg', - 'SQLAlchemy', - 'transaction', - 'repoze.tm2', - 'zope.sqlalchemy', - 'docutils' - ] - -if sys.version_info[:3] < (2,5,0): - requires.append('pysqlite') - -setup(name='tutorial', - version='0.0', - description='tutorial', - long_description=README + '\n\n' + CHANGES, - classifiers=[ - "Programming Language :: Python", - "Framework :: BFG", - "Topic :: Internet :: WWW/HTTP", - "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", - ], - author='', - author_email='', - url='', - keywords='web wsgi bfg', - packages=find_packages(), - include_package_data=True, - zip_safe=False, - test_suite='tutorial', - install_requires = requires, - entry_points = """\ - [paste.app_factory] - app = tutorial.run:app - """ - ) - diff --git a/docs/tutorials/bfgwiki2/src/views/tutorial.ini b/docs/tutorials/bfgwiki2/src/views/tutorial.ini deleted file mode 100644 index 85f131c2e..000000000 --- a/docs/tutorials/bfgwiki2/src/views/tutorial.ini +++ /dev/null @@ -1,23 +0,0 @@ -[DEFAULT] -debug = true - -[app:sqlalchemy] -use = egg:tutorial#app -reload_templates = true -debug_authorization = false -debug_notfound = false -debug_templates = true -default_locale_name = en -db_string = sqlite:///%(here)s/tutorial.db -db_echo = false - -[pipeline:main] -pipeline = - egg:Paste#evalerror - egg:repoze.tm2#tm - sqlalchemy - -[server:main] -use = egg:Paste#http -host = 0.0.0.0 -port = 6543 diff --git a/docs/tutorials/bfgwiki2/src/views/tutorial/__init__.py b/docs/tutorials/bfgwiki2/src/views/tutorial/__init__.py deleted file mode 100644 index cbdfd3ac6..000000000 --- a/docs/tutorials/bfgwiki2/src/views/tutorial/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -# A package - diff --git a/docs/tutorials/bfgwiki2/src/views/tutorial/configure.zcml b/docs/tutorials/bfgwiki2/src/views/tutorial/configure.zcml deleted file mode 100644 index 7b3f73b4e..000000000 --- a/docs/tutorials/bfgwiki2/src/views/tutorial/configure.zcml +++ /dev/null @@ -1,38 +0,0 @@ -<configure xmlns="http://namespaces.repoze.org/bfg"> - - <!-- this must be included for the view declarations to work --> - <include package="repoze.bfg.includes" /> - - <static - path="templates/static" - name="static" - /> - - <route - pattern="" - name="view_wiki" - view=".views.view_wiki" - /> - - <route - pattern=":pagename" - name="view_page" - view=".views.view_page" - view_renderer="templates/view.pt" - /> - - <route - pattern="add_page/:pagename" - name="add_page" - view=".views.add_page" - view_renderer="templates/edit.pt" - /> - - <route - pattern=":pagename/edit_page" - name="edit_page" - view=".views.edit_page" - view_renderer="templates/edit.pt" - /> - -</configure> diff --git a/docs/tutorials/bfgwiki2/src/views/tutorial/models.py b/docs/tutorials/bfgwiki2/src/views/tutorial/models.py deleted file mode 100644 index 8c3f14915..000000000 --- a/docs/tutorials/bfgwiki2/src/views/tutorial/models.py +++ /dev/null @@ -1,43 +0,0 @@ -import transaction - -from sqlalchemy import create_engine -from sqlalchemy import Column -from sqlalchemy import Integer -from sqlalchemy import Text - -from sqlalchemy.exc import IntegrityError -from sqlalchemy.ext.declarative import declarative_base - -from sqlalchemy.orm import scoped_session -from sqlalchemy.orm import 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) - - def __init__(self, name, data): - self.name = name - self.data = data - -def initialize_sql(db_string, echo=False): - engine = create_engine(db_string, echo=echo) - DBSession.configure(bind=engine) - Base.metadata.bind = engine - Base.metadata.create_all(engine) - try: - session = DBSession() - page = Page('FrontPage', 'initial data') - session.add(page) - transaction.commit() - except IntegrityError: - # already created - pass diff --git a/docs/tutorials/bfgwiki2/src/views/tutorial/run.py b/docs/tutorials/bfgwiki2/src/views/tutorial/run.py deleted file mode 100644 index 7225987ee..000000000 --- a/docs/tutorials/bfgwiki2/src/views/tutorial/run.py +++ /dev/null @@ -1,24 +0,0 @@ -from pyramid.configuration import Configurator -from paste.deploy.converters import asbool - -from tutorial.models import initialize_sql - -def app(global_config, **settings): - """ This function returns a WSGI application. - - It is usually called by the PasteDeploy framework during - ``paster serve``. - """ - zcml_file = settings.get('configure_zcml', 'configure.zcml') - db_string = settings.get('db_string') - if db_string is None: - raise ValueError( - "No 'db_string' value in application configuration.") - db_echo = settings.get('db_echo', 'false') - initialize_sql(db_string, asbool(db_echo)) - config = Configurator(settings=settings) - config.begin() - config.load_zcml(zcml_file) - config.end() - return config.make_wsgi_app() - diff --git a/docs/tutorials/bfgwiki2/src/views/tutorial/templates/edit.pt b/docs/tutorials/bfgwiki2/src/views/tutorial/templates/edit.pt deleted file mode 100644 index 8e6827f74..000000000 --- a/docs/tutorials/bfgwiki2/src/views/tutorial/templates/edit.pt +++ /dev/null @@ -1,32 +0,0 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" - "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> -<html - xmlns="http://www.w3.org/1999/xhtml" - xmlns:tal="http://xml.zope.org/namespaces/tal"> - -<head> - <meta content="text/html; charset=utf-8" http-equiv="Content-Type"/> - <title>bfg tutorial wiki (based on TurboGears 20-Minute Wiki) - Editing: ${page.name}</title> - <link rel="stylesheet" type="text/css" - href="${request.application_url}/static/style.css" /> -</head> - -<body> - -<div class="main_content"> - <div style="float:right; width: 10em;"> Viewing - <span tal:replace="page.name">Page Name Goes Here</span> <br/> - You can return to the <a href="${request.application_url}" - >FrontPage</a>. - </div> - - <div> - <form action="${save_url}" method="post"> - <textarea name="body" tal:content="page.data" rows="10" cols="60"/> - <input type="submit" name="form.submitted" value="Save"/> - </form> - </div> -</div> -</body> -</html> diff --git a/docs/tutorials/bfgwiki2/src/views/tutorial/templates/mytemplate.pt b/docs/tutorials/bfgwiki2/src/views/tutorial/templates/mytemplate.pt deleted file mode 100644 index 2aedcad9f..000000000 --- a/docs/tutorials/bfgwiki2/src/views/tutorial/templates/mytemplate.pt +++ /dev/null @@ -1,99 +0,0 @@ -<!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" - xmlns:tal="http://xml.zope.org/namespaces/tal"> -<head> -<meta http-equiv="content-type" content="text/html; charset=utf-8" /> -<title>${project} Application</title> -<meta name="keywords" content="python web application" /> -<meta name="description" content="repoze.bfg web application" /> -<link href="${request.application_url}/static/default.css" rel="stylesheet" type="text/css" /> -</head> -<body> -<!-- start header --> -<div id="logo"> - <h2><code>${project}</code>, a <code>repoze.bfg</code> application</h2> -</div> -<div id="header"> - <div id="menu"> - </div> -</div> -<!-- end header --> -<div id="wrapper"> - <!-- start page --> - <div id="page"> - <!-- start content --> - <div id="content"> - <div class="post"> - <h1 class="title">Welcome to <code>${project}</code>, an - application generated by the <a - href="http://bfg.repoze.org">repoze.bfg</a> web - application framework.</h1> - </div> - </div> - <!-- end content --> - <!-- start sidebar --> - <div id="sidebar"> - <ul> - <li id="search"> - <h2>Search<br/> <code>repoze.bfg</code> Documentation</h2> - <form method="get" - action="http://bfg.repoze.org/searchresults"> - <fieldset> - <input type="text" id="q" name="text" value="" /> - <input type="submit" id="x" value="Search" /> - </fieldset> - </form> - </li> - <li> - <h2><code>repoze.bfg</code> links</h2> - <ul> - <li><a - href="http://docs.repoze.org/bfg/current/#narrative-documentation">Narrative - Documentation</a> - </li> - <li> - <a - href="http://docs.repoze.org/bfg/current/#api-documentation">API - Documentation</a> - </li> - <li> - <a - href="http://docs.repoze.org/bfg/current/#tutorials">Tutorials</a> - </li> - <li> - <a - href="http://docs.repoze.org/bfg/current/#change-history">Change - History</a> - </li> - <li> - <a - href="http://docs.repoze.org/bfg/current/#sample-applications">Sample - Applications</a> - </li> - <li> - <a - href="http://docs.repoze.org/bfg/current/#support-and-development">Support - and Development</a> - </li> - <li> - <a - href="irc://irc.freenode.net#repoze">IRC Channel</a> - </li> - </ul> - </li> - </ul> - </div> - <!-- end sidebar --> - <div style="clear: both;"> </div> - </div> -</div> -<!-- end page --> -<!-- start footer --> -<div id="footer"> - <p id="legal">( c ) 2008. All Rights Reserved. Template design - by <a href="http://www.freecsstemplates.org/">Free CSS - Templates</a>.</p> -</div> -<!-- end footer --> -</body> -</html> diff --git a/docs/tutorials/bfgwiki2/src/views/tutorial/templates/static/default.css b/docs/tutorials/bfgwiki2/src/views/tutorial/templates/static/default.css deleted file mode 100644 index 41b3debde..000000000 --- a/docs/tutorials/bfgwiki2/src/views/tutorial/templates/static/default.css +++ /dev/null @@ -1,380 +0,0 @@ -/* -Design by Free CSS Templates -http://www.freecsstemplates.org -Released for free under a Creative Commons Attribution 2.5 License -*/ - -body { - margin: 0; - padding: 0; - background: url(images/img01.gif) repeat-x left top; - font-size: 13px; - font-family: "Trebuchet MS", Georgia, "Times New Roman", Times, serif; - text-align: justify; - color: #FFFFFF; -} - -h1, h2, h3 { - margin: 0; - text-transform: lowercase; - font-weight: normal; - color: #FFFFFF; -} - -h1 { - letter-spacing: -1px; - font-size: 32px; -} - -h2 { - font-size: 23px; -} - -p, ul, ol { - margin: 0 0 2em 0; - text-align: justify; - line-height: 26px; -} - -a:link { - color: #8BD80E; -} - -a:hover, a:active { - text-decoration: none; - color: #8BD80E; -} - -a:visited { - color: #8BD80E; -} - -img { - border: none; -} - -img.left { - float: left; - margin-right: 15px; -} - -img.right { - float: right; - margin-left: 15px; -} - -/* Form */ - -form { - margin: 0; - padding: 0; -} - -fieldset { - margin: 0; - padding: 0; - border: none; -} - -legend { - display: none; -} - -input, textarea, select { - font-family: "Trebuchet MS", Arial, Helvetica, sans-serif; - font-size: 13px; - color: #333333; -} - -#wrapper { - margin: 0; - padding: 0; - background: #000000; -} - -/* Header */ - -#header { - width: 713px; - margin: 0 auto; - height: 42px; -} - -/* Menu */ - -#menu { - float: left; - width: 713px; - height: 50px; - background: url(images/img02.gif) no-repeat left top; -} - -#menu ul { - margin: 0; - padding: 0px 0 0 10px; - list-style: none; - line-height: normal; -} - -#menu li { - display: block; - float: left; -} - -#menu a { - display: block; - float: left; - background: url(images/img04.gif) no-repeat right 55%; - margin-top: 5px; - margin-right: 3px; - padding: 8px 17px; - text-decoration: none; - font-size: 13px; - color: #000000; -} - -#menu a:hover { - color: #000000; -} - -#menu .current_page_item a { - color: #000000; -} - -/** LOGO */ - -#logo { - width: 713px; - height: 80px; - margin: 0 auto; -} - -#logo h1, #logo h2 { - float: left; - margin: 0; - padding: 30px 0 0 0px; - line-height: normal; -} - -#logo h1 { - font-family: Georgia, "Times New Roman", Times, serif; - font-size:40px; -} - -#logo h1 a { - text-decoration: none; - color: #4C4C4C; -} - -#logo h1 a:hover { text-decoration: underline; } - -#logo h2 { - float: left; - padding: 45px 0 0 18px; - font: 18px Georgia, "Times New Roman", Times, serif; - color: #8BD80E; -} - -#logo p a { - text-decoration: none; - color: #8BD80E; -} - -#logo p a:hover { text-decoration: underline; } - - - -/* Page */ - -#page { - width: 663px; - margin: 0 auto; - background: #4C4C4C url(images/img03.gif) no-repeat left bottom; - padding: 0 25px; -} - -/* Content */ - -#content { - float: left; - width: 410px; - -} - -/* Post */ - -.post { - padding: 15px 0px; - margin-bottom: 20px; -} - -.post .title { - margin-bottom: 20px; - padding-bottom: 5px; -} - -.post h1 { - padding: 0px 0 0 0px; - background: url(images/img08.jpg) no-repeat left top; - font-size: 24px; - color: #FFFFFF; -} - -.post h2 { - padding: 0px 0 0 0px; - font-size: 22px; - color: #FFFFFF; -} - -.post .entry { -} - -.post .meta { - padding: 15px 15px 30px 0px; - font-family: Arial, Helvetica, sans-serif; - font-size: 11px; -} - -.post .meta p { - margin: 0; - padding-top: 15px; - line-height: normal; - color: #FFFFFF; -} - -.post .meta .byline { - float: left; -} - -.post .meta .links { - float: right; -} - -.post .meta .more { - padding: 0 10px 0 18px; -} - -.post .meta .comments { -} - -.post .meta b { - display: none; -} - - -/* Sidebar */ - -#sidebar { - width: 210px; - float: right; - margin: 0; - padding: 0; -} - -#sidebar ul { - margin: 0; - padding: 0; - list-style: none; -} - -#sidebar li { - margin-bottom: 40px; -} - -#sidebar li ul { -} - -#sidebar li li { - margin: 0; -} - -#sidebar h2 { - width: 250px; - padding: 8px 0 0 0px; - margin-bottom: 10px; - background: url(images/img07.jpg) no-repeat left top; - font-size: 20px; - color: #FFFFFF; -} - -/* Search */ - -#search { - -} - -#search h2 { - margin-bottom: 20px; -} - -#s { - width: 140px; - margin-right: 5px; - padding: 3px; - border: 1px solid #BED99C; -} - -#x { - padding: 3px; - border: none; - background: #8BD80E; - text-transform: lowercase; - font-size: 11px; - color: #FFFFFF; -} - -/* Boxes */ - -.box1 { - padding: 20px; -} - -.box2 { - color: #BABABA; -} - -.box2 h2 { - margin-bottom: 15px; - font-size: 16px; - color: #FFFFFF; -} - -.box2 ul { - margin: 0; - padding: 0; - list-style: none; -} - -.box2 a:link, .box2 a:hover, .box2 a:active, .box2 a:visited { - color: #EDEDED; -} - -/* Footer */ -#footer-wrap { -} - -#footer { - margin: 0 auto; - padding: 20px 0 10px 0; - background: #000000; -} - -html>body #footer { - height: auto; -} - -#footer p { - font-size: 11px; -} - -#legal { - clear: both; - padding-top: 17px; - text-align: center; - color: #FFFFFF; -} - -#legal a { - font-weight: normal; - color: #FFFFFF; -} diff --git a/docs/tutorials/bfgwiki2/src/views/tutorial/templates/static/images/img01.gif b/docs/tutorials/bfgwiki2/src/views/tutorial/templates/static/images/img01.gif Binary files differdeleted file mode 100644 index 5f082bd99..000000000 --- a/docs/tutorials/bfgwiki2/src/views/tutorial/templates/static/images/img01.gif +++ /dev/null diff --git a/docs/tutorials/bfgwiki2/src/views/tutorial/templates/static/images/img02.gif b/docs/tutorials/bfgwiki2/src/views/tutorial/templates/static/images/img02.gif Binary files differdeleted file mode 100644 index 45a3ae976..000000000 --- a/docs/tutorials/bfgwiki2/src/views/tutorial/templates/static/images/img02.gif +++ /dev/null diff --git a/docs/tutorials/bfgwiki2/src/views/tutorial/templates/static/images/img03.gif b/docs/tutorials/bfgwiki2/src/views/tutorial/templates/static/images/img03.gif Binary files differdeleted file mode 100644 index d92ea38f9..000000000 --- a/docs/tutorials/bfgwiki2/src/views/tutorial/templates/static/images/img03.gif +++ /dev/null diff --git a/docs/tutorials/bfgwiki2/src/views/tutorial/templates/static/images/img04.gif b/docs/tutorials/bfgwiki2/src/views/tutorial/templates/static/images/img04.gif Binary files differdeleted file mode 100644 index 950c4af9d..000000000 --- a/docs/tutorials/bfgwiki2/src/views/tutorial/templates/static/images/img04.gif +++ /dev/null diff --git a/docs/tutorials/bfgwiki2/src/views/tutorial/templates/static/images/spacer.gif b/docs/tutorials/bfgwiki2/src/views/tutorial/templates/static/images/spacer.gif Binary files differdeleted file mode 100644 index 5bfd67a2d..000000000 --- a/docs/tutorials/bfgwiki2/src/views/tutorial/templates/static/images/spacer.gif +++ /dev/null diff --git a/docs/tutorials/bfgwiki2/src/views/tutorial/templates/static/style.css b/docs/tutorials/bfgwiki2/src/views/tutorial/templates/static/style.css deleted file mode 100644 index cad87e0d4..000000000 --- a/docs/tutorials/bfgwiki2/src/views/tutorial/templates/static/style.css +++ /dev/null @@ -1,109 +0,0 @@ -html, body { - color: black; - background-color: #ddd; - font: x-small "Lucida Grande", "Lucida Sans Unicode", geneva, sans-serif; - margin: 0; - padding: 0; -} - -td, th {padding:3px;border:none;} -tr th {text-align:left;background-color:#f0f0f0;color:#333;} -tr.odd td {background-color:#edf3fe;} -tr.even td {background-color:#fff;} - -#header { - height: 80px; - width: 777px; - background: blue URL('../images/header_inner.png') no-repeat; - border-left: 1px solid #aaa; - border-right: 1px solid #aaa; - margin: 0 auto 0 auto; -} - -a.link, a, a.active { - color: #369; -} - - -#main_content { - color: black; - font-size: 127%; - background-color: white; - width: 757px; - margin: 0 auto 0 auto; - border-left: 1px solid #aaa; - border-right: 1px solid #aaa; - padding: 10px; -} - -#sidebar { - border: 1px solid #aaa; - background-color: #eee; - margin: 0.5em; - padding: 1em; - float: right; - width: 200px; - font-size: 88%; -} - -#sidebar h2 { - margin-top: 0; -} - -#sidebar ul { - margin-left: 1.5em; - padding-left: 0; -} - -h1,h2,h3,h4,h5,h6,#getting_started_steps { - font-family: "Century Schoolbook L", Georgia, serif; - font-weight: bold; -} - -h2 { - font-size: 150%; -} - -#footer { - border: 1px solid #aaa; - border-top: 0px none; - color: #999; - background-color: white; - padding: 10px; - font-size: 80%; - text-align: center; - width: 757px; - margin: 0 auto 1em auto; -} - -.code { - font-family: monospace; -} - -span.code { - font-weight: bold; - background: #eee; -} - -#status_block { - margin: 0 auto 0.5em auto; - padding: 15px 10px 15px 55px; - background: #cec URL('../images/ok.png') left center no-repeat; - border: 1px solid #9c9; - width: 450px; - font-size: 120%; - font-weight: bolder; -} - -.notice { - margin: 0.5em auto 0.5em auto; - padding: 15px 10px 15px 55px; - width: 450px; - background: #eef URL('../images/info.png') left center no-repeat; - border: 1px solid #cce; -} - -.fielderror { - color: red; - font-weight: bold; -} diff --git a/docs/tutorials/bfgwiki2/src/views/tutorial/templates/static/templatelicense.txt b/docs/tutorials/bfgwiki2/src/views/tutorial/templates/static/templatelicense.txt deleted file mode 100644 index ccb6b06ab..000000000 --- a/docs/tutorials/bfgwiki2/src/views/tutorial/templates/static/templatelicense.txt +++ /dev/null @@ -1,243 +0,0 @@ -Creative Commons </> - -Creative Commons Legal Code - -*Attribution 2.5* - -CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE -LEGAL SERVICES. DISTRIBUTION OF THIS LICENSE DOES NOT CREATE AN -ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS INFORMATION -ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES REGARDING THE -INFORMATION PROVIDED, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM -ITS USE. - -/License/ - -THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE -COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). THE WORK IS PROTECTED BY -COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS -AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED. - -BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE -TO BE BOUND BY THE TERMS OF THIS LICENSE. THE LICENSOR GRANTS YOU THE -RIGHTS CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS -AND CONDITIONS. - -*1. Definitions* - - 1. *"Collective Work"* means a work, such as a periodical issue, - anthology or encyclopedia, in which the Work in its entirety in - unmodified form, along with a number of other contributions, - constituting separate and independent works in themselves, are - assembled into a collective whole. A work that constitutes a - Collective Work will not be considered a Derivative Work (as - defined below) for the purposes of this License. - 2. *"Derivative Work"* means a work based upon the Work or upon the - Work and other pre-existing works, such as a translation, musical - arrangement, dramatization, fictionalization, motion picture - version, sound recording, art reproduction, abridgment, - condensation, or any other form in which the Work may be recast, - transformed, or adapted, except that a work that constitutes a - Collective Work will not be considered a Derivative Work for the - purpose of this License. For the avoidance of doubt, where the - Work is a musical composition or sound recording, the - synchronization of the Work in timed-relation with a moving image - ("synching") will be considered a Derivative Work for the purpose - of this License. - 3. *"Licensor"* means the individual or entity that offers the Work - under the terms of this License. - 4. *"Original Author"* means the individual or entity who created the - Work. - 5. *"Work"* means the copyrightable work of authorship offered under - the terms of this License. - 6. *"You"* means an individual or entity exercising rights under this - License who has not previously violated the terms of this License - with respect to the Work, or who has received express permission - from the Licensor to exercise rights under this License despite a - previous violation. - -*2. Fair Use Rights.* Nothing in this license is intended to reduce, -limit, or restrict any rights arising from fair use, first sale or other -limitations on the exclusive rights of the copyright owner under -copyright law or other applicable laws. - -*3. License Grant.* Subject to the terms and conditions of this License, -Licensor hereby grants You a worldwide, royalty-free, non-exclusive, -perpetual (for the duration of the applicable copyright) license to -exercise the rights in the Work as stated below: - - 1. to reproduce the Work, to incorporate the Work into one or more - Collective Works, and to reproduce the Work as incorporated in the - Collective Works; - 2. to create and reproduce Derivative Works; - 3. to distribute copies or phonorecords of, display publicly, perform - publicly, and perform publicly by means of a digital audio - transmission the Work including as incorporated in Collective Works; - 4. to distribute copies or phonorecords of, display publicly, perform - publicly, and perform publicly by means of a digital audio - transmission Derivative Works. - 5. - - For the avoidance of doubt, where the work is a musical composition: - - 1. *Performance Royalties Under Blanket Licenses*. Licensor - waives the exclusive right to collect, whether individually - or via a performance rights society (e.g. ASCAP, BMI, - SESAC), royalties for the public performance or public - digital performance (e.g. webcast) of the Work. - 2. *Mechanical Rights and Statutory Royalties*. Licensor waives - the exclusive right to collect, whether individually or via - a music rights agency or designated agent (e.g. Harry Fox - Agency), royalties for any phonorecord You create from the - Work ("cover version") and distribute, subject to the - compulsory license created by 17 USC Section 115 of the US - Copyright Act (or the equivalent in other jurisdictions). - 6. *Webcasting Rights and Statutory Royalties*. For the avoidance of - doubt, where the Work is a sound recording, Licensor waives the - exclusive right to collect, whether individually or via a - performance-rights society (e.g. SoundExchange), royalties for the - public digital performance (e.g. webcast) of the Work, subject to - the compulsory license created by 17 USC Section 114 of the US - Copyright Act (or the equivalent in other jurisdictions). - -The above rights may be exercised in all media and formats whether now -known or hereafter devised. The above rights include the right to make -such modifications as are technically necessary to exercise the rights -in other media and formats. All rights not expressly granted by Licensor -are hereby reserved. - -*4. Restrictions.*The license granted in Section 3 above is expressly -made subject to and limited by the following restrictions: - - 1. You may distribute, publicly display, publicly perform, or - publicly digitally perform the Work only under the terms of this - License, and You must include a copy of, or the Uniform Resource - Identifier for, this License with every copy or phonorecord of the - Work You distribute, publicly display, publicly perform, or - publicly digitally perform. You may not offer or impose any terms - on the Work that alter or restrict the terms of this License or - the recipients' exercise of the rights granted hereunder. You may - not sublicense the Work. You must keep intact all notices that - refer to this License and to the disclaimer of warranties. You may - not distribute, publicly display, publicly perform, or publicly - digitally perform the Work with any technological measures that - control access or use of the Work in a manner inconsistent with - the terms of this License Agreement. The above applies to the Work - as incorporated in a Collective Work, but this does not require - the Collective Work apart from the Work itself to be made subject - to the terms of this License. If You create a Collective Work, - upon notice from any Licensor You must, to the extent practicable, - remove from the Collective Work any credit as required by clause - 4(b), as requested. If You create a Derivative Work, upon notice - from any Licensor You must, to the extent practicable, remove from - the Derivative Work any credit as required by clause 4(b), as - requested. - 2. If you distribute, publicly display, publicly perform, or publicly - digitally perform the Work or any Derivative Works or Collective - Works, You must keep intact all copyright notices for the Work and - provide, reasonable to the medium or means You are utilizing: (i) - the name of the Original Author (or pseudonym, if applicable) if - supplied, and/or (ii) if the Original Author and/or Licensor - designate another party or parties (e.g. a sponsor institute, - publishing entity, journal) for attribution in Licensor's - copyright notice, terms of service or by other reasonable means, - the name of such party or parties; the title of the Work if - supplied; to the extent reasonably practicable, the Uniform - Resource Identifier, if any, that Licensor specifies to be - associated with the Work, unless such URI does not refer to the - copyright notice or licensing information for the Work; and in the - case of a Derivative Work, a credit identifying the use of the - Work in the Derivative Work (e.g., "French translation of the Work - by Original Author," or "Screenplay based on original Work by - Original Author"). Such credit may be implemented in any - reasonable manner; provided, however, that in the case of a - Derivative Work or Collective Work, at a minimum such credit will - appear where any other comparable authorship credit appears and in - a manner at least as prominent as such other comparable authorship - credit. - -*5. Representations, Warranties and Disclaimer* - -UNLESS OTHERWISE MUTUALLY AGREED TO BY THE PARTIES IN WRITING, LICENSOR -OFFERS THE WORK AS-IS AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY -KIND CONCERNING THE WORK, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE, -INCLUDING, WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTIBILITY, -FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF -LATENT OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE OF ABSENCE OF ERRORS, -WHETHER OR NOT DISCOVERABLE. SOME JURISDICTIONS DO NOT ALLOW THE -EXCLUSION OF IMPLIED WARRANTIES, SO SUCH EXCLUSION MAY NOT APPLY TO YOU. - -*6. Limitation on Liability.* EXCEPT TO THE EXTENT REQUIRED BY -APPLICABLE LAW, IN NO EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY LEGAL -THEORY FOR ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY -DAMAGES ARISING OUT OF THIS LICENSE OR THE USE OF THE WORK, EVEN IF -LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - -*7. Termination* - - 1. This License and the rights granted hereunder will terminate - automatically upon any breach by You of the terms of this License. - Individuals or entities who have received Derivative Works or - Collective Works from You under this License, however, will not - have their licenses terminated provided such individuals or - entities remain in full compliance with those licenses. Sections - 1, 2, 5, 6, 7, and 8 will survive any termination of this License. - 2. Subject to the above terms and conditions, the license granted - here is perpetual (for the duration of the applicable copyright in - the Work). Notwithstanding the above, Licensor reserves the right - to release the Work under different license terms or to stop - distributing the Work at any time; provided, however that any such - election will not serve to withdraw this License (or any other - license that has been, or is required to be, granted under the - terms of this License), and this License will continue in full - force and effect unless terminated as stated above. - -*8. Miscellaneous* - - 1. Each time You distribute or publicly digitally perform the Work or - a Collective Work, the Licensor offers to the recipient a license - to the Work on the same terms and conditions as the license - granted to You under this License. - 2. Each time You distribute or publicly digitally perform a - Derivative Work, Licensor offers to the recipient a license to the - original Work on the same terms and conditions as the license - granted to You under this License. - 3. If any provision of this License is invalid or unenforceable under - applicable law, it shall not affect the validity or enforceability - of the remainder of the terms of this License, and without further - action by the parties to this agreement, such provision shall be - reformed to the minimum extent necessary to make such provision - valid and enforceable. - 4. No term or provision of this License shall be deemed waived and no - breach consented to unless such waiver or consent shall be in - writing and signed by the party to be charged with such waiver or - consent. - 5. This License constitutes the entire agreement between the parties - with respect to the Work licensed here. There are no - understandings, agreements or representations with respect to the - Work not specified here. Licensor shall not be bound by any - additional provisions that may appear in any communication from - You. This License may not be modified without the mutual written - agreement of the Licensor and You. - -Creative Commons is not a party to this License, and makes no warranty -whatsoever in connection with the Work. Creative Commons will not be -liable to You or any party on any legal theory for any damages -whatsoever, including without limitation any general, special, -incidental or consequential damages arising in connection to this -license. Notwithstanding the foregoing two (2) sentences, if Creative -Commons has expressly identified itself as the Licensor hereunder, it -shall have all rights and obligations of Licensor. - -Except for the limited purpose of indicating to the public that the Work -is licensed under the CCPL, neither party will use the trademark -"Creative Commons" or any related trademark or logo of Creative Commons -without the prior written consent of Creative Commons. Any permitted use -will be in compliance with Creative Commons' then-current trademark -usage guidelines, as may be published on its website or otherwise made -available upon request from time to time. - -Creative Commons may be contacted at http://creativecommons.org/ -<http://creativecommons.org>. - -« Back to Commons Deed <./> diff --git a/docs/tutorials/bfgwiki2/src/views/tutorial/templates/view.pt b/docs/tutorials/bfgwiki2/src/views/tutorial/templates/view.pt deleted file mode 100644 index f5037195f..000000000 --- a/docs/tutorials/bfgwiki2/src/views/tutorial/templates/view.pt +++ /dev/null @@ -1,28 +0,0 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" - "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> -<html - xmlns="http://www.w3.org/1999/xhtml" - xmlns:tal="http://xml.zope.org/namespaces/tal"> - -<head> - <meta content="text/html; charset=utf-8" http-equiv="Content-Type"/> - <title>${page.name} - bfg tutorial wiki - (based on TurboGears 20-Minute Wiki)</title> - <link rel="stylesheet" type="text/css" - href="${request.application_url}/static/style.css" /> -</head> - -<body> - -<div class="main_content"> -<div style="float:right; width: 10em;"> Viewing -<span tal:replace="page.name">Page Name Goes Here</span> <br/> -You can return to the <a href="${request.application_url}">FrontPage</a>. -</div> - -<div tal:replace="structure content">Page text goes here.</div> -<p><a tal:attributes="href edit_url" href="">Edit this page</a></p> -</div> - -</body> -</html> diff --git a/docs/tutorials/bfgwiki2/src/views/tutorial/tests.py b/docs/tutorials/bfgwiki2/src/views/tutorial/tests.py deleted file mode 100644 index 40336fca4..000000000 --- a/docs/tutorials/bfgwiki2/src/views/tutorial/tests.py +++ /dev/null @@ -1,140 +0,0 @@ -import unittest - -from pyramid.configuration import Configurator -from pyramid import testing - -def _initTestingDB(): - from tutorial.models import DBSession - from tutorial.models import Base - from sqlalchemy import create_engine - engine = create_engine('sqlite://') - DBSession.configure(bind=engine) - Base.metadata.bind = engine - Base.metadata.create_all(engine) - 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 = Configurator() - self.config.begin() - - def tearDown(self): - self.config.end() - - def test_it(self): - from tutorial.views import view_wiki - self.config.add_route('view_page', ':pagename') - request = testing.DummyRequest() - response = view_wiki(request) - self.assertEqual(response.location, 'http://example.com/FrontPage') - -class ViewPageTests(unittest.TestCase): - def setUp(self): - self.session = _initTestingDB() - self.config = Configurator() - self.config.begin() - - def tearDown(self): - self.session.remove() - self.config.end() - - 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('IDoExist', 'Hello CruelWorld IDoExist') - self.session.add(page) - _registerRoutes(self.config) - info = self._callFUT(request) - self.assertEqual(info['page'], page) - self.assertEqual( - info['content'], - '<div class="document">\n' - '<p>Hello <a href="http://example.com/add_page/CruelWorld">' - 'CruelWorld</a> ' - '<a href="http://example.com/IDoExist">' - 'IDoExist</a>' - '</p>\n</div>\n') - self.assertEqual(info['edit_url'], - 'http://example.com/IDoExist/edit_page') - - -class AddPageTests(unittest.TestCase): - def setUp(self): - self.session = _initTestingDB() - self.config = Configurator() - self.config.begin() - - def tearDown(self): - self.session.remove() - self.config.end() - - 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 = Configurator() - self.config.begin() - - def tearDown(self): - self.session.remove() - self.config.end() - - 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('abc', '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('abc', '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/bfgwiki2/src/views/tutorial/views.py b/docs/tutorials/bfgwiki2/src/views/tutorial/views.py deleted file mode 100644 index c0d793d38..000000000 --- a/docs/tutorials/bfgwiki2/src/views/tutorial/views.py +++ /dev/null @@ -1,65 +0,0 @@ -import re - -from docutils.core import publish_parts - -from webob.exc import HTTPFound - -from pyramid.url import route_url - -from tutorial.models import DBSession -from tutorial.models import Page - -# regular expression used to find WikiWords -wikiwords = re.compile(r"\b([A-Z]\w+[A-Z]+\w+)") - -def view_wiki(request): - return HTTPFound(location = route_url('view_page', request, - pagename='FrontPage')) - -def view_page(request): - matchdict = request.matchdict - session = DBSession() - page = session.query(Page).filter_by(name=matchdict['pagename']).one() - - def check(match): - word = match.group(1) - exists = session.query(Page).filter_by(name=word).all() - if exists: - view_url = route_url('view_page', request, pagename=word) - return '<a href="%s">%s</a>' % (view_url, word) - else: - add_url = route_url('add_page', request, pagename=word) - return '<a href="%s">%s</a>' % (add_url, word) - - content = publish_parts(page.data, writer_name='html')['html_body'] - content = wikiwords.sub(check, content) - edit_url = route_url('edit_page', request, - pagename=matchdict['pagename']) - return dict(page=page, content=content, edit_url=edit_url) - -def add_page(request): - name = request.matchdict['pagename'] - if 'form.submitted' in request.params: - session = DBSession() - body = request.params['body'] - page = Page(name, body) - session.add(page) - return HTTPFound(location = route_url('view_page', request, - pagename=name)) - save_url = route_url('add_page', request, pagename=name) - page = Page('', '') - return dict(page=page, save_url=save_url) - -def edit_page(request): - name = request.matchdict['pagename'] - session = DBSession() - page = session.query(Page).filter_by(name=name).one() - if 'form.submitted' in request.params: - page.data = request.params['body'] - session.add(page) - return HTTPFound(location = route_url('view_page', request, - pagename=name)) - return dict( - page=page, - save_url = route_url('edit_page', request, pagename=name), - ) |
