-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.py
132 lines (95 loc) · 3.53 KB
/
main.py
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
import logging
import firestore
from flask import current_app, flash, Flask, Markup, redirect, render_template
from flask import request, url_for
from google.cloud import error_reporting
import google.cloud
import storage
# [START upload_image_file]
def upload_image_file(img):
"""
Upload the user-uploaded file to Google Cloud Storage and retrieve its
publicly-accessible URL.
"""
if not img:
return None
public_url = storage.upload_file(
img.read(),
img.filename,
img.content_type
)
current_app.logger.info(
'Uploaded file %s as %s.', img.filename, public_url)
return public_url
# [END upload_image_file]
app = Flask(__name__)
app.config.update(
SECRET_KEY='secret',
MAX_CONTENT_LENGTH=8 * 1024 * 1024,
ALLOWED_EXTENSIONS=set(['png', 'jpg', 'jpeg', 'gif'])
)
app.debug = False
app.testing = False
# Configure logging
if not app.testing:
logging.basicConfig(level=logging.INFO)
client = google.cloud.logging.Client()
# Attaches a Google Stackdriver logging handler to the root logger
client.setup_logging(logging.INFO)
@app.route('/')
def list():
start_after = request.args.get('start_after', None)
books, last_title = firestore.next_page(start_after=start_after)
return render_template('list.html', books=books, last_title=last_title)
@app.route('/books/<book_id>')
def view(book_id):
book = firestore.read(book_id)
return render_template('view.html', book=book)
@app.route('/books/add', methods=['GET', 'POST'])
def add():
if request.method == 'POST':
data = request.form.to_dict(flat=True)
# If an image was uploaded, update the data to point to the new image.
image_url = upload_image_file(request.files.get('image'))
if image_url:
data['imageUrl'] = image_url
book = firestore.create(data)
return redirect(url_for('.view', book_id=book['id']))
return render_template('form.html', action='Add', book={})
@app.route('/books/<book_id>/edit', methods=['GET', 'POST'])
def edit(book_id):
book = firestore.read(book_id)
if request.method == 'POST':
data = request.form.to_dict(flat=True)
# If an image was uploaded, update the data to point to the new image.
image_url = upload_image_file(request.files.get('image'))
if image_url:
data['imageUrl'] = image_url
book = firestore.update(data, book_id)
return redirect(url_for('.view', book_id=book['id']))
return render_template('form.html', action='Edit', book=book)
@app.route('/logs')
def logs():
logging.info('Hey, you triggered a custom log entry. Good job!')
flash(Markup('''You triggered a custom log entry. You can view it in the
<a href="https://console.cloud.google.com/logs">Cloud Console</a>'''))
return redirect(url_for('.list'))
@app.route('/errors')
def errors():
raise Exception('This is an intentional exception.')
# Add an error handler that reports exceptions to Stackdriver Error
# Reporting. Note that this error handler is only used when debug
# is False
@app.errorhandler(500)
def server_error(e):
client = error_reporting.Client()
client.report_exception(
http_context=error_reporting.build_flask_context(request))
return """
An internal error occurred: <pre>{}</pre>
See logs for full stacktrace.
""".format(e), 500
# This is only used when running locally. When running live, gunicorn runs
# the application.
if __name__ == '__main__':
app.run(host='127.0.0.1', port=8080, debug=True)