A pure client-side photo album publisher for S3.
Try it out here with your own S3 bucket, or view a demo of a published album.
The albums you publish are private: they can only be found if you know the album's URL.
Being a pure web-app means:
Upload view.html
, publish.html
and publish.js
to a path in
your S3 bucket, for example, public-albums/
. This can be done with
s3cmd:
s3cmd put view.html publish.html publish.js s3://bucket/public-albums/
In your browser, navigate to https://s3.region.amazonaws.com/bucket/public-albums/publish.html
,
enter your S3 credentials, and start publishing albums!
For example, https://s3.sa-east-1.amazonaws.com/www.mycooldomain.com.br/public-albums/publish.html
Since you're sending your AWS credentials, use HTTPS.
CloudFront and FQDN doesn't work - you need to make use of the S3 API endpoint all the time.
publish.html
uses the Amazon JavaScript SDK to browse your bucket for
photos you would like to publish in an album. When you create a new
album, a directory in your published albums path is created. For
example, the album with name 'My Holiday Pics' is created in
public-albums/albums/My Holiday Pics/
. When you add a photo to the
album:
public-albums/albums/My Holiday Pics/photos/
; andpublic-albums/albums/My Holiday Pics/thumbs/
.That's all there is to publishing. No databases. No calls to server-side scripts. No adding filenames to index files.
view.html
is used to view published albums. The name of the album is
specified in the hash of the URL, for example,
https://s3.region.amazonaws.com/bucket/public-albums/view.html#My%20Holiday%20Pics
.
The photos for the album are found by listing the contents of
albums/My Holiday Pics/photos/
(relative to the location of
view.html
) and then dynamically added to the page.
If you want anyone on the web to view your published albums, your bucket policy should allow anonymous getObject and listBucket requests. If your bucket doesn't already allow anonymous requests, the mimimum you need to add is:
public-albums/
:{
"Sid": "AnonGetAlbumObjects",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": [
"arn:aws:s3:::bucket/public-albums/*",
"arn:aws:s3:::bucket/favicon.ico"
]
},
{
"Sid": "AnonListObjects",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:ListBucket",
"Resource": "arn:aws:s3:::bucket",
"Condition": {
"StringLike": {
"s3:prefix": "public-albums/albums/*/"
}
}
},
The S3 user (also called principal) that you use to publish the albums should have permission to:
public-albums/
.If your user has all permisions on the whole bucket, then no changes to the bucket policy are necessary. However, if you want to restrict your user to the minimum permisions necessary, add the following statements:
{
"Sid": "ReadMyPhotosDir",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::1234567890:user/my_albums_user"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::bucket/my/photo/collection/*"
}
{
"Sid": "OnlyListSomeDirs",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::1234567890:user/my_albums_user"
},
"Action": "s3:ListBucket",
"Resource": "arn:aws:s3:::bucket",
"Condition": {
"StringLike": {
"s3:prefix": [
"my/photo/collection/*",
"public-albums/*"
]
}
}
},
{
"Sid": "ObjectActionsOnAlbumsDir",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::1234567890:user/my_albums_user"
},
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::bucket/public-albums/*",
"arn:aws:s3:::bucket/public-albums"
]
},
It is also possible to store the albums in your bucket, but keep the
view.html
on another website. To do this, you can edit the
configuration in view.html
to point to your S3 bucket. Also, you will
need to ensure the CORS configuration for your bucket allows requests
from different origins:
<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
<AllowedOrigin>*</AllowedOrigin>
<AllowedMethod>HEAD</AllowedMethod>
<AllowedMethod>GET</AllowedMethod>
<AllowedMethod>PUT</AllowedMethod>
<AllowedMethod>POST</AllowedMethod>
<AllowedMethod>DELETE</AllowedMethod>
<MaxAgeSeconds>3000</MaxAgeSeconds>
<ExposeHeader>ETag</ExposeHeader>
<ExposeHeader>x-amz-meta-custom-header</ExposeHeader>
<AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>
The following dependencies are included in the HTML files and hosted by CDNs (cdnjs and Goolge Hosted Libraries):
By default, image resizing is done in the browser. This means that the original image is downloaded from S3, resized and then uploaded to its final location. This may perform badly with large photos, slow internet connections and/or slow web browsers. Furthermore, the resizing in the browser isn't perfect and may introduce artifacts.
There is a hook in publish.js
to plugin your own image resizer. You
can, for example, send a XHR request to a PHP script that will download,
resize and upload the photo/thumb to the bucket.
(Here's where you come in)
publish.html