"""
Backend classes which all implement a save method with the following signature::
save(html, target)
The target can be a string specifying a target path, or some other kind of
object. The arguments to save are fields in the two-tuples returned by the
``seites.list_pages()`` function in your app.
"""
import os
try:
string = unicode
except NameError:
def string(b):
return b.decode('utf-8')
[docs]class AbstractSeitegeistBackend(object):
"""
Abstract definition of the interface for a Seitegeist backend.
Please subclass this and implement your own.
"""
def save(self, html, path):
raise NotImplementedError
[docs]class FilelikeBackend(AbstractSeitegeistBackend):
"""
FilelikeBackend writes the HTML to the target, which is a file-like object,
meaning it has a write(str) method.
Settings required for this backend::
SEITGEIST = {
"BACKEND": "seitegeist.backends.FilelikeBackend",
"BACKEND_ARGS": {},
}
When using this backend, the ``seites.list_pages()`` function in your app
should return something like this::
[('http://full.url/path/', StringIO.StringIO())]
Of course it doesn't have to be a ``StringIO``, but anything that can be
written to will work. Maybe you use ``sys.stdout`` to test your system, or
you write your own class with a ``write(str)`` method which writes the
rendered HTML to a remote service.
"""
def save(self, html, f):
"""Write the html to the provided file."""
f.write(string(html))
[docs]class DirectoryPathBackend(AbstractSeitegeistBackend):
"""
DirectoryPathBackend writes the HTML to a target file, provided by a path
string.
Settings required for this backend::
SEITGEIST = {
"BACKEND": "seitegeist.backends.DirectoryPathBackend",
"BACKEND_ARGS": {"path": "/path/to/prerendered/files"}
}
When using this backend, the ``seites.list_pages()`` function in your app
should return something like this::
[('http://full.url/a/path/', 'a/path')]
This will render the HTML from the URL and write it to the provided path
below the base path, in this case /path/to/prerendered/files/a/path.
"""
def __init__(self, path):
"""
Set the root path for this backend.
"""
# We don't create the root path for you. Error out.
assert os.path.exists(path), "{} does not seem to exist".format(path)
self.base_path = path
def save(self, html, path):
"""Write the html the the provided path"""
full_path = os.path.join(self.base_path, path)
dir_path = os.path.dirname(full_path)
try:
os.makedirs(dir_path)
except OSError: # Errors if the dir already exists
pass
# The folder SHOULD exist for sure at this point.
assert os.path.exists(dir_path), "Unable to create {}".format(dir_path)
with open(full_path, 'w') as f:
f.write(string(html))
# Try to import the Boto S3 libraries.
try:
from boto.s3.key import Key
from boto.s3.connection import S3Connection
except ImportError as importerror:
def Key(*args, **kwargs):
raise importerror
def S3Connection(*args, **kwargs):
raise importerror
[docs]class S3Backend(AbstractSeitegeistBackend):
"""
S3Backend writes the HTML to a target key path in an Amazon S3 bucket.
Settings required for this backend::
SEITGEIST = {
"BACKEND": "seitegeist.backends.S3Backend",
"BACKEND_ARGS": {
"access_key_id": "AMZID",
"secret_access_key": "THISISSECRET",
"bucket": "name-of-bucket",
},
}
The ``access_key_id`` arg should be your ``AWS_ACCESS_KEY_ID``, and the
``secret_access_key`` be the ``AWS_SECRET_ACCESS_KEY``, and the ``bucket``
is the name of the S3 bucket to upload to.
When using this backend, the ``seites.list_pages()`` function in your app
should return something like this::
[('http://full.url/a/path/', '/a/path')]
This will write the HTML from the URL to your S3 bucket as
https://s3.amazonaws.com/name-of-bucket/a/path.
The path will be the name of a key in your bucket. There is no provision at
this time to prefix the key.
"""
def __init__(self, access_key_id, secret_access_key, bucket):
"""
Use credentials and bucket name to create an S3 bucket handle for
this backend.
"""
conn = S3Connection(access_key_id, secret_access_key)
self.bucket = conn.get_bucket(bucket)
def save(self, html, path):
"""Write the HTML to an S3 bucket key."""
key = Key(self.bucket)
key.key = path
key.content_type = 'text/html'
key.set_contents_from_string(html)
key.set_acl('public-read')