Created
June 12, 2014 19:03
-
-
Save andrewebdev/1193efbf7cc9b870133b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import os | |
import base64 | |
from subprocess import call | |
from django import http | |
from django.conf import settings | |
from django_seo_js.backends import SEOBackendBase | |
SITE_CONF = getattr(settings, 'SITE_CONF') | |
BASE_URL = "%s%s" % (SITE_CONF['protocol'], SITE_CONF['domain']) | |
SNAPSHOTS_DIR = getattr(settings, 'SNAPSHOTS_DIR') | |
PHANTOM_RUNNER = os.path.join(os.path.dirname(__file__), 'phantom-runner.js') | |
## Backends | |
class PhantomJSBackend(SEOBackendBase): | |
""" | |
A custom backend for django-seo-js that will use phantomjs to | |
render the page, and store it in a predefined location. | |
""" | |
def get_response_for_url(self, url): | |
""" | |
Accepts a fully-qualified url. | |
Returns an HttpResponse, passing through all headers and the status code. | |
""" | |
if not url or "//" not in url: | |
raise ValueError("Missing or invalid url: %s" % url) | |
fragment = url.split('_escaped_fragment_=')[1] | |
return self.render_phantomjs_response(fragment) | |
def update_url(self, url): | |
""" | |
Force an update of the cache for a particular URL. | |
Returns True on success, False on fail. | |
""" | |
self._get_or_create_snapshot(url, force_update=True) | |
return True | |
def _get_fragment_hash(self, fragment): | |
return base64.urlsafe_b64encode(fragment) | |
def _get_or_create_snapshot(self, fragment, force_update=False): | |
""" | |
Generate and cache the html for URL using phantomjs. | |
""" | |
outfile = os.path.join( | |
SNAPSHOTS_DIR, "%s.html" % self._get_fragment_hash(fragment)) | |
url = "%s/#\!%s" % (BASE_URL, fragment) # note we are escaping the '!' | |
if not os.path.exists(outfile) or force_update: | |
phantom_cmd = 'phantomjs %s %s > %s' % (PHANTOM_RUNNER, url, outfile) | |
call(phantom_cmd, shell=True) | |
return outfile | |
def render_phantomjs_response(self, fragment): | |
""" | |
Tries to return the requested snapshot. If it does not exist, | |
generate it first, save it, then return it. | |
""" | |
snapshot_file = self._get_or_create_snapshot(fragment) | |
snapshot_content = open(snapshot_file, 'rb').read() | |
return http.HttpResponse(snapshot_content, content_type="text/html") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment