Skip to content

Commit c0fab24

Browse files
committed
init commit
0 parents  commit c0fab24

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

100 files changed

+23380
-0
lines changed

.gitignore

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Standard ignores
2+
*.pyc
3+
*.pyo
4+
*.DS_Store
5+
*.swp
6+
*.idea
7+
*.project
8+
*.pydevproject
9+
*.kpf
10+
11+
# Don't store secret keys in version control
12+
secret_keys.py
13+

app.yaml

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
application: langdevlinks
2+
version: 1
3+
runtime: python
4+
api_version: 1
5+
6+
default_expiration: "5d"
7+
8+
builtins:
9+
- appstats: on
10+
- datastore_admin: on
11+
- deferred: on
12+
- remote_api: on
13+
14+
inbound_services:
15+
- warmup
16+
17+
handlers:
18+
- url: /favicon.ico
19+
static_files: application/static/img/favicon.ico
20+
upload: application/static/img/favicon.ico
21+
22+
- url: /robots.txt
23+
static_files: application/static/robots.txt
24+
upload: application/static/robots.txt
25+
26+
- url: /static
27+
static_dir: application/static
28+
29+
- url: .*
30+
script: main.py

application/__init__.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
"""
2+
Initialize Flask app
3+
4+
"""
5+
6+
from flask import Flask
7+
from flaskext.gae_mini_profiler import GAEMiniProfiler
8+
9+
app = Flask('application')
10+
app.config.from_object('application.settings')
11+
GAEMiniProfiler(app)
12+
13+
import urls

application/decorators.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
"""
2+
decorators.py
3+
4+
Decorators for URL handlers
5+
6+
"""
7+
8+
from functools import wraps
9+
from google.appengine.api import users
10+
from flask import redirect, request
11+
12+
13+
def login_required(func):
14+
"""Requires standard login credentials"""
15+
@wraps(func)
16+
def decorated_view(*args, **kwargs):
17+
if not users.get_current_user():
18+
return redirect(users.create_login_url(request.url))
19+
return func(*args, **kwargs)
20+
return decorated_view
21+
22+
23+
def admin_required(func):
24+
"""Requires App Engine admin credentials"""
25+
@wraps(func)
26+
def decorated_view(*args, **kwargs):
27+
if not users.is_current_user_admin():
28+
return redirect(users.create_login_url(request.url))
29+
return func(*args, **kwargs)
30+
return decorated_view
31+

application/forms.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
"""
2+
forms.py
3+
4+
Web forms based on Flask-WTForms
5+
6+
See: http://flask.pocoo.org/docs/patterns/wtforms/
7+
http://wtforms.simplecodes.com/
8+
9+
"""
10+
11+
from flaskext import wtf
12+
from flaskext.wtf import validators
13+

application/generate_keys.py

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
#!/usr/bin/env python
2+
# encoding: utf-8
3+
"""
4+
generate_keys.py
5+
6+
Generate CSRF and Session keys, output to secret_keys.py file
7+
8+
Usage:
9+
generate_keys.py [-f]
10+
11+
Outputs secret_keys.py file in current folder
12+
13+
By default, an existing secret_keys file will not be replaced.
14+
Use the '-f' flag to force the new keys to be written to the file
15+
16+
17+
"""
18+
19+
import string
20+
import os.path
21+
22+
from optparse import OptionParser
23+
from random import choice
24+
from string import Template
25+
26+
27+
# File settings
28+
file_name = 'secret_keys.py'
29+
file_template = Template('''# CSRF- and Session keys
30+
31+
CSRF_SECRET_KEY = '$csrf_key'
32+
SESSION_KEY = '$session_key'
33+
''')
34+
35+
36+
# Get options from command line
37+
parser = OptionParser()
38+
parser.add_option("-f", "--force", dest="force",
39+
help="force overwrite of existing secret_keys file", action="store_true")
40+
parser.add_option("-r", "--randomness", dest="randomness",
41+
help="length (randomness) of generated key; default = 24", default=24)
42+
(options, args) = parser.parse_args()
43+
44+
45+
def generate_randomkey(length):
46+
"""Generate random key, given a number of characters"""
47+
chars = string.letters + string.digits
48+
return ''.join([choice(chars) for i in range(length)])
49+
50+
51+
def write_file(contents):
52+
f = open(file_name, 'wb')
53+
f.write(contents)
54+
f.close()
55+
56+
57+
def generate_keyfile(csrf_key, session_key):
58+
"""Generate random keys for CSRF- and session key"""
59+
output = file_template.safe_substitute(dict(
60+
csrf_key=csrf_key, session_key=session_key
61+
))
62+
if os.path.exists(file_name):
63+
if options.force is None:
64+
print "Warning: secret_keys.py file exists. Use '-f' flag to force overwrite."
65+
else:
66+
write_file(output)
67+
else:
68+
write_file(output)
69+
70+
71+
def main():
72+
r = options.randomness
73+
csrf_key = generate_randomkey(r)
74+
session_key = generate_randomkey(r)
75+
generate_keyfile(csrf_key, session_key)
76+
77+
78+
if __name__ == "__main__":
79+
main()
80+

