48 | {{user}}
49 |
50 |
51 |
--------------------------------------------------------------------------------
/app-engine-lab-2/acggiftart/templates/form.html:
--------------------------------------------------------------------------------
1 | {#
2 | # Copyright 2015 Google Inc.
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License");
5 | # you may not use this file except in compliance with the License.
6 | # You may obtain a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 | #}
16 |
17 | {# [START form] #}
18 | {% extends "base.html" %}
19 |
20 | {% block content %}
21 |
{{action}} artwork
22 |
23 |
47 |
48 | {% endblock %}
49 | {# [END form] #}
50 |
--------------------------------------------------------------------------------
/app-engine-lab-2/acggiftart/templates/list.html:
--------------------------------------------------------------------------------
1 | {#
2 | # Copyright 2015 Google Inc.
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License");
5 | # you may not use this file except in compliance with the License.
6 | # You may obtain a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 | #}
16 |
17 | {% extends "base.html" %}
18 |
19 | {% block content %}
20 |
51 |
52 | {% if next_page_token %}
53 |
58 | {% endif %}
59 |
60 | {% endblock %}
61 |
--------------------------------------------------------------------------------
/app-engine-lab-2/acggiftart/templates/view.html:
--------------------------------------------------------------------------------
1 | {#
2 | # Copyright 2015 Google Inc.
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License");
5 | # you may not use this file except in compliance with the License.
6 | # You may obtain a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 | #}
16 |
17 | {% extends "base.html" %}
18 |
19 | {% block content %}
20 |
21 |
50 |
51 | {% endblock %}
52 |
--------------------------------------------------------------------------------
/app-engine-lab-2/app.yaml:
--------------------------------------------------------------------------------
1 | # Copyright 2015 Google Inc.
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
15 | # This file specifies your Python application's runtime configuration.
16 | # See https://cloud.google.com/appengine/docs/managed-vms/config for details.
17 |
18 | runtime: python
19 | env: flex
20 | entrypoint: gunicorn -b :$PORT main:app
21 |
22 | runtime_config:
23 | python_version: 3
24 |
25 | beta_settings:
26 | # If using Cloud SQL, uncomment and set this value to the Cloud SQL
27 | # connection name, e.g.
28 | # "project:region:cloudsql-instance"
29 | # You must also update the values in config.py.
30 | #
31 | # cloud_sql_instances: "your-cloudsql-connection-name"
32 |
--------------------------------------------------------------------------------
/app-engine-lab-2/assets/generic-ACG-album.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linuxacademy/content-gcpro-developer/87219790d5b064a0ea4fa12281d1e5c3fc10b869/app-engine-lab-2/assets/generic-ACG-album.png
--------------------------------------------------------------------------------
/app-engine-lab-2/config.py:
--------------------------------------------------------------------------------
1 | # Copyright 2015 Google Inc.
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
15 | """
16 | This file contains all of the configuration values for the application.
17 | Update this file with the values for your specific Google Cloud project.
18 | You can create and manage projects at https://console.developers.google.com
19 | """
20 |
21 | import os
22 |
23 | # The secret key is used by Flask to encrypt session cookies.
24 | SECRET_KEY = 'secret'
25 |
26 | # There are three different ways to store the data in the application.
27 | # You can choose 'datastore', 'cloudsql', or 'mongodb'. Be sure to
28 | # configure the respective settings for the one you choose below.
29 | # You do not have to configure the other data backends. If unsure, choose
30 | # 'datastore' as it does not require any additional configuration.
31 | DATA_BACKEND = 'datastore'
32 |
33 | # Google Cloud Project ID. This can be found on the 'Overview' page at
34 | # https://console.developers.google.com
35 | PROJECT_ID = '[YOUR-PROJECT-ID]'
36 |
37 | # CloudSQL & SQLAlchemy configuration
38 | # Replace the following values the respective values of your Cloud SQL
39 | # instance.
40 | CLOUDSQL_USER = 'root'
41 | CLOUDSQL_PASSWORD = 'your-cloudsql-password'
42 | CLOUDSQL_DATABASE = 'acggiftart'
43 | # Set this value to the Cloud SQL connection name, e.g.
44 | # "project:region:cloudsql-instance".
45 | # You must also update the value in app.yaml.
46 | CLOUDSQL_CONNECTION_NAME = 'your-cloudsql-connection-name'
47 |
48 | # The CloudSQL proxy is used locally to connect to the cloudsql instance.
49 | # To start the proxy, use:
50 | #
51 | # $ cloud_sql_proxy -instances=your-connection-name=tcp:3306
52 | #
53 | # Port 3306 is the standard MySQL port. If you need to use a different port,
54 | # change the 3306 to a different port number.
55 |
56 | # Alternatively, you could use a local MySQL instance for testing.
57 | LOCAL_SQLALCHEMY_DATABASE_URI = (
58 | 'mysql+pymysql://{user}:{password}@127.0.0.1:3306/{database}').format(
59 | user=CLOUDSQL_USER, password=CLOUDSQL_PASSWORD,
60 | database=CLOUDSQL_DATABASE)
61 |
62 | # When running on App Engine a unix socket is used to connect to the cloudsql
63 | # instance.
64 | LIVE_SQLALCHEMY_DATABASE_URI = (
65 | 'mysql+pymysql://{user}:{password}@localhost/{database}'
66 | '?unix_socket=/cloudsql/{connection_name}').format(
67 | user=CLOUDSQL_USER, password=CLOUDSQL_PASSWORD,
68 | database=CLOUDSQL_DATABASE, connection_name=CLOUDSQL_CONNECTION_NAME)
69 |
70 | if os.environ.get('GAE_INSTANCE'):
71 | SQLALCHEMY_DATABASE_URI = LIVE_SQLALCHEMY_DATABASE_URI
72 | else:
73 | SQLALCHEMY_DATABASE_URI = LOCAL_SQLALCHEMY_DATABASE_URI
74 |
75 | # Mongo configuration
76 | # If using mongolab, the connection URI is available from the mongolab control
77 | # panel. If self-hosting on compute engine, replace the values below.
78 | MONGO_URI = 'mongodb://user:password@host:27017/database'
79 |
80 | # Google Cloud Storage and upload settings.
81 | # Typically, you'll name your bucket the same as your project. To create a
82 | # bucket:
83 | #
84 | # $ gsutil mb gs://
85 | #
86 | # You also need to make sure that the default ACL is set to public-read,
87 | # otherwise users will not be able to see their upload images:
88 | #
89 | # $ gsutil defacl set public-read gs://
90 | #
91 | # You can adjust the max content length and allow extensions settings to allow
92 | # larger or more varied file types if desired.
93 | CLOUD_STORAGE_BUCKET = '[YOUR-BUCKET-NAME]'
94 | MAX_CONTENT_LENGTH = 8 * 1024 * 1024
95 | ALLOWED_EXTENSIONS = set(['png', 'jpg', 'jpeg', 'gif'])
96 |
--------------------------------------------------------------------------------
/app-engine-lab-2/main.py:
--------------------------------------------------------------------------------
1 | # Copyright 2015 Google Inc.
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
15 | import acggiftart
16 | import config
17 |
18 |
19 | app = acggiftart.create_app(config)
20 |
21 |
22 | # This is only used when running locally. When running live, gunicorn runs
23 | # the application.
24 | if __name__ == '__main__':
25 | app.run(host='127.0.0.1', port=8080, debug=True)
26 |
--------------------------------------------------------------------------------
/app-engine-lab-2/requirements-dev.txt:
--------------------------------------------------------------------------------
1 | tox==2.9.1
2 | flake8==3.5.0
3 | flaky==3.4.0
4 | pytest==3.3.2
5 | pytest-cov==2.5.1
6 | retrying==1.3.3
7 |
--------------------------------------------------------------------------------
/app-engine-lab-2/requirements.txt:
--------------------------------------------------------------------------------
1 | Flask>=2.0.2
2 | google-cloud-datastore==2.3.0
3 | google-cloud-storage==1.42.3
4 | gunicorn==20.1.0
5 | oauth2client==4.1.3
6 | Flask-SQLAlchemy==2.5.1
7 | PyMySQL==1.0.2
8 | Flask-PyMongo==2.3.0
9 | PyMongo==3.12.1
10 | six==1.16.0
11 |
--------------------------------------------------------------------------------
/app-engine-lab/app.yaml:
--------------------------------------------------------------------------------
1 | # Copyright 2015 Google Inc.
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
15 | # This file specifies your Python application's runtime configuration.
16 | # See https://cloud.google.com/appengine/docs/managed-vms/config for details.
17 |
18 | runtime: python
19 | env: flex
20 | entrypoint: gunicorn -b :$PORT main:app
21 |
22 | runtime_config:
23 | python_version: 3
24 |
25 | beta_settings:
26 | # If using Cloud SQL, uncomment and set this value to the Cloud SQL
27 | # connection name, e.g.
28 | # "project:region:cloudsql-instance"
29 | # You must also update the values in config.py.
30 | #
31 | # cloud_sql_instances: "your-cloudsql-connection-name"
32 |
--------------------------------------------------------------------------------
/app-engine-lab/assets/LaGiftArt.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linuxacademy/content-gcpro-developer/87219790d5b064a0ea4fa12281d1e5c3fc10b869/app-engine-lab/assets/LaGiftArt.png
--------------------------------------------------------------------------------
/app-engine-lab/assets/albums/Grace-Jones-Island-Life-album-cover.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linuxacademy/content-gcpro-developer/87219790d5b064a0ea4fa12281d1e5c3fc10b869/app-engine-lab/assets/albums/Grace-Jones-Island-Life-album-cover.jpg
--------------------------------------------------------------------------------
/app-engine-lab/assets/albums/The-Beatles-Sgt-Peppers-Lonely-Hearts-Club-Band-Album-Cover-530.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linuxacademy/content-gcpro-developer/87219790d5b064a0ea4fa12281d1e5c3fc10b869/app-engine-lab/assets/albums/The-Beatles-Sgt-Peppers-Lonely-Hearts-Club-Band-Album-Cover-530.jpg
--------------------------------------------------------------------------------
/app-engine-lab/assets/albums/aladdin-sane-david-bowie-768x768.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linuxacademy/content-gcpro-developer/87219790d5b064a0ea4fa12281d1e5c3fc10b869/app-engine-lab/assets/albums/aladdin-sane-david-bowie-768x768.jpg
--------------------------------------------------------------------------------
/app-engine-lab/assets/albums/apollo-18.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linuxacademy/content-gcpro-developer/87219790d5b064a0ea4fa12281d1e5c3fc10b869/app-engine-lab/assets/albums/apollo-18.jpg
--------------------------------------------------------------------------------
/app-engine-lab/assets/albums/houses-of-the-holy.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linuxacademy/content-gcpro-developer/87219790d5b064a0ea4fa12281d1e5c3fc10b869/app-engine-lab/assets/albums/houses-of-the-holy.jpg
--------------------------------------------------------------------------------
/app-engine-lab/assets/generic-LA-album.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linuxacademy/content-gcpro-developer/87219790d5b064a0ea4fa12281d1e5c3fc10b869/app-engine-lab/assets/generic-LA-album.png
--------------------------------------------------------------------------------
/app-engine-lab/config.py:
--------------------------------------------------------------------------------
1 | # Copyright 2015 Google Inc.
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
15 | """
16 | This file contains all of the configuration values for the application.
17 | Update this file with the values for your specific Google Cloud project.
18 | You can create and manage projects at https://console.developers.google.com
19 | """
20 |
21 | import os
22 |
23 | # The secret key is used by Flask to encrypt session cookies.
24 | SECRET_KEY = 'secret'
25 |
26 | # There are three different ways to store the data in the application.
27 | # You can choose 'datastore', 'cloudsql', or 'mongodb'. Be sure to
28 | # configure the respective settings for the one you choose below.
29 | # You do not have to configure the other data backends. If unsure, choose
30 | # 'datastore' as it does not require any additional configuration.
31 | DATA_BACKEND = 'datastore'
32 |
33 | # Google Cloud Project ID. This can be found on the 'Overview' page at
34 | # https://console.developers.google.com
35 | PROJECT_ID = '[YOUR-PROJECT-ID]'
36 |
37 | # CloudSQL & SQLAlchemy configuration
38 | # Replace the following values the respective values of your Cloud SQL
39 | # instance.
40 | CLOUDSQL_USER = 'root'
41 | CLOUDSQL_PASSWORD = 'your-cloudsql-password'
42 | CLOUDSQL_DATABASE = 'lagiftart'
43 | # Set this value to the Cloud SQL connection name, e.g.
44 | # "project:region:cloudsql-instance".
45 | # You must also update the value in app.yaml.
46 | CLOUDSQL_CONNECTION_NAME = 'your-cloudsql-connection-name'
47 |
48 | # The CloudSQL proxy is used locally to connect to the cloudsql instance.
49 | # To start the proxy, use:
50 | #
51 | # $ cloud_sql_proxy -instances=your-connection-name=tcp:3306
52 | #
53 | # Port 3306 is the standard MySQL port. If you need to use a different port,
54 | # change the 3306 to a different port number.
55 |
56 | # Alternatively, you could use a local MySQL instance for testing.
57 | LOCAL_SQLALCHEMY_DATABASE_URI = (
58 | 'mysql+pymysql://{user}:{password}@127.0.0.1:3306/{database}').format(
59 | user=CLOUDSQL_USER, password=CLOUDSQL_PASSWORD,
60 | database=CLOUDSQL_DATABASE)
61 |
62 | # When running on App Engine a unix socket is used to connect to the cloudsql
63 | # instance.
64 | LIVE_SQLALCHEMY_DATABASE_URI = (
65 | 'mysql+pymysql://{user}:{password}@localhost/{database}'
66 | '?unix_socket=/cloudsql/{connection_name}').format(
67 | user=CLOUDSQL_USER, password=CLOUDSQL_PASSWORD,
68 | database=CLOUDSQL_DATABASE, connection_name=CLOUDSQL_CONNECTION_NAME)
69 |
70 | if os.environ.get('GAE_INSTANCE'):
71 | SQLALCHEMY_DATABASE_URI = LIVE_SQLALCHEMY_DATABASE_URI
72 | else:
73 | SQLALCHEMY_DATABASE_URI = LOCAL_SQLALCHEMY_DATABASE_URI
74 |
75 | # Mongo configuration
76 | # If using mongolab, the connection URI is available from the mongolab control
77 | # panel. If self-hosting on compute engine, replace the values below.
78 | MONGO_URI = 'mongodb://user:password@host:27017/database'
79 |
80 | # Google Cloud Storage and upload settings.
81 | # Typically, you'll name your bucket the same as your project. To create a
82 | # bucket:
83 | #
84 | # $ gsutil mb gs://
85 | #
86 | # You also need to make sure that the default ACL is set to public-read,
87 | # otherwise users will not be able to see their upload images:
88 | #
89 | # $ gsutil defacl set public-read gs://
90 | #
91 | # You can adjust the max content length and allow extensions settings to allow
92 | # larger or more varied file types if desired.
93 | CLOUD_STORAGE_BUCKET = '[YOUR-BUCKET-NAME]'
94 | MAX_CONTENT_LENGTH = 8 * 1024 * 1024
95 | ALLOWED_EXTENSIONS = set(['png', 'jpg', 'jpeg', 'gif'])
96 |
--------------------------------------------------------------------------------
/app-engine-lab/lagiftart/__init__.py:
--------------------------------------------------------------------------------
1 | # Copyright 2015 Google Inc.
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
15 | import logging
16 |
17 | from flask import current_app, Flask, redirect, url_for
18 |
19 |
20 | def create_app(config, debug=False, testing=False, config_overrides=None):
21 | app = Flask(__name__)
22 | app.config.from_object(config)
23 |
24 | app.debug = debug
25 | app.testing = testing
26 |
27 | if config_overrides:
28 | app.config.update(config_overrides)
29 |
30 | # Configure logging
31 | if not app.testing:
32 | logging.basicConfig(level=logging.INFO)
33 |
34 | # Setup the data model.
35 | with app.app_context():
36 | model = get_model()
37 | model.init_app(app)
38 |
39 | # Register the LaGiftArt CRUD blueprint.
40 | from .crud import crud
41 | app.register_blueprint(crud, url_prefix='/artworks')
42 |
43 | # Add a default root route.
44 | @app.route("/")
45 | def index():
46 | return redirect(url_for('crud.list'))
47 |
48 | # Add an error handler. This is useful for debugging the live application,
49 | # however, you should disable the output of the exception for production
50 | # applications.
51 | @app.errorhandler(500)
52 | def server_error(e):
53 | return """
54 | An internal error occurred:
{}
55 | See logs for full stacktrace.
56 | """.format(e), 500
57 |
58 | return app
59 |
60 |
61 | def get_model():
62 | model_backend = current_app.config['DATA_BACKEND']
63 | if model_backend == 'cloudsql':
64 | from . import model_cloudsql
65 | model = model_cloudsql
66 | elif model_backend == 'datastore':
67 | from . import model_datastore
68 | model = model_datastore
69 | elif model_backend == 'mongodb':
70 | from . import model_mongodb
71 | model = model_mongodb
72 | else:
73 | raise ValueError(
74 | "No appropriate databackend configured. "
75 | "Please specify datastore, cloudsql, or mongodb")
76 |
77 | return model
78 |
--------------------------------------------------------------------------------
/app-engine-lab/lagiftart/crud.py:
--------------------------------------------------------------------------------
1 | # Copyright 2015 Google Inc.
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
15 | from lagiftart import get_model, storage
16 | from flask import Blueprint, current_app, redirect, render_template, request, \
17 | url_for
18 |
19 |
20 | crud = Blueprint('crud', __name__)
21 |
22 |
23 | # [START upload_image_file]
24 | def upload_image_file(file):
25 | """
26 | Upload the user-uploaded file to Google Cloud Storage and retrieve its
27 | publicly-accessible URL.
28 | """
29 | if not file:
30 | return None
31 |
32 | public_url = storage.upload_file(
33 | file.read(),
34 | file.filename,
35 | file.content_type
36 | )
37 |
38 | current_app.logger.info(
39 | "Uploaded file %s as %s.", file.filename, public_url)
40 |
41 | return public_url
42 | # [END upload_image_file]
43 |
44 |
45 | @crud.route("/")
46 | def list():
47 | token = request.args.get('page_token', None)
48 | if token:
49 | token = token.encode('utf-8')
50 |
51 | artworks, next_page_token = get_model().list(cursor=token)
52 |
53 | return render_template(
54 | "list.html",
55 | artworks=artworks,
56 | next_page_token=next_page_token)
57 |
58 |
59 | @crud.route('/')
60 | def view(id):
61 | artwork = get_model().read(id)
62 | return render_template("view.html", artwork=artwork)
63 |
64 |
65 | @crud.route('/add', methods=['GET', 'POST'])
66 | def add():
67 | if request.method == 'POST':
68 | data = request.form.to_dict(flat=True)
69 |
70 | # If an image was uploaded, update the data to point to the new image.
71 | # [START image_url]
72 | image_url = upload_image_file(request.files.get('photo'))
73 | # [END image_url]
74 |
75 | # [START image_url2]
76 | if image_url:
77 | data['photoUrl'] = image_url
78 | # [END image_url2]
79 |
80 | artwork = get_model().create(data)
81 |
82 | return redirect(url_for('.view', id=artwork['id']))
83 |
84 | return render_template("form.html", action="Add", artwork={})
85 |
86 |
87 | @crud.route('//edit', methods=['GET', 'POST'])
88 | def edit(id):
89 | artwork = get_model().read(id)
90 |
91 | if request.method == 'POST':
92 | data = request.form.to_dict(flat=True)
93 |
94 | image_url = upload_image_file(request.files.get('photo'))
95 |
96 | if image_url:
97 | data['photoUrl'] = image_url
98 |
99 | artwork = get_model().update(data, id)
100 |
101 | return redirect(url_for('.view', id=artwork['id']))
102 |
103 | return render_template("form.html", action="Edit", artwork=artwork)
104 |
105 |
106 | @crud.route('//delete')
107 | def delete(id):
108 | get_model().delete(id)
109 | return redirect(url_for('.list'))
110 |
--------------------------------------------------------------------------------
/app-engine-lab/lagiftart/model_cloudsql.py:
--------------------------------------------------------------------------------
1 | # Copyright 2015 Google Inc.
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
15 | from flask import Flask
16 | from flask_sqlalchemy import SQLAlchemy
17 |
18 |
19 | builtin_list = list
20 |
21 |
22 | db = SQLAlchemy()
23 |
24 |
25 | def init_app(app):
26 | # Disable track modifications, as it unnecessarily uses memory.
27 | app.config.setdefault('SQLALCHEMY_TRACK_MODIFICATIONS', False)
28 | db.init_app(app)
29 |
30 |
31 | def from_sql(row):
32 | """Translates a SQLAlchemy model instance into a dictionary"""
33 | data = row.__dict__.copy()
34 | data['id'] = row.id
35 | data.pop('_sa_instance_state')
36 | return data
37 |
38 |
39 | class Book(db.Model):
40 | __tablename__ = 'albums'
41 |
42 | id = db.Column(db.Integer, primary_key=True)
43 | title = db.Column(db.String(255))
44 | author = db.Column(db.String(255))
45 | publishedDate = db.Column(db.String(255))
46 | imageUrl = db.Column(db.String(255))
47 | description = db.Column(db.String(4096))
48 | createdBy = db.Column(db.String(255))
49 | createdById = db.Column(db.String(255))
50 |
51 | def __repr__(self):
52 | return "
17 |
18 |
19 | LaGiftArt
20 |
21 |
22 |
23 |
24 |
25 |
26 |
46 | {{user}}
47 |
48 |
49 |
--------------------------------------------------------------------------------
/app-engine-lab/lagiftart/templates/form.html:
--------------------------------------------------------------------------------
1 | {#
2 | # Copyright 2015 Google Inc.
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License");
5 | # you may not use this file except in compliance with the License.
6 | # You may obtain a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 | #}
16 |
17 | {# [START form] #}
18 | {% extends "base.html" %}
19 |
20 | {% block content %}
21 |
{{action}} artwork
22 |
23 |
47 |
48 | {% endblock %}
49 | {# [END form] #}
50 |
--------------------------------------------------------------------------------
/app-engine-lab/lagiftart/templates/list.html:
--------------------------------------------------------------------------------
1 | {#
2 | # Copyright 2015 Google Inc.
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License");
5 | # you may not use this file except in compliance with the License.
6 | # You may obtain a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 | #}
16 |
17 | {% extends "base.html" %}
18 |
19 | {% block content %}
20 |
51 |
52 | {% if next_page_token %}
53 |
58 | {% endif %}
59 |
60 | {% endblock %}
61 |
--------------------------------------------------------------------------------
/app-engine-lab/lagiftart/templates/view.html:
--------------------------------------------------------------------------------
1 | {#
2 | # Copyright 2015 Google Inc.
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License");
5 | # you may not use this file except in compliance with the License.
6 | # You may obtain a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 | #}
16 |
17 | {% extends "base.html" %}
18 |
19 | {% block content %}
20 |
21 |