Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Link to ipynb #10

Closed
wants to merge 11 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 14 additions & 14 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
BOOTSTRAP = ./static/assets/css/bootstrap.css
BOOTSTRAP = ./static/css/bootstrap.css
BOOTSTRAP_LESS = ./less/bootstrap.less
BOOTSTRAP_RESPONSIVE = ./static/assets/css/bootstrap-responsive.css
BOOTSTRAP_RESPONSIVE = ./static/css/bootstrap-responsive.css
BOOTSTRAP_RESPONSIVE_LESS = ./less/responsive.less
DATE=$(shell date +%I:%M%p)
CHECK=\033[32m✔\033[39m
Expand All @@ -10,6 +10,7 @@ HR=\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\
#
# BUILD DOCS
#
.PHONY: build

build:
@echo "\n${HR}"
Expand All @@ -21,16 +22,15 @@ build:
@recess --compile ${BOOTSTRAP_LESS} > ${BOOTSTRAP}
@recess --compile ${BOOTSTRAP_RESPONSIVE_LESS} > ${BOOTSTRAP_RESPONSIVE}
@echo "Compiling LESS with Recess... ${CHECK} Done"
@node static/build
@cp img/* static/assets/img/
@cp js/*.js static/assets/js/
@cp js/tests/vendor/jquery.js static/assets/js/
@cp img/* static/img/
@cp js/*.js static/js/
@cp js/tests/vendor/jquery.js static/js/
@echo "Compiling documentation... ${CHECK} Done"
@cat js/bootstrap-transition.js js/bootstrap-alert.js js/bootstrap-button.js js/bootstrap-carousel.js js/bootstrap-collapse.js js/bootstrap-dropdown.js js/bootstrap-modal.js js/bootstrap-tooltip.js js/bootstrap-popover.js js/bootstrap-scrollspy.js js/bootstrap-tab.js js/bootstrap-typeahead.js > static/assets/js/bootstrap.js
@uglifyjs -nc static/assets/js/bootstrap.js > static/assets/js/bootstrap.min.tmp.js
@echo "/**\n* Bootstrap.js by @fat & @mdo\n* Copyright 2012 Twitter, Inc.\n* http://www.apache.org/licenses/LICENSE-2.0.txt\n*/" > static/assets/js/copyright.js
@cat static/assets/js/copyright.js static/assets/js/bootstrap.min.tmp.js > static/assets/js/bootstrap.min.js
@rm static/assets/js/copyright.js static/assets/js/bootstrap.min.tmp.js
@cat js/bootstrap-transition.js js/bootstrap-alert.js js/bootstrap-button.js js/bootstrap-carousel.js js/bootstrap-collapse.js js/bootstrap-dropdown.js js/bootstrap-modal.js js/bootstrap-tooltip.js js/bootstrap-popover.js js/bootstrap-scrollspy.js js/bootstrap-tab.js js/bootstrap-typeahead.js > static/js/bootstrap.js
@uglifyjs -nc static/js/bootstrap.js > static/js/bootstrap.min.tmp.js
@echo "/**\n* Bootstrap.js by @fat & @mdo\n* Copyright 2012 Twitter, Inc.\n* http://www.apache.org/licenses/LICENSE-2.0.txt\n*/" > static/js/copyright.js
@cat static/js/copyright.js static/js/bootstrap.min.tmp.js > static/js/bootstrap.min.js
@rm static/js/copyright.js static/js/bootstrap.min.tmp.js
@echo "Compiling and minifying javascript... ${CHECK} Done"
@echo "\n${HR}"
@echo "Bootstrap successfully built at ${DATE}."
Expand Down Expand Up @@ -75,10 +75,10 @@ bootstrap:
#

gh-pages: bootstrap static
rm -f static/assets/bootstrap.zip
zip -r static/assets/bootstrap.zip bootstrap
rm -f static/bootstrap.zip
zip -r static/bootstrap.zip bootstrap
rm -r bootstrap
rm -f ../bootstrap-gh-pages/assets/bootstrap.zip
rm -f ../bootstrap-gh-pages/bootstrap.zip
node static/build production
cp -r static/* ../bootstrap-gh-pages

Expand Down
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,9 @@ so you will need some dependency like `node`,`uglify-js`.
* any required python package should be availlable via `pip`, and should be added to `requirement.txt`.
see `pip freeze` to know what to write in the file.
* local debug mode is activated by creating a `.debug` file in the root directory, `.debug` is excluded in `.gitignore`and `.slugignore`


Copying
-------

This project is under BSD liscence. Some files are copyind from Twitter Bootstrap Project and so are under Apache Licence. See `Licence-bootstrap`.
115 changes: 6 additions & 109 deletions app.py
Original file line number Diff line number Diff line change
@@ -1,118 +1,15 @@
from gist import app as gist
import os
from flask import Flask , request, render_template
import nbconvert.nbconvert as nbconvert
import requests
from nbformat import current as nbformat
from flask import Flask, redirect, abort
import re

app = Flask(__name__)


def static(strng) :
return open('static/'+strng).read()

@app.route('/')
def hello():
return static('index.html')


@app.route('/assets/<path:path>', methods=['GET'])
def sitemap(path):
return open('static/assets/'+path).read()


@app.errorhandler(500)
def page_not_found(error):
return static('500.html'),500

@app.errorhandler(404)
def page_not_found(error):
return static('404.html'),404

@app.route('/404')
def four_o_foru():
abort(404)

@app.route('/500')
def four_o_foru():
abort(500)

@app.route('/create/',methods=['POST'])
def create(v=None):
value = request.form['gistnorurl']
if v and not value:
value = v
if re.match('^[0-9]+$',value):
return redirect('/'+value)
gist = re.search(r'^https?://gist.github.com/([0-9]+)$',value)
if gist:
return redirect('/'+gist.group(1))
if value.startswith('https://') and value.endswith('.ipynb'):
return redirect('/urls/'+value[8:])

if value.startswith('http://') and value.endswith('.ipynb'):
return redirect('/url/'+value[7:])

return static('unknown_filetype.html')

#https !
@app.route('/urls/<path:url>')
def render_urls(url):
try :
r = requests.get('https://'+url)
except Exception as e :
abort(404)
return(render_request(r))

#http !
@app.route('/url/<path:url>')
def render_url(url):
try :
r = requests.get('http://'+url)
except Exception as e :
abort(404)

return(render_request(r))


def render_request(r):
try:
if r.status_code != 200:
abort(404)
converter = nbconvert.ConverterHTML()
converter.nb = nbformat.reads_json(r.content)
result = converter.convert()
return result
except :
abort(404)


@app.route('/<int:id>')
def fetch_and_render(id):
"""Fetch and render a post from the Github API"""
r = requests.get('https://api.github.com/gists/{}'.format(id))

if r.status_code != 200:
return None
try :
decoded = r.json.copy()
jsonipynb = decoded['files'].values()[0]['content']

converter = nbconvert.ConverterHTML()
converter.nb = nbformat.reads_json(jsonipynb)
result = converter.convert()
except ValueError as e :
abort(404)

return result

if __name__ == '__main__':
# Bind to PORT if defined, otherwise default to 5000.
port = int(os.environ.get('PORT', 5000))
debug = os.path.exists('.debug')
debugfile = os.path.exists('.debug')
debugenv = os.environ.get('DEBUG', False) == 'True'
debug = debugfile or debugenv
print 'url scheme' , os.environ.get('URL_SCHEME', None)
if debug :
print 'DEBUG MODE IS ACTIVATED !!!'
else :
print 'debug is not activated'
app.run(host='0.0.0.0', port=port, debug=debug)
gist.run(host='0.0.0.0', port=port, debug=debug)
191 changes: 191 additions & 0 deletions gist.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
import os
from flask import Flask , request, render_template
import nbconvert.nbconvert as nbconvert
import requests
from flask import Response
from nbformat import current as nbformat
from flask import Flask, redirect, abort
import re

app = Flask(__name__)

try :
import pylibmc
mc = pylibmc.Client(["127.0.0.1"], binary=True,
behaviors={"tcp_nodelay": True,
"ketama": True})

def cachedfirstparam(function):

def wrapper(*args, **kw):
if len(args)+len(kw) != 1:
return function(*args, **kw)
else :
key = kw.values()[0] if kw else args[0]
skey = str(key)+str(function.__name__)
mcv = mc.get(skey)
#mcv = None
if mcv :
return mcv
else :
value = function(key)
mc.set(skey, value, time=600)
return value
return wrapper

except :
def cachedfirstparam(fun):
return fun

@cachedfirstparam
def static(strng) :
return open('static/'+strng).read()

@app.route('/')
def hello():
return render_template('index.html')


@app.errorhandler(500)
def internal_error(error):
return render_template('500.html'), 500

@app.errorhandler(404)
def page_not_found(error):
return render_template('404.html'), 404

@app.route('/404')
def four_o_foru():
abort(404)

@app.route('/500')
def fiveoo():
abort(500)

@app.route('/create/', methods=['POST'])
def create(v=None):
value = request.form['gistnorurl']
if v and not value:
value = v
if re.match('^[0-9]+$', value):
return redirect('/'+value)
gist = re.search(r'^https?://gist.github.com/([0-9]+)$', value)
if gist:
return redirect('/'+gist.group(1))
if value.startswith('https://') and value.endswith('.ipynb'):
return redirect('/urls/'+value[8:])

if value.startswith('http://') and value.endswith('.ipynb'):
return redirect('/url/'+value[7:])

return render_template('unknown_filetype.html')

#https !
@cachedfirstparam
def cachedget(url):
try :
r = requests.get(url)
if r.status_code is not 200 :
abort(404)
return r.content
except Exception :
abort(404)



@cachedfirstparam
@app.route('/urls/<path:url>')
def render_urls(url):
url = 'https://'+url
content = cachedget(url)
return render_content(content, url)

#http !
@cachedfirstparam
@app.route('/url/<path:url>')
def render_url(url):
url = 'http://'+url
content = cachedget(url)
return render_content(content, url)


@cachedfirstparam
def render_request(r=None):
try:
if r.status_code != 200:
abort(404)
return render_content(r.content)
except :
abort(404)

other_views = """<div style="position:absolute; right:1em; top:1em; padding:0.4em; border:1px dashed black;">
<a href="{url}">Download notebook</a>
</div>"""

def render_content(content, url):
converter = nbconvert.ConverterHTML()
converter.extra_body_start_html = other_views.format(url=url)
converter.nb = nbformat.reads_json(content)
return converter.convert()


@cachedfirstparam
@app.route('/<int:id>/')
def fetch_and_render(id=None):
"""Fetch and render a post from the Github API"""
if id is None :
return redirect('/')

r = requests.get('https://api.github.com/gists/{}'.format(id))

if r.status_code != 200:
abort(404)
try :
decoded = r.json.copy()
files = decoded['files'].values()
if len(files) == 1 :
jsonipynb = files[0]['content']
return render_content(jsonipynb, files[0]['raw_url'])
else :
entries = []
for file in files :
entry = {}
entry['path'] = file['filename']
entry['url'] = '/%s/%s' %( id,file['filename'])
entries.append(entry)
return render_template('gistlist.html', entries=entries)
except ValueError as e :
abort(404)

return result


@app.route('/<int:id>/<subfile>')
def gistsubfile(id, subfile):
"""Fetch and render a post from the Github API"""

r = requests.get('https://api.github.com/gists/{}'.format(id))

if r.status_code != 200:
abort(404)
try :
decoded = r.json.copy()
files = decoded['files'].values()
thefile = [f for f in files if f['filename'] == subfile]
jsonipynb = thefile[0]['content']
if subfile.endswith('.ipynb'):
return render_content(jsonipynb, thefile[0]['raw_url'])
else :
return Response(jsonipynb, mimetype='text/plain')
except ValueError as e :
abort(404)

if __name__ == '__main__':
# Bind to PORT if defined, otherwise default to 5000.
port = int(os.environ.get('PORT', 5000))
debug = os.path.exists('.debug')
if debug :
print 'DEBUG MODE IS ACTIVATED !!!'
else :
print 'debug is not activated'
app.run(host='0.0.0.0', port=port, debug=debug)
3 changes: 0 additions & 3 deletions hlog

This file was deleted.

1 change: 0 additions & 1 deletion less/tests/navbar.html
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
<![endif]-->

<!-- Le fav and touch icons -->
<link rel="shortcut icon" href="../../docs/assets/ico/favicon.ico">
<link rel="apple-touch-icon-precomposed" sizes="144x144" href="../../docs/assets/ico/apple-touch-icon-144-precomposed.png">
<link rel="apple-touch-icon-precomposed" sizes="114x114" href="../../docs/assets/ico/apple-touch-icon-114-precomposed.png">
<link rel="apple-touch-icon-precomposed" sizes="72x72" href="../../docs/assets/ico/apple-touch-icon-72-precomposed.png">
Expand Down
Loading