application/models.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
"""
2+
models.py
3+
4+
App Engine datastore models
5+
6+
"""
7+
8+
9+
from google.appengine.ext import db
10+
11+
12+
class LinkModel(db.Model):
13+
author_id = db.StringProperty(required=True)
14+
link_url = db.StringProperty(required=True)
15+
16+
created_at = db.DateTimeProperty(auto_now_add=True)
17+
updated_at = db.DateTimeProperty(auto_now_add=True)
18+

application/settings.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
"""
2+
settings.py
3+
4+
Configuration for Flask app
5+
6+
Important: Place your keys in the secret_keys.py module,
7+
which should be kept out of version control.
8+
9+
"""
10+
11+
import os
12+
13+
from secret_keys import CSRF_SECRET_KEY, SESSION_KEY
14+
15+
16+
DEBUG_MODE = False
17+
18+
# Auto-set debug mode based on App Engine dev environ
19+
if 'SERVER_SOFTWARE' in os.environ and os.environ['SERVER_SOFTWARE'].startswith('Dev'):
20+
DEBUG_MODE = True
21+
22+
DEBUG = DEBUG_MODE
23+
24+
# Set secret keys for CSRF protection
25+
SECRET_KEY = CSRF_SECRET_KEY
26+
CSRF_SESSION_KEY = SESSION_KEY
27+
28+
CSRF_ENABLED = True
29+

application/static/css/main.css

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
2+
/* Main stylesheet */
3+
4+
html {background-color: #333;}
5+
body {background-color: #fff; margin: 2em auto; width: 960px; padding: 1em; border: 8px solid #ccc;}
6+
form label {display: block;}
7+
8+
/* Your customizations here */

application/static/img/favicon.ico

198 Bytes
Binary file not shown.

application/static/img/favicon.png

200 Bytes
Loading

application/static/js/main.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/* Your custom JavaScript here */

application/static/js/modernizr-2.min.js

Lines changed: 4 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

application/static/robots.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
User-agent: *
2+
Disallow: /

application/templates/404.html

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<!DOCTYPE html>
2+
<title>not found</title>
3+
4+
<style>
5+
body { text-align: center;}
6+
h1 { font-size: 50px; }
7+
body { font: 20px Constantia, 'Hoefler Text', "Adobe Caslon Pro", Baskerville, Georgia, Times, serif; color: #999; text-shadow: 2px 2px 2px rgba(200, 200, 200, 0.5); }
8+
::-moz-selection{ background:#FF5E99; color:#fff; }
9+
::selection { background:#FF5E99; color:#fff; }
10+
details { display:block; }
11+
a { color: rgb(36, 109, 56); text-decoration:none; }
12+
a:hover { color: rgb(96, 73, 141) ; text-shadow: 2px 2px 2px rgba(36, 109, 56, 0.5); }
13+
span[frown] { transform: rotate(90deg); display:inline-block; color: #bbb; }
14+
</style>
15+
16+
17+
18+
19+
<details>
20+
<summary><h1>Not found</h1></summary>
21+
<p><span frown>:(</span></p>
22+
</details>

0 commit comments

Comments
 (0)