-
-
Save coleifer/62c6e55e9aa6d1e745ac 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
{% extends "pastebin/base.html" %} | |
{% block title %}Pastebin{% endblock %} | |
{% block content_title %}Add paste{% endblock %} | |
{% block content %} | |
<form method="post" action="{{ url_for('pastebin.add') }}"> | |
{% for field in form %} | |
<p>{{ field.label }} {{ field }}</p> | |
{% endfor %} | |
<p><button type="submit">Add</button> | |
<a href="{{ url_for('pastebin.list') }}">Cancel</a> | |
</p> | |
</form> | |
{% endblock %} |
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
{% extends "base.html" %} | |
{% block extra_head %} | |
<link rel=stylesheet type=text/css href="{{ url_for('pastebin.static', filename='hilite.css') }}" /> | |
{% endblock %} |
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 datetime | |
import hashlib | |
from flask import request, redirect, url_for, render_template, Blueprint, Response | |
from peewee import * | |
from pygments import formatters, highlight, lexers | |
from wtfpeewee.orm import model_form | |
from flaskext.rest import RestResource | |
from flaskext.utils import get_object_or_404, object_list | |
from app import app, db | |
from auth import auth | |
class Paste(db.Model): | |
filename = CharField() | |
content = TextField() | |
highlighted = TextField() | |
created_date = DateTimeField(default=datetime.datetime.now) | |
sha = CharField() | |
class Meta: | |
ordering = (('created_date', 'desc'),) | |
def __unicode__(self): | |
return self.filename | |
def save(self): | |
self.highlighted = self.highlight() | |
self.sha = hashlib.sha1(self.content).hexdigest() | |
super(Paste, self).save() | |
def highlight(self): | |
lexer = None | |
try: | |
lexer = lexers.get_lexer_for_filename(self.filename) | |
except lexers.ClassNotFound: | |
lexer = lexers.guess_lexer(self.content) | |
formatter = formatters.HtmlFormatter(linenos=True) | |
return highlight(self.content, lexer, formatter) | |
pastebin = Blueprint('pastebin', __name__, static_folder='static', template_folder='templates') | |
@pastebin.route('/') | |
@auth.login_required | |
def list(): | |
qr = Paste.select() | |
return object_list('pastebin/index.html', qr) | |
@pastebin.route('/add/', methods=['GET', 'POST']) | |
@auth.login_required | |
def add(): | |
Form = model_form(Paste, only=('filename', 'content',)) | |
if request.method == 'POST': | |
form = Form(request.form) | |
if form.validate(): | |
instance = Paste() | |
form.populate_obj(instance) | |
instance.save() | |
return redirect(url_for('pastebin.list')) | |
else: | |
form = Form() | |
return render_template('pastebin/add.html', form=form) | |
@pastebin.route('/<sha>/') | |
def detail(sha): | |
paste = get_object_or_404(Paste, sha=sha) | |
return render_template('pastebin/detail.html', paste=paste) | |
@pastebin.route('/<sha>/raw/') | |
def detail_raw(sha): | |
paste = get_object_or_404(Paste, sha=sha) | |
return Response(paste.content) | |
@pastebin.route('/<sha>/delete/', methods=['GET', 'POST']) | |
@auth.login_required | |
def delete(sha): | |
paste = get_object_or_404(Paste, sha=sha) | |
if request.method == 'POST': | |
paste.delete_instance() | |
return redirect(url_for('pastebin.list')) | |
return render_template('pastebin/delete.html', paste=paste) | |
class PasteResource(RestResource): | |
exclude = ('highlighted',) |
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
{% extends "pastebin/base.html" %} | |
{% block title %}Pastebin | {{ paste.filename }}{% endblock %} | |
{% block content_title %}Delete {{ paste.filename }}?{% endblock %} | |
{% block content %} | |
<form method="post" action="{{ url_for('pastebin.delete', sha=paste.sha) }}"> | |
<p> | |
<button type="submit">Delete</button> | |
<a href="{{ url_for('pastebin.list') }}">Cancel</a> | |
</p> | |
</form> | |
{% endblock %} |
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
{% extends "pastebin/base.html" %} | |
{% block title %}Pastebin | {{ paste.filename }}{% endblock %} | |
{% block content_title %}{{ paste.filename }}{% endblock %} | |
{% block content %} | |
{% if user %} | |
<p style="float: left;"><a href="{{ url_for('pastebin.list') }}">« back</a></p> | |
<p style="text-align: right;"><a href="{{ url_for('pastebin.add') }}">Add new</a></p> | |
{% endif %} | |
<p>{{ paste.sha }}, created {{ paste.created_date.strftime('%Y-%m-%d %H:%M') }}</p> | |
{% autoescape off %} | |
{{ paste.highlighted }} | |
{% endautoescape %} | |
{% if user %} | |
<form method="post" action="{{ url_for('pastebin.delete', sha=paste.sha) }}"> | |
<p><button type="submit">Delete</button></p> | |
</form> | |
{% endif %} | |
{% endblock %} |
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
.hll { background-color: #ffffcc } | |
.c { color: #999988; font-style: italic } /* Comment */ | |
.err { color: #a61717; background-color: #e3d2d2 } /* Error */ | |
.k { font-weight: bold } /* Keyword */ | |
.o { font-weight: bold } /* Operator */ | |
.cm { color: #999988; font-style: italic } /* Comment.Multiline */ | |
.cp { color: #444444; font-weight: bold } /* Comment.Preproc */ | |
.c1 { color: #999988; font-style: italic } /* Comment.Single */ | |
.cs { color: #444444; font-weight: bold; font-style: italic } /* Comment.Special */ | |
.gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */ | |
.ge { font-style: italic } /* Generic.Emph */ | |
.gr { color: #aa0000 } /* Generic.Error */ | |
.gh { color: #444444 } /* Generic.Heading */ | |
.gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */ | |
.go { color: #888888 } /* Generic.Output */ | |
.gp { color: #555555 } /* Generic.Prompt */ | |
.gs { font-weight: bold } /* Generic.Strong */ | |
.gu { color: #aaaaaa } /* Generic.Subheading */ | |
.gt { color: #aa0000 } /* Generic.Traceback */ | |
.kc { font-weight: bold } /* Keyword.Constant */ | |
.kd { font-weight: bold } /* Keyword.Declaration */ | |
.kn { font-weight: bold } /* Keyword.Namespace */ | |
.kp { font-weight: bold } /* Keyword.Pseudo */ | |
.kr { font-weight: bold } /* Keyword.Reserved */ | |
.kt { color: #445588; font-weight: bold } /* Keyword.Type */ | |
.m { color: #009999 } /* Literal.Number */ | |
.s { color: #bb8844 } /* Literal.String */ | |
.na { color: #008080 } /* Name.Attribute */ | |
.nb { color: #444444 } /* Name.Builtin */ | |
.nc { color: #445588; font-weight: bold } /* Name.Class */ | |
.no { color: #008080 } /* Name.Constant */ | |
.ni { color: #800080 } /* Name.Entity */ | |
.ne { color: #990000; font-weight: bold } /* Name.Exception */ | |
.nf { color: #990000; font-weight: bold } /* Name.Function */ | |
.nn { color: #555555 } /* Name.Namespace */ | |
.nt { color: #000080 } /* Name.Tag */ | |
.nv { color: #008080 } /* Name.Variable */ | |
.ow { font-weight: bold } /* Operator.Word */ | |
.w { color: #bbbbbb } /* Text.Whitespace */ | |
.mf { color: #009999 } /* Literal.Number.Float */ | |
.mh { color: #009999 } /* Literal.Number.Hex */ | |
.mi { color: #009999 } /* Literal.Number.Integer */ | |
.mo { color: #009999 } /* Literal.Number.Oct */ | |
.sb { color: #bb8844 } /* Literal.String.Backtick */ | |
.sc { color: #bb8844 } /* Literal.String.Char */ | |
.sd { color: #bb8844 } /* Literal.String.Doc */ | |
.s2 { color: #bb8844 } /* Literal.String.Double */ | |
.se { color: #bb8844 } /* Literal.String.Escape */ | |
.sh { color: #bb8844 } /* Literal.String.Heredoc */ | |
.si { color: #bb8844 } /* Literal.String.Interpol */ | |
.sx { color: #bb8844 } /* Literal.String.Other */ | |
.sr { color: #808000 } /* Literal.String.Regex */ | |
.s1 { color: #bb8844 } /* Literal.String.Single */ | |
.ss { color: #bb8844 } /* Literal.String.Symbol */ | |
.bp { color: #444444 } /* Name.Builtin.Pseudo */ | |
.vc { color: #008080 } /* Name.Variable.Class */ | |
.vg { color: #008080 } /* Name.Variable.Global */ | |
.vi { color: #008080 } /* Name.Variable.Instance */ | |
.il { color: #009999 } /* Literal.Number.Integer.Long */ |
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
{% extends "pastebin/base.html" %} | |
{% block title %}Pastebin{% endblock %} | |
{% block content_title %}Pastebin{% endblock %} | |
{% block content %} | |
{% if user %} | |
<p style="text-align: right;"><a href="{{ url_for('pastebin.add') }}">Add new</a></p> | |
{% endif %} | |
<ul> | |
{% for paste in object_list %} | |
<li><p><a href="{{ url_for('pastebin.detail', sha=paste.sha) }}">{{ paste.filename }}</a>, {{ paste.created_date.strftime('%Y-%m-%d %H:%M') }}</p> | |
<pre>{{ paste.content[:60] }}</pre> | |
</li> | |
{% endfor %} | |
</ul> | |
{% include "includes/pagination.html" %} | |
{% endblock %} |
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
#!/usr/bin/env python | |
# gitconfig | |
# paste.user / paste.key | |
# env | |
# PASTE_USER PASTE_KEY | |
import datetime | |
import httplib2 | |
import json | |
import optparse | |
import os | |
import subprocess | |
import sys | |
ENDPOINT = 'http://<your site>/api/paste/' | |
URL_TEMPLATE = 'http://<your site>/pastebin/%s/' | |
def get_credentials(options): | |
if options.user and options.key: | |
return [options.user, options.key] | |
elif 'PASTE_USER' in os.environ and 'PASTE_KEY' in os.environ: | |
return [os.environ['PASTE_USER'], os.environ['PASTE_KEY']] | |
else: | |
data = [] | |
for piece in ('user', 'key'): | |
p = subprocess.Popen(['git', 'config', '--global', 'paste.%s' % piece], stdout=subprocess.PIPE) | |
data.append(p.communicate()[0].strip()) | |
return data | |
def post_file(user, key, filename, content): | |
sock = httplib2.Http() | |
sock.add_credentials(user, key) | |
headers, resp = sock.request(ENDPOINT, 'POST', json.dumps({ | |
'filename': filename, | |
'content': content, | |
})) | |
if headers['status'] == '200': | |
resp_data = json.loads(resp) | |
print URL_TEMPLATE % resp_data['sha'] | |
else: | |
print 'Error: %s' % headers['status'] | |
print resp | |
def main(user, key, args): | |
if args: | |
for filename in args: | |
fh = open(filename) | |
post_file(user, key, os.path.basename(filename), fh.read()) | |
else: | |
now = datetime.datetime.now() | |
post_file(user, key, now.strftime('%Y-%m-%d %H:%M:%S'), sys.stdin.read()) | |
if __name__ == '__main__': | |
parser = optparse.OptionParser() | |
parser.add_option('-u', '--user', dest='user') | |
parser.add_option('-k', '--key', dest='key') | |
options, args = parser.parse_args() | |
user, key = get_credentials(options) | |
if not user or not key: | |
print 'Error: unable to determine user or api key' | |
sys.exit(1) | |
main(user, key, args) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment