Merge pull request #145 from nicksergeant/heroku

Docker -> Heroku.
master
Nick Sergeant 2014-10-20 23:35:12 -04:00
commit 742252a729
37 changed files with 271 additions and 491 deletions

14
.gitignore vendored
View File

@ -8,5 +8,17 @@ venv
settings_local.py
media/cache
static
tags
media/css/pro.css
media/css/snipt.css
media/js/src/account.min.js
media/js/src/snipts.min.js
media/js/src/search.min.js
media/js/src/jobs.min.js
media/js/src/application.min.js
media/js/src/modules/site.min.js
media/js/src/modules/snipt.min.js
media/js/src/pro.min.js
media/js/snipt-all.min.js
media/js/pro-all.min.js

View File

@ -1,21 +0,0 @@
FROM debian:jessie
ENV DEBIAN_FRONTEND noninteractive
RUN apt-get update && apt-get install -y \
build-essential \
python \
python-dev \
python-setuptools \
git-core \
mercurial \
libxml2-dev \
libxslt-dev \
libpq-dev
RUN easy_install pip
COPY . /app/snipt
RUN pip install -r /app/snipt/requirements.txt
RUN pip install --index-url https://code.stripe.com --upgrade stripe
ADD .docker/run.sh /docker-run
RUN mkdir -p /tmp/app
WORKDIR /app/snipt
EXPOSE 8000
CMD ["/docker-run"]

68
Makefile Normal file
View File

@ -0,0 +1,68 @@
deploy:
@git push heroku heroku:master
deploy-with-assets:
@cat media/css/bootstrap.min.css \
media/css/blog-themes/pro-adams/style.css \
media/css/highlightjs-themes/tomorrow.css \
media/css/themes.css \
> media/css/pro.css
@cat media/css/bootstrap.min.css \
media/css/style.css \
media/css/themes.css \
media/css/chosen.css \
media/css/codemirror.css \
media/css/codemirror-themes/ambiance.css \
media/css/codemirror-themes/blackboard.css \
media/css/codemirror-themes/cobalt.css \
media/css/codemirror-themes/eclipse.css \
media/css/codemirror-themes/elegant.css \
media/css/codemirror-themes/erlang-dark.css \
media/css/codemirror-themes/lesser-dark.css \
media/css/codemirror-themes/monokai.css \
media/css/codemirror-themes/neat.css \
media/css/codemirror-themes/night.css \
media/css/codemirror-themes/rubyblue.css \
media/css/codemirror-themes/solarized.css \
media/css/codemirror-themes/twilight.css \
media/css/codemirror-themes/vibrant-ink.css \
media/css/codemirror-themes/xq-dark.css \
media/css/highlightjs-themes/tomorrow.css \
media/css/blog-themes/default/style.css \
> media/css/snipt.css
@cat media/js/src/account.js|jsmin > media/js/src/account.min.js
@cat media/js/src/snipts.js|jsmin > media/js/src/snipts.min.js
@cat media/js/src/search.js|jsmin > media/js/src/search.min.js
@cat media/js/src/jobs.js|jsmin > media/js/src/jobs.min.js
@cat media/js/src/application.js|jsmin > media/js/src/application.min.js
@cat media/js/src/modules/site.js|jsmin > media/js/src/modules/site.min.js
@cat media/js/src/modules/snipt.js|jsmin > media/js/src/modules/snipt.min.js
@cat media/js/src/pro.js|jsmin > media/js/src/pro.min.js
@cat media/js/libs/jquery.min.js \
media/js/libs/jquery-ui.min.js \
media/js/libs/angular.min.js \
media/js/libs/angular-route.min.js \
media/js/libs/underscore.js \
media/js/libs/json2.js \
media/js/libs/backbone.js \
media/js/libs/bootstrap.min.js \
media/js/plugins/jquery.hotkeys.js \
media/js/plugins/jquery.infieldlabel.js \
media/js/plugins/jquery.chosen.js \
media/js/src/application.min.js \
media/js/src/modules/site.min.js \
media/js/src/modules/snipt.min.js \
media/js/src/account.min.js \
media/js/src/snipts.min.js \
media/js/src/search.min.js \
media/js/src/jobs.min.js \
media/js/libs/codemirror.js \
media/js/libs/highlight.js \
> media/js/snipt-all.min.js
@cat media/js/libs/highlight.js \
media/js/src/pro.js \
> media/js/pro-all.min.js
/Users/Nick/.virtualenvs/snipt/bin/python manage.py collectstatic --noinput
@git push heroku heroku:master
.PHONY: deploy, deploy-with-assets

1
Procfile Normal file
View File

@ -0,0 +1 @@
web: gunicorn wsgi --log-file -

View File

