-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathapp.py
More file actions
197 lines (163 loc) · 6.51 KB
/
app.py
File metadata and controls
197 lines (163 loc) · 6.51 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
import os.path
import uuid
from flask import Flask, render_template, request, abort, session, g,\
send_from_directory, flash, redirect, url_for, after_this_request
from flask.ext.login import LoginManager, login_user, UserMixin, current_user,\
login_required, logout_user
from flask.ext.sqlalchemy import SQLAlchemy
from flask.ext.bootstrap import Bootstrap
from flask.ext.wtf import Form, URL, Required, TextField
from flask.ext.wtf.html5 import URLField
import qrcode
app = Flask(__name__)
app.config['SECRET_KEY'] = 'my_very_secret_key'
app.config['SQLALCHEMY_DATABASE_URI'] = \
'sqlite:///%s' % os.path.join(app.root_path, 'qrimage.db')
db = SQLAlchemy(app)
bootstrap = Bootstrap(app)
login_manager = LoginManager()
login_manager.setup_app(app)
login_manager.login_view = 'login'
@login_manager.user_loader
def load_user(id):
return User.query.get(int(id))
# Models
qrcodes = db.Table('qrcodes',
db.Column('user_id', db.Integer, db.ForeignKey('user.id')),
db.Column('qrcode_id', db.Integer, db.ForeignKey('qrcode.id'))
)
class User(db.Model, UserMixin):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.Unicode, unique=True)
name = db.Column(db.Unicode)
qrcodes = db.relationship('Qrcode', secondary=qrcodes,
backref=db.backref('users', lazy='dynamic'))
def __init__(self, username, name):
self.username = username
self.name = name
def get_id(self):
return unicode(self.id)
class Qrcode(db.Model):
id = db.Column(db.Integer, primary_key=True)
content = db.Column(db.Unicode, unique=True)
filename = db.Column(db.Unicode, unique=True)
#users: This is an implied column
def __init__(self, content):
self.content = content
self.filename = u'%s.png' % uuid.uuid4()
self.save_image_file()
def save_image_file(self):
full_filename = os.path.join(app.instance_path, self.filename)
if not os.path.exists(full_filename):
img = qrcode.make(self.content)
img.save(full_filename)
# Forms
class CreateForm(Form):
url = URLField(u'Enter a URL', validators=[Required(),
URL(message=u'Please enter a well-formed URL')],
description=u'Create a QR code from this URL')
class LoginForm(Form):
username = TextField(u'Enter your user name', validators=[Required(),])
def process_qrcode(content):
# Remove any previously saved QR objects from the current session
session.pop('last_image_id', None)
g.last_image = None
# Find an existing QR code object or create a new one
qr = Qrcode.query.filter_by(content=content).first()
if not qr:
qr = Qrcode(content)
db.session.add(qr)
# Create (or recreate if necessary) an image file for the QR code and assign
# it to the current user (if they're logged in).
qr.save_image_file()
# Commit any changes to the database (to ensure we have ID values)
db.session.commit()
# Populate the session with this QR image
session['last_image_id'] = qr.id
g.last_image = qr
@app.before_request
def before_request():
g.last_image = Qrcode.query.get(session.get('last_image_id', 0))
@app.after_request
def after_request(response):
response.headers['X-Python-North-East'] = 'Pizza Fueled Awesomeness!'
return response
@app.route('/')
def home():
return render_template('home.html')
@app.route('/brew-coffee/', methods=['GET','POST'])
def coffee():
if request.method == 'POST':
abort(418)
return render_template('coffee.html')
@app.route('/create-qrcode/', methods=['GET','POST'])
def create():
form = CreateForm()
if form.validate_on_submit():
process_qrcode(form.url.data)
return render_template('create.html', form=form, show_last_image=True)
return render_template('create.html', form=form)
@app.route('/most-recent/qrcode.png')
@app.route('/most-recent/qrcode.png<download>')
def last_image(download=None):
if g.last_image:
return send_from_directory(app.instance_path, g.last_image.filename,
cache_timeout=0,
mimetype='image/png',
attachment_filename='qrcode.png',
as_attachment=download == '+' or False)
abort(403)
@app.route('/my-qrcodes/')
@login_required
def user_images():
return render_template('user_images.html')
@app.route('/my-qrcodes/<int:id>/qrcode.png')
@app.route('/my-qrcodes/<int:id>/qrcode.png<download>')
@login_required
def user_image(id, download=None):
qr = Qrcode.query.get(id)
if qr in current_user.qrcodes:
return send_from_directory(app.instance_path, qr.filename,
mimetype='image/png',
attachment_filename='qrcode.png',
as_attachment=download == '+' or False)
abort(404)
@app.route('/login', methods=['GET','POST'])
def login():
form = LoginForm()
if form.validate_on_submit():
user = User.query.filter_by(username=form.username.data).first()
if user:
if login_user(user):
flash('You were logged in as %s' % current_user.name, 'success')
if g.last_image:
g.last_image.users.append(user)
db.session.commit()
flash("We added the last QR code you made to your saved list.\
You're welcome.", 'info')
return redirect(request.args.get('next') or url_for('home'))
flash('Sorry, you could not be logged in.', 'error')
flash('Sorry, we could not find that user.', 'warning')
return render_template('login.html', form=form)
@app.route('/logout')
def logout():
session.pop('last_image_id', None)
g.last_image = None
logout_user()
flash('You were logged out.', 'info')
return redirect(request.args.get('next') or url_for('home'))
@app.errorhandler(404)
def resource_missing(error):
return render_template('errors.html', error=error), 404
@app.errorhandler(401)
def resource_forbidden(error):
return render_template('errors.html', error=error), 401
@app.errorhandler(418)
def i_am_a_teapot(error):
@after_this_request
def after_request(response):
response.headers['X-Biscuits'] = 'Rich Tea Please'
return response
return render_template('errors.html', error=error), 418
if __name__ == '__main__':
app.run(debug=True)