Skip to content
This repository has been archived by the owner on Mar 29, 2019. It is now read-only.

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
janko committed Oct 25, 2015
0 parents commit 09f1bc1
Show file tree
Hide file tree
Showing 16 changed files with 11,808 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
@@ -0,0 +1 @@
.env
25 changes: 25 additions & 0 deletions Gemfile
@@ -0,0 +1,25 @@
source "https://rubygems.org"

gem "shrine"

# Storage
gem "aws-sdk", "~> 2.1"
gem "dotenv"

# Processing
gem "image_processing", ">= 0.2.3"
gem "mini_magick", "~> 4.3.5"
gem "fastimage"

# Database
gem "sequel"
gem "pg"

# App
gem "roda"
gem "tilt"
gem "puma"

# Background
gem "sidekiq"
gem "pry"
87 changes: 87 additions & 0 deletions Gemfile.lock
@@ -0,0 +1,87 @@
GEM
remote: https://rubygems.org/
specs:
addressable (2.3.8)
aws-sdk (2.1.18)
aws-sdk-resources (= 2.1.18)
aws-sdk-core (2.1.18)
jmespath (~> 1.0)
aws-sdk-resources (2.1.18)
aws-sdk-core (= 2.1.18)
celluloid (0.17.2)
celluloid-essentials
celluloid-extras
celluloid-fsm
celluloid-pool
celluloid-supervision
timers (>= 4.1.1)
celluloid-essentials (0.20.5)
timers (>= 4.1.1)
celluloid-extras (0.20.5)
timers (>= 4.1.1)
celluloid-fsm (0.20.5)
timers (>= 4.1.1)
celluloid-pool (0.20.5)
timers (>= 4.1.1)
celluloid-supervision (0.20.5)
timers (>= 4.1.1)
coderay (1.1.0)
connection_pool (2.2.0)
dotenv (2.0.2)
down (1.0.2)
fastimage (1.7.0)
addressable (~> 2.3, >= 2.3.5)
hitimes (1.2.3)
image_processing (0.2.3)
jmespath (1.0.2)
multi_json (~> 1.0)
json (1.8.3)
method_source (0.8.2)
mini_magick (4.3.5)
multi_json (1.11.2)
pg (0.18.3)
pry (0.10.1)
coderay (~> 1.1.0)
method_source (~> 0.8.1)
slop (~> 3.4)
puma (2.13.4)
rack (1.6.4)
redis (3.2.1)
redis-namespace (1.5.2)
redis (~> 3.0, >= 3.0.4)
roda (2.6.0)
rack
sequel (4.26.0)
shrine (0.9.0)
down (>= 1.0.2)
sidekiq (3.5.1)
celluloid (~> 0.17.2)
connection_pool (~> 2.2, >= 2.2.0)
json (~> 1.0)
redis (~> 3.2, >= 3.2.1)
redis-namespace (~> 1.5, >= 1.5.2)
slop (3.6.0)
tilt (2.0.1)
timers (4.1.1)
hitimes

PLATFORMS
ruby

DEPENDENCIES
aws-sdk (~> 2.1)
dotenv
fastimage
image_processing (>= 0.2.3)
mini_magick (~> 4.3.5)
pg
pry
puma
roda
sequel
shrine
sidekiq
tilt

BUNDLED WITH
1.10.6
2 changes: 2 additions & 0 deletions Procfile
@@ -0,0 +1,2 @@
web: bundle exec rackup
worker: bundle exec sidekiq -r ./app.rb
51 changes: 51 additions & 0 deletions README.md
@@ -0,0 +1,51 @@
# Shrine example

