├── src ├── eclipse_gis │ ├── test │ │ ├── __init__.py │ │ └── test_eclipse_gis.py │ ├── src │ │ └── eclipse_gis │ │ │ └── __init__.py │ └── requirements.txt ├── export_eclipse_dataset │ ├── .gitignore │ ├── exiftool_cmd │ ├── exiftool_stripped_cmd │ ├── README.md │ ├── generate_random_id.py │ ├── determine_state.py │ ├── filter_photos.py │ └── extract_metadata_from_datastore.py ├── solar_eclipse_analysis │ ├── eclipse_gis │ │ └── __init__.py │ ├── data │ │ ├── Map_pin.png │ │ ├── berkeley_logo.png │ │ ├── EclipseMovie_logo.png │ │ ├── Grey_map_withline.png │ │ ├── logo_footer_google.png │ │ ├── logo_footer_berkeley.png │ │ ├── EclipseMovie_logo_crop.png │ │ └── collaborator2_Berkeley.png │ ├── ProductSans-Regular.ttf │ ├── geometry.py │ ├── README.md │ ├── read_image_exif.py │ ├── renumber_movie.py │ ├── exif.py │ ├── find_circles.py │ └── map_util.py └── solar_eclipse_renderer │ ├── lune.py │ ├── coords.py │ ├── render_constants.py │ └── convert_location.py ├── app-container ├── conf │ └── requirements.txt └── templates │ └── Dockerfile.tmpl ├── system-test-container ├── conf │ └── requirements.txt ├── app │ ├── __init__.py │ ├── tests │ │ └── __init__.py │ └── run_tests └── templates │ ├── Dockerfile.tmpl │ └── upload_stress_test_pod.yaml.tmpl ├── upload ├── system_tests │ ├── conf │ │ ├── requirements.txt │ │ └── test-supervisor.conf │ ├── app │ │ ├── __init__.py │ │ ├── tests │ │ │ └── __init__.py │ │ └── main.py │ └── templates │ │ └── Dockerfile.tmpl ├── server │ ├── README.md │ ├── app │ │ ├── __init__.py │ │ ├── backend │ │ │ └── __init__.py │ │ └── main.py │ ├── tests │ │ ├── __init__.py │ │ ├── backend │ │ │ └── __init__.py │ │ ├── run_tests │ │ └── upload_server_test_base.py │ └── templates │ │ └── Dockerfile.tmpl ├── daemon │ ├── app │ │ └── __init__.py │ ├── templates │ │ └── Dockerfile.tmpl │ └── tests │ │ └── run_tests ├── nginx │ └── templates │ │ └── Dockerfile.tmpl └── templates │ └── test_pod.yaml.tmpl ├── static-nginx ├── app │ └── static │ │ ├── README.md │ │ ├── src │ │ ├── movie-id.js │ │ ├── simulator │ │ │ └── img │ │ │ │ ├── sun.png │ │ │ │ ├── background.png │ │ │ │ ├── background_dark.png │ │ │ │ └── background_dark_nostars.png │ │ ├── string-endswith-polyfill.js │ │ ├── behaviors │ │ │ └── eclipse-debug-logger.html │ │ ├── eclipse-view404.html │ │ ├── shared-styles.html │ │ ├── eclipse-icons.html │ │ ├── array-findindex-polyfill.js │ │ └── array-includes-polyfill.js │ │ ├── images │ │ ├── bhlogo.jpg │ │ ├── favicon.ico │ │ ├── 01_Home_01.jpg │ │ ├── 01_Home_03.png │ │ ├── 01_Home_04.png │ │ ├── 01_Home_05.png │ │ ├── resources-1.png │ │ ├── 02_Eclipse_04.png │ │ ├── camera_gps-01.png │ │ ├── camera_only-01.png │ │ ├── camera_only-02.png │ │ ├── camera_only-03.png │ │ ├── camera_only-04.png │ │ ├── camera_only-05.png │ │ ├── camera_only-06.png │ │ ├── 03_Megamovie_04.jpg │ │ ├── Icon_arrow_down.png │ │ ├── manifest │ │ │ ├── favicon.ico │ │ │ ├── favicon-16x16.png │ │ │ ├── favicon-32x32.png │ │ │ ├── mstile-150x150.png │ │ │ ├── apple-touch-icon.png │ │ │ ├── android-chrome-192x192.png │ │ │ ├── android-chrome-256x256.png │ │ │ ├── android-chrome-512x512.png │ │ │ └── browserconfig.xml │ │ ├── opengraph_image.png │ │ ├── profile_header-01.png │ │ ├── logo_footer_google.png │ │ ├── collaborator1_Google.png │ │ ├── collaborator2_Berkeley.png │ │ ├── logo_footer_berkeley.png │ │ └── Ribbon.svg │ │ ├── manifest.json │ │ ├── package.json │ │ ├── service-worker.js │ │ ├── polymer.json │ │ ├── sw-precache-config.js │ │ ├── test │ │ └── index.html │ │ └── sitemap.xml ├── conf │ └── cors.json └── templates │ ├── Dockerfile.tmpl │ ├── deployment.yaml.tmpl │ └── pod.yaml.tmpl ├── admin ├── app │ ├── conf │ │ └── requirements.txt │ ├── app │ │ ├── __init__.py │ │ └── backend │ │ │ ├── __init__.py │ │ │ ├── eclipse2017_admin_app.py │ │ │ └── routes.py │ ├── tests │ │ ├── flask │ │ │ ├── __init__.py │ │ │ ├── backend │ │ │ │ └── __init__.py │ │ │ └── run_flask_tests │ │ └── run_tests │ └── templates │ │ └── Dockerfile.tmpl ├── nginx │ └── templates │ │ └── Dockerfile.tmpl └── templates │ └── deployment.yaml.tmpl ├── movie ├── daemon │ ├── conf │ │ └── requirements.txt │ ├── app │ │ └── __init__.py │ ├── tests │ │ └── run_tests │ └── templates │ │ └── Dockerfile.tmpl └── templates │ └── deployment.yaml.tmpl ├── test-container ├── conf │ └── requirements.txt └── templates │ └── Dockerfile.tmpl ├── base-container ├── requirements.txt └── Dockerfile ├── package.json ├── nginx-lb-emulator ├── resources │ ├── upload.conf │ ├── cors.conf │ ├── lb-emulator.crt │ └── lb-emulator.key └── templates │ ├── Dockerfile.tmpl │ └── nginx.conf.tmpl ├── common ├── geometry.py ├── __init__.py ├── image_sorter.py ├── find_circles.py ├── chunks.py ├── flask_users.py ├── id_token.py ├── service_account.py ├── eclipse2017_exceptions.py ├── test_common.py ├── users.py ├── cluster_points.py ├── exif.py └── map_util.py ├── common_tests ├── __init__.py ├── install_dependencies ├── run_tests └── image_sorter_test.py ├── geo ├── app │ ├── app │ │ ├── __init__.py │ │ └── backend │ │ │ ├── __init__.py │ │ │ ├── eclipse2017_app.py │ │ │ └── routes.py │ └── templates │ │ └── Dockerfile.tmpl ├── nginx │ └── templates │ │ └── Dockerfile.tmpl └── templates │ └── deployment.yaml.tmpl ├── photo ├── app │ ├── app │ │ ├── __init__.py │ │ └── backend │ │ │ ├── __init__.py │ │ │ ├── eclipse2017_photo_app.py │ │ │ └── routes.py │ └── templates │ │ └── Dockerfile.tmpl ├── nginx │ └── templates │ │ └── Dockerfile.tmpl └── templates │ └── deployment.yaml.tmpl ├── profile ├── app │ ├── app │ │ ├── __init__.py │ │ └── backend │ │ │ ├── __init__.py │ │ │ ├── eclipse2017_app.py │ │ │ └── routes.py │ ├── tests │ │ ├── flask │ │ │ ├── __init__.py │ │ │ ├── backend │ │ │ │ └── __init__.py │ │ │ └── run_flask_tests │ │ └── run_tests │ ├── README.md │ └── templates │ │ └── Dockerfile.tmpl ├── nginx │ └── templates │ │ └── Dockerfile.tmpl └── templates │ └── deployment.yaml.tmpl ├── image-processor ├── daemon │ ├── app │ │ └── __init__.py │ └── templates │ │ └── Dockerfile.tmpl └── templates │ └── deployment.yaml.tmpl ├── index.yaml ├── scripts ├── run_all_tests.sh ├── upload_many_datas ├── static-build.sh ├── _ingress ├── _create_secret ├── oss_release.sh ├── _systest ├── _update ├── _push ├── _clean ├── map_point.py ├── _unittest ├── print_photos.py ├── print_processed_photos.py ├── _teardown ├── print_users.py ├── add_movie.py ├── extract_metadata.py ├── delete_processed_photos.py ├── create_user.py ├── inspect_clusters.py ├── movie_tool.py ├── get_user_ids.py └── final_numbers_report.py ├── templates └── config.py.tmpl ├── CONTRIBUTING.md ├── nginx-container └── templates │ └── Dockerfile.tmpl ├── .gitignore ├── ingress.yaml └── datastore-emulator └── templates └── Dockerfile.tmpl /src/eclipse_gis/test/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/eclipse_gis/src/eclipse_gis/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app-container/conf/requirements.txt: -------------------------------------------------------------------------------- 1 | Flask==0.12 2 | -------------------------------------------------------------------------------- /src/export_eclipse_dataset/.gitignore: -------------------------------------------------------------------------------- 1 | conf.sh 2 | -------------------------------------------------------------------------------- /src/solar_eclipse_analysis/eclipse_gis/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /system-test-container/conf/requirements.txt: -------------------------------------------------------------------------------- 1 | requests 2 | -------------------------------------------------------------------------------- /upload/system_tests/conf/requirements.txt: -------------------------------------------------------------------------------- 1 | requests 2 | -------------------------------------------------------------------------------- /static-nginx/app/static/README.md: -------------------------------------------------------------------------------- 1 | # Eclipse Megamovie App 2 | -------------------------------------------------------------------------------- /admin/app/conf/requirements.txt: -------------------------------------------------------------------------------- 1 | numpy 2 | scipy 3 | scikit-learn 4 | -------------------------------------------------------------------------------- /src/eclipse_gis/requirements.txt: -------------------------------------------------------------------------------- 1 | shapely 2 | unittest2 3 | pyproj 4 | -------------------------------------------------------------------------------- /static-nginx/app/static/src/movie-id.js: -------------------------------------------------------------------------------- 1 | var movie_id = 'qw-EFL1vxQ4'; 2 | -------------------------------------------------------------------------------- /movie/daemon/conf/requirements.txt: -------------------------------------------------------------------------------- 1 | numpy 2 | scipy 3 | scikit-learn 4 | matplotlib 5 | -------------------------------------------------------------------------------- /src/export_eclipse_dataset/exiftool_cmd: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | b=$(basename $1) 3 | exiftool -c "+%.6f" -a -G1 -s $1 > /mnt/dek/tmp/$b.exif.txt 4 | -------------------------------------------------------------------------------- /static-nginx/app/static/images/bhlogo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/eclipse2017/HEAD/static-nginx/app/static/images/bhlogo.jpg -------------------------------------------------------------------------------- /static-nginx/app/static/images/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/eclipse2017/HEAD/static-nginx/app/static/images/favicon.ico -------------------------------------------------------------------------------- /src/solar_eclipse_analysis/data/Map_pin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/eclipse2017/HEAD/src/solar_eclipse_analysis/data/Map_pin.png -------------------------------------------------------------------------------- /static-nginx/app/static/images/01_Home_01.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/eclipse2017/HEAD/static-nginx/app/static/images/01_Home_01.jpg -------------------------------------------------------------------------------- /static-nginx/app/static/images/01_Home_03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/eclipse2017/HEAD/static-nginx/app/static/images/01_Home_03.png -------------------------------------------------------------------------------- /static-nginx/app/static/images/01_Home_04.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/eclipse2017/HEAD/static-nginx/app/static/images/01_Home_04.png -------------------------------------------------------------------------------- /static-nginx/app/static/images/01_Home_05.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/eclipse2017/HEAD/static-nginx/app/static/images/01_Home_05.png -------------------------------------------------------------------------------- /static-nginx/app/static/images/resources-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/eclipse2017/HEAD/static-nginx/app/static/images/resources-1.png -------------------------------------------------------------------------------- /src/solar_eclipse_analysis/data/berkeley_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/eclipse2017/HEAD/src/solar_eclipse_analysis/data/berkeley_logo.png -------------------------------------------------------------------------------- /static-nginx/app/static/images/02_Eclipse_04.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/eclipse2017/HEAD/static-nginx/app/static/images/02_Eclipse_04.png -------------------------------------------------------------------------------- /static-nginx/app/static/images/camera_gps-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/eclipse2017/HEAD/static-nginx/app/static/images/camera_gps-01.png -------------------------------------------------------------------------------- /static-nginx/app/static/images/camera_only-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/eclipse2017/HEAD/static-nginx/app/static/images/camera_only-01.png -------------------------------------------------------------------------------- /static-nginx/app/static/images/camera_only-02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/eclipse2017/HEAD/static-nginx/app/static/images/camera_only-02.png -------------------------------------------------------------------------------- /static-nginx/app/static/images/camera_only-03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/eclipse2017/HEAD/static-nginx/app/static/images/camera_only-03.png -------------------------------------------------------------------------------- /static-nginx/app/static/images/camera_only-04.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/eclipse2017/HEAD/static-nginx/app/static/images/camera_only-04.png -------------------------------------------------------------------------------- /static-nginx/app/static/images/camera_only-05.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/eclipse2017/HEAD/static-nginx/app/static/images/camera_only-05.png -------------------------------------------------------------------------------- /static-nginx/app/static/images/camera_only-06.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/eclipse2017/HEAD/static-nginx/app/static/images/camera_only-06.png -------------------------------------------------------------------------------- /static-nginx/app/static/src/simulator/img/sun.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/eclipse2017/HEAD/static-nginx/app/static/src/simulator/img/sun.png -------------------------------------------------------------------------------- /src/export_eclipse_dataset/exiftool_stripped_cmd: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | b=$(basename $1) 3 | exiftool -c "+%.6f" -a -G1 -s $1 > /mnt/dek/exif-stripped/$b.exif.txt 4 | -------------------------------------------------------------------------------- /src/solar_eclipse_analysis/ProductSans-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/eclipse2017/HEAD/src/solar_eclipse_analysis/ProductSans-Regular.ttf -------------------------------------------------------------------------------- /static-nginx/app/static/images/03_Megamovie_04.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/eclipse2017/HEAD/static-nginx/app/static/images/03_Megamovie_04.jpg -------------------------------------------------------------------------------- /static-nginx/app/static/images/Icon_arrow_down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/eclipse2017/HEAD/static-nginx/app/static/images/Icon_arrow_down.png -------------------------------------------------------------------------------- /static-nginx/app/static/images/manifest/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/eclipse2017/HEAD/static-nginx/app/static/images/manifest/favicon.ico -------------------------------------------------------------------------------- /static-nginx/app/static/images/opengraph_image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/eclipse2017/HEAD/static-nginx/app/static/images/opengraph_image.png -------------------------------------------------------------------------------- /static-nginx/app/static/images/profile_header-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/eclipse2017/HEAD/static-nginx/app/static/images/profile_header-01.png -------------------------------------------------------------------------------- /src/solar_eclipse_analysis/data/EclipseMovie_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/eclipse2017/HEAD/src/solar_eclipse_analysis/data/EclipseMovie_logo.png -------------------------------------------------------------------------------- /src/solar_eclipse_analysis/data/Grey_map_withline.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/eclipse2017/HEAD/src/solar_eclipse_analysis/data/Grey_map_withline.png -------------------------------------------------------------------------------- /src/solar_eclipse_analysis/data/logo_footer_google.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/eclipse2017/HEAD/src/solar_eclipse_analysis/data/logo_footer_google.png -------------------------------------------------------------------------------- /src/solar_eclipse_analysis/geometry.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | def ratio_to_decimal(ratio): 4 | return ratio.num / float(ratio.den) 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /static-nginx/app/static/images/logo_footer_google.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/eclipse2017/HEAD/static-nginx/app/static/images/logo_footer_google.png -------------------------------------------------------------------------------- /src/solar_eclipse_analysis/data/logo_footer_berkeley.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/eclipse2017/HEAD/src/solar_eclipse_analysis/data/logo_footer_berkeley.png -------------------------------------------------------------------------------- /static-nginx/app/static/images/collaborator1_Google.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/eclipse2017/HEAD/static-nginx/app/static/images/collaborator1_Google.png -------------------------------------------------------------------------------- /static-nginx/app/static/images/collaborator2_Berkeley.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/eclipse2017/HEAD/static-nginx/app/static/images/collaborator2_Berkeley.png -------------------------------------------------------------------------------- /static-nginx/app/static/images/logo_footer_berkeley.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/eclipse2017/HEAD/static-nginx/app/static/images/logo_footer_berkeley.png -------------------------------------------------------------------------------- /static-nginx/app/static/images/manifest/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/eclipse2017/HEAD/static-nginx/app/static/images/manifest/favicon-16x16.png -------------------------------------------------------------------------------- /static-nginx/app/static/images/manifest/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/eclipse2017/HEAD/static-nginx/app/static/images/manifest/favicon-32x32.png -------------------------------------------------------------------------------- /static-nginx/app/static/src/simulator/img/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/eclipse2017/HEAD/static-nginx/app/static/src/simulator/img/background.png -------------------------------------------------------------------------------- /src/solar_eclipse_analysis/data/EclipseMovie_logo_crop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/eclipse2017/HEAD/src/solar_eclipse_analysis/data/EclipseMovie_logo_crop.png -------------------------------------------------------------------------------- /src/solar_eclipse_analysis/data/collaborator2_Berkeley.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/eclipse2017/HEAD/src/solar_eclipse_analysis/data/collaborator2_Berkeley.png -------------------------------------------------------------------------------- /static-nginx/app/static/images/manifest/mstile-150x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/eclipse2017/HEAD/static-nginx/app/static/images/manifest/mstile-150x150.png -------------------------------------------------------------------------------- /static-nginx/conf/cors.json: -------------------------------------------------------------------------------- 1 | [{"maxAgeSeconds": 3600, "method": ["GET", "HEAD"], "origin": ["https://prod.eclipsemega.movie"], "responseHeader": ["Content-Type"]}] 2 | 3 | -------------------------------------------------------------------------------- /static-nginx/app/static/images/manifest/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/eclipse2017/HEAD/static-nginx/app/static/images/manifest/apple-touch-icon.png -------------------------------------------------------------------------------- /static-nginx/app/static/src/simulator/img/background_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/eclipse2017/HEAD/static-nginx/app/static/src/simulator/img/background_dark.png -------------------------------------------------------------------------------- /static-nginx/app/static/images/manifest/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/eclipse2017/HEAD/static-nginx/app/static/images/manifest/android-chrome-192x192.png -------------------------------------------------------------------------------- /static-nginx/app/static/images/manifest/android-chrome-256x256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/eclipse2017/HEAD/static-nginx/app/static/images/manifest/android-chrome-256x256.png -------------------------------------------------------------------------------- /static-nginx/app/static/images/manifest/android-chrome-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/eclipse2017/HEAD/static-nginx/app/static/images/manifest/android-chrome-512x512.png -------------------------------------------------------------------------------- /test-container/conf/requirements.txt: -------------------------------------------------------------------------------- 1 | googlemaps 2 | Flask==0.12 3 | unittest2 4 | mock 5 | six 6 | httplib2 7 | selenium 8 | numpy 9 | scipy 10 | scikit-learn 11 | matplotlib 12 | -------------------------------------------------------------------------------- /static-nginx/app/static/src/simulator/img/background_dark_nostars.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/eclipse2017/HEAD/static-nginx/app/static/src/simulator/img/background_dark_nostars.png -------------------------------------------------------------------------------- /upload/system_tests/conf/test-supervisor.conf: -------------------------------------------------------------------------------- 1 | [program:upload-system-tests] 2 | command = python main.py 3 | directory = /app 4 | user = www-data 5 | stdout_logfile=/dev/stdout 6 | stdout_logfile_maxbytes=0 7 | stderr_logfile=/dev/stderr 8 | stderr_logfile_maxbytes=0 9 | -------------------------------------------------------------------------------- /base-container/requirements.txt: -------------------------------------------------------------------------------- 1 | numpy 2 | google-cloud-core==0.26.0 3 | google-cloud-vision==0.26.0 4 | google-cloud-datastore==1.1.0 5 | google-cloud-storage==1.3.2 6 | google-auth 7 | oauth2client==4.0.0 8 | protobuf==3.0.0 9 | unittest2 10 | mock 11 | requests 12 | googlemaps 13 | shapely 14 | pillow 15 | exifread 16 | rawkit 17 | 18 | -------------------------------------------------------------------------------- /static-nginx/app/static/images/manifest/browserconfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | #da532c 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /upload/server/README.md: -------------------------------------------------------------------------------- 1 | **To run locally:** 2 | 3 | After building the docker image and completing the following, you will be able 4 | to access the app at http://localhost:8080, however note that the only endpoints 5 | are the POST only upload endpoint and the health check. 6 | 7 | ```bash 8 | $ cd upload/server 9 | $ docker run -p 8080:8080 10 | ``` 11 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "eclipse-megamovie-build", 3 | "version": "0.0.0", 4 | "description": "Eclipse Megamovie build system", 5 | "devDependencies": { 6 | "bower": "1.8", 7 | "polymer-cli": "1.1.0", 8 | "generator-polymer-init-custom-build": "2.0.1" 9 | }, 10 | "engines": { 11 | "node": "6.0" 12 | }, 13 | "private": true 14 | } 15 | -------------------------------------------------------------------------------- /src/export_eclipse_dataset/README.md: -------------------------------------------------------------------------------- 1 | Create conf.sh: 2 | 3 | PROJECT_ID= # name of GCP project 4 | OUTPUT= # Directory where data will be exported 5 | IMAGE_DIR= # Directory where input image data will be cached 6 | OUTPUT_IMAGE_DIR= # Directory where processed image data will be stored 7 | EXIF_DIR= # Directory where EXIF data for images will be cached 8 | 9 | Run export_data.sh. 10 | -------------------------------------------------------------------------------- /nginx-lb-emulator/resources/upload.conf: -------------------------------------------------------------------------------- 1 | location /services/upload { 2 | proxy_set_header Host $host; 3 | proxy_set_header X-Real-IP $remote_addr; 4 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 5 | proxy_set_header X-Forwarded-Proto $scheme; 6 | proxy_pass http://upload-nginx:80/services/upload; 7 | proxy_read_timeout 90s; 8 | proxy_redirect off; 9 | 10 | client_max_body_size 100m; 11 | } 12 | -------------------------------------------------------------------------------- /common/geometry.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | def getRescaledDimensions(width, height, max_w, max_h): 3 | given_ratio = max_w / float(max_h) 4 | ratio = width / float(height) 5 | if ratio > given_ratio: 6 | first = max_w 7 | else: 8 | first = int(round(ratio * float(max_h))) 9 | if ratio <= given_ratio: 10 | second = max_h 11 | else: 12 | second = int(round(ratio * float(max_w))) 13 | return first, second 14 | 15 | def ratio_to_decimal(ratio): 16 | return ratio.num / float(ratio.den) 17 | -------------------------------------------------------------------------------- /static-nginx/app/static/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Eclipse Megamovie 2017", 3 | "short_name": "Eclipse Megamovie", 4 | "start_url": "/?homescreen=1", 5 | "display": "standalone", 6 | "theme_color": "#3f51b5", 7 | "background_color": "#3f51b5", 8 | "icons": [ 9 | { 10 | "src": "images/manifest/android-chrome-192x192.png", 11 | "sizes": "192x192", 12 | "type": "image/png" 13 | }, 14 | { 15 | "src": "\/images\/icons\/android-chrome-256x256.png", 16 | "sizes": "256x256", 17 | "type": "image\/png" 18 | } 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /common/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2016 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 | -------------------------------------------------------------------------------- /admin/app/app/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2017 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 | -------------------------------------------------------------------------------- /common_tests/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2016 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 | -------------------------------------------------------------------------------- /geo/app/app/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2017 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 | -------------------------------------------------------------------------------- /photo/app/app/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2017 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 | -------------------------------------------------------------------------------- /movie/daemon/app/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2016 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 | -------------------------------------------------------------------------------- /profile/app/app/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2016 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 | -------------------------------------------------------------------------------- /upload/daemon/app/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2016 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 | -------------------------------------------------------------------------------- /upload/server/app/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2016 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 | -------------------------------------------------------------------------------- /admin/app/app/backend/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2017 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 | -------------------------------------------------------------------------------- /admin/app/tests/flask/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2016 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 | -------------------------------------------------------------------------------- /geo/app/app/backend/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2017 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 | -------------------------------------------------------------------------------- /photo/app/app/backend/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2017 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 | -------------------------------------------------------------------------------- /profile/app/app/backend/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2016 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 | -------------------------------------------------------------------------------- /profile/app/tests/flask/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2016 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 | -------------------------------------------------------------------------------- /upload/server/tests/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2016 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 | -------------------------------------------------------------------------------- /upload/system_tests/app/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2016 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 | -------------------------------------------------------------------------------- /image-processor/daemon/app/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2016 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 | -------------------------------------------------------------------------------- /static-nginx/app/static/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "eclipse-megamovie", 3 | "version": "0.0.1", 4 | "description": "Eclipse Megamovie site", 5 | "license": "http://polymer.github.io/LICENSE.txt", 6 | "scripts": { 7 | "build": "gulp" 8 | }, 9 | "devDependencies": { 10 | "bower-locker": "^1.0.7", 11 | "del": "^2.2.1", 12 | "gulp": "gulpjs/gulp#4.0", 13 | "gulp-if": "^2.0.1", 14 | "gulp-imagemin": "^3.0.1", 15 | "merge-stream": "^1.0.0", 16 | "plylog": "^0.4.0", 17 | "polymer-build": "^0.4.0", 18 | "polymer-cli": "^1.0.0" 19 | }, 20 | "engines": { 21 | "node": ">=4.0" 22 | }, 23 | "private": true 24 | } 25 | -------------------------------------------------------------------------------- /system-test-container/app/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2016 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 | -------------------------------------------------------------------------------- /upload/server/app/backend/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2016 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 | -------------------------------------------------------------------------------- /upload/server/tests/backend/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2016 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 | -------------------------------------------------------------------------------- /admin/app/tests/flask/backend/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2016 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 | -------------------------------------------------------------------------------- /profile/app/tests/flask/backend/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2016 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 | -------------------------------------------------------------------------------- /system-test-container/app/tests/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2016 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 | -------------------------------------------------------------------------------- /upload/system_tests/app/tests/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2016 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 | -------------------------------------------------------------------------------- /static-nginx/app/static/src/string-endswith-polyfill.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Any copyright is dedicated to the Public Domain. http://creativecommons.org/publicdomain/zero/1.0/" 4 | */ 5 | if (!String.prototype.endsWith) { 6 | String.prototype.endsWith = function(searchString, position) { 7 | var subjectString = this.toString(); 8 | if (typeof position !== 'number' || !isFinite(position) || Math.floor(position) !== position || position > subjectString.length) { 9 | position = subjectString.length; 10 | } 11 | position -= searchString.length; 12 | var lastIndex = subjectString.lastIndexOf(searchString, position); 13 | return lastIndex !== -1 && lastIndex === position; 14 | }; 15 | } -------------------------------------------------------------------------------- /index.yaml: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2016 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 | indexes: 17 | - kind: "Photo" 18 | properties: 19 | - name: "image_bucket" 20 | - name: "num_reviews" 21 | -------------------------------------------------------------------------------- /admin/app/tests/run_tests: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright 2016 Google Inc. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | echo; echo "Running admin flask application tests..."; 18 | cd flask 19 | ./run_flask_tests 20 | -------------------------------------------------------------------------------- /static-nginx/app/static/images/Ribbon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Fill 272 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /profile/app/tests/run_tests: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright 2016 Google Inc. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | echo; echo "Running profile flask application tests..."; 18 | cd flask 19 | ./run_flask_tests 20 | -------------------------------------------------------------------------------- /scripts/run_all_tests.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright 2017 Google Inc. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | failed=0 17 | pushd common_tests; ./run_tests; if [ $? != 0 ]; then failed=1; fi; popd 18 | exit $failed 19 | -------------------------------------------------------------------------------- /static-nginx/app/static/service-worker.js: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright 2016 Google Inc. 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | 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 | console.info('Service worker disabled for development, will be generated at build time.'); 17 | -------------------------------------------------------------------------------- /scripts/upload_many_datas: -------------------------------------------------------------------------------- 1 | DIR="/tmp/upload_data" 2 | NUM_UPLOADS=50 3 | IP="130.211.11.238" 4 | 5 | if ! test -d $DIR; then 6 | echo "Saving files to $DIR. These will persist once script finishes." 7 | 8 | mkdir -p $DIR 9 | python -c "a = ['a' for _ in range(25*1024*1024)]; open('$DIR/data25.txt', 'w').write(''.join(a))" 10 | 11 | I=0 12 | while [ $I -lt $NUM_UPLOADS ]; do 13 | FILE="data25-$I.txt" 14 | cp $DIR/data25.txt $DIR/$FILE 15 | I=$[ $I + 1 ] 16 | done 17 | 18 | rm -f $DIR/data25.txt 19 | fi 20 | 21 | I=0 22 | while [ $I -lt $NUM_UPLOADS ]; do 23 | FILE="data25-$I.txt" 24 | curl -d @$DIR/$FILE -H "X-Filename:$FILE" -H "Content-type:text/plain" -H "Expect:" -vv $IP/services/upload/ & 25 | I=$[ $I + 1 ] 26 | done 27 | -------------------------------------------------------------------------------- /static-nginx/app/static/polymer.json: -------------------------------------------------------------------------------- 1 | { 2 | "entrypoint": "index.html", 3 | "shell": "src/eclipse-app.html", 4 | "fragments": [ 5 | "src/eclipse-overview.html", 6 | "src/eclipse-about.html", 7 | "src/eclipse-megamovie.html", 8 | "src/eclipse-resources.html", 9 | "src/eclipse-safety.html", 10 | "src/eclipse-simulator.html", 11 | "src/eclipse-view404.html", 12 | "src/eclipse-faq.html", 13 | "src/eclipse-instructions.html" 14 | ], 15 | "sources": [ 16 | "sitemap.xml", 17 | "src/**/*", 18 | "images/**/*", 19 | "bower.json" 20 | ], 21 | "extraDependencies": [ 22 | "manifest.json", 23 | "bower_components/webcomponentsjs/webcomponents-lite.min.js" 24 | ], 25 | "lint" : { 26 | "rules": ["polymer-1"] 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /admin/nginx/templates/Dockerfile.tmpl: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2017 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 | FROM {{GCR_PREFIX_WITH_SLASH}}nginx-container:latest 17 | 18 | RUN rm -rf /etc/nginx/* 19 | COPY conf/nginx /etc/nginx 20 | -------------------------------------------------------------------------------- /common/image_sorter.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2017 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 | def pick_image(complete_images): 17 | complete_images.sort(key=lambda x: x["image_datetime"]) 18 | return complete_images[-1] 19 | -------------------------------------------------------------------------------- /geo/nginx/templates/Dockerfile.tmpl: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2017 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 | FROM {{GCR_PREFIX_WITH_SLASH}}nginx-container:latest 17 | 18 | RUN rm -rf /etc/nginx/* 19 | COPY conf/nginx /etc/nginx 20 | -------------------------------------------------------------------------------- /photo/nginx/templates/Dockerfile.tmpl: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2017 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 | FROM {{GCR_PREFIX_WITH_SLASH}}nginx-container:latest 17 | 18 | RUN rm -rf /etc/nginx/* 19 | COPY conf/nginx /etc/nginx 20 | -------------------------------------------------------------------------------- /profile/nginx/templates/Dockerfile.tmpl: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2016 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 | FROM {{GCR_PREFIX_WITH_SLASH}}nginx-container:latest 17 | 18 | RUN rm -rf /etc/nginx/* 19 | COPY conf/nginx /etc/nginx 20 | -------------------------------------------------------------------------------- /upload/nginx/templates/Dockerfile.tmpl: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2016 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 | FROM {{GCR_PREFIX_WITH_SLASH}}nginx-container:latest 17 | 18 | RUN rm -rf /etc/nginx/* 19 | COPY conf/nginx /etc/nginx 20 | -------------------------------------------------------------------------------- /scripts/static-build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -l 2 | set -e 3 | # Install nvm 4 | curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.32.1/install.sh | bash 5 | source $HOME/.bashrc 6 | install node.js v6 7 | nvm install 6 8 | NODE_VER=v6.11.0 npm install 9 | 10 | # Cleanup 11 | rm -rf build 12 | mkdir build 13 | mkdir -p build/static-nginx 14 | mkdir -p build/static-nginx/app/static/build/default/src 15 | 16 | cp -a static-nginx/app build/static-nginx 17 | echo -e "var client_id = 'foobar';\nvar api_key = 'foobar';" > build/static-nginx/app/static/src/client-id.js 18 | 19 | pushd build/static-nginx/app/static 20 | npm install --no-spin bower 21 | npm install --no-spin polymer 22 | PATH=~/eclipse2017/node_modules/.bin:$PATH bower install 23 | polymer build --preset es5-bundled --name default 24 | popd 25 | 26 | -------------------------------------------------------------------------------- /common/find_circles.py: -------------------------------------------------------------------------------- 1 | import cv2 2 | from common.geometry import getRescaledDimensions 3 | HD_MAX_X = 1920 4 | HD_MAX_Y = 1080 5 | 6 | def findCircles(image): 7 | image_cols, image_rows, _ = image.shape 8 | 9 | gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) 10 | first, second = getRescaledDimensions(gray.shape[1], gray.shape[0], HD_MAX_X, HD_MAX_Y) 11 | gray = cv2.resize(gray, (first, second)) 12 | blurred = cv2.bilateralFilter(gray, 9, 75, 75) 13 | gray = cv2.addWeighted(gray, 1.5, blurred, -0.5, 0) 14 | gray = cv2.bilateralFilter(gray, 9, 75, 75) 15 | 16 | # # detect circles in the image 17 | dp = 1 18 | c1 = 100 19 | c2 = 15 20 | circles = cv2.HoughCircles(gray, cv2.cv.CV_HOUGH_GRADIENT, dp, second / 8, param1=c1, param2=c2) 21 | if not len(circles): 22 | return None 23 | return circles[0][0] 24 | -------------------------------------------------------------------------------- /static-nginx/templates/Dockerfile.tmpl: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2016 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 | FROM {{GCR_PREFIX_WITH_SLASH}}nginx-container:latest 17 | 18 | RUN rm -rf /etc/nginx/* 19 | COPY conf/nginx /etc/nginx 20 | RUN chown -R www-data /etc/nginx 21 | ADD application.tar /app 22 | -------------------------------------------------------------------------------- /scripts/_ingress: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright 2016 Google Inc. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | set -e 18 | echo "Ingressing..." 19 | 20 | if [ "$LOCAL_DEV" != "true" ]; then 21 | 22 | kubectl apply -f $PROJ_DIR/conf/tls_secret_$TARGET_ENV.yaml 23 | kubectl apply -f ingress.yaml 24 | 25 | fi 26 | -------------------------------------------------------------------------------- /common/chunks.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2017 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 | def chunks(list_, num_items): 17 | """break list_ into n-sized chunks...""" 18 | results = [] 19 | for i in range(0, len(list_), num_items): 20 | results.append(list_[i:i+num_items]) 21 | return results 22 | -------------------------------------------------------------------------------- /common_tests/install_dependencies: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright 2016 Google Inc. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | set -e 18 | 19 | echo "Installing common dependencies..." 20 | pip install -r ../conf/requirements.txt -t lib 21 | # Google folder missing __init__ file preventing imports 22 | touch lib/google/__init__.py 23 | -------------------------------------------------------------------------------- /common/flask_users.py: -------------------------------------------------------------------------------- 1 | from common.eclipse2017_exceptions import MissingCredentialTokenError, MissingUserError, ApplicationIdentityError 2 | from common import util 3 | from common import users 4 | import flask 5 | 6 | def authn_check(headers): 7 | try: 8 | token = users.get_id_token(headers) 9 | except MissingCredentialTokenError: 10 | return flask.Response("The request is missing a credential token.", 405) 11 | try: 12 | idinfo = util._validate_id_token(token) 13 | except ApplicationIdentityError: 14 | return flask.Response("The request id token is invalid.", 405) 15 | except ValueError: 16 | return flask.Response("The request id token is expired.", 401) 17 | try: 18 | userid = users.get_userid(idinfo) 19 | except MissingUserError: 20 | return flask.Response("The user is missing.", 405) 21 | return userid 22 | -------------------------------------------------------------------------------- /profile/app/README.md: -------------------------------------------------------------------------------- 1 | **To run locally:** 2 | After building the docker image and completing the following, you will be able to access the app at 3 | http://localhost:8080 4 | 5 | ```bash 6 | $ cd profile 7 | $ docker run -p 8080:8080 8 | ``` 9 | 10 | 11 | **Note:** 12 | 13 | The file `profile/tests/flask/test_flask_util.py` was copied from the 14 | google/oauth2client GitHub repo (https://github.com/google/oauth2client). This 15 | was included so we could subclass `FlaskOAuth2Tests` because the 16 | oauth2client/tests module is not included in the oauth2client pypi distribution. 17 | 18 | 19 | **Coming Soon** 20 | 21 | To run system tests, you will need a copy of the latest selenium chromedriver 22 | executable in your newly created profile/lib folder. You can download the driver 23 | corresponding to your platform here: 24 | http://chromedriver.storage.googleapis.com/index.html 25 | -------------------------------------------------------------------------------- /scripts/_create_secret: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright 2016 Google Inc. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | # # Create kubernetes tls secret 18 | if ! test -f $PROJ_DIR/conf/tls_secret_$TARGET_ENV.yaml; then 19 | python $PROJ_DIR/scripts/yaml_secret.py --create --save_files --yaml_output $PROJ_DIR/conf/tls_secret_$TARGET_ENV.yaml 20 | fi 21 | -------------------------------------------------------------------------------- /common_tests/run_tests: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright 2016 Google Inc. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | # If installation fails then we do not want to run tests 18 | set -e 19 | 20 | # / (used for common. imports) 21 | PRJ_PATH=$(dirname $PWD) 22 | export PYTHONPATH=$PRJ_PATH:$PYTHONPATH 23 | 24 | python -m unittest discover . "*_test.py" 25 | -------------------------------------------------------------------------------- /static-nginx/app/static/sw-precache-config.js: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright 2016 Google Inc. 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | 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 | module.exports = { 17 | staticFileGlobs: [ 18 | '/index.html', 19 | '/manifest.json', 20 | '/bower_components/webcomponentsjs/webcomponents-lite.min.js' 21 | ], 22 | navigateFallback: '/index.html' 23 | }; 24 | -------------------------------------------------------------------------------- /system-test-container/templates/Dockerfile.tmpl: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2016 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 | FROM {{GCR_PREFIX}}/base-container:latest 17 | 18 | COPY conf/requirements.txt /tmp/requirements.txt 19 | RUN pip install -r /tmp/requirements.txt 20 | 21 | ADD application.tar /app 22 | USER www-data 23 | WORKDIR /app 24 | CMD ["./run_tests"] 25 | -------------------------------------------------------------------------------- /static-nginx/templates/deployment.yaml.tmpl: -------------------------------------------------------------------------------- 1 | apiVersion: extensions/v1beta1 2 | kind: Deployment 3 | metadata: 4 | name: static-nginx 5 | spec: 6 | replicas: 3 7 | selector: 8 | matchLabels: 9 | tier: static-nginx-backend 10 | matchExpressions: 11 | - {key: tier, operator: In, values: [static-nginx-backend]} 12 | template: 13 | metadata: 14 | labels: 15 | app: static-nginx 16 | tier: static-nginx-backend 17 | spec: 18 | containers: 19 | - name: static-nginx 20 | image: {{GCR_PREFIX}}/static-nginx 21 | ports: 22 | - containerPort: 80 23 | livenessProbe: 24 | httpGet: 25 | path: / 26 | port: 80 27 | resources: 28 | limits: 29 | cpu: 1000m 30 | memory: 128M 31 | requests: 32 | cpu: 100m 33 | memory: 128M 34 | -------------------------------------------------------------------------------- /nginx-lb-emulator/templates/Dockerfile.tmpl: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2016 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 | FROM {{GCR_PREFIX_WITH_SLASH}}nginx-container:latest 17 | 18 | RUN rm -rf /etc/nginx/* 19 | 20 | COPY resources/lb-emulator.crt etc/nginx/ 21 | COPY resources/lb-emulator.key etc/nginx/ 22 | COPY resources/nginx.conf etc/nginx/ 23 | COPY resources/cors.conf etc/nginx/ 24 | -------------------------------------------------------------------------------- /geo/app/templates/Dockerfile.tmpl: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2017 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 | FROM {{GCR_PREFIX_WITH_SLASH}}app-container:latest 17 | 18 | ADD application.tar /app 19 | 20 | USER www-data 21 | WORKDIR /app 22 | CMD ["gunicorn", "main:app", "-b", "0.0.0.0:8080", "-t", "90", "-w", "8", "--log-level", "INFO", "--access-logfile", "/dev/stdout", "--error-logfile", "/dev/stderr"] 23 | -------------------------------------------------------------------------------- /photo/app/templates/Dockerfile.tmpl: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2017 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 | FROM {{GCR_PREFIX_WITH_SLASH}}app-container:latest 17 | 18 | ADD application.tar /app 19 | 20 | USER www-data 21 | WORKDIR /app 22 | CMD ["gunicorn", "main:app", "-b", "0.0.0.0:8080", "-t", "90", "-w", "8", "--log-level", "INFO", "--access-logfile", "/dev/stdout", "--error-logfile", "/dev/stderr"] 23 | -------------------------------------------------------------------------------- /profile/app/templates/Dockerfile.tmpl: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2016 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 | FROM {{GCR_PREFIX_WITH_SLASH}}app-container:latest 17 | 18 | ADD application.tar /app 19 | 20 | USER www-data 21 | WORKDIR /app 22 | CMD ["gunicorn", "main:app", "-b", "0.0.0.0:8080", "-t", "90", "-w", "8", "--log-level", "INFO", "--access-logfile", "/dev/stdout", "--error-logfile", "/dev/stderr"] 23 | -------------------------------------------------------------------------------- /upload/system_tests/templates/Dockerfile.tmpl: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2016 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 | FROM {{GCR_PREFIX}}/base-container:latest 17 | 18 | COPY conf/requirements.txt /tmp/requirements.txt 19 | RUN pip install -r /tmp/requirements.txt 20 | 21 | ADD application.tar /app 22 | COPY conf/test-supervisor.conf /etc/supervisor/conf.d/test.conf 23 | 24 | CMD ["/usr/bin/supervisord", "-n"] 25 | -------------------------------------------------------------------------------- /upload/daemon/templates/Dockerfile.tmpl: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2016 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 | FROM {{GCR_PREFIX_WITH_SLASH}}base-container:latest 17 | 18 | ADD application.tar /app 19 | 20 | ENV DEBIAN_FRONTEND noninteractive 21 | ENV APT_LISTCHANGES_FRONTEND none 22 | 23 | RUN apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* 24 | 25 | WORKDIR /app 26 | USER www-data 27 | 28 | CMD ["python", "main.py"] 29 | -------------------------------------------------------------------------------- /templates/config.py.tmpl: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2016 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 | GCS_BUCKET = '{{GCLOUD_PROJ}}-photos' 17 | GCS_PROCESSED_PHOTOS_BUCKET = '{{GCLOUD_PROJ}}-processed-photos' 18 | GCS_MOVIE_BUCKET = '{{GCLOUD_PROJ}}-movies' 19 | PROJECT_ID = '{{PROJECT_ID}}' 20 | 21 | UPLOAD_SERVER_RSS_MAX_USAGE = {{UPLOAD_SERVER_RSS_MAX_USAGE_BYTES}} 22 | PENDING_UPLOADS_MAX_USAGE = {{PENDING_UPLOADS_MAX_USAGE_BYTES}} 23 | 24 | CDN_HOSTNAME = '{{CDN_HOSTNAME}}' 25 | -------------------------------------------------------------------------------- /scripts/oss_release.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright 2017 Google Inc. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | set -e 18 | 19 | TMPDIR=$(mktemp -d) 20 | echo "Copying git tree to $TMPDIR" 21 | git archive --format=tar --prefix=./ HEAD | (cd $TMPDIR && tar xf -) 22 | find $TMPDIR -wholename '*scripts/oss_release.sh' -prune -o -type f -exec grep -l Copyright {} \; > STOPSHIP.files 23 | if [ $? != 0 ]; then 24 | echo "Found STOPSHIP:" 25 | cat STOPSHIP.files 26 | exit 1 27 | fi 28 | -------------------------------------------------------------------------------- /scripts/_systest: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright 2016 Google Inc. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | set -e 18 | echo "System testing..." 19 | 20 | if [ "$LOCAL_DEV" != "true" ]; then 21 | kubectl apply -f build/system-test-container/test_pod.yaml --record 22 | else 23 | GCR_PREFIX="gcr.io/$GCLOUD_PROJ_PREFIX${GCLOUD_PROJ_PREFIX:+"/"}$GCLOUD_PROJ" 24 | LINK="--link static-nginx" 25 | docker run -ti --link static-nginx --name system-test ${GCR_PREFIX}/system-test-container 26 | fi 27 | -------------------------------------------------------------------------------- /scripts/_update: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright 2016 Google Inc. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | set -e 18 | echo "Update..." 19 | 20 | if [[ $LOCAL_DEV != true ]]; then 21 | if [[ -z $APP ]]; then 22 | echo "MUST provide an APP selector for update" 23 | exit 1 24 | fi 25 | 26 | GCR_PREFIX="gcr.io/$GCLOUD_PROJ_PREFIX${GCLOUD_PROJ_PREFIX:+"/"}$GCLOUD_PROJ" 27 | kubectl set image deployment/$DEPLOYMENT $APP=$GCR_PREFIX/$APP:$GIT_TAG 28 | fi 29 | 30 | echo "Done updating." 31 | -------------------------------------------------------------------------------- /upload/daemon/tests/run_tests: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright 2016 Google Inc. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | echo; echo "Running upload daemon tests..."; 18 | 19 | # If installation fails then we do not want to run tests 20 | set -e 21 | 22 | # upload/daemon used for app. imports 23 | DAEMON_PATH=$(dirname $PWD) 24 | 25 | # / (used for common. imports) 26 | PRJ_PATH=$(dirname $(dirname $DAEMON_PATH)) 27 | export PYTHONPATH=$DAEMON_PATH:$PRJ_PATH:$PYTHONPATH 28 | python -m unittest discover . "*_test.py" 29 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # How to contribute 2 | 3 | We'd love to accept your patches and contributions to this project. There are 4 | just a few small guidelines you need to follow. 5 | 6 | ## Contributor License Agreement 7 | 8 | Contributions to this project must be accompanied by a Contributor License 9 | Agreement. You (or your employer) retain the copyright to your contribution, 10 | this simply gives us permission to use and redistribute your contributions as 11 | part of the project. Head over to to see 12 | your current agreements on file or to sign a new one. 13 | 14 | You generally only need to submit a CLA once, so if you've already submitted one 15 | (even if it was for a different project), you probably don't need to do it 16 | again. 17 | 18 | ## Code reviews 19 | 20 | All submissions, including submissions by project members, require review. We 21 | use GitHub pull requests for this purpose. Consult [GitHub Help] for more 22 | information on using pull requests. 23 | 24 | [GitHub Help]: https://help.github.com/articles/about-pull-requests/ 25 | -------------------------------------------------------------------------------- /nginx-container/templates/Dockerfile.tmpl: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2016 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 | FROM {{GCR_PREFIX_WITH_SLASH}}base-container:latest 17 | 18 | ENV DEBIAN_FRONTEND noninteractive 19 | ENV APT_LISTCHANGES_FRONTEND none 20 | 21 | RUN apt-get install -y --no-install-recommends nginx sudo && \ 22 | service nginx stop && \ 23 | mkdir -p /var/run/nginx/cache && \ 24 | apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* 25 | 26 | CMD ["/usr/sbin/nginx", "-c", "/etc/nginx/nginx.conf"] 27 | -------------------------------------------------------------------------------- /upload/server/tests/run_tests: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright 2016 Google Inc. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | echo; echo "Running upload server tests..."; 18 | 19 | # If installation fails then we do not want to run tests 20 | set -e 21 | 22 | # upload/server used for app. imports 23 | SERVER_PATH=$(dirname $PWD) 24 | 25 | # / (used for common. imports) 26 | PRJ_PATH=$(dirname $(dirname $SERVER_PATH)) 27 | 28 | export PYTHONPATH=$SERVER_PATH:$PRJ_PATH:$PYTHONPATH 29 | 30 | python -m unittest discover . "*_test.py" 31 | -------------------------------------------------------------------------------- /movie/daemon/tests/run_tests: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright 2016 Google Inc. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | echo "Running upload daemon tests..."; 18 | 19 | # Append directories to $PYTHONPATH 20 | # DAEMON_DIR = movie/daemon - Used for app. imports 21 | # PRJ_DIR = eclipse2017 - Used for common. imports 22 | DAEMON_DIR=$(dirname $PWD) 23 | PRJ_DIR=$(dirname $(dirname $DAEMON_DIR)) 24 | 25 | export PYTHONPATH=$DAEMON_DIR:$PRJ_DIR:$PYTHONPATH 26 | export GEOS_DIR=/usr/local 27 | 28 | python -m unittest discover . "*_test.py" 29 | -------------------------------------------------------------------------------- /upload/server/templates/Dockerfile.tmpl: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2016 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 | FROM {{GCR_PREFIX_WITH_SLASH}}app-container:latest 17 | 18 | RUN apt-get install -y --no-install-recommends python-wand libmagickwand-dev && \ 19 | apt-get clean && rm -rf /tmp/* /var/tmp/* 20 | ADD application.tar /app 21 | 22 | WORKDIR /app 23 | USER www-data 24 | CMD ["gunicorn", "main:app", "-b", "0.0.0.0:8080", "-t", "600", "-w", "8", "--log-level", "INFO", "--access-logfile", "/dev/stdout", "--error-logfile", "/dev/stderr"] 25 | -------------------------------------------------------------------------------- /app-container/templates/Dockerfile.tmpl: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2016 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 | FROM {{GCR_PREFIX_WITH_SLASH}}base-container:latest 17 | 18 | ENV DEBIAN_FRONTEND noninteractive 19 | ENV APT_LISTCHANGES_FRONTEND none 20 | 21 | COPY conf/requirements.txt /tmp/requirements-eclipse2017.txt 22 | 23 | RUN apt-get install -y --no-install-recommends gunicorn && \ 24 | pip install -r /tmp/requirements-eclipse2017.txt && \ 25 | install -d -o www-data -g www-data /app/logs && \ 26 | apt-get clean && rm -rf /tmp/* /var/tmp/* 27 | -------------------------------------------------------------------------------- /image-processor/daemon/templates/Dockerfile.tmpl: -------------------------------------------------------------------------------- 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 | FROM {{GCR_PREFIX_WITH_SLASH}}base-container:latest 17 | 18 | USER root 19 | 20 | ENV DEBIAN_FRONTEND noninteractive 21 | ENV APT_LISTCHANGES_FRONTEND none 22 | ENV CLOUDSDK_CORE_DISABLE_PROMPTS 1 23 | 24 | RUN apt-get install -y --no-install-recommends python-opencv python-wand libmagickwand-dev libgeos-dev && \ 25 | apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* 26 | 27 | WORKDIR /app 28 | USER www-data 29 | ADD application.tar /app 30 | 31 | CMD ["python", "main.py"] 32 | -------------------------------------------------------------------------------- /system-test-container/app/run_tests: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright 2017 Google Inc. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | set -e 18 | 19 | 20 | # eclipse2017/profile/app/app 21 | APP_PATH=$(dirname $(dirname $PWD)) 22 | 23 | # eclipse2017/profile/ 24 | PROFILE_PATH=$(dirname $APP_PATH) 25 | 26 | # eclipse2017/ 27 | PRJ_PATH=$(dirname $PROFILE_PATH) 28 | BUILD_DIR=$PRJ_PATH/build 29 | 30 | # common_tests/ 31 | COMMON_TEST_PATH=$PRJ_PATH/common_tests 32 | 33 | # common_tests/lib 34 | COMMON_LIB_PATH=$COMMON_TEST_PATH/lib 35 | 36 | export PYTHONPATH=/app 37 | python -m unittest2 discover tests "*_test.py" 38 | -------------------------------------------------------------------------------- /scripts/_push: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright 2016 Google Inc. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | set -e 18 | echo "Pushing docker images..." 19 | 20 | # command aliases 21 | PUSHCMD="gcloud docker -- push" 22 | 23 | # Gcloud values 24 | GCR_PREFIX="gcr.io/$GCLOUD_PROJ_PREFIX${GCLOUD_PROJ_PREFIX:+"/"}$GCLOUD_PROJ" 25 | 26 | IMAGES="base-container \ 27 | app-container \ 28 | geo-server \ 29 | geo-nginx \ 30 | static-nginx \ 31 | system-test-container" 32 | 33 | for img in ${IMAGES}; do 34 | [[ -z $APP || $APP == $img ]] && $PUSHCMD $GCR_PREFIX/$img 35 | done 36 | 37 | echo "Done." 38 | -------------------------------------------------------------------------------- /static-nginx/app/static/test/index.html: -------------------------------------------------------------------------------- 1 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | Tests 24 | 25 | 26 | 27 | 28 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /admin/app/templates/Dockerfile.tmpl: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2017 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 | FROM {{GCR_PREFIX_WITH_SLASH}}app-container:latest 17 | 18 | ADD application.tar /app 19 | COPY conf/requirements.txt /tmp/requirements.txt 20 | RUN apt-get install -y --no-install-recommends python-pip && \ 21 | pip install -r /tmp/requirements.txt && \ 22 | apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* 23 | 24 | USER www-data 25 | WORKDIR /app 26 | CMD ["gunicorn", "main:app", "-b", "0.0.0.0:8080", "-t", "90", "-w", "8", "--log-level", "INFO", "--access-logfile", "/dev/stdout", "--error-logfile", "/dev/stderr"] 27 | -------------------------------------------------------------------------------- /scripts/_clean: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright 2016 Google Inc. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | echo "Cleaning..." 18 | 19 | GCR_PREFIX="gcr.io/$GCLOUD_PROJ_PREFIX${GCLOUD_PROJ_PREFIX:+"/"}$GCLOUD_PROJ" 20 | IMAGES="nginx-lb-emulator \ 21 | static-nginx \ 22 | nginx-container \ 23 | app-container \ 24 | base-container" 25 | 26 | remove_image() { 27 | if [ "$LOCAL_DEV" != "true" ]; then 28 | docker rmi -f $GCR_PREFIX/$1 29 | else 30 | docker rmi -f $1 31 | fi 32 | } 33 | 34 | for img in $IMAGES; do 35 | [[ -z $APP || $APP == $img ]] && remove_image $img 36 | done 37 | 38 | [ -d build/ ] && rm -rf build/ 39 | -------------------------------------------------------------------------------- /src/solar_eclipse_renderer/lune.py: -------------------------------------------------------------------------------- 1 | import ephem 2 | import math 3 | deg = math.degrees 4 | def get_lune(sun, moon): 5 | r_sun=sun.size/2 6 | r_moon=moon.size/2 7 | s=math.degrees(ephem.separation((sun.az, sun.alt), (moon.az, moon.alt)))*60*60 8 | 9 | ## Calculate the size of the lune (http://mathworld.wolfram.com/Lune.html) in arcsec^2 10 | if s<(r_moon+r_sun): 11 | x = (r_sun+r_moon+s)*(r_moon+s-r_sun)*(s+r_sun-r_moon)*(r_sun+r_moon-s) 12 | lunedelta=0.25*math.sqrt(abs(x)) 13 | else: ### If s>r_moon+r_sun there is no eclipse taking place 14 | lunedelta=None 15 | percent_eclipse=0 16 | if lunedelta: 17 | x = ((r_moon*r_moon)-(r_sun*r_sun)-(s*s)) 18 | y = ((r_moon*r_moon)+(s*s)-(r_sun*r_sun)) 19 | # Total eclipse 20 | if x/(2*r_sun*s) > 1: 21 | return 100. 22 | else: 23 | lune_area=2*lunedelta + r_sun*r_sun*(math.acos(x/(2*r_sun*s))) - r_moon*r_moon*(math.acos(y/(2*r_moon*s))) 24 | percent_eclipse=(1-(lune_area/(math.pi*r_sun*r_sun)))*100 # Calculate percentage of sun's disc eclipsed using lune area and sun size 25 | return percent_eclipse 26 | else: 27 | return 0. 28 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | *__pycache__/ 3 | *application.tar 4 | cert 5 | key 6 | conf/* 7 | *.iml 8 | 9 | build/ 10 | 11 | common/service_account.json 12 | common/flask/secret_keys.py 13 | common_tests/lib/ 14 | common/config.py 15 | 16 | profile/app/tests/flask/lib/ 17 | profile/app/tests/js/lib/ 18 | profile/nginx/app/static/third_party/node_modules/bower/package.json 19 | profile/nginx/app/static/third_party/bower_components 20 | profile/nginx/app/static/third_party/node_modules 21 | profile/app/Dockerfile 22 | profile/nginx/Dockerfile 23 | profile/nginx/conf/nginx/nginx.conf 24 | profile/deployment.yaml 25 | 26 | upload/server/app/config.py 27 | upload/test_pod.yaml 28 | upload/deployment.yaml 29 | upload/daemon/Dockerfile 30 | upload/server/app/config.py 31 | upload/server/Dockerfile 32 | upload/nginx/Dockerfile 33 | upload/nginx/conf/nginx/nginx.conf 34 | upload/system_tests/Dockerfile 35 | 36 | movie/daemon/Dockerfile 37 | movie/deployment.yaml 38 | 39 | static-nginx/Dockerfile 40 | static-nginx/deployment.yaml 41 | static-nginx/app/static/node_modules 42 | static-nginx/app/static/bower_components 43 | static-nginx/app/static/build 44 | 45 | app-container/Dockerfile 46 | nginx-container/Dockerfile 47 | 48 | /pending-uploads 49 | -------------------------------------------------------------------------------- /nginx-lb-emulator/resources/cors.conf: -------------------------------------------------------------------------------- 1 | if ($request_method = 'OPTIONS') { 2 | add_header 'Access-Control-Allow-Origin' '*' always; 3 | add_header 'Access-Control-Allow-Methods' 'GET, DELETE, POST, PUT, OPTIONS, UPDATE, PATCH' always; 4 | # 5 | # Custom headers and headers various browsers *should* be OK with but aren't 6 | # 7 | add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,X-IdToken,X-UploadSessionId,X-Image-Bucket,X-CC0-Agree,X-Public-Agree' always; 8 | # 9 | # Tell client that this pre-flight info is valid for 20 days 10 | # 11 | add_header 'Access-Control-Max-Age' 1728000 always; 12 | add_header 'Content-Type' 'text/plain charset=UTF-8' always; 13 | add_header 'Content-Length' 0 always; 14 | return 204; 15 | } 16 | 17 | add_header 'Access-Control-Allow-Origin' '*' always; 18 | add_header 'Access-Control-Allow-Methods' 'GET, DELETE, POST, PUT, OPTIONS, UPDATE' always; 19 | add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,X-IdToken,X-UploadSessionId,X-Image-Bucket,X-CC0-Agree,X-Public-Agree' always; 20 | -------------------------------------------------------------------------------- /common/id_token.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2016 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 | import google.auth 17 | import google.auth.transport.requests 18 | import google.oauth2._client 19 | 20 | def get_id_token(): 21 | # Only works w/ user credentials 22 | credentials, _ = google.auth.default() 23 | 24 | request = google.auth.transport.requests.Request() 25 | response = google.oauth2._client.refresh_grant( 26 | request, credentials.token_uri, credentials.refresh_token, 27 | credentials.client_id, credentials.client_secret) 28 | 29 | _, _, _, grant_response = response 30 | id_token = grant_response['id_token'] 31 | return id_token 32 | -------------------------------------------------------------------------------- /ingress.yaml: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2016 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 | apiVersion: extensions/v1beta1 17 | kind: Ingress 18 | metadata: 19 | name: eclipse2017 20 | spec: 21 | backend: 22 | serviceName: static-nginx 23 | servicePort: 80 24 | rules: 25 | - http: 26 | paths: 27 | - path: /* 28 | backend: 29 | serviceName: static-nginx 30 | servicePort: 80 31 | - path: /services/geo/* 32 | backend: 33 | serviceName: geo 34 | servicePort: 80 35 | tls: 36 | - secretName: eclipse2017 37 | -------------------------------------------------------------------------------- /src/solar_eclipse_analysis/README.md: -------------------------------------------------------------------------------- 1 | Create conf.sh: 2 | 3 | PROJECT_ID= # name of GCP project 4 | IMAGE_BUCKET=megamovie # name of image_bucket to select images from 5 | OUTPUT= # where to write output data, filesystem needs ~1TB free space 6 | IMAGE_DIR= # directory containing all the input images 7 | PHOTO_TABLE=Photo # Name of the photo table 8 | MAP_DIR=$OUTPUT/map # where map output will be written 9 | RESCALED_DIR=$OUTPUT/rescaled # where rescaled images will be written 10 | CIRCLES_DIR=$OUTPUT/circles # where detected circles will be written 11 | CLASSIFY_DIR=$OUTPUT/classify # where cloud vision classifications will be written 12 | CREDITS_DIR=$OUTPUT/credits # where the credits output will be written 13 | MOVIE_DIR=$OUTPUT/movie # where the movie output files will be written 14 | MOVIE_RENUMBER_DIR=$OUTPUT/movie_renumber # where the renumbered movie files will be written 15 | PARTITION_DIR=$OUTPUT/partition # where thre partitioned movie files will be written 16 | FINAL_DIR=$OUTPUT/final # final directory where output files will appear 17 | SELECTED_DIR=$OUTPUT/selected # where the list of selected images will be written 18 | VIDEO_SETTINGS="-c:v libx264 -preset slow -crf 8" # video settings for movie encoding 19 | 20 | Run make_movie.sh. 21 | -------------------------------------------------------------------------------- /nginx-lb-emulator/resources/lb-emulator.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIDKzCCAhOgAwIBAgIJAJGGfnIBC5GAMA0GCSqGSIb3DQEBCwUAMCwxFDASBgNV 3 | BAMMC2VjbGlwc2UyMDE3MRQwEgYDVQQKDAtlY2xpcHNlMjAxNzAeFw0xNjA5MDkx 4 | OTM0MDdaFw0xNzA5MDkxOTM0MDdaMCwxFDASBgNVBAMMC2VjbGlwc2UyMDE3MRQw 5 | EgYDVQQKDAtlY2xpcHNlMjAxNzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC 6 | ggEBAMw0cComknAPeCd70phv4XpbPwYO33+KG3vNY6PfG/2AiBM5nq3mLAEbBf1p 7 | nBNEXkK4D7sI6tE0dyE8+vnzx0HHKV8WlMuCKWYzj+nHKrvmOQPdkjco7Z7IHK0p 8 | zK8LdQ0mI73CtoH0IC0Sf5yaZC+6y4g2CQVBq2ft2gthsfS5pTotX9SdX337MChn 9 | saLZtH70SHE/NM1W4t+7cMgUzoZkV/f4Di9dlM65Ip/h8MjDUjOtraMj/gAUAbE7 10 | 11Y67Lv+lwB4693ArC9l/4TEPwsQgWkLjBC1sxT00VKaTYC20RI1MyHuFAHceHY0 11 | 3Uvs5ipLEs5u1V2xynDzxi+/8aMCAwEAAaNQME4wHQYDVR0OBBYEFLpt2h4WQWlQ 12 | urtiu0H7qoZF7F6DMB8GA1UdIwQYMBaAFLpt2h4WQWlQurtiu0H7qoZF7F6DMAwG 13 | A1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBALjJvNP2nSkkJoFVtHACWZiD 14 | UAAHR96cyo5HnbR6jwIQeJMvXVIUeBsuXk7MG5So+gOLA1wDpW7G8VAl8jh9ryus 15 | IBFQOf3EYuX4bHxiNJsOBTA/CTBLfs9yYlohPGzlA8jEJqi6XgFwuSKi/uirOYpE 16 | BXjq0Ga9XY1af0U4C5qeyoy0AYgTXvz0yXagwjvXuGPZWg+UFRXK8yfEtOefOU3V 17 | GWR39AmOy0vU7ac7DzlCmq1/PAgahqmBR3/bt7SXiX5aKOKwPgVapvnqaN5IOizm 18 | 8MW7Gvss1l5Gaqw9TCl8cpZL+ZtyL1yjnyqcwRcqxyR0GmVTLl9ViIPnTcALvo8= 19 | -----END CERTIFICATE----- 20 | -------------------------------------------------------------------------------- /scripts/map_point.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2017 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 | from eclipse_gis import eclipse_gis 17 | times, points = eclipse_gis.load_stripped_data(open("src/eclipse_gis/data/eclipse_data.txt").readlines()) 18 | boundary, center = eclipse_gis.generate_polygon(points) 19 | print center 20 | eclipse_gis = eclipse_gis.EclipseGIS(boundary, center) 21 | from shapely.geometry import Point 22 | print eclipse_gis.find_nearest_point_on_line(Point(44.62, -117.13)) 23 | print eclipse_gis.interpolate_nearest_point_on_line(Point(44.62, -117.13)) 24 | print eclipse_gis.find_nearest_point_on_line(Point(37, -88)) 25 | print eclipse_gis.interpolate_nearest_point_on_line(Point(37, -88)) 26 | -------------------------------------------------------------------------------- /src/solar_eclipse_renderer/coords.py: -------------------------------------------------------------------------------- 1 | # Copyright 2017 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 math 16 | 17 | def horizontal_to_cartesian(altitude, azimuth): 18 | """Convert a "horizontal" coordinate given in altitude and azimuth to the 19 | corresponding 3D cartesian location.""" 20 | theta = math.pi / 2 - math.radians(altitude) 21 | phi = math.radians(-azimuth) 22 | x = math.sin(phi) * math.sin(-theta) 23 | y = math.sin(theta) * math.cos(phi) 24 | z = math.cos(theta) 25 | return x, y, z 26 | 27 | def scale_vector(vector, scale): 28 | """Scale a 3D vector's components by scale.""" 29 | return vector[0] * scale, vector[1] * scale, vector[2] * scale 30 | -------------------------------------------------------------------------------- /movie/daemon/templates/Dockerfile.tmpl: -------------------------------------------------------------------------------- 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 | FROM {{GCR_PREFIX_WITH_SLASH}}base-container:latest 17 | 18 | ENV DEBIAN_FRONTEND noninteractive 19 | ENV APT_LISTCHANGES_FRONTEND none 20 | ENV CLOUDSDK_CORE_DISABLE_PROMPTS 1 21 | 22 | COPY conf/requirements.txt /tmp/requirements-eclipse2017.txt 23 | RUN apt-get install -y --no-install-recommends ffmpeg unzip python-tk python-mpltoolkits.basemap && \ 24 | pip install -r /tmp/requirements-eclipse2017.txt && \ 25 | apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* 26 | 27 | ADD application.tar /app 28 | 29 | WORKDIR /app 30 | USER www-data 31 | 32 | CMD ["python", "main.py"] 33 | -------------------------------------------------------------------------------- /scripts/_unittest: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright 2016 Google Inc. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | 18 | #set -e 19 | 20 | if [ "$APP" != "" ]; then 21 | echo "NO TESTS RUN" 22 | exit 0 23 | fi 24 | 25 | # Common tests 26 | COMMON_PASS=0 27 | if [ "$APP" == "" ]; then 28 | echo; echo "=== Common tests ===" 29 | cd common_tests 30 | ./run_tests 31 | COMMON_PASS=$? 32 | cd .. 33 | fi 34 | 35 | 36 | # Final result 37 | echo 38 | test $COMMON_PASS -eq 0 -a $UPLOAD_DAEMON_PASS -eq 0 -a \ 39 | $UPLOAD_SERVER_PASS -eq 0 -a $PROFILE_PASS -eq 0 -a \ 40 | $MOVIE_DAEMON_PASS -eq 0 41 | if [ $? == 0 ]; then 42 | echo "ALL TESTS PASSED" 43 | else 44 | echo "SOME TEST(S) FAILED" 45 | fi 46 | -------------------------------------------------------------------------------- /src/solar_eclipse_analysis/read_image_exif.py: -------------------------------------------------------------------------------- 1 | """Read images""" 2 | 3 | import os 4 | import logging 5 | import argparse 6 | import pickle 7 | from exif import _extract_exif_metadata, _extract_image_metadata 8 | from PIL import Image 9 | from rawkit.raw import Raw 10 | from multiprocessing import Pool 11 | from functools import partial 12 | 13 | IMGDIR=os.getenv("IMAGE_DIR") 14 | 15 | 16 | def get_arguments(): 17 | parser = argparse.ArgumentParser(description='Read images.') 18 | parser.add_argument('--input', type=str, default="extracted_metadata.pkl") 19 | parser.add_argument('--files', type=str) 20 | return parser.parse_args() 21 | 22 | def process_image(d filename): 23 | img = Image.open(filename) 24 | format_ = img.format 25 | width = img.width 26 | height = img.height 27 | return filename, (format_, width, height) 28 | 29 | def main(): 30 | args = get_arguments() 31 | r = pickle.load(open(args.input)) 32 | for key in r: 33 | s = r[key] 34 | if s.has_key('width') and s.has_key('height'): 35 | width, height = s['width'], s['height'] 36 | else: 37 | width, height = None 38 | process_image(r, os.path.join(IMGDIR, key)) 39 | if __name__ == '__main__': 40 | main() 41 | -------------------------------------------------------------------------------- /static-nginx/templates/pod.yaml.tmpl: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2016 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 | apiVersion: v1 17 | kind: Pod 18 | metadata: 19 | name: static-nginx 20 | labels: 21 | app: static-nginx 22 | spec: 23 | containers: 24 | - name: static-nginx 25 | image: {{GCR_PREFIX}}/static-nginx 26 | ports: 27 | - containerPort: 80 28 | livenessProbe: 29 | httpGet: 30 | path: /static/css/main.css 31 | port: 80 32 | resources: 33 | limits: 34 | cpu: 500m 35 | memory: 1000M 36 | requests: 37 | cpu: 500m 38 | memory: 1000M 39 | -------------------------------------------------------------------------------- /admin/app/tests/flask/run_flask_tests: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright 2016 Google Inc. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | # If installation fails then we do not want to run tests 18 | set -e 19 | 20 | 21 | # eclipse2017/admin/app/app 22 | APP_PATH=$(dirname $(dirname $PWD)) 23 | 24 | # eclipse2017/admin/ 25 | ADMIN_PATH=$(dirname $APP_PATH) 26 | 27 | # eclipse2017/ 28 | PRJ_PATH=$(dirname $ADMIN_PATH) 29 | BUILD_DIR=$PRJ_PATH/build 30 | 31 | # common_tests/ 32 | COMMON_TEST_PATH=$PRJ_PATH/common_tests 33 | 34 | # admin/tests/flask/lib 35 | ADMIN_LIB_PATH=$PWD/lib 36 | # common_tests/lib 37 | COMMON_LIB_PATH=$COMMON_TEST_PATH/lib 38 | 39 | export PYTHONPATH=/app:/app/admin/app 40 | python -m unittest discover . "*_test.py" 41 | -------------------------------------------------------------------------------- /common/service_account.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2016 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 | import os 17 | 18 | from google.oauth2 import service_account 19 | 20 | import constants 21 | from eclipse2017_exceptions import CouldNotObtainCredentialsError 22 | 23 | def get_credentials(scopes=''): 24 | """ 25 | Returns credentials object for eclipse service account or None. 26 | """ 27 | try: 28 | credentials = service_account.Credentials.from_service_account_file( 29 | constants.SERVICE_ACCOUNT_PATH) 30 | credentials = credentials.with_scopes(scopes) 31 | except (IOError, ValueError, KeyError) as e: 32 | raise CouldNotObtainCredentialsError(e.message) 33 | return credentials 34 | -------------------------------------------------------------------------------- /static-nginx/app/static/src/behaviors/eclipse-debug-logger.html: -------------------------------------------------------------------------------- 1 | 17 | 43 | -------------------------------------------------------------------------------- /movie/templates/deployment.yaml.tmpl: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2016 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 | apiVersion: v1 17 | kind: ReplicationController 18 | metadata: 19 | name: movie 20 | spec: 21 | selector: 22 | app: movie 23 | template: 24 | metadata: 25 | labels: 26 | app: movie 27 | spec: 28 | containers: 29 | - name: movie-daemon 30 | image: {{GCR_PREFIX}}/movie-daemon 31 | resources: 32 | limits: 33 | cpu: 1000m 34 | memory: 2000M 35 | requests: 36 | cpu: 1000m 37 | memory: 2000M 38 | -------------------------------------------------------------------------------- /profile/app/tests/flask/run_flask_tests: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright 2016 Google Inc. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | # If installation fails then we do not want to run tests 18 | set -e 19 | 20 | 21 | # eclipse2017/profile/app/app 22 | APP_PATH=$(dirname $(dirname $PWD)) 23 | 24 | # eclipse2017/profile/ 25 | PROFILE_PATH=$(dirname $APP_PATH) 26 | 27 | # eclipse2017/ 28 | PRJ_PATH=$(dirname $PROFILE_PATH) 29 | BUILD_DIR=$PRJ_PATH/build 30 | 31 | # common_tests/ 32 | COMMON_TEST_PATH=$PRJ_PATH/common_tests 33 | 34 | # profile/tests/flask/lib 35 | PROFILE_LIB_PATH=$PWD/lib 36 | # common_tests/lib 37 | COMMON_LIB_PATH=$COMMON_TEST_PATH/lib 38 | 39 | export PYTHONPATH=/app:/app/profile/app 40 | python -m unittest discover . "*_test.py" 41 | -------------------------------------------------------------------------------- /upload/system_tests/app/main.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2016 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 | import logging 17 | import time 18 | 19 | from common import constants 20 | 21 | from tests.upload_server_stress_test import UploadServerStressTest 22 | 23 | 24 | logging.basicConfig(level=logging.INFO, format=constants.LOG_FMT_M_THREADED) 25 | 26 | TESTS = ( 27 | (UploadServerStressTest, [], {'logger': logging}), 28 | ) 29 | 30 | 31 | def main(): 32 | 33 | for test_cls, args, kwargs in TESTS: 34 | 35 | test = test_cls(*args, **kwargs) 36 | res = test.run_when_ready() 37 | 38 | # Loop forever. Otherwise kubernetes will restart the container 39 | while True: time.sleep(1000) 40 | 41 | 42 | if __name__ == '__main__': 43 | main() 44 | -------------------------------------------------------------------------------- /base-container/Dockerfile: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2016 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 | FROM ubuntu:16.04 17 | 18 | ENV APT_LISTCHANGES_FRONTEND none 19 | ENV DEBIAN_FRONTEND noninteractive 20 | 21 | #RUN sed -i -e 's/archive.ubuntu.com/mirror.symnds.com/g' /etc/apt/sources.list && \ 22 | COPY requirements.txt /tmp/requirements.txt 23 | 24 | RUN sed -i -e 's/archive.ubuntu.com/mirrors.kernel.org/g' /etc/apt/sources.list && \ 25 | apt-get update -y && \ 26 | apt-get upgrade -y && \ 27 | apt-get install -y --no-install-recommends apt-utils curl iputils-ping telnet netcat-traditional python-setuptools python-pip libraw-dev && \ 28 | pip install --upgrade pip && \ 29 | pip install -r /tmp/requirements.txt && \ 30 | apt-get clean && rm -rf /tmp/* /var/tmp/* 31 | -------------------------------------------------------------------------------- /image-processor/templates/deployment.yaml.tmpl: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2016 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 | apiVersion: v1 17 | kind: ReplicationController 18 | metadata: 19 | name: image-processor 20 | spec: 21 | selector: 22 | app: image-processor 23 | template: 24 | metadata: 25 | labels: 26 | app: image-processor 27 | spec: 28 | containers: 29 | - name: image-processor-daemon 30 | image: {{GCR_PREFIX}}/image-processor-daemon 31 | resources: 32 | limits: 33 | cpu: 1000m 34 | memory: 2000M 35 | requests: 36 | cpu: 1000m 37 | memory: 2000M 38 | -------------------------------------------------------------------------------- /static-nginx/app/static/sitemap.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | https://eclipsemega.movie/ 7 | 2017-01-01 8 | daily 9 | 1.0 10 | 11 | 12 | https://eclipsemega.movie/about 13 | 2017-01-01 14 | daily 15 | 1.0 16 | 17 | 18 | https://eclipsemega.movie/megamovie 19 | 2017-01-01 20 | daily 21 | 1.0 22 | 23 | 24 | https://eclipsemega.movie/safety 25 | 2017-01-01 26 | daily 27 | 1.0 28 | 29 | 30 | https://eclipsemega.movie/resources 31 | 2017-01-01 32 | daily 33 | 1.0 34 | 35 | 36 | -------------------------------------------------------------------------------- /src/solar_eclipse_renderer/render_constants.py: -------------------------------------------------------------------------------- 1 | # Copyright 2017 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 math 16 | 17 | SUN_RADIUS = 695.700 * 1.e6 18 | # MOON_RADIUS = 1.737 * 1.e6 19 | # Note: artificially lowered to make in-umbra areas appear "total" 20 | MOON_RADIUS = 1.7 * 1.e6 21 | EARTH_MOON_DISTANCE = 355.567238 * 1.e6 22 | SUN_EARTH_DISTANCE = 152.060 * 1e9 23 | 24 | SEGMENTS = 100 25 | RING_COUNT = 100 26 | 27 | colors = (255, 0, 0), (0, 255, 0), (0, 0, 255) 28 | 29 | RES_X = 1920 30 | RES_Y = 1080 31 | 32 | NORTHERN_MIN = math.radians(45) 33 | NORTHERN_MAX = math.radians(135) 34 | SOUTHERN_MIN = math.radians(225) 35 | SOUTHERN_MAX = math.radians(315) 36 | WESTERN_MIN = math.radians(-45) 37 | WESTERN_MAX = math.radians(45) 38 | EASTERN_MIN = math.radians(180-45) 39 | EASTERN_MAX = math.radians(180+45) 40 | -------------------------------------------------------------------------------- /scripts/print_photos.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2017 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 | """Print list of photos (debug tool).""" 17 | 18 | import argparse 19 | from google.cloud import datastore 20 | import common.service_account as sa 21 | 22 | DEFAULT_PROJECT = 'eclipse-2017-test-147301' 23 | 24 | def get_arguments(): 25 | parser = argparse.ArgumentParser(description='Print list of photos.') 26 | parser.add_argument('--project_id', type=str, default=DEFAULT_PROJECT) 27 | return parser.parse_args() 28 | 29 | def main(): 30 | args = get_arguments() 31 | 32 | client = datastore.Client(project=args.project_id) 33 | 34 | query = client.query(kind="Photo") 35 | entities = query.fetch() 36 | for entity in entities: 37 | print "Photo id (hashed):", entity 38 | 39 | if __name__ == '__main__': 40 | main() 41 | -------------------------------------------------------------------------------- /scripts/print_processed_photos.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2017 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 | """Print list of photos (debug tool).""" 17 | 18 | import argparse 19 | from google.cloud import datastore 20 | import common.service_account as sa 21 | 22 | DEFAULT_PROJECT = 'eclipse-2017-test-147301' 23 | 24 | def get_arguments(): 25 | parser = argparse.ArgumentParser(description='Print list of photos.') 26 | parser.add_argument('--project_id', type=str, default=DEFAULT_PROJECT) 27 | return parser.parse_args() 28 | 29 | def main(): 30 | args = get_arguments() 31 | 32 | client = datastore.Client(project=args.project_id) 33 | 34 | query = client.query(kind="ProcessedImage") 35 | entities = query.fetch() 36 | for entity in entities: 37 | print "ProcessedImage:", entity 38 | 39 | if __name__ == '__main__': 40 | main() 41 | -------------------------------------------------------------------------------- /datastore-emulator/templates/Dockerfile.tmpl: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2016 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 | FROM {{GCR_PREFIX_WITH_SLASH}}base-container:latest 17 | 18 | USER root 19 | 20 | ENV CLOUDSDK_CORE_DISABLE_PROMPTS 1 21 | ENV DATA_DIR "/data" 22 | 23 | RUN apt-get install -yqq python openjdk-8-jre && \ 24 | curl https://sdk.cloud.google.com | bash && \ 25 | /root/google-cloud-sdk/bin/gcloud config set project {{PROJECT_ID}} && \ 26 | /root/google-cloud-sdk/bin/gcloud components install beta && \ 27 | /root/google-cloud-sdk/bin/gcloud components install cloud-datastore-emulator && \ 28 | apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* 29 | 30 | EXPOSE {{HOST_PORT}} 31 | 32 | CMD /root/google-cloud-sdk/bin/gcloud beta emulators datastore start --no-legacy --host-port=0.0.0.0:{{HOST_PORT}} --consistency="1.0" --data-dir=$DATA_DIR 33 | -------------------------------------------------------------------------------- /static-nginx/app/static/src/eclipse-view404.html: -------------------------------------------------------------------------------- 1 | 16 | 17 | 18 | 19 | 20 | 43 | 44 | 49 | 50 | -------------------------------------------------------------------------------- /common/eclipse2017_exceptions.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2016 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 | from exceptions import Exception 17 | 18 | 19 | class Eclipse2017Exception(Exception): 20 | pass 21 | 22 | 23 | class CloudStorageError(Eclipse2017Exception): 24 | pass 25 | 26 | 27 | class CouldNotObtainCredentialsError(Eclipse2017Exception): 28 | pass 29 | 30 | 31 | class FailedToRenameFileError(Eclipse2017Exception): 32 | pass 33 | 34 | 35 | class FailedToSaveToDatastoreError(Eclipse2017Exception): 36 | pass 37 | 38 | 39 | class FailedToUploadToGCSError(Eclipse2017Exception): 40 | pass 41 | 42 | 43 | class UserDeletedError(Eclipse2017Exception): 44 | pass 45 | 46 | 47 | class ApplicationIdentityError(Exception): 48 | pass 49 | class MissingCredentialTokenError(Exception): 50 | pass 51 | class MissingUserError(Exception): 52 | pass 53 | -------------------------------------------------------------------------------- /src/solar_eclipse_analysis/renumber_movie.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2017 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 | import shutil 17 | import glob 18 | import os 19 | import argparse 20 | 21 | def get_arguments(): 22 | parser = argparse.ArgumentParser(description='Render movie.') 23 | parser.add_argument('--output_directory', type=str, default='movie') 24 | parser.add_argument('--renumber_directory', type=str, default='renumber') 25 | return parser.parse_args() 26 | 27 | 28 | def main(): 29 | args = get_arguments() 30 | gs = glob.glob(args.output_directory + "/*") 31 | gs.sort() 32 | r = [] 33 | for g in gs: 34 | r.append(g) 35 | 36 | for i in range(len(r)): 37 | source = r[i] 38 | dest = os.path.join(args.renumber_directory, "%05d.png" % i) 39 | shutil.copyfile(source, dest) 40 | 41 | 42 | if __name__ == '__main__': 43 | main() 44 | -------------------------------------------------------------------------------- /static-nginx/app/static/src/shared-styles.html: -------------------------------------------------------------------------------- 1 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 44 | 45 | -------------------------------------------------------------------------------- /static-nginx/app/static/src/eclipse-icons.html: -------------------------------------------------------------------------------- 1 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /test-container/templates/Dockerfile.tmpl: -------------------------------------------------------------------------------- 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 | FROM {{GCR_PREFIX_WITH_SLASH}}base-container:latest 17 | 18 | ENV DEBIAN_FRONTEND noninteractive 19 | ENV APT_LISTCHANGES_FRONTEND none 20 | ENV CLOUDSDK_CORE_DISABLE_PROMPTS 1 21 | 22 | COPY conf/requirements.txt /tmp/requirements.txt 23 | RUN apt-get install -y --no-install-recommends gcc python-dev && \ 24 | pip install -r /tmp/requirements.txt && \ 25 | apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* 26 | RUN mkdir /var/www 27 | RUN chown www-data:www-data /var/www 28 | USER www-data 29 | RUN curl https://sdk.cloud.google.com | bash && ls /var/www && /var/www/google-cloud-sdk/bin/gcloud config set project {{PROJECT_ID}} 30 | 31 | USER root 32 | ENV GOOGLE_APPLICATION_CREDENTIALS=/app/common/service_account.json 33 | ADD application.tar /app 34 | RUN chown -R www-data /app 35 | 36 | USER www-data 37 | WORKDIR /app 38 | # No default. 39 | -------------------------------------------------------------------------------- /src/export_eclipse_dataset/generate_random_id.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2017 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 | import uuid 17 | import os 18 | import pickle 19 | import datetime 20 | from google.cloud import datastore 21 | import argparse 22 | import pytz 23 | import metadata 24 | 25 | 26 | def get_arguments(): 27 | parser = argparse.ArgumentParser(description='Generate mapping table from ID to random UUID.') 28 | parser.add_argument('--user_metadata', type=str, default="user_metadata.pkl") 29 | parser.add_argument('--user_random_uuid', type=str, default="user_random_uuid.pkl") 30 | return parser.parse_args() 31 | 32 | def main(): 33 | args = get_arguments() 34 | user_metadata = pickle.load(open(args.user_metadata, "rb")) 35 | r = {} 36 | for user in user_metadata: 37 | r[user.key.name] = uuid.uuid4().get_hex() 38 | pickle.dump(r, open(args.user_random_uuid, "wb")) 39 | 40 | if __name__ == '__main__': 41 | main() 42 | -------------------------------------------------------------------------------- /scripts/_teardown: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright 2016 Google Inc. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | echo "Tearing down deployment..." 18 | 19 | if [[ $LOCAL_DEV != true ]]; then 20 | # TODO(dek): support APP selector here to selectively restart some containers. 21 | if [[ -z $APP || $APP == static-nginx ]]; then 22 | kubectl delete service --ignore-not-found static-nginx 23 | kubectl delete -f build/static-nginx/deployment.yaml --ignore-not-found 24 | fi 25 | if [[ -z $APP || $APP == geo-server || $APP == geo-nginx ]]; then 26 | kubectl delete service --ignore-not-found geo 27 | kubectl delete -f build/geo/deployment.yaml --ignore-not-found 28 | fi 29 | else 30 | IMAGES="geo-server \ 31 | geo-nginx \ 32 | datastore-emulator \ 33 | static-nginx \ 34 | nginx-lb-emulator" 35 | 36 | for img in $IMAGES; do 37 | [[ -z $APP || $APP == $img ]] && docker rm -f $img 38 | done 39 | fi 40 | 41 | echo "Done tearing down deployment." 42 | -------------------------------------------------------------------------------- /static-nginx/app/static/src/array-findindex-polyfill.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Any copyright is dedicated to the Public Domain. http://creativecommons.org/publicdomain/zero/1.0/" 4 | */ 5 | if (!Array.prototype.findIndex) { 6 | Object.defineProperty(Array.prototype, 'findIndex', { 7 | value: function(predicate) { 8 | // 1. Let O be ? ToObject(this value). 9 | if (this == null) { 10 | throw new TypeError('"this" is null or not defined'); 11 | } 12 | 13 | var o = Object(this); 14 | 15 | // 2. Let len be ? ToLength(? Get(O, "length")). 16 | var len = o.length >>> 0; 17 | 18 | // 3. If IsCallable(predicate) is false, throw a TypeError exception. 19 | if (typeof predicate !== 'function') { 20 | throw new TypeError('predicate must be a function'); 21 | } 22 | 23 | // 4. If thisArg was supplied, let T be thisArg; else let T be undefined. 24 | var thisArg = arguments[1]; 25 | 26 | // 5. Let k be 0. 27 | var k = 0; 28 | 29 | // 6. Repeat, while k < len 30 | while (k < len) { 31 | // a. Let Pk be ! ToString(k). 32 | // b. Let kValue be ? Get(O, Pk). 33 | // c. Let testResult be ToBoolean(? Call(predicate, T, « kValue, k, O »)). 34 | // d. If testResult is true, return k. 35 | var kValue = o[k]; 36 | if (predicate.call(thisArg, kValue, k, o)) { 37 | return k; 38 | } 39 | // e. Increase k by 1. 40 | k++; 41 | } 42 | 43 | // 7. Return -1. 44 | return -1; 45 | } 46 | }); 47 | } -------------------------------------------------------------------------------- /src/solar_eclipse_analysis/exif.py: -------------------------------------------------------------------------------- 1 | import exifread 2 | from gps import exifread_tags_to_latlon, hms_to_deg, exifread_tags_to_gps_datetime, exifread_tags_to_camera_datetime 3 | def _extract_exif_metadata(fpath): 4 | """ 5 | Extracts EXIF metadata corresponding to image with fpath 6 | Returns metadata_dictionary 7 | """ 8 | 9 | metadata = {} 10 | # convert to exifread support 11 | f = open(fpath, 'rb') 12 | try: 13 | tags = exifread.process_file(f) 14 | except Exception as e: 15 | print "exifread failed to process file:", fpath, e 16 | lat, lon, image_datetime = None, None, None 17 | else: 18 | lat, lon = exifread_tags_to_latlon(tags) 19 | image_datetime = exifread_tags_to_gps_datetime(tags) 20 | camera_datetime = exifread_tags_to_camera_datetime(tags) 21 | if image_datetime: 22 | metadata['image_datetime'] = image_datetime 23 | if camera_datetime: 24 | metadata['camera_datetime'] = camera_datetime 25 | else: 26 | print "Image", fpath, "is missing camera datetime" 27 | if lat: 28 | metadata['lat'] = lat 29 | if lon: 30 | metadata['lon'] = lon 31 | return metadata 32 | 33 | def _extract_image_metadata(filename, format_, width, height, bucket): 34 | """ 35 | Extracts image format-specific metadata corresponding to image with fpath 36 | Returns metadata_dictionary 37 | """ 38 | metadata = {} 39 | metadata['image_type'] = unicode(format_) 40 | metadata['width'] = width 41 | metadata['height'] = height 42 | return metadata 43 | -------------------------------------------------------------------------------- /upload/server/tests/upload_server_test_base.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2016 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 | import os 17 | 18 | import unittest2 19 | 20 | from common import constants 21 | 22 | 23 | class UploadServerTestBase(unittest2.TestCase): 24 | """ 25 | Base class for upload server tests. 26 | """ 27 | temp_dir = '/tmp/eclipse2017_upload_server_test_files' 28 | readiness_file = os.path.join(temp_dir, 'readiness_status') 29 | upload_dir = os.path.join(temp_dir, 'uploads') 30 | 31 | @classmethod 32 | def setUpClass(cls): 33 | """ 34 | One time setup. 35 | """ 36 | os.mkdir(cls.temp_dir) 37 | os.mkdir(cls.upload_dir) 38 | 39 | with open(cls.readiness_file, 'w') as f: 40 | f.write(constants.STATUS_READY) 41 | 42 | @classmethod 43 | def tearDownClass(cls): 44 | """ 45 | One time tear down. 46 | """ 47 | os.remove(cls.readiness_file) 48 | os.rmdir(cls.upload_dir) 49 | os.rmdir(cls.temp_dir) 50 | -------------------------------------------------------------------------------- /scripts/print_users.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2016 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 | """Print list of users (debug tool).""" 17 | 18 | import argparse 19 | from google.cloud import datastore 20 | import common.service_account as sa 21 | 22 | DEFAULT_PROJECT = 'eclipse-2017-test-147301' 23 | 24 | def get_arguments(): 25 | parser = argparse.ArgumentParser(description='Print list of users.') 26 | parser.add_argument('--project_id', type=str, default=DEFAULT_PROJECT) 27 | return parser.parse_args() 28 | 29 | def main(): 30 | args = get_arguments() 31 | 32 | client = datastore.Client(project=args.project_id) 33 | 34 | query = client.query(kind="User") 35 | 36 | entities = query.fetch() 37 | for entity in entities: 38 | print "User id (hashed):", entity.key.name 39 | if 'badges' in entity: 40 | print "Badges ", entity['badges'] 41 | key = client.key("UserRole", entity.key.name) 42 | entity = client.get(key) 43 | print "\troles:", entity['roles'] 44 | 45 | if __name__ == '__main__': 46 | main() 47 | -------------------------------------------------------------------------------- /geo/templates/deployment.yaml.tmpl: -------------------------------------------------------------------------------- 1 | apiVersion: extensions/v1beta1 2 | kind: Deployment 3 | metadata: 4 | name: geo 5 | spec: 6 | replicas: 3 7 | selector: 8 | matchLabels: 9 | tier: geo-backend 10 | matchExpressions: 11 | - {key: tier, operator: In, values: [geo-backend]} 12 | template: 13 | metadata: 14 | labels: 15 | app: geo 16 | tier: geo-backend 17 | spec: 18 | containers: 19 | - name: geo-server 20 | image: {{GCR_PREFIX}}/geo-server 21 | ports: 22 | - containerPort: 8080 23 | livenessProbe: 24 | httpGet: 25 | path: /healthz 26 | port: 8080 27 | readinessProbe: 28 | httpGet: 29 | path: /healthz 30 | port: 8080 31 | # TODO(dek): health probe 32 | resources: 33 | limits: 34 | cpu: 1000m 35 | memory: 512M 36 | requests: 37 | cpu: 100m 38 | memory: 512M 39 | - name: geo-nginx 40 | image: {{GCR_PREFIX}}/geo-nginx 41 | ports: 42 | - containerPort: 80 43 | livenessProbe: 44 | httpGet: 45 | path: /healthz 46 | port: 80 47 | readinessProbe: 48 | httpGet: 49 | path: /healthz 50 | port: 80 51 | resources: 52 | limits: 53 | cpu: 1000m 54 | memory: 128M 55 | requests: 56 | cpu: 100m 57 | memory: 128M 58 | -------------------------------------------------------------------------------- /geo/app/app/backend/eclipse2017_app.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2017 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 | from flask import Flask 17 | 18 | from geo import geo 19 | from routes import Routes 20 | 21 | 22 | blueprints = ( 23 | (geo.create_blueprint(), '/services/geo'),) 24 | 25 | base_routes = Routes() 26 | 27 | 28 | class Eclipse2017GeoApp(Flask): 29 | """ 30 | Eclipse 2017 application. 31 | """ 32 | def __init__( 33 | self, project_id, session_enc_key, google_oauth2_client_id, 34 | google_oauth2_client_secret, debug=False, 35 | blueprints=blueprints, routes=base_routes, geo=geo, 36 | **kwargs): 37 | super(Eclipse2017GeoApp, self).__init__(__name__, **kwargs) 38 | 39 | self.config['PROJECT_ID'] = project_id 40 | self.config['SECRET_KEY'] = session_enc_key 41 | self.config['GOOGLE_OAUTH2_CLIENT_ID'] = google_oauth2_client_id 42 | self.config['GOOGLE_OAUTH2_CLIENT_SECRET'] = google_oauth2_client_secret 43 | 44 | 45 | self.geo = geo 46 | 47 | self.debug = debug 48 | routes.register(self, blueprints) 49 | -------------------------------------------------------------------------------- /admin/templates/deployment.yaml.tmpl: -------------------------------------------------------------------------------- 1 | apiVersion: extensions/v1beta1 2 | kind: Deployment 3 | metadata: 4 | name: admin 5 | spec: 6 | replicas: 2 7 | selector: 8 | matchLabels: 9 | tier: admin-backend 10 | matchExpressions: 11 | - {key: tier, operator: In, values: [admin-backend]} 12 | template: 13 | metadata: 14 | labels: 15 | app: admin 16 | tier: admin-backend 17 | spec: 18 | containers: 19 | - name: admin-server 20 | image: {{GCR_PREFIX}}/admin-server 21 | ports: 22 | - containerPort: 8080 23 | livenessProbe: 24 | httpGet: 25 | path: /healthz 26 | port: 8080 27 | readinessProbe: 28 | httpGet: 29 | path: /healthz 30 | port: 8080 31 | # TODO(dek): health probe 32 | resources: 33 | limits: 34 | cpu: 1000m 35 | memory: 2G 36 | requests: 37 | cpu: 100m 38 | memory: 2G 39 | - name: admin-nginx 40 | image: {{GCR_PREFIX}}/admin-nginx 41 | ports: 42 | - containerPort: 80 43 | livenessProbe: 44 | httpGet: 45 | path: /healthz 46 | port: 80 47 | readinessProbe: 48 | httpGet: 49 | path: /healthz 50 | port: 80 51 | resources: 52 | limits: 53 | cpu: 1000m 54 | memory: 128M 55 | requests: 56 | cpu: 100m 57 | memory: 128M 58 | -------------------------------------------------------------------------------- /photo/templates/deployment.yaml.tmpl: -------------------------------------------------------------------------------- 1 | apiVersion: extensions/v1beta1 2 | kind: Deployment 3 | metadata: 4 | name: photo 5 | spec: 6 | replicas: 3 7 | selector: 8 | matchLabels: 9 | tier: photo-backend 10 | matchExpressions: 11 | - {key: tier, operator: In, values: [photo-backend]} 12 | template: 13 | metadata: 14 | labels: 15 | app: photo 16 | tier: photo-backend 17 | spec: 18 | containers: 19 | - name: photo-server 20 | image: {{GCR_PREFIX}}/photo-server 21 | ports: 22 | - containerPort: 8080 23 | livenessProbe: 24 | httpGet: 25 | path: /healthz 26 | port: 8080 27 | readinessProbe: 28 | httpGet: 29 | path: /healthz 30 | port: 8080 31 | # TODO(dek): health probe 32 | resources: 33 | limits: 34 | cpu: 1000m 35 | memory: 512M 36 | requests: 37 | cpu: 100m 38 | memory: 512M 39 | - name: photo-nginx 40 | image: {{GCR_PREFIX}}/photo-nginx 41 | ports: 42 | - containerPort: 80 43 | livenessProbe: 44 | httpGet: 45 | path: /healthz 46 | port: 80 47 | readinessProbe: 48 | httpGet: 49 | path: /healthz 50 | port: 80 51 | resources: 52 | limits: 53 | cpu: 1000m 54 | memory: 128M 55 | requests: 56 | cpu: 100m 57 | memory: 128M 58 | -------------------------------------------------------------------------------- /scripts/add_movie.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2017 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 | """Script to add movie to Movie table.""" 17 | 18 | import datetime 19 | import argparse 20 | from google.cloud import datastore 21 | 22 | def get_arguments(): 23 | parser = argparse.ArgumentParser(description='Add movie to Movie table and write to file') 24 | parser.add_argument('--project_id', type=str, default="eclipse-2017-test-147301") 25 | parser.add_argument('--id', type=str, default="3syEpviPtjs") 26 | parser.add_argument('--outfile', type=str, default="static-nginx/app/static/src/movie-id.js") 27 | return parser.parse_args() 28 | 29 | def main(): 30 | args = get_arguments() 31 | client = datastore.Client(project=args.project_id) 32 | key = client.key("Movie") 33 | entity = datastore.Entity(key = key) 34 | entity.key = key 35 | entity.update({'id': args.id, 36 | 'time': datetime.datetime.utcnow()}) 37 | client.put(entity) 38 | f = open(args.outfile, "w") 39 | f.write("var movie_id = '%s';\n" % args.id) 40 | f.close() 41 | 42 | if __name__ == '__main__': 43 | main() 44 | -------------------------------------------------------------------------------- /profile/templates/deployment.yaml.tmpl: -------------------------------------------------------------------------------- 1 | apiVersion: extensions/v1beta1 2 | kind: Deployment 3 | metadata: 4 | name: profile 5 | spec: 6 | replicas: 3 7 | selector: 8 | matchLabels: 9 | tier: profile-backend 10 | matchExpressions: 11 | - {key: tier, operator: In, values: [profile-backend]} 12 | template: 13 | metadata: 14 | labels: 15 | app: profile 16 | tier: profile-backend 17 | spec: 18 | containers: 19 | - name: profile-server 20 | image: {{GCR_PREFIX}}/profile-server 21 | ports: 22 | - containerPort: 8080 23 | livenessProbe: 24 | httpGet: 25 | path: /healthz 26 | port: 8080 27 | readinessProbe: 28 | httpGet: 29 | path: /healthz 30 | port: 8080 31 | # TODO(dek): health probe 32 | resources: 33 | limits: 34 | cpu: 1000m 35 | memory: 1G 36 | requests: 37 | cpu: 100m 38 | memory: 1G 39 | - name: profile-nginx 40 | image: {{GCR_PREFIX}}/profile-nginx 41 | ports: 42 | - containerPort: 80 43 | livenessProbe: 44 | httpGet: 45 | path: /healthz 46 | port: 80 47 | readinessProbe: 48 | httpGet: 49 | path: /healthz 50 | port: 80 51 | resources: 52 | limits: 53 | cpu: 1000m 54 | memory: 128M 55 | requests: 56 | cpu: 100m 57 | memory: 128M 58 | -------------------------------------------------------------------------------- /src/export_eclipse_dataset/determine_state.py: -------------------------------------------------------------------------------- 1 | from functools import partial 2 | import pickle 3 | import argparse 4 | import googlemaps 5 | from multiprocessing import Pool 6 | 7 | def get_arguments(): 8 | parser = argparse.ArgumentParser(description='') 9 | parser.add_argument('--filtered_photo_metadata', type=str, default="filtered_photo_metadata.pkl") 10 | parser.add_argument('--google_maps_api_key', type=str) 11 | parser.add_argument('--state_output', type=str, default="states.pkl") 12 | return parser.parse_args() 13 | 14 | def get_state(gmaps, item): 15 | lat = item['lat'] 16 | lng = -item['lon'] 17 | try: 18 | reverse_geocode_result = gmaps.reverse_geocode((lat, lng)) 19 | except googlemaps.exceptions.Timeout: 20 | return item.key.name, None 21 | for result in reverse_geocode_result: 22 | for address_component in result['address_components']: 23 | if u'administrative_area_level_1' in address_component['types'] : 24 | state = address_component['short_name'] 25 | return item.key.name, state 26 | return item.key.name, None 27 | 28 | def main(): 29 | args = get_arguments() 30 | 31 | TIMEOUT=30 32 | RETRY_TIMEOUT=30 33 | gmaps = googlemaps.Client(key=args.google_maps_api_key, 34 | timeout=TIMEOUT, 35 | retry_timeout=RETRY_TIMEOUT) 36 | # Load photo points 37 | r = pickle.load(open(args.filtered_photo_metadata)) 38 | f = partial(get_state, gmaps) 39 | p = Pool(5) 40 | results = p.map(f, r) 41 | pickle.dump(dict(results), open(args.state_output, "wb")) 42 | 43 | if __name__ == '__main__': 44 | main() 45 | -------------------------------------------------------------------------------- /photo/app/app/backend/eclipse2017_photo_app.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2017 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 | from flask import Flask 17 | 18 | from photo import photo 19 | from routes import Routes 20 | 21 | 22 | blueprints = ( 23 | (photo.create_blueprint(), '/services/photo'),) 24 | 25 | base_routes = Routes() 26 | 27 | 28 | class Eclipse2017PhotoApp(Flask): 29 | """ 30 | Eclipse 2017 Photo application. 31 | """ 32 | def __init__( 33 | self, project_id, session_enc_key, google_oauth2_client_id, 34 | google_oauth2_client_secret, debug=False, 35 | blueprints=blueprints, routes=base_routes, photo=photo, 36 | **kwargs): 37 | super(Eclipse2017PhotoApp, self).__init__(__name__, **kwargs) 38 | 39 | self.config['PROJECT_ID'] = project_id 40 | self.config['SECRET_KEY'] = session_enc_key 41 | self.config['GOOGLE_OAUTH2_CLIENT_ID'] = google_oauth2_client_id 42 | self.config['GOOGLE_OAUTH2_CLIENT_SECRET'] = google_oauth2_client_secret 43 | 44 | 45 | self.photo = photo 46 | 47 | self.debug = debug 48 | routes.register(self, blueprints) 49 | -------------------------------------------------------------------------------- /profile/app/app/backend/eclipse2017_app.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2016 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 | from flask import Flask 17 | 18 | from profile import profile 19 | from routes import Routes 20 | 21 | 22 | blueprints = ( 23 | (profile.create_blueprint(), '/services/user/profile'),) 24 | 25 | base_routes = Routes() 26 | 27 | 28 | class Eclipse2017App(Flask): 29 | """ 30 | Eclipse 2017 application. 31 | """ 32 | def __init__( 33 | self, project_id, session_enc_key, google_oauth2_client_id, 34 | google_oauth2_client_secret, debug=False, 35 | blueprints=blueprints, routes=base_routes, profile=profile, 36 | **kwargs): 37 | super(Eclipse2017App, self).__init__(__name__, **kwargs) 38 | 39 | self.config['PROJECT_ID'] = project_id 40 | self.config['SECRET_KEY'] = session_enc_key 41 | self.config['GOOGLE_OAUTH2_CLIENT_ID'] = google_oauth2_client_id 42 | self.config['GOOGLE_OAUTH2_CLIENT_SECRET'] = google_oauth2_client_secret 43 | 44 | 45 | self.profile = profile 46 | 47 | self.debug = debug 48 | routes.register(self, blueprints) 49 | -------------------------------------------------------------------------------- /src/export_eclipse_dataset/filter_photos.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2017 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 | """Filter photos based on criteria.""" 17 | 18 | import os 19 | import pickle 20 | import datetime 21 | import argparse 22 | import pytz 23 | import metadata 24 | 25 | DEFAULT_PROJECT = 'eclipse-2017-test' 26 | 27 | def get_arguments(): 28 | parser = argparse.ArgumentParser(description='Filter photos based on criteria.') 29 | parser.add_argument('--project_id', type=str, default=DEFAULT_PROJECT) 30 | parser.add_argument('--photo_metadata', type=str, default="photo_metadata.pkl") 31 | parser.add_argument('--filtered_photo_metadata', type=str, default="filtered_photo_metadata.pkl") 32 | parser.add_argument('--directory', type=str, default="photos") 33 | return parser.parse_args() 34 | 35 | def main(): 36 | args = get_arguments() 37 | 38 | entities = pickle.load(open(args.photo_metadata, "rb")) 39 | filtered_entities = [entity for entity in entities if metadata.filter_photo_record(entity)] 40 | pickle.dump(filtered_entities, open(args.filtered_photo_metadata, "wb")) 41 | 42 | if __name__ == '__main__': 43 | main() 44 | -------------------------------------------------------------------------------- /scripts/extract_metadata.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2017 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 | """Extract metadata from image.""" 17 | 18 | import argparse 19 | import exifread 20 | from PIL import Image 21 | from common.gps import exifread_tags_to_latlon, hms_to_deg, exifread_tags_to_gps_datetime, exifread_tags_to_camera_datetime, apply_timezone_offset 22 | from common.geometry import ratio_to_decimal 23 | 24 | def get_arguments(): 25 | parser = argparse.ArgumentParser(description='Extract metadata from image') 26 | parser.add_argument('--filename', type=str) 27 | return parser.parse_args() 28 | 29 | def main(): 30 | args = get_arguments() 31 | f = open(args.filename, 'rb') 32 | tags = exifread.process_file(f) 33 | lat, lon = exifread_tags_to_latlon(tags) 34 | image_datetime = exifread_tags_to_gps_datetime(tags) 35 | camera_datetime = exifread_tags_to_camera_datetime(tags) 36 | if lat is not None and lon is not None and camera_datetime is not None: 37 | camera_datetime = apply_timezone_offset(lat, -lon, camera_datetime) 38 | print lat, -lon, image_datetime, camera_datetime 39 | 40 | if __name__ == '__main__': 41 | main() 42 | -------------------------------------------------------------------------------- /scripts/delete_processed_photos.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2017 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 | """Deletes processed photos (debug tool).""" 17 | 18 | import argparse 19 | from google.cloud import datastore 20 | import common.service_account as sa 21 | 22 | # This is not a valid project name (for safety) 23 | DEFAULT_PROJECT = 'eclipse-2017-test' 24 | 25 | def get_arguments(): 26 | parser = argparse.ArgumentParser(description='Delete processed photos.') 27 | parser.add_argument('--project_id', type=str, default=DEFAULT_PROJECT) 28 | return parser.parse_args() 29 | 30 | def main(): 31 | args = get_arguments() 32 | 33 | client = datastore.Client(project=args.project_id) 34 | 35 | query = client.query(kind="ProcessedImage") 36 | query.keys_only() 37 | 38 | entities = query.fetch() 39 | batch = client.batch() 40 | batch.begin() 41 | i = 0 42 | for entity in entities: 43 | batch.delete(entity.key) 44 | i = i + 1 45 | if i == 500: 46 | batch.commit() 47 | batch = client.batch() 48 | batch.begin() 49 | i = 0 50 | batch.commit() 51 | 52 | if __name__ == '__main__': 53 | main() 54 | -------------------------------------------------------------------------------- /scripts/create_user.py: -------------------------------------------------------------------------------- 1 | # Copyright 2017 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 | """Add user.""" 15 | 16 | import functools 17 | import multiprocessing 18 | import argparse 19 | import json 20 | import os 21 | import requests 22 | 23 | from common.id_token import get_id_token 24 | 25 | def get_arguments(): 26 | parser = argparse.ArgumentParser(description='Add a user') 27 | parser.add_argument('--hostname', type=str, default="localhost") 28 | parser.add_argument('--user_id', type=str) 29 | parser.add_argument('--name', type=str) 30 | parser.add_argument('--email', type=str) 31 | return parser.parse_args() 32 | 33 | 34 | def create_user(id_token, args): 35 | headers = { 'x-idtoken': id_token, 'content-type': 'application/json' } 36 | url = 'https://%s/services/user/profile/%s' % (args.hostname, args.user_id) 37 | data = json.dumps({ 'name': args.name, 'email': args.email }) 38 | r = requests.put(url, headers=headers, data=data, verify=False) 39 | 40 | return r 41 | 42 | 43 | def main(): 44 | args = get_arguments() 45 | id_token = get_id_token() 46 | r = create_user(id_token, args) 47 | print r.text 48 | 49 | 50 | if __name__ == '__main__': 51 | main() 52 | -------------------------------------------------------------------------------- /static-nginx/app/static/src/array-includes-polyfill.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Any copyright is dedicated to the Public Domain. http://creativecommons.org/publicdomain/zero/1.0/" 4 | */ 5 | if (!Array.prototype.includes) { 6 | Object.defineProperty(Array.prototype, 'includes', { 7 | value: function(searchElement, fromIndex) { 8 | 9 | // 1. Let O be ? ToObject(this value). 10 | if (this == null) { 11 | throw new TypeError('"this" is null or not defined'); 12 | } 13 | 14 | var o = Object(this); 15 | 16 | // 2. Let len be ? ToLength(? Get(O, "length")). 17 | var len = o.length >>> 0; 18 | 19 | // 3. If len is 0, return false. 20 | if (len === 0) { 21 | return false; 22 | } 23 | 24 | // 4. Let n be ? ToInteger(fromIndex). 25 | // (If fromIndex is undefined, this step produces the value 0.) 26 | var n = fromIndex | 0; 27 | 28 | // 5. If n ≥ 0, then 29 | // a. Let k be n. 30 | // 6. Else n < 0, 31 | // a. Let k be len + n. 32 | // b. If k < 0, let k be 0. 33 | var k = Math.max(n >= 0 ? n : len - Math.abs(n), 0); 34 | 35 | function sameValueZero(x, y) { 36 | return x === y || (typeof x === 'number' && typeof y === 'number' && isNaN(x) && isNaN(y)); 37 | } 38 | 39 | // 7. Repeat, while k < len 40 | while (k < len) { 41 | // a. Let elementK be the result of ? Get(O, ! ToString(k)). 42 | // b. If SameValueZero(searchElement, elementK) is true, return true. 43 | // c. Increase k by 1. 44 | if (sameValueZero(o[k], searchElement)) { 45 | return true; 46 | } 47 | k++; 48 | } 49 | 50 | // 8. Return false 51 | return false; 52 | } 53 | }); 54 | } 55 | -------------------------------------------------------------------------------- /common/test_common.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2017 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 | def _clear_data(client): 17 | query = client.query(kind='__kind__') 18 | entities = query.fetch() 19 | for entity in entities: 20 | kind = entity.key.name 21 | # Keys starting with __ are reserved and shouldn't be deleted. 22 | if not kind.startswith("__"): 23 | query = client.query(kind=kind) 24 | query.keys_only() 25 | entities = query.fetch() 26 | results = [] 27 | for entity in entities: 28 | results.append(entity.key) 29 | client.delete_multi(results) 30 | 31 | def _print_data(client): 32 | print "data:" 33 | query = client.query(kind='__kind__') 34 | entities = query.fetch() 35 | for entity in entities: 36 | kind = entity.key.name 37 | query = client.query(kind=kind) 38 | query.keys_only() 39 | entities = query.fetch() 40 | results = [] 41 | for entity in entities: 42 | results.append(entity.key) 43 | print kind, results 44 | 45 | def _set_user_roles(roles, client, user_hash, set_roles): 46 | return roles.create_user_role(client, user_hash, set_roles) 47 | -------------------------------------------------------------------------------- /nginx-lb-emulator/resources/lb-emulator.key: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDMNHAqJpJwD3gn 3 | e9KYb+F6Wz8GDt9/iht7zWOj3xv9gIgTOZ6t5iwBGwX9aZwTRF5CuA+7COrRNHch 4 | PPr588dBxylfFpTLgilmM4/pxyq75jkD3ZI3KO2eyBytKcyvC3UNJiO9wraB9CAt 5 | En+cmmQvusuINgkFQatn7doLYbH0uaU6LV/UnV99+zAoZ7Gi2bR+9EhxPzTNVuLf 6 | u3DIFM6GZFf3+A4vXZTOuSKf4fDIw1Izra2jI/4AFAGxO9dWOuy7/pcAeOvdwKwv 7 | Zf+ExD8LEIFpC4wQtbMU9NFSmk2AttESNTMh7hQB3Hh2NN1L7OYqSxLObtVdscpw 8 | 88Yvv/GjAgMBAAECggEAY8+Jt4CM+QsGnr3uDKY63pR09KAWa/90OYoFltZ5lunZ 9 | GRSD09n6TjwILHoPWHeFXzUaM0BDjigHxo5I2h1mmmcfeKPP7LzdQWAYiprX72mz 10 | GomVazKtGnwTUCxrKHAAMYIf3COtE03g4Eb3avMn3xB9ZUGMHS6g+jaO6htBYSzv 11 | o8M6zPCcUil/l2zIZDjdA7a456pM1UJs0/5zWNZWrNccLComwrE7dxJrXkvk4kF1 12 | IVLtQgzTOzQ8Azyh4/FDmEHNM6H/FfhTfntaL/jZ+h8T6h1d/9duB4pJa0/FyqcJ 13 | F53cFLYxNPqQ7YmydBl9gZN6Lg6qJyW8zF4vxE2Y4QKBgQD+dzXUHnLRJvM6avSk 14 | EUKmgGsmqLAh1xwVZwJVVyKqSdHOyf3VP0jECbGNgiAvXxIQkt0/gOvU/P7TX+6Y 15 | Cey1HjgJfp35/fjv4wZOzN5+AjhAn3/93RTNWr0t50nR3NPkxMP01CVsHa5kkP8n 16 | Oi4sZONKZqvpSUe431TplKaP0wKBgQDNb6Vcq7WwwRliSOL6ot2/dGRpsrtUFQs6 17 | G7JgGqU3fs1EZnwMk6on/0xna/Aphz5ChmalimxaJSfnZRuweQaz5Fj/gZcGbeDd 18 | rGdrxVbcn1ApQAE1kDvLb0zRHH15ymqDZcDwihp54aPy66d3SaXXrP2fTKeUqM5h 19 | sX/y07fE8QKBgEJ1J93KRfpRzdxH6rSevWV2zIVAMR/lajQ8vuNC6o7G0MDNCDoV 20 | WQ+56GEoxvcYQUOK17WqGe16VaMmvs1+ag+zYLc6FlAgAE/GXvNdlg4azk4yWd8X 21 | SkOHmzjN2v2wSrbInNToQw3FgrJJHBpGm6CEiMf5oJRAyzaBPU/zvrx5AoGAC91b 22 | 1otQNgIg/i0pdsI7PlhxiC07ZnLEsDlzRtujGR5oqn+kwHEyzZaQChUQzMUz0lHC 23 | 0eK5uUcWE+YiAEItIeyZO0B3wXZNG2BepLnD93/3+DnrF/XZjjlCXX1gvczz89zH 24 | lNzVBJ8Egf4cMOZ+/oLOLwoVT5+kM741noedwHECgYBO4FIKCQO+CcXEBBZwOx4i 25 | rucGIKSat5YkK2grX8rP5q6C6kWu2A6jjpDmx1YYaLTz6rhnDBRMTmJEoxMN2br6 26 | TdwhndMTaqp+NLfkq8KWNiZ1g6DLMjWavaBMvpdSlxYw5Bp0ykNfvybEKFt6hjoc 27 | 2Tef09CMVlcUMDzMHHeKaw== 28 | -----END PRIVATE KEY----- 29 | -------------------------------------------------------------------------------- /scripts/inspect_clusters.py: -------------------------------------------------------------------------------- 1 | # Copyright 2017 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 | """Add user.""" 15 | 16 | import argparse 17 | import json 18 | import os 19 | import requests 20 | 21 | from common.id_token import get_id_token 22 | 23 | def get_arguments(): 24 | parser = argparse.ArgumentParser(description='Add a user') 25 | parser.add_argument('--hostname', type=str, default="localhost") 26 | return parser.parse_args() 27 | 28 | 29 | def inspect_user_clusters(id_token, args): 30 | headers = { 'x-idtoken': id_token } 31 | url = 'https://%s/services/admin/clusters/users' % args.hostname 32 | r = requests.get(url, headers=headers, verify=False) 33 | 34 | return r 35 | 36 | def inspect_photo_clusters(id_token, args): 37 | headers = { 'x-idtoken': id_token } 38 | url = 'https://%s/services/admin/clusters/photos' % args.hostname 39 | r = requests.get(url, headers=headers, verify=False) 40 | 41 | return r 42 | 43 | 44 | def main(): 45 | args = get_arguments() 46 | id_token = get_id_token() 47 | r = inspect_user_clusters(id_token, args) 48 | print r 49 | print r.text 50 | r = inspect_photo_clusters(id_token, args) 51 | print r 52 | print r.text 53 | 54 | if __name__ == '__main__': 55 | main() 56 | -------------------------------------------------------------------------------- /scripts/movie_tool.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2017 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 | """Map image data.""" 17 | 18 | import logging 19 | import argparse 20 | from google.cloud import datastore, storage 21 | import movie.pipeline 22 | from common import config, constants 23 | from common.chunks import chunks 24 | 25 | DEFAULT_PROJECT = 'eclipse-2017-test' 26 | 27 | def get_arguments(): 28 | parser = argparse.ArgumentParser(description='Map image data.') 29 | parser.add_argument('--project_id', type=str, default=DEFAULT_PROJECT) 30 | return parser.parse_args() 31 | 32 | def main(): 33 | logging.basicConfig(level=logging.INFO, 34 | format=constants.LOG_FMT_S_THREADED) 35 | args = get_arguments() 36 | datastore_client = datastore.Client(project=args.project_id) 37 | storage_client = storage.client.Client(project=args.project_id) 38 | movie_pipeline = movie.pipeline.Pipeline(datastore_client, storage_client) 39 | fnames = movie_pipeline.scan() 40 | movie_pipeline.download(fnames) 41 | print "Rendering %d frames" % len(fnames) 42 | files_in_movie = movie_pipeline.assemble(fnames) 43 | print files_in_movie 44 | movie_pipeline.upload(files_in_movie) 45 | 46 | if __name__ == '__main__': 47 | main() 48 | -------------------------------------------------------------------------------- /upload/templates/test_pod.yaml.tmpl: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2016 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 | apiVersion: v1 17 | kind: Pod 18 | metadata: 19 | name: upload 20 | labels: 21 | app: upload 22 | spec: 23 | containers: 24 | 25 | - name: upload-server 26 | image: {{GCR_PREFIX}}/upload-server 27 | ports: 28 | - containerPort: 8080 29 | livenessProbe: 30 | exec: 31 | command: 32 | - cat 33 | - /health/liveness_status 34 | readinessProbe: 35 | exec: 36 | command: 37 | - bash 38 | - /health/readiness_probe 39 | volumeMounts: 40 | - name: upload-volume 41 | mountPath: /pending-uploads 42 | resources: 43 | limits: 44 | memory: {{UPLOAD_SERVER_TOTAL_MAX_USAGE_MB}}M 45 | requests: 46 | memory: {{UPLOAD_SERVER_TOTAL_MAX_USAGE_MB}}M 47 | 48 | # Don't include upload-daemon, this allows for simpler testing 49 | 50 | - name: upload-system-tests 51 | image: {{GCR_PREFIX}}/upload-system-tests 52 | 53 | volumes: 54 | 55 | - name: upload-volume 56 | emptyDir: 57 | medium: "" 58 | -------------------------------------------------------------------------------- /src/solar_eclipse_analysis/find_circles.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2017 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 | import traceback 17 | import pickle 18 | import os 19 | import numpy as np 20 | import string 21 | import argparse 22 | import cv2 23 | from multiprocessing import Pool 24 | from rawkit.raw import Raw 25 | 26 | ignore = [ '7569b99296da7ea2328065cbacb12c39fd65cbf4ba897ab078c573d998c4c470' ] 27 | 28 | def findCircles(fname, image, circles_directory): 29 | f = os.path.join(circles_directory, os.path.basename(fname) + ".pkl") 30 | if os.path.exists(f): 31 | circles = pickle.load(open(f, "rb")) 32 | return circles 33 | image_cols, image_rows, _ = image.shape 34 | 35 | gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) 36 | blurred = cv2.bilateralFilter(gray, 9, 75, 75) 37 | gray = cv2.addWeighted(gray, 1.5, blurred, -0.5, 0) 38 | gray = cv2.bilateralFilter(gray, 9, 75, 75) 39 | 40 | # # detect circles in the image 41 | dp = 1 42 | c1 = 100 43 | c2 = 15 44 | print "start hough", fname 45 | circles = cv2.HoughCircles(gray, cv2.cv.CV_HOUGH_GRADIENT, dp, image_cols / 8, param1=c1, param2=c2) 46 | print "finish hough", fname 47 | pickle.dump(circles, open(f, "wb")) 48 | if circles is None or not len(circles): 49 | return None 50 | return circles 51 | -------------------------------------------------------------------------------- /src/export_eclipse_dataset/extract_metadata_from_datastore.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2017 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 | """Extract all metadata from datastore and cache in local pickle files.""" 17 | 18 | import os 19 | import pickle 20 | import datetime 21 | from google.cloud import datastore 22 | import argparse 23 | import pytz 24 | import metadata 25 | 26 | DEFAULT_PROJECT = 'eclipse-2017-test' 27 | 28 | def get_arguments(): 29 | parser = argparse.ArgumentParser(description='Extract metadata.') 30 | parser.add_argument('--project_id', type=str, default=DEFAULT_PROJECT) 31 | parser.add_argument('--photo_metadata', type=str, default="photo_metadata.pkl") 32 | parser.add_argument('--user_metadata', type=str, default="user_metadata.pkl") 33 | parser.add_argument('--directory', type=str, default="photos") 34 | return parser.parse_args() 35 | 36 | def main(): 37 | args = get_arguments() 38 | client = datastore.Client(project=args.project_id) 39 | 40 | query = client.query(kind='Photo') 41 | entities = list(query.fetch()) 42 | pickle.dump(entities, open(args.photo_metadata, "wb")) 43 | 44 | query = client.query(kind='User') 45 | entities = list(query.fetch()) 46 | pickle.dump(entities, open(args.user_metadata, "wb")) 47 | 48 | if __name__ == '__main__': 49 | main() 50 | -------------------------------------------------------------------------------- /src/eclipse_gis/test/test_eclipse_gis.py: -------------------------------------------------------------------------------- 1 | # Copyright 2017 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 | """Tests for eclipse_gis.""" 16 | import sys 17 | sys.path.append("../src") 18 | from eclipse_gis import eclipse_gis 19 | import unittest2 20 | from shapely.geometry import Point, Polygon, LineString 21 | 22 | test_boundary = Polygon( ((-1,-1), (-1, 1), (1, 1), (1, -1)) ) 23 | test_center = LineString( ((-1, 0), (1, 0)) ) 24 | 25 | class EclipseGisTest(unittest2.TestCase): 26 | def setUp(self): 27 | self.eg = eclipse_gis.EclipseGIS(test_boundary, test_center) 28 | 29 | def tearDown(self): 30 | self.eg = None 31 | 32 | def testPointIsInPolygon(self): 33 | point = Point((0, 0)) 34 | self.assertTrue(self.eg.test_point_within_eclipse_boundary(point)) 35 | 36 | def testPointIsNotInPolygon(self): 37 | point = Point((42, 42)) 38 | self.assertFalse(self.eg.test_point_within_eclipse_boundary(point)) 39 | 40 | def testNearestPointInPolygon(self): 41 | point = Point((-0.5, 0.75)) 42 | np = self.eg.find_nearest_point_on_line(point) 43 | self.assertEqual(np, Point(-0.5, 0)) 44 | 45 | def testRandomPointIsInPolygon(self): 46 | rp = self.eg.get_random_point_in_polygon() 47 | self.assertTrue(self.eg.test_point_within_eclipse_boundary(rp)) 48 | 49 | if __name__ == '__main__': 50 | unittest2.main() 51 | -------------------------------------------------------------------------------- /common/users.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2016 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 | import hashlib 17 | from common import util 18 | from common import test_common 19 | from google.cloud import datastore 20 | 21 | from common.eclipse2017_exceptions import MissingCredentialTokenError, MissingUserError 22 | def get_id_token(headers): 23 | if 'X-IDTOKEN' not in headers: 24 | raise MissingCredentialTokenError 25 | return headers['X-IDTOKEN'] 26 | 27 | def get_userid(idinfo): 28 | if 'sub' not in idinfo: 29 | raise MissingUserError 30 | return idinfo["sub"] 31 | 32 | def get_userid_hash(userid): 33 | return unicode(hashlib.sha256(userid).hexdigest()) 34 | 35 | def get_empty_user_entity(client, user_id): 36 | key = client.key("User", user_id) 37 | entity = datastore.Entity(key=key) 38 | return entity 39 | 40 | def get_user(client, user_id): 41 | """Returns user entity.""" 42 | key = client.key("User", user_id) 43 | entity = client.get(key) 44 | return entity 45 | 46 | def check_if_user_exists(client, user_id): 47 | """Returns True if User with user_id already exists.""" 48 | return get_user(client, user_id) is not None 49 | 50 | def create_or_update_user(client, entity): 51 | client.put(entity) 52 | 53 | def delete_user(client, user_id): 54 | key = client.key("User", user_id) 55 | client.delete(key) 56 | -------------------------------------------------------------------------------- /system-test-container/templates/upload_stress_test_pod.yaml.tmpl: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2016 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 | apiVersion: v1 17 | kind: Pod 18 | metadata: 19 | name: upload-stress-test-container 20 | labels: 21 | app: upload-stress-test-container 22 | spec: 23 | containers: 24 | - name: upload-server 25 | image: {{GCR_PREFIX}}/upload-server 26 | ports: 27 | - containerPort: 8080 28 | livenessProbe: 29 | exec: 30 | command: 31 | - cat 32 | - /health/liveness_status 33 | readinessProbe: 34 | exec: 35 | command: 36 | - bash 37 | - /health/readiness_probe 38 | volumeMounts: 39 | - name: upload-volume 40 | mountPath: /pending-uploads 41 | resources: 42 | limits: 43 | memory: {{UPLOAD_SERVER_TOTAL_MAX_USAGE_MB}}M 44 | requests: 45 | memory: {{UPLOAD_SERVER_TOTAL_MAX_USAGE_MB}}M 46 | 47 | # Don't include upload-daemon, this allows for simpler testing 48 | 49 | - name: upload-stress-test-container 50 | image: {{GCR_PREFIX}}/upload-stress-test-container 51 | 52 | volumes: 53 | 54 | - name: upload-volume 55 | emptyDir: 56 | medium: "" 57 | -------------------------------------------------------------------------------- /upload/server/app/main.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2016 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 | import logging 17 | import os 18 | 19 | import flask 20 | from werkzeug import wsgi 21 | 22 | from common import config, constants 23 | from common import datastore_schema as ds 24 | from common import secret_keys as sk 25 | 26 | from backend.upload_server import UploadServer 27 | 28 | 29 | service_account_path = os.path.abspath('./common/service_account.json') 30 | os.environ['GOOGLE_APPLICATION_CREDENTIALS'] = service_account_path 31 | 32 | logging.basicConfig(level=logging.INFO, 33 | format=constants.LOG_FMT_M_THREADED) 34 | 35 | upload_server = UploadServer( 36 | config.PROJECT_ID, 37 | sk.FLASK_SESSION_ENC_KEY, 38 | sk.GOOGLE_OAUTH2_CLIENT_ID, 39 | sk.GOOGLE_OAUTH2_CLIENT_SECRET, 40 | file_not_ready_suffix=constants.FILE_NOT_READY_SUFFIX, 41 | directory=constants.UPLOAD_DIR, 42 | datastore_kind=ds.DATASTORE_PHOTO, 43 | user_datastore_kind=ds.DATASTORE_USER, 44 | retrys=constants.RETRYS) 45 | 46 | # Set up the app so that all it's routes live under the /upload url prefix 47 | # A dummy no-op flask app is used for all other routes, so they will result in 48 | # a 404 not found error. 49 | app = wsgi.DispatcherMiddleware(flask.Flask('nop'), 50 | {constants.UPLOAD_SERVICE_URL_PREFIX: upload_server}) 51 | -------------------------------------------------------------------------------- /common_tests/image_sorter_test.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2017 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 | import unittest2 17 | import datetime 18 | from google.cloud import datastore 19 | from common import image_sorter 20 | from common import config 21 | import time 22 | 23 | class ImageSorterTest(unittest2.TestCase): 24 | """ 25 | Tests for image_sorter code. 26 | """ 27 | 28 | def test_sort_newest(self): 29 | datastore_client = datastore.Client(config.PROJECT_ID) 30 | key = datastore_client.key('Photo', '1') 31 | entity = datastore.Entity(key=key) 32 | entity["image_datetime"] = datetime.datetime.utcnow() 33 | time.sleep(1) 34 | key = datastore_client.key('Photo', '2') 35 | entity2 = datastore.Entity(key=key) 36 | entity2["image_datetime"] = datetime.datetime.utcnow() 37 | time.sleep(1) 38 | key = datastore_client.key('Photo', '3') 39 | entity3 = datastore.Entity(key=key) 40 | entity3["image_datetime"] = datetime.datetime.utcnow() 41 | 42 | entities = [entity, entity2, entity3] 43 | self.assertEqual(image_sorter.pick_image(entities), entity3) 44 | entities = [entity3, entity2, entity] 45 | self.assertEqual(image_sorter.pick_image(entities), entity3) 46 | entities = [entity2, entity3, entity] 47 | self.assertEqual(image_sorter.pick_image(entities), entity3) 48 | -------------------------------------------------------------------------------- /scripts/get_user_ids.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2017 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 | """Print user ids matching email addresses.""" 17 | 18 | import argparse 19 | from google.cloud import datastore 20 | import common.service_account as sa 21 | 22 | DEFAULT_PROJECT_ID = 'eclipse-2017-test-147301' 23 | DEFAULT_EMAIL_ADDRESS_FILE = 'email_addresses.txt' 24 | 25 | def get_arguments(): 26 | parser = argparse.ArgumentParser(description='Print user ids matching email addresses.') 27 | parser.add_argument('--project_id', type=str, default=DEFAULT_PROJECT_ID) 28 | parser.add_argument('--email_address_file', type=str, default=DEFAULT_EMAIL_ADDRESS_FILE) 29 | return parser.parse_args() 30 | 31 | def main(): 32 | args = get_arguments() 33 | 34 | client = datastore.Client(project=args.project_id) 35 | 36 | addresses = [address.strip() for address in open(args.email_address_file).readlines()] 37 | # Can't find a way to query a collection of records matching different email addresses. 38 | for email in addresses: 39 | query = client.query(kind="User") 40 | query.add_filter('email', '=', email) 41 | entities = query.fetch() 42 | l = list(entities) 43 | if l == []: 44 | print "No match for", email 45 | else: 46 | for entity in l: 47 | print entity.key.name, entity['email'] 48 | 49 | if __name__ == '__main__': 50 | main() 51 | -------------------------------------------------------------------------------- /admin/app/app/backend/eclipse2017_admin_app.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2017 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 | from flask import Flask 17 | 18 | from count import count 19 | from locations import locations 20 | from photo_count import photo_count 21 | from clusters import clusters 22 | from routes import Routes 23 | 24 | 25 | blueprints = ( 26 | (count.create_blueprint(), '/services/admin/users/count'), 27 | (locations.create_blueprint(), '/services/admin/users/locations'), 28 | (clusters.create_blueprint(), '/services/admin/clusters'), 29 | (photo_count.create_blueprint(), '/services/admin/photos/count')) 30 | 31 | base_routes = Routes() 32 | 33 | 34 | class Eclipse2017AdminApp(Flask): 35 | """ 36 | Eclipse 2017 application. 37 | """ 38 | def __init__( 39 | self, project_id, session_enc_key, google_oauth2_client_id, 40 | google_oauth2_client_secret, debug=False, 41 | blueprints=blueprints, routes=base_routes, count=count, 42 | **kwargs): 43 | super(Eclipse2017AdminApp, self).__init__(__name__, **kwargs) 44 | 45 | self.config['PROJECT_ID'] = project_id 46 | self.config['SECRET_KEY'] = session_enc_key 47 | self.config['GOOGLE_OAUTH2_CLIENT_ID'] = google_oauth2_client_id 48 | self.config['GOOGLE_OAUTH2_CLIENT_SECRET'] = google_oauth2_client_secret 49 | 50 | 51 | self.count = count 52 | 53 | self.debug = debug 54 | routes.register(self, blueprints) 55 | -------------------------------------------------------------------------------- /scripts/final_numbers_report.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2017 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 | import os 17 | import pickle 18 | import datetime 19 | from google.cloud import datastore 20 | from google.cloud import storage 21 | import argparse 22 | import pytz 23 | 24 | DEFAULT_PROJECT = 'eclipse-2017-prod' 25 | 26 | def get_arguments(): 27 | parser = argparse.ArgumentParser(description='Map image data.') 28 | parser.add_argument('--project_id', type=str, default=DEFAULT_PROJECT) 29 | parser.add_argument('--photo_table', type=str, default="Photo") 30 | parser.add_argument('--image_bucket', type=str, default="megamovie") 31 | return parser.parse_args() 32 | 33 | 34 | def main(): 35 | args = get_arguments() 36 | datastore_client = datastore.Client(project=args.project_id) 37 | 38 | query = datastore_client.query(kind=args.photo_table) 39 | query.add_filter("image_bucket","=", args.image_bucket) 40 | entities = list(query.fetch()) 41 | images = set() 42 | for entity in entities: 43 | images.add(entity.key.name) 44 | 45 | # Instantiates a client 46 | storage_client = storage.Client() 47 | 48 | # The name for the new bucket 49 | bucket_name = args.project_id + "-photos" 50 | bucket = storage_client.get_bucket(bucket_name) 51 | blobs = bucket.list_blobs() 52 | blob_sizes = [] 53 | for blob in blobs: 54 | if blob.name in images: 55 | blob_sizes.append(blob.size) 56 | 57 | print len(images), sum(blob_sizes) 58 | 59 | 60 | if __name__ == '__main__': 61 | main() 62 | -------------------------------------------------------------------------------- /common/cluster_points.py: -------------------------------------------------------------------------------- 1 | from sklearn.cluster import DBSCAN 2 | from common import constants 3 | import numpy as np 4 | 5 | def cluster_points(coordinates, eps, min_samples, n_jobs=1): 6 | """Given coordinates, function returns the number of clusters in the 7 | set of coordinates and a list of integer labels corresponding to 8 | the input coordinate list 9 | 10 | Arguments: 11 | coordinates: a sequence of (lat, lon) tuples 12 | eps: the cluster size in radial degrees 13 | min_samples: the size of the smallest cluster 14 | n_jobs: number of CPUs to use to compute the clusters 15 | Returns: 16 | n_clusters: number of clusters 17 | labels: the labels of the clusters 18 | """ 19 | 20 | db = DBSCAN(eps=eps, 21 | min_samples=min_samples, 22 | n_jobs=n_jobs).fit(coordinates) 23 | 24 | 25 | return db 26 | 27 | def count_clusters(db): 28 | labels = db.labels_ 29 | n_clusters = len(set(labels)) - (1 if -1 in labels else 0) 30 | return (n_clusters, labels) 31 | 32 | def compute_centers(clusters, locations, suppress_negative=True): 33 | """Compute centroids of clusters. 34 | 35 | Arguments: 36 | clusters: sklearn cluster object with labels_ attribute 37 | locations: the x,y coordinates of the items 38 | suppress_negative: if True, will suppress any cluster label which is -1. -1 means "not assigned to a cluster". 39 | 40 | Returns: 41 | centers: dictionary of label -> centroids 42 | sizes: dictionary of label -> the sizes of the centroid (number of members) 43 | """ 44 | 45 | points = {} 46 | print clusters 47 | for i, label in enumerate(clusters.labels_): 48 | if suppress_negative and label == -1: 49 | continue 50 | if label not in points: 51 | points[label] = [] 52 | points[label].append( (locations[i][0], locations[i][1])) 53 | 54 | centers = {} 55 | sizes = {} 56 | for label in points: 57 | centers[label] = np.mean(points[label], axis=0) 58 | sizes[label] = len(points[label]) 59 | 60 | return centers, sizes 61 | -------------------------------------------------------------------------------- /common/exif.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2017 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 | import exifread 17 | from common.gps import exifread_tags_to_latlon, hms_to_deg, exifread_tags_to_gps_datetime, exifread_tags_to_camera_datetime 18 | def _extract_exif_metadata(fpath): 19 | """ 20 | Extracts EXIF metadata corresponding to image with fpath 21 | Returns metadata_dictionary 22 | """ 23 | 24 | metadata = {} 25 | # convert to exifread support 26 | f = open(fpath, 'rb') 27 | try: 28 | tags = exifread.process_file(f) 29 | except Exception as e: 30 | print "exifread failed to process file:", fpath, e 31 | lat, lon, image_datetime = None, None, None 32 | else: 33 | lat, lon = exifread_tags_to_latlon(tags) 34 | image_datetime = exifread_tags_to_gps_datetime(tags) 35 | camera_datetime = exifread_tags_to_camera_datetime(tags) 36 | if image_datetime: 37 | metadata['image_datetime'] = image_datetime 38 | if camera_datetime: 39 | metadata['camera_datetime'] = camera_datetime 40 | if lat: 41 | metadata['lat'] = lat 42 | if lon: 43 | metadata['lon'] = lon 44 | return metadata 45 | 46 | def _extract_image_metadata(filename, format_, width, height, bucket): 47 | """ 48 | Extracts image format-specific metadata corresponding to image with fpath 49 | Returns metadata_dictionary 50 | """ 51 | metadata = {} 52 | metadata['image_type'] = unicode(format_) 53 | metadata['width'] = width 54 | metadata['height'] = height 55 | return metadata 56 | -------------------------------------------------------------------------------- /common/map_util.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2017 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 | from shapely.geometry import LineString 17 | from eclipse_gis import eclipse_gis 18 | from BeautifulSoup import BeautifulSoup 19 | import shapefile 20 | from shapely.geometry import shape 21 | 22 | def parse_html(eclipse_path_html): 23 | doc = BeautifulSoup(eclipse_path_html, convertEntities=BeautifulSoup.HTML_ENTITIES) 24 | data = doc.body.find('pre').text.replace("\r", "\n").split("\n") 25 | times, points = eclipse_gis.load_data(data) 26 | return times, points 27 | 28 | def load_map(map_path): 29 | sh = shapefile.Reader(map_path) 30 | feature = sh.shapeRecords()[0] 31 | first = feature.shape.__geo_interface__ 32 | shp_geom = shape(first) 33 | return shp_geom 34 | 35 | def points_to_latlong(points, color='r'): 36 | lats = [] 37 | lons = [] 38 | colors = [] 39 | for point in points: 40 | lat = point[0] 41 | lon = point[1] 42 | colors.append(color) 43 | lats.append(lat) 44 | lons.append(lon) 45 | return lats, lons, colors 46 | 47 | def us_shape_to_points(main_us): 48 | points = [] 49 | for line in main_us.geoms: 50 | for point in line.coords: 51 | points.append((point[1], point[0])) 52 | return points 53 | 54 | def load_path(eclipse_path_data): 55 | times, points = eclipse_gis.load_stripped_data(open(eclipse_path_data).readlines()) 56 | boundary, center = eclipse_gis.generate_polygon(points) 57 | eg = eclipse_gis.EclipseGIS(boundary, center) 58 | return eg 59 | -------------------------------------------------------------------------------- /src/solar_eclipse_analysis/map_util.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2017 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 | from shapely.geometry import LineString 17 | from eclipse_gis import eclipse_gis 18 | from BeautifulSoup import BeautifulSoup 19 | import shapefile 20 | from shapely.geometry import shape 21 | 22 | def parse_html(eclipse_path_html): 23 | doc = BeautifulSoup(eclipse_path_html, convertEntities=BeautifulSoup.HTML_ENTITIES) 24 | data = doc.body.find('pre').text.replace("\r", "\n").split("\n") 25 | times, points = eclipse_gis.load_data(data) 26 | return times, points 27 | 28 | def load_map(map_path): 29 | sh = shapefile.Reader(map_path) 30 | feature = sh.shapeRecords()[0] 31 | first = feature.shape.__geo_interface__ 32 | shp_geom = shape(first) 33 | return shp_geom 34 | 35 | def points_to_latlong(points, color='r'): 36 | lats = [] 37 | lons = [] 38 | colors = [] 39 | for point in points: 40 | lat = point[0] 41 | lon = point[1] 42 | colors.append(color) 43 | lats.append(lat) 44 | lons.append(lon) 45 | return lats, lons, colors 46 | 47 | def us_shape_to_points(main_us): 48 | points = [] 49 | for line in main_us.geoms: 50 | for point in line.coords: 51 | points.append((point[1], point[0])) 52 | return points 53 | 54 | def load_path(eclipse_path_data): 55 | times, points = eclipse_gis.load_stripped_data(open(eclipse_path_data).readlines()) 56 | boundary, center = eclipse_gis.generate_polygon(points) 57 | eg = eclipse_gis.EclipseGIS(boundary, center) 58 | return eg 59 | -------------------------------------------------------------------------------- /admin/app/app/backend/routes.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2017 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 | import flask 17 | 18 | class Routes(object): 19 | """ 20 | Class with base route definitions, responsible for registration of base 21 | routes and additional module blueprints. 22 | """ 23 | def __init__(self, redirect=flask.redirect, 24 | render_template=flask.render_template, request=flask.request, 25 | Response=flask.Response, session=flask.session, 26 | url_for=flask.url_for): 27 | # Dependency injection 28 | self.redirect = redirect 29 | self.render_template = render_template 30 | self.request = request 31 | self.Response = Response 32 | self.session = session 33 | self.url_for = url_for 34 | 35 | # Define routes within this class, all routes from this class have 36 | # no prefix 37 | self._routes = ( 38 | ('/', 'index', self.health_check), 39 | ('/healthz', 'heathz', self.health_check)) 40 | 41 | # TODO make this useful 42 | def health_check(self): 43 | """ 44 | Health check for GKE. 45 | """ 46 | return self.Response('OK', status=200) 47 | 48 | def register(self, app, blueprints): 49 | """ 50 | Define standard routes and register module blueprints. 51 | """ 52 | 53 | for path, name, method in self._routes: 54 | app.add_url_rule(path, name, method) 55 | 56 | for bp, url_prefix in blueprints: 57 | app.register_blueprint(bp, url_prefix=url_prefix) 58 | -------------------------------------------------------------------------------- /geo/app/app/backend/routes.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2017 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 | import flask 17 | 18 | class Routes(object): 19 | """ 20 | Class with base route definitions, responsible for registration of base 21 | routes and additional module blueprints. 22 | """ 23 | def __init__(self, redirect=flask.redirect, 24 | render_template=flask.render_template, request=flask.request, 25 | Response=flask.Response, session=flask.session, 26 | url_for=flask.url_for): 27 | # Dependency injection 28 | self.redirect = redirect 29 | self.render_template = render_template 30 | self.request = request 31 | self.Response = Response 32 | self.session = session 33 | self.url_for = url_for 34 | 35 | # Define routes within this class, all routes from this class have 36 | # no prefix 37 | self._routes = ( 38 | ('/', 'index', self.health_check), 39 | ('/healthz', 'heathz', self.health_check)) 40 | 41 | # TODO make this useful 42 | def health_check(self): 43 | """ 44 | Health check for GKE. 45 | """ 46 | return self.Response('OK', status=200) 47 | 48 | def register(self, app, blueprints): 49 | """ 50 | Define standard routes and register module blueprints. 51 | """ 52 | 53 | for path, name, method in self._routes: 54 | app.add_url_rule(path, name, method) 55 | 56 | for bp, url_prefix in blueprints: 57 | app.register_blueprint(bp, url_prefix=url_prefix) 58 | -------------------------------------------------------------------------------- /photo/app/app/backend/routes.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2017 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 | import flask 17 | 18 | class Routes(object): 19 | """ 20 | Class with base route definitions, responsible for registration of base 21 | routes and additional module blueprints. 22 | """ 23 | def __init__(self, redirect=flask.redirect, 24 | render_template=flask.render_template, request=flask.request, 25 | Response=flask.Response, session=flask.session, 26 | url_for=flask.url_for): 27 | # Dependency injection 28 | self.redirect = redirect 29 | self.render_template = render_template 30 | self.request = request 31 | self.Response = Response 32 | self.session = session 33 | self.url_for = url_for 34 | 35 | # Define routes within this class, all routes from this class have 36 | # no prefix 37 | self._routes = ( 38 | ('/', 'index', self.health_check), 39 | ('/healthz', 'heathz', self.health_check)) 40 | 41 | # TODO make this useful 42 | def health_check(self): 43 | """ 44 | Health check for GKE. 45 | """ 46 | return self.Response('OK', status=200) 47 | 48 | def register(self, app, blueprints): 49 | """ 50 | Define standard routes and register module blueprints. 51 | """ 52 | 53 | for path, name, method in self._routes: 54 | app.add_url_rule(path, name, method) 55 | 56 | for bp, url_prefix in blueprints: 57 | app.register_blueprint(bp, url_prefix=url_prefix) 58 | -------------------------------------------------------------------------------- /profile/app/app/backend/routes.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2016 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 | import flask 17 | 18 | class Routes(object): 19 | """ 20 | Class with base route definitions, responsible for registration of base 21 | routes and additional module blueprints. 22 | """ 23 | def __init__(self, redirect=flask.redirect, 24 | render_template=flask.render_template, request=flask.request, 25 | Response=flask.Response, session=flask.session, 26 | url_for=flask.url_for): 27 | # Dependency injection 28 | self.redirect = redirect 29 | self.render_template = render_template 30 | self.request = request 31 | self.Response = Response 32 | self.session = session 33 | self.url_for = url_for 34 | 35 | # Define routes within this class, all routes from this class have 36 | # no prefix 37 | self._routes = ( 38 | ('/', 'index', self.health_check), 39 | ('/healthz', 'heathz', self.health_check)) 40 | 41 | # TODO make this useful 42 | def health_check(self): 43 | """ 44 | Health check for GKE. 45 | """ 46 | return self.Response('OK', status=200) 47 | 48 | def register(self, app, blueprints): 49 | """ 50 | Define standard routes and register module blueprints. 51 | """ 52 | 53 | for path, name, method in self._routes: 54 | app.add_url_rule(path, name, method) 55 | 56 | for bp, url_prefix in blueprints: 57 | app.register_blueprint(bp, url_prefix=url_prefix) 58 | -------------------------------------------------------------------------------- /src/solar_eclipse_renderer/convert_location.py: -------------------------------------------------------------------------------- 1 | # Copyright 2017 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 ephem 16 | import math 17 | deg = math.degrees 18 | from coords import horizontal_to_cartesian 19 | from lune import get_lune 20 | 21 | def convert_location(lat, lon, start_datetime, end_datetime, inclusion_threshold, dt = 1): 22 | """Convert a lat, lon and start to end datetime to a series of sun and moon positions. 23 | 24 | The resulting positions are filtered by inclusion_threshold, which 25 | is compared to the seperation angle. The datetime clock is 26 | incremented by dt seconds by iteration.""" 27 | 28 | obs = ephem.Observer() 29 | obs.lat = math.radians(lat) 30 | obs.lon = math.radians(lon) 31 | 32 | sun = ephem.Sun() 33 | moon = ephem.Moon() 34 | 35 | d = ephem.Date(start_datetime) 36 | pos = [] 37 | 38 | while d < ephem.Date(end_datetime): 39 | obs.date = d 40 | sun.compute(obs) 41 | moon.compute(obs) 42 | l = get_lune(sun, moon) 43 | 44 | if l > inclusion_threshold: 45 | # print(str(d), "Sun: %.3f %.3f" % (deg(sun.alt), deg(sun.az)), "Moon: %.3f %.3f" % (deg(moon.alt), deg(moon.az)), "%.4f" % s, parallactic_angle, ph) 46 | r_sun=sun.size/2 47 | r_moon=moon.size/2 48 | parallactic_angle = sun.parallactic_angle() 49 | pos.append( (str(d), float(sun.alt), float(sun.az), float(moon.alt), float(moon.az), r_sun, r_moon, l, parallactic_angle, lat, lon)) 50 | 51 | d = ephem.Date(d + (dt*ephem.second)) 52 | return pos 53 | -------------------------------------------------------------------------------- /nginx-lb-emulator/templates/nginx.conf.tmpl: -------------------------------------------------------------------------------- 1 | daemon off; 2 | user www-data; 3 | worker_processes auto; 4 | pid /run/nginx.pid; 5 | 6 | events { 7 | use epoll; 8 | worker_connections 4096; ## Default: 1024 9 | multi_accept on; 10 | } 11 | 12 | http { 13 | 14 | proxy_buffer_size 128k; 15 | proxy_buffers 4 256k; 16 | proxy_busy_buffers_size 256k; 17 | 18 | ## 19 | # Logging Settings 20 | ## 21 | log_format main '$http_x_forwarded_for - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent"'; 22 | access_log /dev/stdout main; 23 | error_log stderr; 24 | 25 | server { 26 | listen *:80; 27 | 28 | listen 443 ssl; 29 | ssl_certificate /etc/nginx/lb-emulator.crt; 30 | ssl_certificate_key /etc/nginx/lb-emulator.key; 31 | 32 | location / { 33 | proxy_set_header Host $host; 34 | proxy_set_header X-Real-IP $remote_addr; 35 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 36 | proxy_set_header X-Forwarded-Proto $scheme; 37 | proxy_pass http://static-nginx:80/; 38 | proxy_read_timeout 90s; 39 | proxy_redirect off; 40 | 41 | client_max_body_size 1m; 42 | } 43 | location /services/geo/ { 44 | proxy_set_header Host $host; 45 | proxy_set_header X-Real-IP $remote_addr; 46 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 47 | proxy_set_header X-Forwarded-Proto $scheme; 48 | proxy_pass http://geo-nginx:80/services/geo/; 49 | proxy_read_timeout 90s; 50 | proxy_redirect off; 51 | 52 | client_max_body_size 100m; 53 | 54 | include 'cors.conf'; 55 | } 56 | } 57 | } 58 | --------------------------------------------------------------------------------