Skip to content
Browse files

initial commit

  • Loading branch information...
0 parents commit dceb8c5670f9bba928e46f5d75d8419b18528d45 @mcdonc mcdonc committed Aug 11, 2011
Showing with 887 additions and 0 deletions.
  1. +14 −0 .gitignore
  2. +4 −0 CHANGES.txt
  3. +100 −0 CONTRIBUTORS.txt
  4. +2 −0 COPYRIGHT.txt
  5. +38 −0 LICENSE.txt
  6. +6 −0 README.rst
  7. +3 −0 docs/.gitignore
  8. +88 −0 docs/Makefile
  9. +11 −0 docs/api.rst
  10. +210 −0 docs/conf.py
  11. +17 −0 docs/glossary.rst
  12. +110 −0 docs/index.rst
  13. +67 −0 pyramid_errmail/__init__.py
  14. +125 −0 pyramid_errmail/tests.py
  15. +9 −0 setup.cfg
  16. +55 −0 setup.py
  17. +28 −0 tox.ini
14 .gitignore
@@ -0,0 +1,14 @@
+*.egg
+*.egg-info
+*.pyc
+*$py.class
+*.pt.py
+*.txt.py
+*~
+.coverage
+build/
+dist/
+.tox/
+nosetests.xml
+pyramid_tm/coverage.xml
+env26/
4 CHANGES.txt
@@ -0,0 +1,4 @@
+Initial release
+---------------
+
+- ...
100 CONTRIBUTORS.txt
@@ -0,0 +1,100 @@
+Pylons Project Contributor Agreement
+====================================
+
+The submitter agrees by adding his or her name within the section below named
+"Contributors" and submitting the resulting modified document to the
+canonical shared repository location for this software project (whether
+directly, as a user with "direct commit access", or via a "pull request"), he
+or she is signing a contract electronically. The submitter becomes a
+Contributor after a) he or she signs this document by adding their name
+beneath the "Contributors" section below, and b) the resulting document is
+accepted into the canonical version control repository.
+
+Treatment of Account
+---------------------
+
+Contributor will not allow anyone other than the Contributor to use his or
+her username or source repository login to submit code to a Pylons Project
+source repository. Should Contributor become aware of any such use,
+Contributor will immediately by notifying Agendaless Consulting.
+Notification must be performed by sending an email to
+webmaster@agendaless.com. Until such notice is received, Contributor will be
+presumed to have taken all actions made through Contributor's account. If the
+Contributor has direct commit access, Agendaless Consulting will have
+complete control and discretion over capabilities assigned to Contributor's
+account, and may disable Contributor's account for any reason at any time.
+
+Legal Effect of Contribution
+----------------------------
+
+Upon submitting a change or new work to a Pylons Project source Repository (a
+"Contribution"), you agree to assign, and hereby do assign, a one-half
+interest of all right, title and interest in and to copyright and other
+intellectual property rights with respect to your new and original portions
+of the Contribution to Agendaless Consulting. You and Agendaless Consulting
+each agree that the other shall be free to exercise any and all exclusive
+rights in and to the Contribution, without accounting to one another,
+including without limitation, the right to license the Contribution to others
+under the Repoze Public License. This agreement shall run with title to the
+Contribution. Agendaless Consulting does not convey to you any right, title
+or interest in or to the Program or such portions of the Contribution that
+were taken from the Program. Your transmission of a submission to the Pylons
+Project source Repository and marks of identification concerning the
+Contribution itself constitute your intent to contribute and your assignment
+of the work in accordance with the provisions of this Agreement.
+
+License Terms
+-------------
+
+Code committed to the Pylons Project source repository (Committed Code) must
+be governed by the Repoze Public License (http://repoze.org/LICENSE.txt, aka
+"the RPL") or another license acceptable to Agendaless Consulting. Until
+Agendaless Consulting declares in writing an acceptable license other than
+the RPL, only the RPL shall be used. A list of exceptions is detailed within
+the "Licensing Exceptions" section of this document, if one exists.
+
+Representations, Warranty, and Indemnification
+----------------------------------------------
+
+Contributor represents and warrants that the Committed Code does not violate
+the rights of any person or entity, and that the Contributor has legal
+authority to enter into this Agreement and legal authority over Contributed
+Code. Further, Contributor indemnifies Agendaless Consulting against
+violations.
+
+Cryptography
+------------
+
+Contributor understands that cryptographic code may be subject to government
+regulations with which Agendaless Consulting and/or entities using Committed
+Code must comply. Any code which contains any of the items listed below must
+not be checked-in until Agendaless Consulting staff has been notified and has
+approved such contribution in writing.
+
+- Cryptographic capabilities or features
+
+- Calls to cryptographic features
+
+- User interface elements which provide context relating to cryptography
+
+- Code which may, under casual inspection, appear to be cryptographic.
+
+Notices
+-------
+
+Contributor confirms that any notices required will be included in any
+Committed Code.
+
+List of Contributors
+====================
+
+The below-signed are contributors to a code repository that is part of the
+project named "pyramid_errmail". Each below-signed contributor has read,
+understand and agrees to the terms above in the section within this document
+entitled "Pylons Project Contributor Agreement" as of the date beside his or
+her name.
+
+Contributors
+------------
+
+- Chris McDonough, 2011/08/11
2 COPYRIGHT.txt
@@ -0,0 +1,2 @@
+Copyright (c) 2008-2011 Agendaless Consulting and Contributors.
+(http://www.agendaless.com), All Rights Reserved
38 LICENSE.txt
@@ -0,0 +1,38 @@
+A copyright notice accompanies this license document that identifies
+the copyright holders.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+1. Redistributions in source code must retain the accompanying
+ copyright notice, this list of conditions, and the following
+ disclaimer.
+
+2. Redistributions in binary form must reproduce the accompanying
+ copyright notice, this list of conditions, and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution.
+
+3. Names of the copyright holders must not be used to endorse or
+ promote products derived from this software without prior
+ written permission from the copyright holders.
+
+4. If any files are modified, you must cause the modified files to
+ carry prominent notices stating that you changed the files and
+ the date of any change.
+
+Disclaimer
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND
+ ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ HOLDERS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+ THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
6 README.rst
@@ -0,0 +1,6 @@
+``pyramid_errmail``
+===================
+
+A package which sends email when an exception occurs in your Pyramid
+application.
+
3 docs/.gitignore
@@ -0,0 +1,3 @@
+_themes
+_build/
+.static
88 docs/Makefile
@@ -0,0 +1,88 @@
+# Makefile for Sphinx documentation
+#
+
+# You can set these variables from the command line.
+SPHINXOPTS =
+SPHINXBUILD = sphinx-build
+PAPER =
+
+# Internal variables.
+PAPEROPT_a4 = -D latex_paper_size=a4
+PAPEROPT_letter = -D latex_paper_size=letter
+ALLSPHINXOPTS = -d _build/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
+
+.PHONY: help clean html web pickle htmlhelp latex changes linkcheck
+
+help:
+ @echo "Please use \`make <target>' where <target> is one of"
+ @echo " html to make standalone HTML files"
+ @echo " pickle to make pickle files (usable by e.g. sphinx-web)"
+ @echo " htmlhelp to make HTML files and a HTML help project"
+ @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
+ @echo " changes to make an overview over all changed/added/deprecated items"
+ @echo " linkcheck to check all external links for integrity"
+
+clean:
+ -rm -rf _build/*
+
+html: _themes/
+ mkdir -p _build/html _build/doctrees
+ $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) _build/html
+ @echo
+ @echo "Build finished. The HTML pages are in _build/html."
+
+text:
+ mkdir -p _build/text _build/doctrees
+ $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) _build/text
+ @echo
+ @echo "Build finished. The HTML pages are in _build/text."
+
+pickle:
+ mkdir -p _build/pickle _build/doctrees
+ $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) _build/pickle
+ @echo
+ @echo "Build finished; now you can process the pickle files or run"
+ @echo " sphinx-web _build/pickle"
+ @echo "to start the sphinx-web server."
+
+web: pickle
+
+htmlhelp: _themes
+ mkdir -p _build/htmlhelp _build/doctrees
+ $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) _build/htmlhelp
+ @echo
+ @echo "Build finished; now you can run HTML Help Workshop with the" \
+ ".hhp project file in _build/htmlhelp."
+
+latex:
+ mkdir -p _build/latex _build/doctrees
+ $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) _build/latex
+ cp _static/*.png _build/latex
+ ./convert_images.sh
+ cp _static/latex-warning.png _build/latex
+ cp _static/latex-note.png _build/latex
+ @echo
+ @echo "Build finished; the LaTeX files are in _build/latex."
+ @echo "Run \`make all-pdf' or \`make all-ps' in that directory to" \
+ "run these through (pdf)latex."
+
+changes:
+ mkdir -p _build/changes _build/doctrees
+ $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) _build/changes
+ @echo
+ @echo "The overview file is in _build/changes."
+
+linkcheck:
+ mkdir -p _build/linkcheck _build/doctrees
+ $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) _build/linkcheck
+ @echo
+ @echo "Link check complete; look for any errors in the above output " \
+ "or in _build/linkcheck/output.txt."
+
+epub:
+ $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) _build/epub
+ @echo
+ @echo "Build finished. The epub file is in _build/epub."
+
+_themes:
+ git clone git://github.com/Pylons/pylons_sphinx_theme.git _themes
11 docs/api.rst
@@ -0,0 +1,11 @@
+.. _pyramid_tm_api:
+
+:mod:`pyramid_errmail` API
+---------------------------
+
+.. automodule:: pyramid_errmail
+
+.. autofunction:: includeme
+
+
+
210 docs/conf.py
@@ -0,0 +1,210 @@
+# -*- coding: utf-8 -*-
+#
+# pyramid_errmail documentation build configuration file
+#
+# This file is execfile()d with the current directory set to its containing
+# dir.
+#
+# The contents of this file are pickled, so don't put values in the
+# namespace that aren't pickleable (module imports are okay, they're
+# removed automatically).
+#
+# All configuration values have a default value; values that are commented
+# out serve to show the default value.
+
+# If your extensions are in another directory, add it here. If the
+# directory is relative to the documentation root, use os.path.abspath to
+# make it absolute, like shown here.
+#sys.path.append(os.path.abspath('some/directory'))
+
+import sys, os
+
+parent = os.path.dirname(os.path.dirname(__file__))
+sys.path.append(os.path.abspath(parent))
+wd = os.getcwd()
+os.chdir(parent)
+os.system('%s setup.py test -q' % sys.executable)
+os.chdir(wd)
+
+for item in os.listdir(parent):
+ if item.endswith('.egg'):
+ sys.path.append(os.path.join(parent, item))
+
+# General configuration
+# ---------------------
+
+# Add any Sphinx extension module names here, as strings. They can be
+# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
+extensions = [
+ 'sphinx.ext.autodoc',
+ 'sphinx.ext.intersphinx',
+ ]
+
+# Looks for pyramid's objects
+intersphinx_mapping = {
+ 'pyramid':
+ ('http://docs.pylonsproject.org/projects/pyramid/dev/', None)}
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = ['.templates']
+
+# The suffix of source filenames.
+source_suffix = '.rst'
+
+# The master toctree document.
+master_doc = 'index'
+
+# General substitutions.
+project = 'pyramid_errmail'
+copyright = '2011, Agendaless Consulting <chrism@plope.com>'
+
+# The default replacements for |version| and |release|, also used in various
+# other places throughout the built documents.
+#
+# The short X.Y version.
+version = '0.2'
+# The full version, including alpha/beta/rc tags.
+release = version
+
+# There are two options for replacing |today|: either, you set today to
+# some non-false value, then it is used:
+#today = ''
+# Else, today_fmt is used as the format for a strftime call.
+today_fmt = '%B %d, %Y'
+
+# List of documents that shouldn't be included in the build.
+#unused_docs = []
+
+# List of directories, relative to source directories, that shouldn't be
+# searched for source files.
+#exclude_dirs = []
+
+# The reST default role (used for this markup: `text`) to use for all
+# documents.
+#default_role = None
+
+# If true, '()' will be appended to :func: etc. cross-reference text.
+#add_function_parentheses = True
+
+# If true, the current module name will be prepended to all description
+# unit titles (such as .. function::).
+#add_module_names = True
+
+# If true, sectionauthor and moduleauthor directives will be shown in the
+# output. They are ignored by default.
+#show_authors = False
+
+# The name of the Pygments (syntax highlighting) style to use.
+pygments_style = 'sphinx'
+
+
+# Options for HTML output
+# -----------------------
+
+# Add and use Pylons theme
+sys.path.append(os.path.abspath('_themes'))
+html_theme_path = ['_themes']
+html_theme = 'pyramid'
+html_theme_options = dict(github_url='http://github.com/Pylons/pyramid_errmail')
+
+# The style sheet to use for HTML and HTML Help pages. A file of that name
+# must exist either in Sphinx' static/ path, or in one of the custom paths
+# given in html_static_path.
+# html_style = 'repoze.css'
+
+# The name for this set of Sphinx documents. If None, it defaults to
+# "<project> v<release> documentation".
+#html_title = None
+
+# A shorter title for the navigation bar. Default is the same as
+# html_title.
+#html_short_title = None
+
+# The name of an image file (within the static path) to place at the top of
+# the sidebar.
+# html_logo = '.static/logo_hi.gif'
+
+# The name of an image file (within the static path) to use as favicon of
+# the docs. This file should be a Windows icon file (.ico) being 16x16 or
+# 32x32 pixels large.
+#html_favicon = None
+
+# Add any paths that contain custom static files (such as style sheets)
+# here, relative to this directory. They are copied after the builtin
+# static files, so a file named "default.css" will overwrite the builtin
+# "default.css".
+#html_static_path = ['.static']
+
+# If not '', a 'Last updated on:' timestamp is inserted at every page
+# bottom, using the given strftime format.
+html_last_updated_fmt = '%b %d, %Y'
+
+# If true, SmartyPants will be used to convert quotes and dashes to
+# typographically correct entities.
+#html_use_smartypants = True
+
+# Custom sidebar templates, maps document names to template names.
+#html_sidebars = {}
+
+# Additional templates that should be rendered to pages, maps page names to
+# template names.
+#html_additional_pages = {}
+
+# If false, no module index is generated.
+#html_use_modindex = True
+
+# If false, no index is generated.
+#html_use_index = True
+
+# If true, the index is split into individual pages for each letter.
+#html_split_index = False
+
+# If true, the reST sources are included in the HTML build as
+# _sources/<name>.
+#html_copy_source = True
+
+# If true, an OpenSearch description file will be output, and all pages
+# will contain a <link> tag referring to it. The value of this option must
+# be the base URL from which the finished HTML is served.
+#html_use_opensearch = ''
+
+# If nonempty, this is the file name suffix for HTML files (e.g. ".xhtml").
+#html_file_suffix = ''
+
+# Output file base name for HTML help builder.
+htmlhelp_basename = 'atemplatedoc'
+
+
+# Options for LaTeX output
+# ------------------------
+
+# The paper size ('letter' or 'a4').
+#latex_paper_size = 'letter'
+
+# The font size ('10pt', '11pt' or '12pt').
+#latex_font_size = '10pt'
+
+# Grouping the document tree into LaTeX files. List of tuples
+# (source start file, target name, title,
+# author, document class [howto/manual]).
+latex_documents = [
+ ('index', 'pyramid_errmail.tex', 'pyramid_errmail Documentation',
+ 'Repoze Developers', 'manual'),
+]
+
+# The name of an image file (relative to this directory) to place at the
+# top of the title page.
+latex_logo = '.static/logo_hi.gif'
+
+# For "manual" documents, if this is true, then toplevel headings are
+# parts, not chapters.
+#latex_use_parts = False
+
+# Additional stuff for the LaTeX preamble.
+#latex_preamble = ''
+
+# Documents to append as an appendix to all manuals.
+#latex_appendices = []
+
+# If false, no module index is generated.
+#latex_use_modindex = True
17 docs/glossary.rst
@@ -0,0 +1,17 @@
+.. _glossary:
+
+Glossary
+========
+
+.. glossary::
+ :sorted:
+
+ Pyramid
+ A `web framework <http://pylonsproject.org>`_.
+
+ pyramid_mailer
+ A `Pyramid add on
+ <https://docs.pylonsproject.org/projects/pyramid_mailer/dev/>`_ used by
+ the error mailer to send mail.
+
+.
110 docs/index.rst
@@ -0,0 +1,110 @@
+pyramid_errmail
+===============
+
+Overview
+--------
+
+A package which sends email when an exception occurs in your Pyramid
+application.
+
+Installation
+------------
+
+Install using setuptools, e.g. (within a virtualenv)::
+
+ $ easy_install pyramid_errmail
+
+Setup
+-----
+
+Once ``pyramid_errmail`` is installed, you must use the ``config.include``
+mechanism to include it into your Pyramid project's configuration. In your
+Pyramid project's ``__init__.py``:
+
+.. code-block:: python
+ :linenos:
+
+ config = Configurator(.....)
+ config.include('pyramid_errmail')
+
+Alternately you can use the ``pyramid.includes`` configuration value in your
+``.ini`` file:
+
+.. code-block:: python
+ :linenos:
+
+ pyramid.includes = pyramid_errmail
+
+Using
+-----
+
+This package uses the :term:`pyramid_mailer` package to send mail. It uses
+the mailer settings from that package to determine the SMTP host and port,
+and other mailout-related configuration. See that package for those
+settings.
+
+However it has some knobs, in the form of configuration settings (usually in
+the application section of your ``.ini`` file).
+
+``pyramid_errmail.catchall``
+
+ If this value is ``true``, catch and report all errors, even those that
+ might later be caught by a Pyramid exception view. Otherwise, only
+ exceptions that are not caught by a Pyramid exception view are emailed.
+
+``pyramid_errmail.sender``
+
+ The email address of the sender. If this setting is not set, a default
+ sender address will be used.
+
+``pyramid_errmail.recipients``
+
+ A carriage-return-separated list of recipients for the error emails. If
+ this setting is not set, no email will be sent.
+
+``pyramid_errmail.subject``
+
+ The subject line of each email. If this setting is not set, the subject
+ line will consist of the exception title.
+
+Explicit Tween Configuration
+----------------------------
+
+Note that the error mailer is a Pyramid "tween", and it can be used in the
+explicit tween list if its implicit position in the tween chain is incorrect
+(see the output of ``paster ptweens``)::
+
+ [app:myapp]
+ pyramid.tweens = someothertween
+ pyramid.tweens.excview_tween_factory
+ pyramid_errmail.errmail_tween_factory
+
+It usually belongs directly above the "MAIN" entry in the ``paster ptweens``
+output, and will attempt to sort there by default as the result of having
+``include('pyramid_errmail')`` invoked.
+
+More Information
+----------------
+
+.. toctree::
+ :maxdepth: 1
+
+ api.rst
+ glossary.rst
+
+
+Reporting Bugs / Development Versions
+-------------------------------------
+
+Visit http://github.com/Pylons/pyramid_errmail to download development or
+tagged versions.
+
+Visit http://github.com/Pylons/pyramid_errmail/issues to report bugs.
+
+Indices and tables
+------------------
+
+* :ref:`glossary`
+* :ref:`genindex`
+* :ref:`modindex`
+* :ref:`search`
67 pyramid_errmail/__init__.py
@@ -0,0 +1,67 @@
+import sys
+import traceback
+from functools import partial
+
+from pyramid.tweens import EXCVIEW
+from pyramid.settings import asbool
+
+from pyramid_mailer.message import Message
+from pyramid_mailer import get_mailer
+
+def errmail_tween_factory(handler, registry):
+
+ sender = registry.settings.get('pyramid_errmail.sender',
+ 'Pyramid <no-reply@example.com>')
+ recipients = registry.settings.get('pyramid_errmail.recipients')
+ subject = registry.settings.get('pyramid_errmail.subject')
+
+ if recipients is None:
+ return handler
+
+ recipients = [ x.strip() for x in recipients.splitlines() ]
+
+ if not recipients:
+ return handler
+
+ def errmail_tween(request, subject=subject):
+ try:
+ return handler(request)
+ except Exception, e:
+ mailer = get_mailer(request)
+ if subject is None:
+ subject = repr(e)
+ body = ''.join(traceback.format_exception(*sys.exc_info()))
+ message = Message(subject=subject,
+ sender=sender,
+ recipients=recipients,
+ body=body)
+ mailer.send_immediately(message, fail_silently=True)
+ raise
+
+ return errmail_tween
+
+def includeme(config):
+ """
+ Set up am implicit 'tween' to send emails when an exception is raised by
+ your Pyramid application.
+
+ By default this tween configured to be place 'above' the exception view
+ tween, which will cause only exceptions which are not caught by an
+ exception view to be mailed.
+
+ The tween can alternately be configured to be placed between the main
+ Pyramid app and the Pyramid exception view tween, which will cause *all*
+ exceptions (even those eventually caught by a Pyramid exception view,
+ which will include exceptions such as ``HTTPFound`` and others
+ signifiying redirects) to be mailed. To turn this feature on, use the
+ ``pyramid_errmail.catchall`` configuration setting with a value of
+ ``true``.
+ """
+ config.include('pyramid_mailer')
+ catchall = config.registry.settings.get('pyramid_errmail.catchall','false')
+ catchall = asbool(catchall)
+ add = partial(config.add_tween, errmail_tween_factory, alias='errmail')
+ if catchall:
+ add(under=EXCVIEW)
+ else:
+ add(over=EXCVIEW)
125 pyramid_errmail/tests.py
@@ -0,0 +1,125 @@
+import unittest
+from pyramid import testing
+
+class Test_errmail_tween_factory(unittest.TestCase):
+ def setUp(self):
+ self.config = testing.setUp()
+ self.registry = self.config.registry
+
+ def handler(self, request): pass
+
+ def _callFUT(self, handler=None, registry=None):
+ from pyramid_errmail import errmail_tween_factory
+ if handler is None:
+ handler = self.handler
+ if registry is None:
+ registry = self.registry
+ return errmail_tween_factory(handler, registry)
+
+ def test_no_recipients(self):
+ handler = self._callFUT()
+ self.assertEqual(handler, self.handler)
+
+ def test_empty_recipients(self):
+ self.registry.settings['pyramid_errmail.recipients'] = ''
+ handler = self._callFUT()
+ self.assertEqual(handler, self.handler)
+
+ def test_normal_recipients(self):
+ self.registry.settings['pyramid_errmail.recipients']='chrism@plope.com'
+ handler = self._callFUT()
+ self.assertNotEqual(handler, self.handler)
+
+
+class Test_errmail_tween(unittest.TestCase):
+ def setUp(self):
+ from pyramid.request import Request
+ request = Request.blank('/')
+ self.request = request
+ self.config = testing.setUp(request=request)
+ self.registry = self.config.registry
+ self.registry.settings['pyramid_errmail.recipients'] = 'chrism'
+ request.registry = self.registry
+
+ def _setupMailer(self):
+ from pyramid_mailer.testing import includeme
+ includeme(self.config)
+
+ def handler(self, request):
+ raise NotImplementedError
+
+ def _callFUT(self, handler=None, registry=None, request=None):
+ from pyramid_errmail import errmail_tween_factory
+ if handler is None:
+ handler = self.handler
+ if registry is None:
+ registry = self.registry
+ if request is None:
+ request = self.request
+ tween = errmail_tween_factory(handler, registry)
+ return tween(request)
+
+ def test_nomailer(self):
+ from zope.component.registry import ComponentLookupError
+ self.assertRaises(ComponentLookupError, self._callFUT)
+
+
+ def test_nosubject(self):
+ from pyramid_mailer import get_mailer
+ self._setupMailer()
+ self.assertRaises(NotImplementedError, self._callFUT)
+ mailer = get_mailer(self.request)
+ self.assertEqual(len(mailer.outbox), 1)
+ message = mailer.outbox[0]
+ self.assertEqual(message.sender, 'Pyramid <no-reply@example.com>')
+
+ def test_withsubject(self):
+ from pyramid_mailer import get_mailer
+ self.registry.settings['pyramid_errmail.sender'] = 'chris'
+ self._setupMailer()
+ self.assertRaises(NotImplementedError, self._callFUT)
+ mailer = get_mailer(self.request)
+ self.assertEqual(len(mailer.outbox), 1)
+ message = mailer.outbox[0]
+ self.assertEqual(message.sender, 'chris')
+ self.assertTrue('Traceback' in message.body)
+ self.assertEqual(message.recipients, ['chrism'])
+
+class Test_includeme(unittest.TestCase):
+ def _callFUT(self, config):
+ from pyramid_errmail import includeme
+ return includeme(config)
+
+ def test_it(self):
+ from pyramid_errmail import errmail_tween_factory
+ from pyramid.tweens import EXCVIEW
+ config = DummyConfig()
+ self._callFUT(config)
+ self.assertEqual(config.tweens,
+ [(errmail_tween_factory, 'errmail', None, EXCVIEW)])
+ self.assertEqual(config.included, ['pyramid_mailer'])
+
+ def test_it_catchall(self):
+ from pyramid_errmail import errmail_tween_factory
+ from pyramid.tweens import EXCVIEW
+ config = DummyConfig()
+ config.settings['pyramid_errmail.catchall'] = 'true'
+ self._callFUT(config)
+ self.assertEqual(config.tweens,
+ [(errmail_tween_factory, 'errmail', EXCVIEW, None)])
+ self.assertEqual(config.included, ['pyramid_mailer'])
+
+
+class DummyConfig(object):
+ def __init__(self):
+ self.tweens = []
+ self.included = []
+ self.registry = self
+ self.settings = {}
+
+ def add_tween(self, factory, alias=None, under=None, over=None):
+ self.tweens.append((factory, alias, under, over))
+
+ def include(self, path):
+ self.included.append(path)
+
9 setup.cfg
@@ -0,0 +1,9 @@
+[easy_install]
+zip_ok = false
+
+[nosetests]
+match=^test
+where=pyramid_errmail
+nocapture=1
+cover-package=pyramid_errmail
+cover-erase=1
55 setup.py
@@ -0,0 +1,55 @@
+##############################################################################
+#
+# Copyright (c) 2008-2011 Agendaless Consulting and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the BSD-like license at
+# http://www.repoze.org/LICENSE.txt. A copy of the license should accompany
+# this distribution. THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL
+# EXPRESS OR IMPLIED WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO,
+# THE IMPLIED WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND
+# FITNESS FOR A PARTICULAR PURPOSE
+#
+##############################################################################
+
+import os
+
+from setuptools import setup, find_packages
+
+here = os.path.abspath(os.path.dirname(__file__))
+try:
+ README = open(os.path.join(here, 'README.rst')).read()
+ CHANGES = open(os.path.join(here, 'CHANGES.txt')).read()
+except IOError:
+ README = CHANGES = ''
+
+install_requires = [
+ 'pyramid>=1.2dev',
+ 'pyramid_mailer',
+ ]
+
+setup(name='pyramid_errmail',
+ version='0.0',
+ description=('A package which sends email when an exception is raised '
+ 'by a Pyramid application'),
+ long_description=README + '\n\n' + CHANGES,
+ classifiers=[
+ "Intended Audience :: Developers",
+ "Programming Language :: Python",
+ "Framework :: Pylons",
+ "Topic :: Internet :: WWW/HTTP :: WSGI",
+ "License :: Repoze Public License",
+ ],
+ keywords='wsgi pylons pyramid mail tween exception handler',
+ author="Chris McDonough",
+ author_email="pylons-devel@googlegroups.com",
+ url="http://docs.pylonsproject.org",
+ license="BSD-derived (http://www.repoze.org/LICENSE.txt)",
+ packages=find_packages(),
+ include_package_data=True,
+ zip_safe=False,
+ install_requires=install_requires,
+ tests_require=install_requires,
+ test_suite="pyramid_errmail",
+ entry_points='',
+ )
28 tox.ini
@@ -0,0 +1,28 @@
+[tox]
+envlist =
+ py25,py26,py27,jython,pypy,cover
+
+[testenv]
+commands =
+ python setup.py test -q
+
+[testenv:jython]
+commands =
+ jython setup.py test -q
+
+[testenv:cover]
+basepython =
+ python2.6
+commands =
+ python setup.py nosetests --with-xunit --with-xcoverage
+deps =
+ nose
+ coverage==3.4
+ nosexcover
+
+
+# we separate coverage into its own testenv because a) "last run wins" wrt
+# cobertura jenkins reporting and b) pypy and jython can't handle any
+# combination of versions of coverage and nosexcover that i can find.
+# coverage==3.4 is required by nosexcover.
+

0 comments on commit dceb8c5

Please sign in to comment.
Something went wrong with that request. Please try again.