This is an example app demonstrating how easy it is to complex file uploads
using [Shrine]. It implements the perfect user experience™ (like Google's),
and the underlying complexity is completely hidden away from the user.

The application allows the user to do multiple file uploads via AJAX, directly
to S3, where additional processing and deleting is done in background jobs.

## Requirements

To run the app you need to setup the following things:

* Install ImageMagick:

```rb
$ brew install imagemagick
```

* Install the gems:

```rb
$ bundle install
$ gem install foreman
```

* Have Postgres on your machine, and run

```sh
$ createdb shrine-example
$ sequel -m db/migrations postgres:///shrine-example
```

* Put your Amazon S3 credentials in `.env`

```sh
S3_ACCESS_KEY_ID="..."
S3_SECRET_ACCESS_KEY="..."
S3_REGION="..."
S3_BUCKET="..."
```

* Install Redis and have it running (for Sidekiq)

Once you have all of these things set up, you can run the app:

```sh
$ foreman start
```

[Shrine]: https://github.com/janko-m/shrine
127 changes: 127 additions & 0 deletions app.rb
@@ -0,0 +1,127 @@
require "dotenv"
Dotenv.load!

##########
# Shrine #
##########

require "shrine"
require "shrine/storage/file_system"
require "shrine/storage/s3"
require "image_processing/mini_magick"

s3_options = {
access_key_id: ENV.fetch("S3_ACCESS_KEY_ID"),
secret_access_key: ENV.fetch("S3_SECRET_ACCESS_KEY"),
region: ENV.fetch("S3_REGION"),
bucket: ENV.fetch("S3_BUCKET"),
}

Shrine.storages = {
cache: Shrine::Storage::S3.new(prefix: "cache", **s3_options),
store: Shrine::Storage::S3.new(prefix: "store", **s3_options),
}

Shrine.plugin :sequel
Shrine.plugin :background_helpers

Shrine::Attacher.promote { |data| UploadJob.perform_async(data) }
Shrine::Attacher.delete { |data| DeleteJob.perform_async(data) }

class ImageUploader < Shrine
include ImageProcessing::MiniMagick

plugin :determine_mime_type
plugin :store_dimensions
plugin :direct_upload, presign: true, max_size: 20*1024*1024
plugin :versions, names: [:original, :thumb]
plugin :remove_attachment
plugin :logging

def process(io, context)
case context[:phase]
when :promote
thumb = resize_to_limit!(io.download, 300, 300)
{original: io, thumb: thumb}
end
end
end

############
# Database #
############

require "sequel"

DB = Sequel.connect("postgres:///shrine-example")
Sequel::Model.plugin :nested_attributes

class Album < Sequel::Model
one_to_many :photos
nested_attributes :photos, destroy: true
end

class Photo < Sequel::Model
include ImageUploader[:image]
end

Album.first || Album.create(name: "My Album")

###################
# Background jobs #
###################

require "sidekiq"

Sidekiq.default_worker_options[:retry] = false

class UploadJob
include Sidekiq::Worker
def perform(data)
Shrine::Attacher.promote(data)
end
end

class DeleteJob
include Sidekiq::Worker
def perform(data)
Shrine::Attacher.delete(data)
end
end

###############
# Application #
###############

require "roda"
require "tilt/erb"

class App < Roda
plugin :indifferent_params
plugin :render
plugin :partials
plugin :static, ["/assets"]

route do |r|
r.on "attachments/images" do
r.run ImageUploader.direct_endpoint
end

@album = Album.first!

r.root do
view(:index)
end

r.post "album" do
@album.update(params[:album])
r.redirect r.referer
end

r.post "album/photos" do
p params
photo = @album.add_photo(params[:photo])
partial("photo", locals: {photo: photo, idx: @album.photos.count})
end
end
end
3 changes: 3 additions & 0 deletions config.ru
@@ -0,0 +1,3 @@
require "./app"

run App
14 changes: 14 additions & 0 deletions db/migrations/001_create.rb
@@ -0,0 +1,14 @@
Sequel.migration do
change do
create_table :albums do
primary_key :id
column :name, :varchar
end

create_table :photos do
primary_key :id
foreign_key :album_id, :albums
column :image_data, :text
end
end
end

0 comments on commit 09f1bc1

Please sign in to comment.