Skip to content

Commit

Permalink
integrate instructions about github and AWS hosting for gigapixel to FAQ
Browse files Browse the repository at this point in the history
  • Loading branch information
JoeGermuska committed Dec 21, 2017
2 parents 692db94 + 66a1da4 commit 8136e48
Show file tree
Hide file tree
Showing 129 changed files with 7,026 additions and 2,988 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Expand Up @@ -15,3 +15,6 @@ s3analysis/mirror
s3analysis/*csv

env.sh
local_only.key
local_only.crt

Binary file added AWS_Hosting/1.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added AWS_Hosting/2.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added AWS_Hosting/3.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added AWS_Hosting/4.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added AWS_Hosting/5.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added AWS_Hosting/6.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added AWS_Hosting/7.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
23 changes: 23 additions & 0 deletions AWS_Hosting/AWS_Hosting.md
@@ -0,0 +1,23 @@
# Hosting your Gigapixel through Amazon Web Services

Before you can begin this process, you wil need to have generated Zoomify images. You can learn more about how to make one [here](/gigapixel/).

Note: While Amazon supports free web hosting through its Free Tier option, after a year, you will have to pay to use their hosting services. It's relatively cheap (~$.03 / month for 1 GB, using their [pricing calculator](https://calculator.s3.amazonaws.com/index.html), but if you want an entirely free option, you can check out our GitHub hosting tutorial [here](https://github.com/NUKnightLab/StoryMapJS/blob/master/GITHUB_HOSTING/GITHUB_HOSTING.md).

1. Sign up to create an account on [Amazon Web Services](https://aws.amazon.com/). If prompted, choose the 'Basic' account setting.
![](1.png)
2. Once your account has been created, choose the 'Host a Static Website' option on your dashboard. You can also click [here](https://console.aws.amazon.com/quickstart-website/new) to go to the same place.
![](2.png)
3. On your computer, navigate to the folder where you've stored your Gigapixel tiles. Inside the directory, create an empty file called 'index.html.'
![](3.png)
4. Compress your Gigapixel image folder. On Macs, you can right-click and select the 'compress' option. On PCs, you should right-click and then select send > to compressed file.
![](4.png)
5. Now, go back to the quickstart web hosting page, and upload your compressed folder.
![](5.png)
6. Amazon will spend ~15 minutes to publish your Gigapixel to their servers, but once Amazon is done, they will provide you a link to your hosted webpage. The location of the link is highlighted in the red box below.
![](6.png)

You're done! Use the [Storymap authoring tool](/select/) to create your Gigapixel and include the link to your Amazon webpage. If you need more information on best practices after creating your Gigapixel, you can read our documentation [here](https://github.com/NUKnightLab/StoryMapJS/blob/master/BEST_PRACTICES/BEST_PRACTICES.md).

![](7.png)
/
Binary file added BEST_PRACTICES/1.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added BEST_PRACTICES/2.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added BEST_PRACTICES/3.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added BEST_PRACTICES/4.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added BEST_PRACTICES/5.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
46 changes: 46 additions & 0 deletions BEST_PRACTICES/BEST_PRACTICES.md
@@ -0,0 +1,46 @@
#Storymap Gigapixel Best Practices#


After you’ve created a Gigapixel image through the process described [here](https://storymap.knightlab.com/gigapixel/), there are two options for displaying your Gigapixel in the Options Panel: ‘Image’ and ‘Cartography.’ While most of the features are the same in each mode, there are a few quirks of each mode that you might want to be aware of when creating your StoryMap.

![Options Panel](1.png)

##Best Practices for Image Mode:##


In Image Mode, StoryMap markers are displayed only on hover, and path lines between markers are removed. Since these lines are removed, you should use this option if there is no spatial relationship between consecutive slides.


For the overview image, your Gigapixel will be resized to fit only the left hand pane of your StoryMap. If you’re using an image that has a dimension that’s more than 5x the size of the other dimension, the image may be difficult to see. Thus, when choosing images for your Gigapixel, you should try to use images that have a width:length ratio of 3:1 or less. You may also want to avoid images that have excess margin, if you want to maximize the size of your image in the overview panel.


![Proper Size](2.png) versus ![Improper Size](3.png)


If you want the image to fill the entire panel, you should choose an image that is sized in portrait view (2:3 or 1:2), rather than landscape. If none of these options work for you, you can use Cartography Mode instead.


##Best Practices for Cartography Mode:##


In Cartography Mode, StoryMap markers will always be displayed, and path lines between consecutive markers will be displayed. You should use this mode if you want to emphasize the spatial relationship between events, or if you want to customize sizing without the constraints of Image Mode.


For the Cartography overview image, your Gigapixel will be resized so that all of your markers will be displayed in the left hand pane, making it possible for your image to fill the entire screen.


If you want to have your map fill the entire screen in the overview, the best way to do this is to have your markers concentrated on a single area of your map. For example, in the Arya’s Journey Gigapixel, the map markers were concentrated in the left-hand side of the map, allowing the right-hand side to fill up the rest of the screen.

![Cartography Sizing](4.png)



If you’re having trouble aligning your map, you can also tweak the maximum width and length of your map in the ‘Options Panel,’ which will adjust the display sizing.


![Max Width/Height Adjustment](5.png)


If your StoryMap is not displaying as described above, or if you have any other questions/bugs regarding Gigapixel displays, reach out to us at Zendesk!


9 changes: 9 additions & 0 deletions CHANGELOG
@@ -1,3 +1,12 @@
0.6.6 (2017-09-08)
* PR #377 Adds Turkish translation

0.6.4 (207-04-06)
* PR #357 Fixes #351 YouTube link obscured by nav button

0.6.2 (2016-12-13)
* PR #333 Adds zoomify analytics

0.6.1 (2016-10-14)
------------------------
* PR #302 Media fixes including pause of video types when navigating away from slide
Expand Down
2 changes: 1 addition & 1 deletion GITHUB_HOSTING/GITHUB_HOSTING.md
@@ -1,6 +1,6 @@
# Hosting your Gigapixel through Github

Before you can being this process, you wil need to have generated Zoomify images. You can learn more about how to make one [here](https://storymap.knightlab.com/gigapixel/).
Before you can being this process, you will need to have generated Zoomify images. You can learn more about how to make one [here](https://storymap.knightlab.com/gigapixel/).

1. Sign up to create an account on Github. A free account is fine. If you already have an account, you can proceed to the next step.
<br><br>
Expand Down
51 changes: 50 additions & 1 deletion README.md
Expand Up @@ -6,6 +6,29 @@ If you want information on creating JSON with your own code and embedding it, se

The rest of this document gets into a few technical details that some folks might want.

## TL;DR

Follow this quickstart guide to get StoryMapJS set up locally or see below for a more in-depth process explanation.

* Clone the StoryMapJS repository to your machine.
* Clone the [fabfile](https://github.com/NUKnightLab/fablib) repository into the same *parent* folder that stores the StoryMap repo.
* Install [virtualenv](https://pypi.python.org/pypi/virtualenv), [virtualenvwrapper](http://virtualenvwrapper.readthedocs.org/), and [MongoDB](https://www.mongodb.org/).
* To run the server, copy `env.sh.sample` to `env.sh` and, if necessary, modify any values in it. Execute this script with `source env.sh` when you are working on StoryMapJS. If you're unsure whether you need to run the server for your project, see below this quickstart for more information.
* Set up your virtual environment:
`mkvirtualenv storymapjs`
* Activate the virtual environemnt:
`workon storymapjs`
* Install python requirements:
`pip install -r requirements.txt`
* `fab build` the project
* Start making changes!
* To see your changes, run a simple local web server (we like [http-server](https://www.npmjs.com/package/http-server)) and load the following url (assuming your local server runs on port 8080):
`http://0.0.0.0:8080/embed/index.html?url=http://media.knightlab.com/StoryMapJS/demo/sochi.json`

#### Setup for working on the StoryMap editor

There are a number of environment variables critical to working on the edior that are only available to Knight Lab staff and students. Ask a staff member for this information if applicable.

## Contributing translations for new languages

StoryMap's older sibling, [TimelineJS](http://timeline.knightlab.com) has proven internationally popular, in part because users have contributed translation support for dozens of languages. StoryMap is also ready to be used in languages other than English, but once again, we'll need your help.
Expand Down Expand Up @@ -46,7 +69,7 @@ In order to stay consistent with other kinds of deployment tools, we use python

If you don't use CodeKit, you must have Python installed. We use python 2.7.

Clone our [fabfile](https://github.com/NUKnightLab/fablib) repository and place it in the same parent directory as your StoryMapJS respository.
Clone our [fabfile](https://github.com/NUKnightLab/fablib) repository and place it in the same parent directory as your StoryMapJS repository.

Install [virtualenv](https://pypi.python.org/pypi/virtualenv), [virtualenvwrapper](http://virtualenvwrapper.readthedocs.org/), and [MongoDB](https://www.mongodb.org/).

Expand Down Expand Up @@ -87,6 +110,18 @@ Files located in the `source` directory are assets for storymapjs itself. The co

At this time, edits to the HTML for the website are automatically visible when reloading the local server. Edits to CSS and JavaScript must be manually compiled before you'll see them. Run `fab build`. This is something we'd like to make more automatic eventually.

**Note:** Recent updates to Google's OAuth policies mean that the above only works for editing the StoryMapJS website/documentation. If you want to work on the authoring tool and test it locally, you will need to set up for local secure development.

First, you must create a certificate pair. These files should NOT be put in the repository. Use this command, executed from the root of the project repository:

openssl req -x509 -sha256 -nodes -days 10000 -newkey rsa:2048 -keyout local_only.key -out local_only.crt

Once you've done this, to run the server, use this instead of the above command:

fab serve:ssl=y

Of course, you'll need to use `https://localhost:5000/select/` to access the authoring tool. You'll get a warning that the security certificate is not trusted. Disable that warning to proceed.

### A note about installing python requirements on Mac OS X 10.11 "El Capitan"
Apparently, Apple removed support for `openssl` in Mac OS X 10.11. Here's the solution we've found.

Expand All @@ -98,3 +133,17 @@ Apparently, Apple removed support for `openssl` in Mac OS X 10.11. Here's the so

Users may be directed to our userinfo page to help with troubleshooting. This page provides information about the user's account and saved storymaps. The endpoint is `https://storymap.knightlab.com/userinfo/`


## Using Atlassian localstack for development/testing

NOTE: boto3 is required for localstack. Until transition to boto3 is complete, development and testing involving s3 connections still requires AWS credentials

Be sure to have the aws cli installed (http://docs.aws.amazon.com/cli/latest/userguide/installing.html)

In your StoryMap virtualenvironment, install localstack and create the test bucket:

* git clone https://github.com/atlassian/localstack.git
* cd localstack
* make clean install test
* make infra
* aws --endpoint-url=http://localhost:4572 s3 mb s3://test.knilab.com
64 changes: 54 additions & 10 deletions api.py
@@ -1,6 +1,7 @@
from __future__ import division
from flask import Flask, request, session, redirect, url_for, \
render_template, jsonify, abort
from werkzeug.exceptions import Forbidden
from collections import defaultdict
import math
import os
Expand Down Expand Up @@ -36,14 +37,17 @@
from storymap import storage, google
from storymap.connection import _user


app = Flask(__name__)
app.config.from_envvar('FLASK_SETTINGS_FILE')

settings = sys.modules[settings_module]
app.config['TEST_MODE'] = settings.TEST_MODE
examples_json = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'examples.json')
faq_json = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'faq.json')

_GOOGLE_OAUTH_SCOPES = [
'https://www.googleapis.com/auth/drive.readonly',
# 'https://www.googleapis.com/auth/drive.readonly', # we may need to restore this if there are legacy accounts unmigrated
'https://www.googleapis.com/auth/userinfo.profile'
];

Expand Down Expand Up @@ -73,6 +77,12 @@ def inject_urls():
STORAGE_URL=storage_url, storage_url=storage_url,
CDN_URL=cdn_url, cdn_url=cdn_url)


@app.context_processor
def inject_index_data():
return dict(examples=json.load(open(examples_json)),faqs=json.load(open(faq_json)))


class APIEncoder(json.JSONEncoder):
def default(self, obj):
"""Format obj as json."""
Expand Down Expand Up @@ -166,14 +176,21 @@ def _session_pop(*keys):
# https://developers.google.com/drive/web/quickstart/quickstart-python
#

def _build_oauth_redirect(request,path):
host = request.host
protocol = request.url.split(':')[0]
url = '{}://{}{}'.format(protocol, host, path)
return url


@app.route("/google/auth/start/", methods=['GET', 'POST'])
def google_auth_start():
"""Initiate google authorization"""
flow = OAuth2WebServerFlow(
settings.GOOGLE_CLIENT_ID,
settings.GOOGLE_CLIENT_SECRET,
_GOOGLE_OAUTH_SCOPES,
redirect_uri='https://'+request.host+url_for('google_auth_verify')
redirect_uri=_build_oauth_redirect(request, url_for('google_auth_verify'))
)
authorize_url = flow.step1_get_authorize_url()
return redirect(authorize_url)
Expand All @@ -192,7 +209,7 @@ def google_auth_verify():
settings.GOOGLE_CLIENT_ID,
settings.GOOGLE_CLIENT_SECRET,
_GOOGLE_OAUTH_SCOPES,
redirect_uri='https://'+request.host+url_for('google_auth_verify')
redirect_uri=_build_oauth_redirect(request, url_for('google_auth_verify'))
)
credentials = flow.step2_exchange(code)
# ^ this is an oauth2client.client.OAuth2Credentials object
Expand All @@ -211,6 +228,10 @@ def google_auth_verify():
if not info['id']:
raise Exception('Could not get Google user ID')

if 'storymap.knilab.com' in domains and not info['id'] in allowed_ids:
print('User id not in ALLOWED_IDS: %s ' % info['id'])
raise Exception('You are not authorized to access this page. Please send the following information to support@knightlab.zendesk.com: storymap.knilab.com unauthorized %s' % info['id'])

# Upsert user record
uid = _get_uid('google:'+info['id'])

Expand Down Expand Up @@ -244,6 +265,9 @@ def _user_get():
"""Enforce authenticated user"""
uid = session.get('uid')
user = _user.find_one({'uid': uid})
# google data field in user record no longer used
if 'google' in user:
del user['google']
if not user and 'uid' in session:
session.pop('uid')
return user
Expand Down Expand Up @@ -690,7 +714,11 @@ def storymap_image_save(user, id):

@app.route("/")
def index():
return render_template('index.html')
if 'storymap.knightlab.com' in domains:
production = True
else:
production = False
return render_template('index.html', production=production)

@app.route("/gigapixel/")
def gigapixel():
Expand Down Expand Up @@ -850,11 +878,18 @@ def qunit():
# SERVE URLS FROM DIRECTORIES
#

from flask import send_from_directory
from flask import send_file, send_from_directory

build_dir = os.path.join(settings.PROJECT_ROOT, 'build')
compiled_dir = os.path.join(settings.PROJECT_ROOT, 'compiled')
templates_dir = os.path.join(settings.PROJECT_ROOT, 'compiled/templates')
domains = os.environ.get('APPLICATION_DOMAINS')
allowed_ids = os.environ.get('ALLOWED_IDS', '').split(',')

@app.route('/robots.txt')
def robots_txt():
if 'storymap.knilab.com' in domains:
return send_file('templates/robots.txt')

@app.route('/build/embed/')
def catch_build_embed():
Expand All @@ -872,7 +907,6 @@ def catch_compiled(path):
def catch_compiled_templates(path):
return send_from_directory(templates_dir, path)


# redirect old documentation URLs
@app.route('/<path:path>')
def redirect_old_urls(path):
Expand All @@ -895,8 +929,18 @@ def redirect_old_urls(path):
opts, args = getopt.getopt(sys.argv[1:], "sp:", ["port="])
for opt, arg in opts:
if opt == '-s':
ssl_context = 'adhoc'
print 'ssl context: %s' % ssl_context
if (os.path.isfile('local_only.crt') and os.path.isfile('local_only.key')):
ssl_context = ('local_only.crt', 'local_only.key')
else:
print '''
To run HTTPS locally you should create a crt/key file.
Don't put them in the repository, because if you tell your browser to trust the certificate
and an adversary got the cert from the public repository, they could take
advantage of you.
Use this command to create the files:
openssl req -x509 -sha256 -nodes -days 10000 -newkey rsa:2048 -keyout local_only.key -out local_only.crt
'''
sys.exit(1)
elif opt in ('-p', '--port'):
port = int(arg)
else:
Expand All @@ -905,5 +949,5 @@ def redirect_old_urls(path):
except getopt.GetoptError:
print 'Usage: app.py [-s] [-p port]'
sys.exit(1)

app.run(host='0.0.0.0', port=port, debug=True, ssl_context=ssl_context)
# Google OAuth requires localhost, not a raw IP address
app.run(host='localhost', port=port, debug=True, ssl_context=ssl_context)
1 change: 1 addition & 0 deletions compiled/css/site.css
@@ -0,0 +1 @@
body{background:#fff;color:#000}
11 changes: 10 additions & 1 deletion compiled/css/storymap.css

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions compiled/fonts/font.abril-droidsans.css

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 8136e48

Please sign in to comment.