diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..6c4daba --- /dev/null +++ b/.editorconfig @@ -0,0 +1,18 @@ +root = true + +[*] +charset = utf-8 +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true + +[*.{py,rst,ini}] +indent_style = space +indent_size = 4 + +[*.{html,css,scss,js,json,yml}] +indent_style = space +indent_size = 2 + +[*.md] +trim_trailing_whitespace = false diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..059fb00 --- /dev/null +++ b/.gitignore @@ -0,0 +1,24 @@ +*~ +*.DS_Store +*.lock +*.swp +*.out +*.pid +*.pyc +*.sql +*.sqlite +*.db +*.swp +*~ +__pycache__/ +/tmp/ +.bundle/ +.sass-cache/ +bower_components/ +bundle/ +dist/ +tests/ +node_modules/ +.env +npm-debug.log +newrelic.ini diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..3676160 --- /dev/null +++ b/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2015, ISL + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of ogs3proxy nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS 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 OWNER OR +CONTRIBUTORS 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. diff --git a/Procfile b/Procfile new file mode 100644 index 0000000..4422e5a --- /dev/null +++ b/Procfile @@ -0,0 +1,2 @@ +web: waitress-serve --port=$PORT web:app + diff --git a/README.md b/README.md new file mode 100644 index 0000000..ebff9c4 --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +# Open Graph S3 Proxy + +Try [locally](http://localhost:8000/2015/07/islco-peterCorbett@2x-500x500.jpg?fb) diff --git a/app.json b/app.json new file mode 100644 index 0000000..0d64df0 --- /dev/null +++ b/app.json @@ -0,0 +1,25 @@ +{ + "name": "ogs3proxy", + "env":{ + "REDIRECT_URL": { + "description": "URL for non-Facebook redirects" + }, + "OG_TITLE": { + "description": "Object Open Graph title" + }, + "OG_DESCRIPTION": { + "description": "Object Open Graph description" + }, + "S3_BUCKET": { + "description": "The S3 bucket to pull images from" + }, + "SECRET_KEY": { + "generator": "secret" + } + }, + "buildpacks": [ + { + "url": "https://github.com/heroku/heroku-buildpack-python" + } + ] +} diff --git a/env.example b/env.example new file mode 100644 index 0000000..62a9507 --- /dev/null +++ b/env.example @@ -0,0 +1,9 @@ +PORT=8000 +DEBUG=True + +S3_BUCKET=media.isl.co +OG_TITLE=A digital agency founded on invention. +OG_DESCRIPTION=ISL invents digital & physical experiences for the world’s biggest brands. Our designers, developers, marketers and makers build everything from apps, to connected devices, to wildly creative campaigns that reach audiences globally. Take a look for yourself! +REDIRECT_URL=https://isl.co + +SECRET_KEY=notasecret diff --git a/mo.yml b/mo.yml new file mode 100644 index 0000000..93ea5ad --- /dev/null +++ b/mo.yml @@ -0,0 +1,4 @@ +domain: ogs3proxy.herokuapp.com +heroku: + staging: ogs3proxy-staging + production: ogs3proxy-prod diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..7bffc9e --- /dev/null +++ b/requirements.txt @@ -0,0 +1,3 @@ +Flask==0.10.1 +waitress==0.8.10 +python-decouple==2.3 diff --git a/runtime.txt b/runtime.txt new file mode 100644 index 0000000..bc42bd0 --- /dev/null +++ b/runtime.txt @@ -0,0 +1 @@ +python-3.4.2 diff --git a/templates/opengraph.html b/templates/opengraph.html new file mode 100644 index 0000000..224372b --- /dev/null +++ b/templates/opengraph.html @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/web.py b/web.py new file mode 100644 index 0000000..8c9c58d --- /dev/null +++ b/web.py @@ -0,0 +1,46 @@ +from decouple import config +from flask import Flask, redirect, render_template, request + +try: + from urlparse import urljoin +except ImportError: + from urllib.parse import urljoin + +S3_BUCKET = config('S3_BUCKET') +REDIRECT_URL = config('REDIRECT_URL') +OG_TITLE = config('OG_TITLE') +OG_DESCRIPTION = config('OG_DESCRIPTION') + +S3_ROOT = 'https://s3.amazonaws.com/' + +app = Flask(__name__) + + +def is_facebook(ua): + return ua.startswith('facebookexternalhit') or ua == 'Facebot' + + +@app.route("/", methods=['GET']) +def opengraph(path): + + ua = request.headers.get('User-Agent') + + if is_facebook(ua) or 'fb' in request.args: + + context = { + 'og_title': OG_TITLE, + 'og_description': OG_DESCRIPTION, + 'og_image': urljoin(S3_ROOT, '{}/{}'.format(S3_BUCKET, path)), + 'og_url': REDIRECT_URL, + } + return render_template('opengraph.html', **context) + + else: + + return redirect(REDIRECT_URL) + + +if __name__ == "__main__": + DEBUG = config('DEBUG', default=False, cast=bool) + PORT = config('PORT', default=8000, cast=int) + app.run(debug=DEBUG, port=PORT)