@ -2,22 +2,36 @@
This is the codebase for the website, [Snipt.net](https://snipt.net/).
It's a relatively well-kept Django app, so you shouldn't have too many problems getting a local copy running.
**Note:** These instructions assume you already have [Git](http://git-scm.com/) and [Mercurial](http://mercurial.selenic.com/) installed.
If you need help, visit `#snipt` on irc.freenode.net.
# Running the Django app
1. Clone the repo.
2. Setup a virtualenv.
3. `pip install -r requirements.txt`
4. `pip install --index-url https://code.stripe.com --upgrade stripe`
5. Copy settings_local-template.py to settings_local.py and edit the settings. Be sure to change the [`SESSION_COOKIE_DOMAIN`](https://github.com/nicksergeant/snipt/blob/master/settings_local-template.py#L58), or authentication won't work.
6. `python manage.py syncdb`
7. `python manage.py migrate`
8. `python manage.py runserver`
9. If you created a superuser in the syncdb step, you need to also run `python manage.py backfill_api_keys` to generate an API key for that user.
5. `python manage.py syncdb`
6. `python manage.py migrate`
7. `python manage.py runserver`
8. If you created a superuser in the syncdb step, you need to also run `python manage.py backfill_api_keys` to generate an API key for that user.
# Deploying to Heroku
1. Clone the repo.
2. `heroku create`
3. `heroku addons:add heroku-postgresql:standard-0`
4. `heroku addons:add bonsai`
5. `heroku config:add AWS_ACCESS_KEY_ID=`
6. `heroku config:add AWS_SECRET_ACCESS_KEY=`
7. `heroku config:add AWS_STORAGE_BUCKET_NAME=`
8. `heroku config:add DEBUG=False`
9. `heroku config:add INTERCOM_SECRET_KEY=`
9. `heroku config:add POSTMARK_API_KEY=`
11. `heroku config:add RAVEN_CONFIG_DSN=`
12. `heroku config:add SECRET_KEY=`
13. `heroku config:add STRIPE_SECRET_KEY=`
14. `heroku config:add USE_SSL=False`
15. `git push heroku`
16. `heroku run pip install --index-url https://code.stripe.com --upgrade stripe`
17. `heroku run python manage.py syncdb`
18. `heroku run python manage.py migrate`
Any problems / questions / bugs, [create an issue](https://github.com/nicksergeant/snipt/issues). Thanks! :)

View File

@ -2,9 +2,7 @@ from django.contrib.auth.decorators import login_required
from annoying.decorators import ajax_request, render_to
from snipts.models import Snipt
import stripe
from settings_local import STRIPE_SECRET_KEY
import os, stripe
@login_required
@ -20,7 +18,7 @@ def cancel_subscription(request):
if request.user.profile.stripe_id is None:
return {}
else:
stripe.api_key = STRIPE_SECRET_KEY
stripe.api_key = os.environ.get('STRIPE_SECRET_KEY', '')
customer = stripe.Customer.retrieve(request.user.profile.stripe_id)
customer.delete()
@ -38,7 +36,7 @@ def stripe_account_details(request):
if request.user.profile.stripe_id is None:
return {}
else:
stripe.api_key = STRIPE_SECRET_KEY
stripe.api_key = os.environ.get('STRIPE_SECRET_KEY', '')
customer = stripe.Customer.retrieve(request.user.profile.stripe_id)
data = {

View File

@ -35,7 +35,7 @@
<link rel="stylesheet" type="text/css" href="{{ STATIC_URL }}css/pro.css?26" />
{% endif %}
<link rel="shortcut icon" href="/static/img/blog-favicon.ico" >
<link rel="shortcut icon" href="{{ STATIC_URL }}img/blog-favicon.ico" >
{% if custom_css %}
<style type="text/css">

83
fabfile.py vendored
View File

@ -1,83 +0,0 @@
#!/usr/bin/env python
# -- coding: utf-8 --
from fabric.api import cd, local, env, run, sudo
from boto.s3.connection import S3Connection
from boto.s3.key import Key
import datetime, hashlib, sys
from settings_local import AMAZON_API_KEY, AMAZON_API_SECRET, ENV_HOST
env.hosts = [ENV_HOST]
env.site_path = '/home/nick/snipt'
def dep():
local('python manage.py collectstatic --ignore cache --noinput')
try:
local('git push')
except:
pass
with cd(env.site_path):
run('git pull')
run('/home/nick/snipt/.docker/control.sh collectstatic')
run('/home/nick/snipt/.docker/control.sh deploy')
def db_backup():
conn = S3Connection(AMAZON_API_KEY, AMAZON_API_SECRET)
snipt_bucket = conn.get_bucket('snipt')
k = Key(snipt_bucket)
k.key = filename
k.set_contents_from_filename('/tmp/snipt.pgdump')
local('rm {}'.format('/tmp/snipt.pgdump'))
def db():
with cd(env.site_path):
run('/home/nick/snipt/.docker/control.sh syncdb')
run('/home/nick/snipt/.docker/control.sh migrate')
def gravatars():
from fabric.contrib import django
django.settings_module('settings')
from django.contrib.auth.models import User
import requests
for user in User.objects.all().order_by('id'):
email_md5 = hashlib.md5(user.email.lower()).hexdigest()
print 'Email MD5: {}'.format(email_md5)
greq = requests.get('https://secure.gravatar.com/avatar/{}?s=50&d=404'.format(email_md5))
if greq.status_code == 404:
has_gravatar = False
else:
has_gravatar = True
profile = user.profile
profile.has_gravatar = has_gravatar
profile.save()
try:
from fabric.colors import green, red
if has_gravatar:
print 'Has Gravatar: {}'.format(green(has_gravatar))
else:
print 'Has Gravatar: {}'.format(red(has_gravatar))
except ImportError:
print 'Has Gravatar: {}'.format(has_gravatar)
def re():
with cd(env.site_path):
run('/home/nick/snipt/.docker/control.sh restart')

32
fig.yml
View File

@ -1,32 +0,0 @@
postgres:
image: postgres:9.1
expose:
- "5432"
elasticsearch:
image: arcus/elasticsearch
expose:
- "9200"
- "9300"
app:
build: .
links:
- postgres:db
- elasticsearch:es
ports:
- "8000:80"
expose:
- "8000"
environment:
- DB_NAME=postgres
- DB_USER=postgres
proxy:
image: nginx
ports:
- "80"
volumes:
- .docker/nginx.conf:/etc/nginx.conf
- static:/app/snipt/static
net: "container:snipt_app_1"

View File

@ -1,12 +0,0 @@
bind = "0.0.0.0:8000"
daemon = False # Whether work in the background
debug = False # Some extra logging
logfile = ".gunicorn.log" # Name of the log file
loglevel = "info" # The level at which to log
pidfile = ".gunicorn.pid" # Path to a PID file
workers = 9 # Number of workers to initialize
umask = 0 # Umask to set when daemonizing
user = None # Change process owner to user
group = None # Change process group to group
proc_name = "gunicorn-snipt" # Change the process name
tmp_upload_dir = None # Set path used to store temporary uploads

View File

@ -1 +1 @@
body.blog-site article.snipt div.group div.container{width:718px}body.blog-site article.snipt div.group div.container header{min-height:0}body.blog-site article.snipt div.group div.container header h1{margin:11px 15px}body.blog-site article.snipt footer ul.attrs li.tweet{margin-right:30px}body.blog-site section.main div.ruler{z-index:50}body.blog-site section.main aside.main nav.footer{margin-right:0}body.blog-site section.main aside.main nav.footer ul.powered{border-top:1px solid #DDDDDD;padding-top:30px}body.blog-site section.main aside.main nav.footer ul.powered li{background:transparent url("/static/img/favicon.png") top left no-repeat}body.blog-site section.main aside.main nav.footer ul.powered li a{border:none;color:#3E6B73;display:inline-block;font-style:italic}body.blog-site section.main aside.main nav.footer ul.powered li a:hover{border-bottom:1px solid #333;color:#333}body.blog-site section.main aside.main nav.footer.with-sidebar{margin-top:30px}body.blog-site section.main aside.main section.sidebar{margin-bottom:30px;margin-left:15px}body.blog-site section.main aside.main section.sidebar p{line-height:16px;margin-bottom:15px}body.blog-site section.main aside.main section.sidebar a:hover{text-decoration:none}body.blog-site header.main{background:transparent url("/static/img/blog-header-bg.png") top left repeat;height:auto}body.blog-site header.main div.inner{height:auto}body.blog-site header.main div.inner h1{float:none;position:static}body.blog-site header.main div.inner h1 a{background:none;border-bottom:2px solid transparent;color:#2A535C;font:normal 30px "Helvetica Neue",Helvetica,Arial,"Liberation Sans",FreeSans,sans-serif;height:auto;letter-spacing:-1px;line-height:30px;margin:17px 0 17px 16px;text-decoration:none;text-indent:0;text-shadow:none;width:auto;-webkit-transition:border .08s linear;-moz-transition:border .08s linear;-o-transition:border .08s linear;transition:border .08s linear}body.blog-site header.main div.inner h1 a:hover{border-bottom:2px solid #3A5E67}body.blog-site header.sub div.inner{z-index:51}body.blog-detail section.main div.inner{width:718px}body.blog-detail section.main div.inner section.snipts article.snipt{margin-bottom:0}body.blog-detail section.main div.inner section.snipts article.snipt div.container{width:100%}body.blog-detail section.main div.inner section.snipts article.snipt div.container h1 a{white-space:normal}body.blog-detail section.main div.inner section.snipts article.snipt div.container section.code{height:auto}body.blog-detail section.main div.inner section.snipts article.snipt div.container section.code td.code div.highlight pre{width:683px}body.blog-detail section.main div.inner section.snipts article.snipt footer ul.attrs li.tweet{margin-right:116px}body.blog-detail div#disqus_thread{width:704px}body.blog-detail div#disqus_thread #dsq-content{margin-top:-38px}body.blog-list article.snipt div.container section.code td.code div.highlight pre{width:683px}
body.blog-site article.snipt div.group div.container{width:718px}body.blog-site article.snipt div.group div.container header{min-height:0}body.blog-site article.snipt div.group div.container header h1{margin:11px 15px}body.blog-site article.snipt footer ul.attrs li.tweet{margin-right:30px}body.blog-site section.main div.ruler{z-index:50}body.blog-site section.main aside.main nav.footer{margin-right:0}body.blog-site section.main aside.main nav.footer ul.powered{border-top:1px solid #DDDDDD;padding-top:30px}body.blog-site section.main aside.main nav.footer ul.powered li{background:transparent url("https://snipt.s3.amazonaws.com/img/favicon.png") top left no-repeat}body.blog-site section.main aside.main nav.footer ul.powered li a{border:none;color:#3E6B73;display:inline-block;font-style:italic}body.blog-site section.main aside.main nav.footer ul.powered li a:hover{border-bottom:1px solid #333;color:#333}body.blog-site section.main aside.main nav.footer.with-sidebar{margin-top:30px}body.blog-site section.main aside.main section.sidebar{margin-bottom:30px;margin-left:15px}body.blog-site section.main aside.main section.sidebar p{line-height:16px;margin-bottom:15px}body.blog-site section.main aside.main section.sidebar a:hover{text-decoration:none}body.blog-site header.main{background:transparent url("https://snipt.s3.amazonaws.com/img/blog-header-bg.png") top left repeat;height:auto}body.blog-site header.main div.inner{height:auto}body.blog-site header.main div.inner h1{float:none;position:static}body.blog-site header.main div.inner h1 a{background:none;border-bottom:2px solid transparent;color:#2A535C;font:normal 30px "Helvetica Neue",Helvetica,Arial,"Liberation Sans",FreeSans,sans-serif;height:auto;letter-spacing:-1px;line-height:30px;margin:17px 0 17px 16px;text-decoration:none;text-indent:0;text-shadow:none;width:auto;-webkit-transition:border .08s linear;-moz-transition:border .08s linear;-o-transition:border .08s linear;transition:border .08s linear}body.blog-site header.main div.inner h1 a:hover{border-bottom:2px solid #3A5E67}body.blog-site header.sub div.inner{z-index:51}body.blog-detail section.main div.inner{width:718px}body.blog-detail section.main div.inner section.snipts article.snipt{margin-bottom:0}body.blog-detail section.main div.inner section.snipts article.snipt div.container{width:100%}body.blog-detail section.main div.inner section.snipts article.snipt div.container h1 a{white-space:normal}body.blog-detail section.main div.inner section.snipts article.snipt div.container section.code{height:auto}body.blog-detail section.main div.inner section.snipts article.snipt div.container section.code td.code div.highlight pre{width:683px}body.blog-detail section.main div.inner section.snipts article.snipt footer ul.attrs li.tweet{margin-right:116px}body.blog-detail div#disqus_thread{width:704px}body.blog-detail div#disqus_thread #dsq-content{margin-top:-38px}body.blog-list article.snipt div.container section.code td.code div.highlight pre{width:683px}

View File

@ -36,7 +36,7 @@ body.blog-site {
padding-top: 30px;
li {
background: transparent url('/static/img/favicon.png') top left no-repeat;
background: transparent url('https://snipt.s3.amazonaws.com/img/favicon.png') top left no-repeat;
a {
border: none;
@ -72,7 +72,7 @@ body.blog-site {
}
}
header.main {
background: transparent url('/static/img/blog-header-bg.png') top left repeat;
background: transparent url('https://snipt.s3.amazonaws.com/img/blog-header-bg.png') top left repeat;
height: auto;
div.inner {

File diff suppressed because one or more lines are too long

View File

@ -323,7 +323,7 @@ article {
}
}
&:after {
background: transparent url('/static/img/date-arrow.gif') top left no-repeat;
background: transparent url('https://snipt.s3.amazonaws.com/img/date-arrow.gif') top left no-repeat;
content: "";
display: block;
height: 11px;

File diff suppressed because one or more lines are too long

View File

@ -1870,4 +1870,4 @@ THE SOFTWARE.
.cm-s-xq-dark span.cm-tag {color: #FFBD40;}
.cm-s-xq-dark span.cm-attribute {color: #FFF700;}
div.markdown .tomorrow-comment,div.markdown pre .comment,div.markdown pre .title{color:#8e908c}div.markdown .tomorrow-red,div.markdown pre .variable,div.markdown pre .attribute,div.markdown pre .tag,div.markdown pre .regexp,div.markdown pre .ruby .constant,div.markdown pre .xml .tag .title,div.markdown pre .xml .pi,div.markdown pre .xml .doctype,div.markdown pre .html .doctype,div.markdown pre .css .id,div.markdown pre .css .class,div.markdown pre .css .pseudo{color:#c82829}div.markdown .tomorrow-orange,div.markdown pre .number,div.markdown pre .preprocessor,div.markdown pre .built_in,div.markdown pre .literal,div.markdown pre .params,div.markdown pre .constant{color:#f5871f}div.markdown .tomorrow-yellow,div.markdown pre .class,div.markdown pre .ruby .class .title,div.markdown pre .css .rules .attribute{color:#eab700}div.markdown .tomorrow-green,div.markdown pre .string,div.markdown pre .value,div.markdown pre .inheritance,div.markdown pre .header,div.markdown pre .ruby .symbol,div.markdown pre .xml .cdata{color:#718c00}div.markdown .tomorrow-aqua,div.markdown pre .css .hexcolor{color:#3e999f}div.markdown .tomorrow-blue,div.markdown pre .function,div.markdown pre .python .decorator,div.markdown pre .python .title,div.markdown pre .ruby .function .title,div.markdown pre .ruby .title .keyword,div.markdown pre .perl .sub,div.markdown pre .javascript .title,div.markdown pre .coffeescript .title{color:#4271ae}div.markdown .tomorrow-purple,div.markdown pre .keyword,div.markdown pre .javascript .function{color:#8959a8}div.markdown pre code{color:#4d4d4c}div.markdown pre .coffeescript .javascript,div.markdown pre .javascript .xml,div.markdown pre .tex .formula,div.markdown pre .xml .javascript,div.markdown pre .xml .vbscript,div.markdown pre .xml .css,div.markdown pre .xml .cdata{opacity:0.5}
body.blog-site article.snipt div.group div.container{width:718px}body.blog-site article.snipt div.group div.container header{min-height:0}body.blog-site article.snipt div.group div.container header h1{margin:11px 15px}body.blog-site article.snipt footer ul.attrs li.tweet{margin-right:30px}body.blog-site section.main div.ruler{z-index:50}body.blog-site section.main aside.main nav.footer{margin-right:0}body.blog-site section.main aside.main nav.footer ul.powered{border-top:1px solid #DDDDDD;padding-top:30px}body.blog-site section.main aside.main nav.footer ul.powered li{background:transparent url("/static/img/favicon.png") top left no-repeat}body.blog-site section.main aside.main nav.footer ul.powered li a{border:none;color:#3E6B73;display:inline-block;font-style:italic}body.blog-site section.main aside.main nav.footer ul.powered li a:hover{border-bottom:1px solid #333;color:#333}body.blog-site section.main aside.main nav.footer.with-sidebar{margin-top:30px}body.blog-site section.main aside.main section.sidebar{margin-bottom:30px;margin-left:15px}body.blog-site section.main aside.main section.sidebar p{line-height:16px;margin-bottom:15px}body.blog-site section.main aside.main section.sidebar a:hover{text-decoration:none}body.blog-site header.main{background:transparent url("/static/img/blog-header-bg.png") top left repeat;height:auto}body.blog-site header.main div.inner{height:auto}body.blog-site header.main div.inner h1{float:none;position:static}body.blog-site header.main div.inner h1 a{background:none;border-bottom:2px solid transparent;color:#2A535C;font:normal 30px "Helvetica Neue",Helvetica,Arial,"Liberation Sans",FreeSans,sans-serif;height:auto;letter-spacing:-1px;line-height:30px;margin:17px 0 17px 16px;text-decoration:none;text-indent:0;text-shadow:none;width:auto;-webkit-transition:border .08s linear;-moz-transition:border .08s linear;-o-transition:border .08s linear;transition:border .08s linear}body.blog-site header.main div.inner h1 a:hover{border-bottom:2px solid #3A5E67}body.blog-site header.sub div.inner{z-index:51}body.blog-detail section.main div.inner{width:718px}body.blog-detail section.main div.inner section.snipts article.snipt{margin-bottom:0}body.blog-detail section.main div.inner section.snipts article.snipt div.container{width:100%}body.blog-detail section.main div.inner section.snipts article.snipt div.container h1 a{white-space:normal}body.blog-detail section.main div.inner section.snipts article.snipt div.container section.code{height:auto}body.blog-detail section.main div.inner section.snipts article.snipt div.container section.code td.code div.highlight pre{width:683px}body.blog-detail section.main div.inner section.snipts article.snipt footer ul.attrs li.tweet{margin-right:116px}body.blog-detail div#disqus_thread{width:704px}body.blog-detail div#disqus_thread #dsq-content{margin-top:-38px}body.blog-list article.snipt div.container section.code td.code div.highlight pre{width:683px}
body.blog-site article.snipt div.group div.container{width:718px}body.blog-site article.snipt div.group div.container header{min-height:0}body.blog-site article.snipt div.group div.container header h1{margin:11px 15px}body.blog-site article.snipt footer ul.attrs li.tweet{margin-right:30px}body.blog-site section.main div.ruler{z-index:50}body.blog-site section.main aside.main nav.footer{margin-right:0}body.blog-site section.main aside.main nav.footer ul.powered{border-top:1px solid #DDDDDD;padding-top:30px}body.blog-site section.main aside.main nav.footer ul.powered li{background:transparent url("https://snipt.s3.amazonaws.com/img/favicon.png") top left no-repeat}body.blog-site section.main aside.main nav.footer ul.powered li a{border:none;color:#3E6B73;display:inline-block;font-style:italic}body.blog-site section.main aside.main nav.footer ul.powered li a:hover{border-bottom:1px solid #333;color:#333}body.blog-site section.main aside.main nav.footer.with-sidebar{margin-top:30px}body.blog-site section.main aside.main section.sidebar{margin-bottom:30px;margin-left:15px}body.blog-site section.main aside.main section.sidebar p{line-height:16px;margin-bottom:15px}body.blog-site section.main aside.main section.sidebar a:hover{text-decoration:none}body.blog-site header.main{background:transparent url("https://snipt.s3.amazonaws.com/img/blog-header-bg.png") top left repeat;height:auto}body.blog-site header.main div.inner{height:auto}body.blog-site header.main div.inner h1{float:none;position:static}body.blog-site header.main div.inner h1 a{background:none;border-bottom:2px solid transparent;color:#2A535C;font:normal 30px "Helvetica Neue",Helvetica,Arial,"Liberation Sans",FreeSans,sans-serif;height:auto;letter-spacing:-1px;line-height:30px;margin:17px 0 17px 16px;text-decoration:none;text-indent:0;text-shadow:none;width:auto;-webkit-transition:border .08s linear;-moz-transition:border .08s linear;-o-transition:border .08s linear;transition:border .08s linear}body.blog-site header.main div.inner h1 a:hover{border-bottom:2px solid #3A5E67}body.blog-site header.sub div.inner{z-index:51}body.blog-detail section.main div.inner{width:718px}body.blog-detail section.main div.inner section.snipts article.snipt{margin-bottom:0}body.blog-detail section.main div.inner section.snipts article.snipt div.container{width:100%}body.blog-detail section.main div.inner section.snipts article.snipt div.container h1 a{white-space:normal}body.blog-detail section.main div.inner section.snipts article.snipt div.container section.code{height:auto}body.blog-detail section.main div.inner section.snipts article.snipt div.container section.code td.code div.highlight pre{width:683px}body.blog-detail section.main div.inner section.snipts article.snipt footer ul.attrs li.tweet{margin-right:116px}body.blog-detail div#disqus_thread{width:704px}body.blog-detail div#disqus_thread #dsq-content{margin-top:-38px}body.blog-list article.snipt div.container section.code td.code div.highlight pre{width:683px}

File diff suppressed because one or more lines are too long

View File

@ -1,3 +0,0 @@
(function(){'use strict';if(typeof angular!=='undefined'){var root=this;var $=root.jQuery;var controllers={};var app=root.app;app.config(function($routeProvider){$routeProvider.when('/account/',{templateUrl:'/static/js/src/modules/partials/profile.html',controller:controllers.ProfileController});$routeProvider.when('/account/billing/',{templateUrl:'/static/js/src/modules/partials/billing.html',controller:controllers.BillingController});$routeProvider.when('/account/blogging/',{templateUrl:'/static/js/src/modules/partials/blogging.html',controller:controllers.BloggingController});$routeProvider.when('/account/editor/',{templateUrl:'/static/js/src/modules/partials/editor.html',controller:controllers.EditorController});$routeProvider.otherwise({'redirectTo':function(routeParams,locationPath){window.location=locationPath;}});});app.factory('AccountStorage',function($http){return{cancelSubscription:function(){var promise=$http({method:'GET',url:'/account/cancel-subscription/',headers:{'Authorization':'ApiKey '+window.user+':'+window.api_key}});return promise;},getAccount:function(){var promise=$http({method:'GET',url:'/api/private/profile/'+window.user_profile_id+'/',headers:{'Authorization':'ApiKey '+window.user+':'+window.api_key}});return promise;},getStripeAccount:function(){var promise=$http({method:'GET',url:'/account/stripe-account-details/'});return promise;},saveAccount:function(user,fields){var promise=$http({method:'PUT',url:'/api/private/profile/'+window.user_profile_id+'/',headers:{'Authorization':'ApiKey '+window.user+':'+window.api_key},data:function(){var userData={};for(var i=0;i<fields.length;i++){userData[fields[i]]=user[fields[i]];}
return userData;}()});return promise;}};});controllers.BillingController=function($scope,AccountStorage){$scope.section='Billing';$scope.cancelSubscription=function(){if(confirm('Are you sure you want to cancel your subscription?\n\nYou will no longer be able to create new Snipts. Your existing snipts will still be accessible. This action is effective immediately and we unfortunately cannot issue any refunds.')){$scope.cancelled=true;$scope.cancelling=true;AccountStorage.cancelSubscription().then(function(response){if(response.data.deleted){$scope.cancelling=false;}else{$scope.cancelling=false;$scope.cancelled=false;}});}};};controllers.BloggingController=function($scope){$scope.fields=['blog_title','blog_theme','blog_domain','gittip_username','disqus_shortname','google_analytics_tracking_id','gauges_site_id','google_ad_client','google_ad_slot','google_ad_width','google_ad_height'];$scope.section='Blogging';$scope.blogThemeOptions=[{id:'D',label:'Default'},{id:'A',label:'Pro Adams'}];};controllers.EditorController=function($scope){$scope.fields=['default_editor','editor_theme'];$scope.section='Editor';$scope.editorOptions=[{id:'C',label:'CodeMirror'},{id:'T',label:'Textarea'}];$scope.editorThemeOptions=[{id:'default',label:'Default'},{id:'ambiance',label:'Ambiance'},{id:'blackboard',label:'Blackboard'},{id:'cobalt',label:'Cobalt'},{id:'eclipse',label:'Eclipse'},{id:'elegant',label:'Elegant'},{id:'erlang-dark',label:'Erlang Dark'},{id:'lesser-dark',label:'Lesser Dark'},{id:'monokai',label:'Monokai'},{id:'neat',label:'Neat'},{id:'night',label:'Night'},{id:'rubyblue',label:'Ruby Blue'},{id:'solarized dark',label:'Solarized Dark'},{id:'solarized light',label:'Solarized Light'},{id:'twilight',label:'Twilight'},{id:'vibrant-ink',label:'Vibrant Ink'},{id:'xq-dark',label:'XQ Dark'}];};controllers.AccountController=function($scope,$route,AccountStorage){$scope.errors=[];$scope.saveButtonText='Save';$scope.route=$route;AccountStorage.getAccount().then(function(response){$scope.user=response.data;if($scope.user.is_pro&&$scope.user.stripe_id&&$scope.user.stripe_id!=='COMP'){AccountStorage.getStripeAccount().then(function(response){$scope.user.stripeAccount=response.data;});}});$scope.saveFields=function(fields){$scope.saveButtonText='Saving…';AccountStorage.saveAccount($scope.user,fields).then(function onSuccess(response){$scope.user=response.data;$scope.success=true;$scope.message=$scope.route.current.scope.section+' settings saved.';$scope.saveButtonText='Save';$scope.errors=[];setTimeout(function(){$scope.success=null;$scope.message='';$scope.$apply();},3000);},function onError(response){$scope.success=false;$scope.saveButtonText='Save';if(response){$scope.errors=response.data.profile;$scope.message='Only spaces, letters, numbers, underscores, dashes, periods, forward slashes, and "at sign" are valid.';}else{$scope.message='There was an error saving your settings.';}});};};controllers.ProfileController=function($scope){$scope.section='Profile';};app.controller(controllers);}}).call(this);

View File

@ -41,91 +41,91 @@ jQuery(function($) {
$scope.ads = [
{
url: 'http://showroom.is/?from=snipt',
image: '/static/img/logo-showroom.png',
image: 'https://snipt.s3.amazonaws.com/img/logo-showroom.png',
company: 'Showroom.is',
title: 'New-car research for the modern web.'
},
{
url: 'http://showroom.is/?from=snipt',
image: '/static/img/logo-showroom.png',
image: 'https://snipt.s3.amazonaws.com/img/logo-showroom.png',
company: 'Showroom.is',
title: 'New-car research for the modern web.'
},
{
url: 'http://showroom.is/?from=snipt',
image: '/static/img/logo-showroom.png',
image: 'https://snipt.s3.amazonaws.com/img/logo-showroom.png',
company: 'Showroom.is',
title: 'New-car research for the modern web.'
},
{
url: 'http://showroom.is/?from=snipt',
image: '/static/img/logo-showroom.png',
image: 'https://snipt.s3.amazonaws.com/img/logo-showroom.png',
company: 'Showroom.is',
title: 'New-car research for the modern web.'
},
{
url: 'http://showroom.is/?from=snipt',
image: '/static/img/logo-showroom.png',
image: 'https://snipt.s3.amazonaws.com/img/logo-showroom.png',
company: 'Showroom.is',
title: 'New-car research for the modern web.'
},
{
url: 'http://showroom.is/?from=snipt',
image: '/static/img/logo-showroom.png',
image: 'https://snipt.s3.amazonaws.com/img/logo-showroom.png',
company: 'Showroom.is',
title: 'New-car research for the modern web.'
},
{
url: 'http://showroom.is/?from=snipt',
image: '/static/img/logo-showroom.png',
image: 'https://snipt.s3.amazonaws.com/img/logo-showroom.png',
company: 'Showroom.is',
title: 'New-car research for the modern web.'
},
{
url: 'http://showroom.is/?from=snipt',
image: '/static/img/logo-showroom.png',
image: 'https://snipt.s3.amazonaws.com/img/logo-showroom.png',
company: 'Showroom.is',
title: 'New-car research for the modern web.'
},
{
url: 'http://showroom.is/?from=snipt',
image: '/static/img/logo-showroom.png',
image: 'https://snipt.s3.amazonaws.com/img/logo-showroom.png',
company: 'Showroom.is',
title: 'New-car research for the modern web.'
},
{
url: 'http://showroom.is/?from=snipt',
image: '/static/img/logo-showroom.png',
image: 'https://snipt.s3.amazonaws.com/img/logo-showroom.png',
company: 'Showroom.is',
title: 'New-car research for the modern web.'
},
{
url: 'http://showroom.is/?from=snipt',
image: '/static/img/logo-showroom.png',
image: 'https://snipt.s3.amazonaws.com/img/logo-showroom.png',
company: 'Showroom.is',
title: 'New-car research for the modern web.'
},
{
url: 'http://showroom.is/?from=snipt',
image: '/static/img/logo-showroom.png',
image: 'https://snipt.s3.amazonaws.com/img/logo-showroom.png',
company: 'Showroom.is',
title: 'New-car research for the modern web.'
},
{
url: 'http://showroom.is/?from=snipt',
image: '/static/img/logo-showroom.png',
image: 'https://snipt.s3.amazonaws.com/img/logo-showroom.png',
company: 'Showroom.is',
title: 'New-car research for the modern web.'
},
{
url: 'http://showroom.is/?from=snipt',
image: '/static/img/logo-showroom.png',
image: 'https://snipt.s3.amazonaws.com/img/logo-showroom.png',
company: 'Showroom.is',
title: 'New-car research for the modern web.'
},
{
url: 'http://showroom.is/?from=snipt',
image: '/static/img/logo-showroom.png',
image: 'https://snipt.s3.amazonaws.com/img/logo-showroom.png',
company: 'Showroom.is',
title: 'New-car research for the modern web.'
},

View File

@ -1,2 +0,0 @@
'use strict';var snipt={module:function(){var modules={};return function(name){if(modules[name]){return modules[name];}
return modules[name]={};};}()};jQuery(function($){var SiteView=snipt.module('site').SiteView;window.site=new SiteView();});(function(){var root=this;var app=angular.module('Snipt',['ngRoute'],function($locationProvider){$locationProvider.html5Mode(true);});app.config(function($interpolateProvider){$interpolateProvider.startSymbol('{[{');$interpolateProvider.endSymbol('}]}');});root.app=app;app.controller('AppController',function($scope){$scope.ads=[{url:'http://showroom.is/?from=snipt',image:'/static/img/logo-showroom.png',company:'Showroom.is',title:'New-car research for the modern web.'},{url:'http://showroom.is/?from=snipt',image:'/static/img/logo-showroom.png',company:'Showroom.is',title:'New-car research for the modern web.'},{url:'http://showroom.is/?from=snipt',image:'/static/img/logo-showroom.png',company:'Showroom.is',title:'New-car research for the modern web.'},{url:'http://showroom.is/?from=snipt',image:'/static/img/logo-showroom.png',company:'Showroom.is',title:'New-car research for the modern web.'},{url:'http://showroom.is/?from=snipt',image:'/static/img/logo-showroom.png',company:'Showroom.is',title:'New-car research for the modern web.'},{url:'http://showroom.is/?from=snipt',image:'/static/img/logo-showroom.png',company:'Showroom.is',title:'New-car research for the modern web.'},{url:'http://showroom.is/?from=snipt',image:'/static/img/logo-showroom.png',company:'Showroom.is',title:'New-car research for the modern web.'},{url:'http://showroom.is/?from=snipt',image:'/static/img/logo-showroom.png',company:'Showroom.is',title:'New-car research for the modern web.'},{url:'http://showroom.is/?from=snipt',image:'/static/img/logo-showroom.png',company:'Showroom.is',title:'New-car research for the modern web.'},{url:'http://showroom.is/?from=snipt',image:'/static/img/logo-showroom.png',company:'Showroom.is',title:'New-car research for the modern web.'},{url:'http://showroom.is/?from=snipt',image:'/static/img/logo-showroom.png',company:'Showroom.is',title:'New-car research for the modern web.'},{url:'http://showroom.is/?from=snipt',image:'/static/img/logo-showroom.png',company:'Showroom.is',title:'New-car research for the modern web.'},{url:'http://showroom.is/?from=snipt',image:'/static/img/logo-showroom.png',company:'Showroom.is',title:'New-car research for the modern web.'},{url:'http://showroom.is/?from=snipt',image:'/static/img/logo-showroom.png',company:'Showroom.is',title:'New-car research for the modern web.'},{url:'http://showroom.is/?from=snipt',image:'/static/img/logo-showroom.png',company:'Showroom.is',title:'New-car research for the modern web.'},{url:'http://bruce-springsteen-the-e-street-band.gigs.is/?from=snipt',image:'http://cdn.chairnerd.com/images/performers-landscape/bruce-springsteen-bf99a8/4275/huge.jpg',company:'Gigs.is',title:'Bruce Springsteen & The E Street Band on tour.'},{url:'http://beyonce.gigs.is/?from=snipt',image:'http://cdn.chairnerd.com/images/performers-landscape/beyonce-b28ec9/37/huge.jpg',company:'Gigs.is',title:'Beyonce on tour. View current tour dates on:'},{url:'http://paul-mccartney.gigs.is/?from=snipt',image:'http://cdn.chairnerd.com/images/performers-landscape/paul-mccartney-0ab8df/1408/huge.jpg',company:'Gigs.is',title:'Paul McCartney on tour. View current tour dates on:'},{url:'http://rolling-stones.gigs.is/?from=snipt',image:'http://cdn.chairnerd.com/images/performers-landscape/rolling-stones-73ab94/2597/huge.jpg',company:'Gigs.is',title:'Rolling Stones on tour. View current tour dates on:'},{url:'http://justin-timberlake.gigs.is/?from=snipt',image:'http://cdn.chairnerd.com/images/performers-landscape/justin-timberlake-c30b82/1019/huge.jpg',company:'Gigs.is',title:'Justin Timberlake on tour. View current tour dates on:'},{url:'http://billy-joel.gigs.is/?from=snipt',image:'http://cdn.chairnerd.com/images/performers-landscape/billy-joel-254023/303/huge.jpg',company:'Gigs.is',title:'Billy Joel on tour. View current tour dates on:'},{url:'http://taylor-swift.gigs.is/?from=snipt',image:'http://cdn.chairnerd.com/images/performers-landscape/taylor-swift-1cdf83/35/huge.jpg',company:'Gigs.is',title:'Taylor Swift on tour. View current tour dates on:'},{url:'http://one-direction.gigs.is/?from=snipt',image:'http://cdn.chairnerd.com/images/performers-landscape/one-direction-a22937/12586/huge.jpg',company:'Gigs.is',title:'One Direction on tour. View current tour dates on:'},{url:'http://george-strait.gigs.is/?from=snipt',image:'http://cdn.chairnerd.com/images/performers-landscape/george-strait-92a4b8/780/huge.jpg',company:'Gigs.is',title:'George Strait on tour. View current tour dates on:'},{url:'http://pearl-jam.gigs.is/?from=snipt',image:'http://cdn.chairnerd.com/images/performers-landscape/pearl-jam-fb4480/1416/huge.jpg',company:'Gigs.is',title:'Pearl Jam on tour. View current tour dates on:'}];var randomIndex=Math.floor(Math.random()*(($scope.ads.length-1)-0+1))+0;$scope.randomAd=$scope.ads[randomIndex];});}).call(this);

View File

@ -1 +0,0 @@
'use strict';(function(window){if(typeof angular!=='undefined'){var root=window;var $=root.jQuery;var controllers={};var app=root.app;app.filter('startFrom',function(){return function(input,start){start=+start;return input?input.slice(start):input;};});controllers.JobSearchController=function($http,$scope,filterFilter,$timeout){$scope.currentPage=0;$scope.pageSize=10;$http.get('/jobs-json/').then(function(response){$scope.jobs=response.data;$scope.filterJobs();});$scope.filterJobs=function(){$scope.filteredJobs=filterFilter($scope.jobs,$scope.query);$scope.currentPage=0;};$scope.numberOfPages=function(){if($scope.filteredJobs){return Math.ceil($scope.filteredJobs.length/$scope.pageSize);}};$scope.$watch('query',function(val){$scope.filterJobs();});};app.controller(controllers);}})(window);

View File

@ -1,31 +0,0 @@
(function(Snipt){Snipt.SniptModel=Backbone.Model.extend({toSafe:function(){var snipt=this.toJSON();snipt.code=this.escape('code');snipt.title=this.escape('title');snipt.tags_list=this.escape('tags_list');if(typeof snipt.tags==='object'){for(var i;i<snipt.tags.length;i++){snipt.tags[i].name=_.escape(snipt.tags[i].name);}}
return snipt;}});Snipt.SniptView=Backbone.View.extend({tagName:'article',initialize:function(){this.model.view=this;this.model.bind('change',this.render,this);this.template=_.template($('#snipt').html());this.editTemplate=_.template($('#edit').html());this.initLocalVars();this.initLineNumbers();},events:{'click a.copy':'copyFromClick','click a.edit':'edit','click a.favorite':'favoriteToggle','click a.embed':'embedFromClick','click a.expand':'expand','click .container':'selectFromClick','copyClose':'copyClose','copyRaw':'copy','detail':'detail','deselect':'deselect','destroy':'destroy','edit':'edit','embed':'embed','embedClose':'embedClose','expand':'expand','fadeAndRemove':'fadeAndRemove','goToAuthor':'goToAuthor','next':'next','prev':'prev','selectSnipt':'select'},copy:function(){$('textarea',this.$copyModal).remove();window.ui_halted=true;this.$copyModalBody.append('<textarea class="raw"></textarea>');$textarea=$('textarea.raw',this.$copyModalBody).val(this.model.get('code'));this.$copyModal.modal('show');$textarea.select();},copyClose:function(){$('textarea',this.$copyModal).remove();},copyFromClick:function(){this.copy();return false;},deselect:function(){this.$el.removeClass('selected');window.$selected=false;},detail:function(){window.location=this.model.get('absolute_url');},destroy:function(){this.model.destroy();},edit:function(adding){window.editing=true;window.ui_halted=true;this.select();that=this;var editPane=this.editTemplate({snipt:this.model.toSafe()});window.site.$main.hide();window.site.$body.addClass('detail editing');window.site.$main_edit.html(editPane);$('option[value="'+this.model.get('lexer')+'"]',window.site.$main_edit).attr('selected','selected');var $selectLexer=$('select#id_lexer',window.site.$main_edit);$selectLexer.chosen();$('label.blog-post input',window.site.$main_edit).on('change',function(){var $checkbox=$(this);var $label=$checkbox.parent();var $publish_date=$label.siblings('label.publish-date');if($checkbox.attr('checked')){$label.removeClass('is-not-blog-post').addClass('is-blog-post');$publish_date.show();}else{$label.addClass('is-not-blog-post').removeClass('is-blog-post');$publish_date.hide();}
return false;}).trigger('change');$('label.public input',window.site.$main_edit).on('change',function(){var $checkbox=$(this);var $label=$checkbox.parent();if($checkbox.attr('checked')){$label.removeClass('is-private').addClass('is-public');}else{$label.addClass('is-private').removeClass('is-public');}
return false;}).trigger('change');window.site.$main_edit.show();this.$editorCodeMirror=$('div.editor',window.site.$main_edit);this.$editorTextarea=$('textarea.editor',window.site.$main_edit);window.editor=CodeMirror(this.$editorCodeMirror.get(0),{autofocus:true,fixedGutter:true,gutter:true,indentUnit:4,lineNumbers:true,javascriptHint:true,matchBrackets:true,mode:that.guessCodeMirrorLexer($selectLexer.val()),value:that.model.get('code')});$selectLexer.change(function(){var $selectedLexer=$('option:selected',$selectLexer);var lexer=$selectLexer.val();window.editor.setOption('mode',that.guessCodeMirrorLexer($selectedLexer.val()));if(lexer==='markdown'||lexer==='text'){window.editor.setOption('lineWrapping',true);}else{window.editor.setOption('lineWrapping',false);}});$selectLexer.trigger('change');window.editorHeight=$(window).height()-147;window.editor.setSize('100%',window.editorHeight);this.$editorTextarea.height(window.editorHeight-8);$('textarea, input',window.site.$main_edit).bind('keydown','esc',function(e){$(this).blur();return false;});var $selectEditor=$('select#id_editor',window.site.$main_edit);var $selectTheme=$('select#id_theme',window.site.$main_edit);$selectEditor.chosen();$selectEditor.change(function(){var newEditor=$selectEditor.val();if(newEditor==='textarea'){that.$editorCodeMirror.hide();that.$editorTextarea.show();that.$editorTextarea.val(window.editor.getValue());}
if(newEditor==='codemirror'){that.$editorTextarea.hide();that.$editorCodeMirror.show();window.editor.setValue(that.$editorTextarea.val());}});$selectTheme.chosen();$selectTheme.change(function(){window.editor.setOption('theme',$selectTheme.val());});if(window.editor_theme!='default'){$selectTheme.val(window.editor_theme);$selectTheme.trigger('liszt:updated');$selectTheme.trigger('change');}
if(window.default_editor!='codemirror'){$selectEditor.val(window.default_editor);$selectEditor.trigger('liszt:updated');$selectEditor.trigger('change');}
this.setupCodeMirrorFullScreen();$('button.delete',window.site.$main_edit).on('click',function(){if(confirm('Are you sure you want to delete this snipt?')){that.model.destroy();window.site.snipt_list.escapeUI(true);}
return false;});$('button.cancel',window.site.$main_edit).on('click',function(){window.site.snipt_list.escapeUI();return false;});$('button.save',window.site.$main_edit).on('click',function(){$('button.cancel').text('Close');that.save();return false;});$('button.save-and-close',window.site.$main_edit).on('click',function(){that.save();window.site.snipt_list.escapeUI();return false;});window.scrollTo(0,0);return false;},embed:function(){$('textarea',this.$embedModal).remove();window.ui_halted=true;this.$embedModalBody.append('<textarea class="raw"></textarea>');$textarea=$('textarea.raw',this.$embedModalBody).val('<script type="text/javascript" src="'+this.model.get('embed_url')+'"></script>');this.$embedModal.modal('show');$textarea.select();},embedFromClick:function(){this.embed();return false;},embedClose:function(){$('textarea',this.$embedModal).remove();},expand:function(){this.$container.toggleClass('expanded',100);this.$tags.toggleClass('expanded');this.select(true);return false;},fadeAndRemove:function(){var $toRemove=$(this.el);var $nextSnipt=$toRemove.next('article.snipt');window.$selected=false;$toRemove.fadeOut('fast',function(){$(this).remove();$nextSnipt.trigger('selectSnipt');});return false;},goToAuthor:function(){window.location=this.model.get('user').absolute_url;},guessCodeMirrorLexer:function(val){if(val==='html'){return'htmlmixed';}
if(val==='js')return'javascript';if(val==='rb')return'ruby';if(val==='java')return'clike';if(val==='c')return'clike';if(val==='cpp')return'clike';if(val==='csharp')return'clike';return val;},favoriteToggle:function(){var that=this;if(this.$el.hasClass('favorited')){$.ajax('/api/private/favorite/'+this.model.get('favorite_id')+'/',{type:'delete',success:function(){that.$el.removeClass('favorited');that.$favorite.text('Favorite');},headers:{'Authorization':'ApiKey '+window.user+':'+window.api_key}});}else{$.ajax('/api/private/favorite/',{data:'{"snipt": '+this.model.get('id')+'}',contentType:'application/json',type:'post',success:function(resp){that.$el.addClass('favorited');that.model.set({'favorite_id':resp.id},{'silent':true});that.$favorite.text('Favorited');},headers:{'Authorization':'ApiKey '+window.user+':'+window.api_key}});}
return false;},initEmbeddedTweets:function(){var $embeddedTweets=$('div.embedded-tweet');if($embeddedTweets.length){$.each($embeddedTweets,function(){var $tweetPlaceholder=$(this);var tweetID=$tweetPlaceholder.attr('data-tweet-id');$.ajax({url:'https://api.twitter.com/1/statuses/oembed.json?id='+tweetID+'&align=center',dataType:'jsonp',type:'get',success:function(resp){$tweetPlaceholder.replaceWith($(resp.html));}});});}},initLineNumbers:function(){var lines=$('span.special',this.$el);var that=this;$.each(lines,function(){var l=$(this);var num=l.text().trim();var url=that.model.get('absolute_url');l.replaceWith('<a href="'+url+'#line-'+num+'">'+num+'</a>');});},initLocalVars:function(){this.$aside=$('aside',this.$el);this.$container=$('div.container',this.$el);this.$copyModal=$('div.copy-modal',this.$el);this.$copyModalBody=$('div.modal-body',this.$copyModal);this.$embedModal=$('div.embed-modal',this.$el);this.$embedModalBody=$('div.modal-body',this.$embedModal);this.$favorite=$('a.favorite',this.$el);this.$h1=$('header h1 a',this.$el);this.$tags=$('section.tags ul',this.$aside);this.$copyModal.on('hidden',function(e){$(this).parent().trigger('copyClose');window.ui_halted=false;window.from_modal=true;});this.$embedModal.on('hidden',function(e){$(this).parent().trigger('embedClose');window.ui_halted=false;window.from_modal=true;});},next:function(){if(!window.ui_halted){nextSnipt=this.$el.next('article.snipt');if(nextSnipt.length){return nextSnipt.trigger('selectSnipt');}}},prev:function(){if(!window.ui_halted){prevSnipt=this.$el.prev('article.snipt');if(prevSnipt.length){return prevSnipt.trigger('selectSnipt');}}},remove:function(){return false;},render:function(){this.$el.html(this.template({snipt:this.model.toSafe()}));this.initLocalVars();this.initLineNumbers();this.initEmbeddedTweets();if(this.model.get('blog_post')===true){this.$el.addClass('blog-post');}else{this.$el.removeClass('blog-post');}
if(this.model.get('public')===true){this.$el.removeClass('private-snipt');}else{this.$el.addClass('private-snipt');}
if(this.model.get('user').username===window.user){this.$el.addClass('editable');}else{this.$el.removeClass('editable');}
if(this.model.get('line_count')>8&&!window.detail){this.$el.addClass('expandable');}else{this.$el.removeClass('expandable');}
$('script#disqus').remove();window.site.$body.append('<script id="disqus" type="text/javascript">'+$('script#disqus-template').text()+'</script>');if(this.$el.attr('id')==='new-snipt'){this.$el.fadeIn('fast');this.$el.attr('id','snipt-'+this.model.get('id'));}
return this;},save:function(){$('button.save, button.save-and-close, button.delete, button.cancel',window.site.$main_edit).attr('disabled','disabled');var code;if(this.$editorTextarea.is(':visible')){code=this.$editorTextarea.val();}else{code=window.editor.getValue();}
that.model.save({'title':$('input#snipt_title').val(),'tags':$('label.tags textarea').val(),'tags_list':$('label.tags textarea').val(),'lexer':$('select[name="lexer"]').val(),'lexer_name':$('select[name="lexer"] option:selected').text(),'code':code,'description':$('textarea[name="description"]').val(),'blog_post':$('label.blog-post input').is(':checked'),'publish_date':$('label.publish-date input').val(),'public':$('label.public input').is(':checked')},{success:function(model,response){$('button.save, button.save-and-close, button.delete, button.cancel',window.site.$main_edit).removeAttr('disabled');},error:function(model,response){alert('There was a problem saving your snipt. We\'ve been notified. Sorry about that!');}});},select:function(fromClick){$('article.selected',window.site.snipt_list.$el).removeClass('selected');this.$el.addClass('selected');if(fromClick!==true){if(window.site.$snipts.index(this.$el)===0){window.scrollTo(0,0);}else{window.site.$html_body.animate({scrollTop:this.$el.offset().top-50},0);}}
window.$selected=this.$el;},selectFromClick:function(e){this.select(true);e.stopPropagation();window.site.$aside_nav.removeClass('open');},setupCodeMirrorFullScreen:function(){function isFullScreen(cm){return(/\bCodeMirror-fullscreen\b/).test(cm.getWrapperElement().className);}
function winHeight(){return window.innerHeight||(document.documentElement||document.body).clientHeight;}
function setFullScreen(cm,full){var wrap=cm.getWrapperElement();if(full){wrap.className+=' CodeMirror-fullscreen';wrap.style.height=winHeight()+'px';document.documentElement.style.overflow='hidden';$('header.fixed-save').hide();$('div.container').addClass('full-screened');}else{wrap.className=wrap.className.replace(' CodeMirror-fullscreen','');window.editor.setSize('100%',window.editorHeight);document.documentElement.style.overflow='';$('header.fixed-save').show();$('div.container').removeClass('full-screened');}
cm.refresh();}
window.editor.on(window,'resize',function(){var showing=document.body.getElementsByClassName('CodeMirror-fullscreen')[0];if(!showing)return;showing.CodeMirror.getWrapperElement().style.height=winHeight()+'px';});window.editor.setOption('extraKeys',{'Cmd-Enter':function(cm){that.save();window.site.snipt_list.escapeUI();return false;},'F11':function(cm){setFullScreen(cm,!isFullScreen(cm));},'Esc':function(cm){if(isFullScreen(cm))setFullScreen(cm,false);}});}});Snipt.SniptListView=Backbone.View.extend({el:'section#snipts',initialize:function(opts){var that=this;opts.snipts.each(this.addExistingSnipt);this.keyboardShortcuts();var cmd;if(navigator.platform=='MacPPC'||navigator.platform=='MacIntel'){cmd='Cmd';}
else{cmd='Ctrl';}
$('span.cmd-ctrl').text(cmd);$('button#add-snipt').click(function(){if(window.user_account_age>7&&!window.user_is_pro){window.location='/pro/?expired=true';}else{that.addNewSnipt();}});},addExistingSnipt:function(){var $el=$(this);var $created=$('li.created',$el);var $h1=$('header h1 a',$el);var $public=$('div.public',$el);var $blog_post=$('div.blog-post',$el);var $publish_date=$('div.publish-date',$el);var $user=$('li.author a',$el);var is_public=$public.text()==='True'?true:false;var is_blog_post=$blog_post.text()==='True'?true:false;var tag_lis=$('section.tags li',$el);var tags=[];for(var i=0;i<tag_lis.length;i++){var $tag=$('a',tag_lis.eq(i));tags[i]={name:$tag.text(),absolute_url:$tag.attr('href')};}
var is_pro=$user.siblings('span.pro').length?true:false;var data={code:$('textarea.raw',$el).text(),description:$('textarea.description',$el).text(),created:$created.attr('title'),created_formatted:$created.text(),embed_url:$('div.embed-url',$el).text(),raw_url:$('div.raw-url',$el).text(),absolute_url:$h1.attr('href'),favorite_id:$el.data('favorite-id'),id:parseInt($el.attr('id').replace('snipt-',''),0),key:$('div.key',$el).text(),lexer:$('div.lexer',$el).text(),lexer_name:$('div.lexer-name',$el).text(),line_count:parseInt($('div.line-count',$el).text(),0),modified:$('div.modified',$el).text(),resource_uri:$('div.resource-uri',$el).text(),slug:$('div.slug',$el).text(),stylized:$('div.stylized',$el).text(),tags:tags,publish_date:$publish_date.text(),tags_list:$('div.tags-list',$el).text(),title:$h1.text(),user:{absolute_url:$user.attr('href'),username:$user.text(),profile:{is_pro:is_pro}}};data['public']=is_public;data.blog_post=is_blog_post;var view=new Snipt.SniptView({el:this,model:new Snipt.SniptModel(data)});},addNewSnipt:function(){var $articleNewSnipt=$('article#new-snipt');if($articleNewSnipt.length===0){window.site.snipt_list.$el.prepend('<article id="new-snipt" class="hidden snipt"></article>');var data={id:'',blog_post:false,code:'',description:'',tags:[],tags_list:'',title:'',lexer:'text',lexer_name:'Text only',new_from_js:true,public:false,user:{username:'',profile:{is_pro:window.user_is_pro}}};var newSniptView=new Snipt.SniptView({el:$('article#new-snipt'),model:new Snipt.SniptModel(data)});newSniptView.edit(true);}else{$articleNewSnipt.trigger('edit');}
return false;},escapeUI:function(destroyed){if(window.editing||destroyed){if(!window.site.$html.hasClass('detail')){window.site.$body.removeClass('detail');}
window.site.$main_edit.hide();window.site.$body.removeClass('editing');window.site.$main.show();window.editing=true;window.ui_halted=false;if(window.site.$snipts.index(window.$selected)===0){window.scrollTo(0,0);}else{window.site.$html_body.animate({scrollTop:window.$selected.offset().top-50},0);}
if(destroyed){window.$selected.trigger('fadeAndRemove');}}else{if(!window.ui_halted){if($selected){$selected.trigger('deselect');}
window.site.$aside_nav.removeClass('open');}}},keyboardShortcuts:function(){var that=this;$selected=window.selected;$document=$(document);$document.bind('keydown','j',function(){if(!window.ui_halted){if(!$selected){window.site.$snipts.eq(0).trigger('selectSnipt');}else{$selected.trigger('next');}}});$document.bind('keydown','k',function(){if(!window.ui_halted){if(!$selected){window.site.$snipts.eq(0).trigger('selectSnipt');}else{$selected.trigger('prev');}}});$document.bind('keydown','c',function(e){if(!window.ui_halted&&!window.blog_post){if($selected){e.preventDefault();$selected.trigger('copyRaw');}}});$document.bind('keydown','Ctrl+e',function(){if(!window.ui_halted){if($selected){if($selected.hasClass('editable')){$selected.trigger('edit');}}}});$document.bind('keydown','Ctrl+backspace',function(){if(!window.ui_halted||window.editing){if($selected){if($selected.hasClass('editable')){if(confirm('Are you sure you want to delete this snipt?')){$selected.trigger('destroy');window.site.snipt_list.escapeUI(true);}}}}});$document.bind('keydown','Ctrl+del',function(){if(!window.ui_halted||window.editing){if($selected){if($selected.hasClass('editable')){if(confirm('Are you sure you want to delete this snipt?')){$selected.trigger('destroy');window.site.snipt_list.escapeUI(true);}}}}});$document.bind('keydown','Alt+n',function(){if(!window.ui_halted){that.addNewSnipt();}});$document.bind('keydown','Ctrl+n',function(){if(!window.ui_halted){that.addNewSnipt();}});$document.bind('keydown','Ctrl+s',function(){if(window.editing){if($selected){if($selected.hasClass('editable')){$('button.save').click();}}}});$document.bind('keydown','Ctrl+c',function(){if(window.editing){if($selected){if($selected.hasClass('editable')){$('button.save-and-close').click();}}}});$document.bind('keydown','esc',function(){that.escapeUI();});$document.bind('keydown','g',function(){if(!window.ui_halted){if(window.$selected){window.$selected.trigger('deselect');}
window.scrollTo(0,0);}});$document.bind('keydown','Shift+g',function(){if(!window.ui_halted){if(window.$selected){window.$selected.trigger('deselect');}
window.scrollTo(0,document.body.scrollHeight);}});$document.bind('keydown','n',function(){if(!window.ui_halted){var $anc=$('li.next a');if($anc.length){if($anc.attr('href')!=='#'){window.location=$anc.attr('href');}}}});$document.bind('keydown','e',function(){if(!window.ui_halted){if($selected){if($selected.hasClass('expandable')){$selected.trigger('expand');}}}});$document.bind('keydown','u',function(){if(!window.ui_halted){if($selected){$selected.trigger('goToAuthor');}}});$document.bind('keydown','p',function(){if(!window.ui_halted){var $anc=$('li.prev a');if($anc.length){if($anc.attr('href')!=='#'){window.location=$anc.attr('href');}}}});$document.bind('keydown','v',function(e){if(!window.ui_halted&&!window.blog_post){if($selected){e.preventDefault();$selected.trigger('embed');}}});$document.bind('keydown','o',function(){if(!window.ui_halted){if($selected){$selected.trigger('detail');}}});$document.bind('keydown','return',function(){if(!window.ui_halted){if($selected){$selected.trigger('detail');}}});}});})(snipt.module('snipt'));

View File

@ -1,3 +0,0 @@
$(function(){var $aside=$('aside');$('a:contains("View more")',$aside).addClass('more');if(window.gittip_username){$aside.html($aside.html().replace(/\[\[.*gittip.*\]\]/,'<iframe style="border: 0; margin: 0; padding: 0;" src="https://www.gittip.com/'+window.gittip_username+'/widget.html" width="48pt" height="22pt"></iframe>'));$('iframe',$aside).parent('p').prev('p').css('margin-bottom','10px');}
$('div.markdown pre code').each(function(i,e){hljs.highlightBlock(e);});});

View File

@ -1,3 +0,0 @@
(function(){if(typeof angular!=='undefined'){var root=this;var $=root.jQuery;var controllers={};var app=root.app;app.factory('SearchService',function(){return{mineOnly:false,query:''};});controllers.HeaderSearchController=function($scope,SearchService){$scope.search=SearchService;};controllers.SearchController=function($scope,SearchService){$scope.search=SearchService;$scope.$watch('search.query',function(query){if(query.indexOf('--mine')!==-1){$scope.search.mineOnly=true;}else{$scope.search.mineOnly=false;}});$scope.toggleMineOnly=function(){if($scope.search.mineOnly){if($scope.search.query.indexOf('--mine')===-1){$scope.search.query=$scope.search.query.trim()+' --mine';}}
else{$scope.search.query=$scope.search.query.replace('--mine','').trim();}};};app.controller(controllers);}}).call(this);

View File

@ -1,2 +0,0 @@
(function(){'use strict';if(typeof angular!=='undefined'){var root=this;var $=root.jQuery;var controllers={};var app=root.app;controllers.SniptListController=function($scope,AccountStorage){$scope.$root.account={list_view:'N'};AccountStorage.getAccount().then(function(response){$scope.$root.account=response.data;$scope.$root.$watch('account.list_view',function(newView,oldView){if(oldView!==newView){AccountStorage.saveAccount($scope.$root.account,['list_view']).then(function(response){$scope.$root.account=response.data;});}});});};app.controller(controllers);}}).call(this);

View File

@ -1,6 +1,6 @@
argparse==1.2.1
biplist==0.6
boto==2.16.0
boto==2.33.0
defusedxml==0.4.1
Django==1.6
django-annoying==0.7.7
@ -9,9 +9,12 @@ django-debug-toolbar==0.11.0
django-extensions==1.2.5
django-markdown-deux==1.0.4
django-pagination==1.0.7
django-sslify>=0.2
django-storages==1.1.5
django-taggit==0.10
django-tastypie==0.10.0
django-templatetag-sugar==0.1
django-toolbelt==0.0.1
ecdsa==0.10
Fabric==1.8.0
gunicorn==18.0

View File

@ -1,86 +1,93 @@
# Django settings for snipt project.
import dj_database_url, os
import os
from urlparse import urlparse
DEBUG = True
BASE_PATH = os.path.dirname(__file__)
if 'DATABASE_URL' in os.environ:
ADMINS = (
('Name', 'name@domain.com'),
)
DATABASES = { 'default': dj_database_url.config() }
MANAGERS = ADMINS
es = urlparse(os.environ.get('SEARCHBOX_SSL_URL') or 'http://127.0.0.1:9200/')
port = es.port or 80
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': os.environ.get('DB_NAME', 'snipt'),
'USER': os.environ.get('DB_USER', ''),
'PASSWORD': os.environ.get('DB_PASS', ''),
'HOST': os.environ.get('DB_PORT_5432_TCP_ADDR', '127.0.0.1'),
'PORT': os.environ.get('DB_PORT_5432_TCP_PORT', ''),
HAYSTACK_CONNECTIONS = {
'default': {
'ENGINE': 'haystack.backends.elasticsearch_backend.ElasticsearchSearchEngine',
'URL': es.scheme + '://' + es.hostname + ':' + str(port),
'INDEX_NAME': 'snipts',
},
}
}
if es.username:
HAYSTACK_CONNECTIONS['default']['KWARGS'] = {"http_auth": es.username + ':' + es.password}
else:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'snipt',
'USER': '',
'PASSWORD': '',
'HOST': 'localhost',
'PORT': ''
}
}
HAYSTACK_CONNECTIONS = {
'default': {
'ENGINE': 'haystack.backends.simple_backend.SimpleEngine',
},
}
ABSOLUTE_URL_OVERRIDES = { 'auth.user': lambda u: "/%s/" % u.username, }
ACCOUNT_ACTIVATION_DAYS = 0
ADMINS = (('Nick Sergeant', 'nick@snipt.net'),)
ALLOWED_HOSTS = ['*']
AUTH_PROFILE_MODULE = 'accounts.UserProfile'
AUTHENTICATION_BACKENDS = ('utils.backends.EmailOrUsernameModelBackend',)
BASE_PATH = os.path.dirname(__file__)
CSRF_COOKIE_DOMAIN = '.snipt.net'
CSRF_COOKIE_SECURE = True if 'USE_SSL' in os.environ else False
DEBUG = True if 'DEBUG' in os.environ else False
DEFAULT_FROM_EMAIL = 'support@snipt.net'
EMAIL_BACKEND = 'postmark.django_backend.EmailBackend'
HAYSTACK_SIGNAL_PROCESSOR = 'haystack.signals.RealtimeSignalProcessor'
INTERCOM_SECRET_KEY = os.environ.get('INTERCOM_SECRET_KEY', '')
INTERNAL_IPS = ('127.0.0.1',)
SITE_ID = 1
# If you set this to False, Django will make some optimizations so as not
# to load the internationalization machinery.
USE_I18N = True
# If you set this to False, Django will not format dates, numbers and
# calendars according to the current locale
USE_L10N = True
# Local time zone. Choices can be found here:
# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
#
# On Unix systems, a value of None will cause Django to use the same timezone as
# the operating system. On a Windows environment, this must be set to the same
# as your system time zone
TIME_ZONE = 'America/New_York'
USE_TZ = True
# Language code for the Django installation. All choices can be found here:
# http://www.i18nguy.com/unicode/language-identifiers.html
LANGUAGE_CODE = 'en-us'
# Absolute filesystem path to the directory that will hold user-uploaded files.
# Example: "/home/media/media.lawrence.com/media/"
LOGIN_REDIRECT_URL = '/login-redirect/'
LOGIN_URL = '/login/'
LOGOUT_URL = '/logout/'
MANAGERS = ADMINS
MEDIA_ROOT = os.path.join(BASE_PATH, 'media/uploads')
# URL that handles the media served from MEDIA_ROOT. Make sure to use a
# trailing slash.
# Examples: "http://media.lawrence.com/media/", "http://example.com/media/"
MEDIA_URL = '/media/uploads/'
# Absolute path to the directory static files should be collected to.
# Don't put anything in this directory yourself; store your static files
# in apps' "static/" subdirectories and in STATICFILES_DIRS.
# Example: "/home/media/media.lawrence.com/static/"
MESSAGE_STORAGE = 'django.contrib.messages.storage.cookie.CookieStorage'
POSTMARK_API_KEY = os.environ.get('POSTMARK_API_KEY', '')
PROJECT_PATH = os.path.abspath(os.path.dirname(__file__))
RAVEN_CONFIG = { 'dsn': os.environ.get('RAVEN_CONFIG_DSN', '') }
ROOT_URLCONF = 'urls'
SECRET_KEY = os.environ.get('SECRET_KEY', 'changeme')
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
SEND_BROKEN_LINK_EMAILS = False
SERVER_EMAIL = 'support@snipt.net'
SESSION_COOKIE_AGE = 15801100
SESSION_COOKIE_SECURE = True if 'USE_SSL' in os.environ else False
SITE_ID = 1
STATICFILES_DIRS = (os.path.join(BASE_PATH, 'media'),)
STATICFILES_FINDERS = ('django.contrib.staticfiles.finders.FileSystemFinder','django.contrib.staticfiles.finders.AppDirectoriesFinder',)
STATIC_ROOT = os.path.join(BASE_PATH, 'static')
STATIC_URL = '/static/'
# Additional locations of static files
STATICFILES_DIRS = (
os.path.join(BASE_PATH, 'media'),
)
# List of finder classes that know how to find static files in
# various locations.
STATICFILES_FINDERS = (
'django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
)
SECRET_KEY = 'changethis'
STATIC_URL = 'https://snipt.s3.amazonaws.com/'
TASTYPIE_CANNED_ERROR = "There was an error with your request. The site developers have a record of this error, please email api@snipt.net and we'll help you out."
TEMPLATE_DIRS = (os.path.join(PROJECT_PATH, 'templates'),)
TEMPLATE_DEBUG = DEBUG
TIME_ZONE = 'America/New_York'
USE_HTTPS = True if 'USE_SSL' in os.environ else False
USE_I18N = True
USE_L10N = True
USE_TZ = True
INSTALLED_APPS = (
'gunicorn',
'raven.contrib.django.raven_compat',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.humanize',
@ -89,7 +96,6 @@ INSTALLED_APPS = (
'django.contrib.messages',
'django.contrib.staticfiles',
'django.contrib.admin',
'django_bcrypt',
'haystack',
'markdown_deux',
@ -97,22 +103,36 @@ INSTALLED_APPS = (
'postmark',
'registration',
'south',
'storages',
'taggit',
'tastypie',
'typogrify',
'accounts',
'blogs',
'jobs',
'snipts',
'utils',
)
# List of callables that know how to import templates from various sources.
TEMPLATE_LOADERS = (
'django.template.loaders.filesystem.Loader',
'django.template.loaders.app_directories.Loader',
# 'django.template.loaders.eggs.Loader',
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'filters': {
'require_debug_false': {
'()': 'django.utils.log.RequireDebugFalse'
}
},
'handlers': {},
'loggers': {}
}
MIDDLEWARE_CLASSES = (
'sslify.middleware.SSLifyMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'pagination.middleware.PaginationMiddleware',
'blogs.middleware.BlogMiddleware',
)
TEMPLATE_CONTEXT_PROCESSORS = (
'django.contrib.auth.context_processors.auth',
@ -123,87 +143,11 @@ TEMPLATE_CONTEXT_PROCESSORS = (
'django.core.context_processors.static',
'django.contrib.messages.context_processors.messages',
)
MIDDLEWARE_CLASSES = (
'django.middleware.csrf.CsrfViewMiddleware',
'django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'pagination.middleware.PaginationMiddleware',
'blogs.middleware.BlogMiddleware',
TEMPLATE_LOADERS = (
'django.template.loaders.filesystem.Loader',
'django.template.loaders.app_directories.Loader',
)
AUTHENTICATION_BACKENDS = (
'utils.backends.EmailOrUsernameModelBackend',
)
ROOT_URLCONF = 'urls'
PROJECT_PATH = os.path.abspath(os.path.dirname(__file__))
TEMPLATE_DIRS = (
os.path.join(PROJECT_PATH, 'templates')
)
SESSION_COOKIE_AGE = 15801100
# A sample logging configuration. The only tangible logging
# performed by this configuration is to send an email to
# the site admins on every HTTP 500 error.
# See http://docs.djangoproject.com/en/dev/topics/logging for
# more details on how to customize your logging configuration.
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'filters': {
'require_debug_false': {
'()': 'django.utils.log.RequireDebugFalse'
}
},
'handlers': {
#'mail_admins': {
#'level': 'ERROR',
#'filters': ['require_debug_false'],
#'class': 'django.utils.log.AdminEmailHandler'
#}
},
'loggers': {
#'django.request': {
#'handlers': ['mail_admins'],
#'level': 'ERROR',
#'propagate': True,
#},
}
}
HAYSTACK_CONNECTIONS = {
'default': {
'ENGINE': 'haystack.backends.simple_backend.SimpleEngine',
},
}
HAYSTACK_SIGNAL_PROCESSOR = 'haystack.signals.RealtimeSignalProcessor'
# Account settings
LOGIN_REDIRECT_URL = '/login-redirect/'
LOGIN_URL = '/login/'
LOGOUT_URL = '/logout/'
ACCOUNT_ACTIVATION_DAYS = 0
# Messages
MESSAGE_STORAGE = 'django.contrib.messages.storage.cookie.CookieStorage'
# User absolute URLs
ABSOLUTE_URL_OVERRIDES = {
'auth.user': lambda u: "/%s/" % u.username,
}
# Accounts
AUTH_PROFILE_MODULE = 'accounts.UserProfile'
# API
TASTYPIE_CANNED_ERROR = "There was an error with your request. The site developers have a record of this error, please email api@snipt.net and we'll help you out."
try:
from settings_local import *
except ImportError:

View File

@ -1,89 +0,0 @@
import os
from settings import INSTALLED_APPS, MIDDLEWARE_CLASSES
DEBUG = True
if os.environ.get('DEBUG', '').lower() == 'false':
DEBUG = False
TEMPLATE_DEBUG = DEBUG
BASE_PATH = os.path.dirname(__file__)
PROJECT_PATH = os.path.abspath(os.path.dirname(__file__))
ADMINS = (
('Name', 'name@domain.com'),
)
MANAGERS = ADMINS
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': os.environ.get('DB_NAME', 'snipt'),
'USER': os.environ.get('DB_USER', ''),
'PASSWORD': os.environ.get('DB_PASS', ''),
'HOST': os.environ.get('DB_PORT_5432_TCP_ADDR', 'localhost'),
'PORT': os.environ.get('DB_PORT_5432_TCP_PORT', ''),
}
}
TIME_ZONE = 'America/New_York'
LANGUAGE_CODE = 'en-us'
MEDIA_ROOT = os.path.join(BASE_PATH, 'media/uploads')
MEDIA_URL = '/media/uploads/'
STATIC_URL = '/static/'
SECRET_KEY = ''
DEFAULT_FROM_EMAIL = 'support@snipt.net'
SERVER_EMAIL = 'support@snipt.net'
EMAIL_BACKEND = 'postmark.django_backend.EmailBackend'
POSTMARK_API_KEY = ''
VIRTUALENV_PATH = ''
AMAZON_API_KEY = ''
AMAZON_API_SECRET = ''
STRIPE_SECRET_KEY = ''
ENV_HOST = 'user@domain.com:22'
USE_HTTPS = False
SESSION_COOKIE_SECURE = False
CSRF_COOKIE_SECURE = False
SESSION_COOKIE_DOMAIN = '.snipt.net'
ALLOWED_HOSTS = ['*']
ES_HOST = os.environ.get('ES_PORT_9200_TCP_ADDR', '127.0.0.1')
ES_PORT = os.environ.get('ES_PORT_9200_TCP_PORT', '9200')
HAYSTACK_CONNECTIONS = {
'default': {
'ENGINE': 'haystack.backends.elasticsearch_backend.ElasticsearchSearchEngine',
'URL': 'http://{}:{}/'.format(ES_HOST, ES_PORT),
'INDEX_NAME': 'haystack',
},
}
INSTALLED_APPS += (
'debug_toolbar',
'django_extensions',
'raven.contrib.django.raven_compat',
)
RAVEN_CONFIG = {
'dsn': '',
}
MIDDLEWARE_CLASSES = MIDDLEWARE_CLASSES + (
'raven.contrib.django.raven_compat.middleware.Sentry404CatchMiddleware',
)
INTERCOM_SECRET_KEY = ''

View File

@ -0,0 +1,8 @@
AWS_ACCESS_KEY_ID = ''
AWS_SECRET_ACCESS_KEY = ''
AWS_STORAGE_BUCKET_NAME = ''
DEBUG=True
S3_URL = 'https://%s.s3.amazonaws.com/' % AWS_STORAGE_BUCKET_NAME
SSLIFY_DISABLE = True
STATICFILES_STORAGE = 'storages.backends.s3boto.S3BotoStorage'
STATIC_URL = '/static/'

View File

@ -71,7 +71,7 @@
<footer>
<ul class="attrs">
<li class="author">
<span class="avatar" style="background-image: url('https://secure.gravatar.com/avatar/<%= snipt.user.email_md5 %>?s=15&d=https://snipt.net/static/img/author-icon.png');"></span>
<span class="avatar" style="background-image: url('https://secure.gravatar.com/avatar/<%= snipt.user.email_md5 %>?s=15&d=https://snipt.s3.amazonaws.com/img/author-icon.png');"></span>
<a href="<%= snipt.user.absolute_url %>">
<%= snipt.user.username %>
</a>

View File

@ -148,7 +148,7 @@
<ul class="attrs">
{% block author %}
<li class="author">
<span class="avatar" style="background-image: url('https://secure.gravatar.com/avatar/{{ snipt.user.email|md5 }}?s=15&amp;d=https://snipt.net/static/img/author-icon.png');"></span>
<span class="avatar" style="background-image: url('https://secure.gravatar.com/avatar/{{ snipt.user.email|md5 }}?s=15&amp;d=https://snipt.s3.amazonaws.com/img/author-icon.png');"></span>
<a href="{{ snipt.user.get_absolute_url }}">{{ snipt.user.username }}</a>
{% if snipt.user.profile.is_pro %}
<span class="pro"><a href="/pro/">Pro</a></span>

0
static/__init__ Normal file
View File

View File

@ -56,10 +56,10 @@
<label class="control-label" for="number">Card number:</label>
<div class="controls cards">
<input type="text" class="input-xlarge" id="number" />
<img src="/static/img/card-visa.png" alt="Visa" />
<img src="/static/img/card-mastercard.png" alt="MasterCard" />
<img src="/static/img/card-discover.png" alt="Discover" />
<img src="/static/img/card-american-express.png" alt="American Express" />
<img src="{{ STATIC_URL }}img/card-visa.png" alt="Visa" />
<img src="{{ STATIC_URL }}img/card-mastercard.png" alt="MasterCard" />
<img src="{{ STATIC_URL }}img/card-discover.png" alt="Discover" />
<img src="{{ STATIC_URL }}img/card-american-express.png" alt="American Express" />
</div>
</div>
<div class="control-group">

View File

@ -69,5 +69,5 @@ urlpatterns = patterns('',
)
urlpatterns += patterns('',
(r'^static/(?P<path>.*)$', 'django.views.static.serve', {'document_root': '/Users/Nick/Code/snipt/static'}),
(r'^static/(?P<path>.*)$', 'django.views.static.serve', {'document_root': os.path.join(os.path.dirname(__file__), 'media')}),
)

View File

@ -1,10 +1,9 @@
from django import template
from settings_local import INTERCOM_SECRET_KEY
import hmac, hashlib
import hmac, hashlib, os
register = template.Library()
@register.filter
def intercom_sha_256(user_id):
return hmac.new(INTERCOM_SECRET_KEY, str(user_id), digestmod=hashlib.sha256).hexdigest()
return hmac.new(os.environ.get('INTERCOM_SECRET_KEY', ''), str(user_id), digestmod=hashlib.sha256).hexdigest()

View File

@ -14,10 +14,9 @@ from taggit.models import Tag
import datetime
import hashlib
import os
import stripe
from settings_local import STRIPE_SECRET_KEY
@ajax_request
def user_api_key(request):
@ -103,7 +102,7 @@ def pro_complete(request):
if request.method == 'POST':
token = request.POST['token']
stripe.api_key = STRIPE_SECRET_KEY
stripe.api_key = os.environ.get('STRIPE_SECRET_KEY', '')
customer = stripe.Customer.create(email=request.user.email,
card=token)

16
wsgi.py Normal file
View File

@ -0,0 +1,16 @@
"""
WSGI config for what project.
It exposes the WSGI callable as a module-level variable named ``application``.
For more information on this file, see
https://docs.djangoproject.com/en/1.6/howto/deployment/wsgi/
"""
import os
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "settings")
from django.core.wsgi import get_wsgi_application
from dj_static import Cling
application = Cling(get_wsgi_application())