paperclip-imgur 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +18 -0
- data/.rspec +1 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +71 -0
- data/Rakefile +5 -0
- data/config/imgur.yml +4 -0
- data/lib/paperclip-imgur.rb +2 -0
- data/lib/paperclip/imgur.rb +1 -0
- data/lib/paperclip/storage/imgur.rb +107 -0
- data/paperclip-imgur.gemspec +20 -0
- data/spec/paperclip/storage/imgur_spec.rb +95 -0
- metadata +71 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 55e4fc058747f3de3d7d5f3ac1c60eb5e50d08ab
|
4
|
+
data.tar.gz: 51760bd9e810ba8a9e5f14aa4722aebd2652f9b3
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: bcfe5c84a4bc6835b28618795d8b7420d0194006bbb5666f9acf6cb41e3b24deb46c694d5b6beba4767b9b918e628c9b19b01e8c6c29c306f434526a0d8fa24c
|
7
|
+
data.tar.gz: 08ec4452008de121fe831a32e1e82b1ec4f03ba155acda02e3210e90c71d62da486f935bbb66411af1a041e3e11b82767102debf6039651727472de6996851b6
|
data/.gitignore
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color -fs
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 Daniel Cruz Horts
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
# Paperclip::Imgur
|
2
|
+
|
3
|
+
This gem extends [Paperclip](https://github.com/thoughtbot/paperclip) with [Imgur](http://imgur.com/) storage. It's been tested with Paperclip 3.3.1 and 4.3.
|
4
|
+
|
5
|
+
If you want Paperclip Dropbox support, have a look at this [great gem](https://github.com/janko-m/paperclip-dropbox/).
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
```ruby
|
11
|
+
gem 'paperclip-imgur'
|
12
|
+
```
|
13
|
+
|
14
|
+
And then run:
|
15
|
+
```bash
|
16
|
+
$ bundle install
|
17
|
+
```
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
Tell your typical model™ to use Imgur as storage:
|
22
|
+
```ruby
|
23
|
+
class User < ActiveRecord::Base
|
24
|
+
has_attached_file :avatar, storage: :imgur
|
25
|
+
end
|
26
|
+
```
|
27
|
+
|
28
|
+
### Credentials
|
29
|
+
|
30
|
+
The credentials to upload and delete images from Imgur will be read from `#{Rails.root}/config/imgur.yml`. This file must contain the following keys:
|
31
|
+
```yml
|
32
|
+
client_id: 'CLIENT_ID'
|
33
|
+
client_secret: 'CLIENT_SECRET'
|
34
|
+
refresh_token: 'REFRESH_TOKEN'
|
35
|
+
```
|
36
|
+
|
37
|
+
Get these keys with:
|
38
|
+
```bash
|
39
|
+
rake imgur:authorize CLIENT_ID='CLIENT_ID' CLIENT_SECRET='CLIENT_SECRET'
|
40
|
+
```
|
41
|
+
Please refer to the [API client gem documentation](https://github.com/dncrht/imgur) for more information on this.
|
42
|
+
|
43
|
+
You can also specify the credentials per model attribute, using a hash:
|
44
|
+
```ruby
|
45
|
+
has_attached_file :avatar, storage: :imgur, imgur_credentials: {client_id: 'CLIENT_ID', client_secret: 'CLIENT_SECRET', refresh_token: 'REFRESH_TOKEN'}
|
46
|
+
```
|
47
|
+
...or path to a YAML file
|
48
|
+
```ruby
|
49
|
+
has_attached_file :avatar, storage: :imgur, imgur_credentials: 'path.to/file.yml'
|
50
|
+
```
|
51
|
+
...or a File itself
|
52
|
+
```ruby
|
53
|
+
has_attached_file :avatar, storage: :imgur, imgur_credentials: File.open('path.to/file.yml', 'r')
|
54
|
+
```
|
55
|
+
|
56
|
+
### Use attachment in views
|
57
|
+
|
58
|
+
The image is available in your views in three different sizes:
|
59
|
+
```ruby
|
60
|
+
<%= image_path @user.avatar %>
|
61
|
+
<%= image_path @user.avatar.url(:small) %>
|
62
|
+
<%= image_path @user.avatar.url(:large) %>
|
63
|
+
```
|
64
|
+
|
65
|
+
### Deleting images
|
66
|
+
|
67
|
+
To delete an image, follow the usual Paperclip procedure:
|
68
|
+
```ruby
|
69
|
+
@user.avatar = nil
|
70
|
+
@user.save
|
71
|
+
```
|
data/Rakefile
ADDED
data/config/imgur.yml
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'paperclip/storage/imgur'
|
@@ -0,0 +1,107 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
require 'erb'
|
3
|
+
require 'imgur'
|
4
|
+
|
5
|
+
module Paperclip
|
6
|
+
module Storage
|
7
|
+
module Imgur
|
8
|
+
|
9
|
+
# Specify credentials in a file, path, string or hash.
|
10
|
+
# Required fields: client_id, client_secret, refresh_token
|
11
|
+
def self.extended(base)
|
12
|
+
base.instance_eval do
|
13
|
+
imgur_credentials = parse_credentials(@options[:imgur_credentials])
|
14
|
+
imgur_options = @options[:imgur_options] || {}
|
15
|
+
environment = defined?(Rails) ? Rails.env : imgur_options[:environment].to_s
|
16
|
+
|
17
|
+
# Use credentials for the current Rails environment, if any
|
18
|
+
@imgur_credentials = (imgur_credentials[environment] || imgur_credentials).symbolize_keys
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
# We have to trust that any Imgur hash stored into *_file_name represents an existing Imgur image.
|
23
|
+
# This assumption let us avoid the latency of a network call.
|
24
|
+
# If not, someone has touched where he shouldn't!
|
25
|
+
def exists?(style_name = default_style)
|
26
|
+
if original_filename
|
27
|
+
true
|
28
|
+
else
|
29
|
+
false
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def flush_writes
|
34
|
+
@queued_for_write.each do |style, file| #style is 'original' etc...
|
35
|
+
|
36
|
+
begin
|
37
|
+
image = imgur_session.image.image_upload(file)
|
38
|
+
image_id = image.id
|
39
|
+
rescue
|
40
|
+
# Sometimes there are API or network errors.
|
41
|
+
# In this cases, we don't store anything.
|
42
|
+
image_id = nil
|
43
|
+
end
|
44
|
+
|
45
|
+
# We cannot use update_attribute because it internally calls save, and save calls
|
46
|
+
# flush_writes again, and it will end up in a stack overflow due excessive recursion
|
47
|
+
instance.update_column :"#{name}_#{:file_name}", image_id
|
48
|
+
end
|
49
|
+
after_flush_writes
|
50
|
+
@queued_for_write = {}
|
51
|
+
end
|
52
|
+
|
53
|
+
def flush_deletes
|
54
|
+
@queued_for_delete.each do |path|
|
55
|
+
imgur_session.image.image_delete(path) # Doesn't matter if the image doesn't really exists
|
56
|
+
end
|
57
|
+
@queued_for_delete = []
|
58
|
+
end
|
59
|
+
|
60
|
+
# Returns the image's URL.
|
61
|
+
# We don't use imgur_session.find to avoid the latency of a network call.
|
62
|
+
def url(size = default_style)
|
63
|
+
image_id = instance.send("#{name}_#{:file_name}")
|
64
|
+
|
65
|
+
return @url_generator.for(size, {}) if image_id.nil? || image_id.empty? # Show Paperclip's default missing image path
|
66
|
+
|
67
|
+
::Imgur::Image.new(id: image_id).url(size)
|
68
|
+
end
|
69
|
+
|
70
|
+
# Returns the path of the attachment.
|
71
|
+
# It's exactly the Imgur hash.
|
72
|
+
def path(style_name = default_style)
|
73
|
+
original_filename
|
74
|
+
end
|
75
|
+
|
76
|
+
def copy_to_local_file(style, destination_path)
|
77
|
+
# TO BE DONE
|
78
|
+
#local_file = File.open(destination_path, 'wb')
|
79
|
+
#local_file.write(imgur_session.get_file(path(style)))
|
80
|
+
#local_file.close
|
81
|
+
end
|
82
|
+
|
83
|
+
private
|
84
|
+
|
85
|
+
def imgur_session
|
86
|
+
@imgur_session ||= ::Imgur::Session.new(@imgur_credentials)
|
87
|
+
end
|
88
|
+
|
89
|
+
def parse_credentials(credentials = nil)
|
90
|
+
if credentials.nil? && defined?(Rails)
|
91
|
+
credentials = "#{Rails.root}/config/imgur.yml"
|
92
|
+
end
|
93
|
+
|
94
|
+
credentials = case credentials
|
95
|
+
when File
|
96
|
+
YAML.load(ERB.new(File.read(credentials.path)).result)
|
97
|
+
when String, Pathname
|
98
|
+
YAML.load(ERB.new(File.read(credentials)).result)
|
99
|
+
end
|
100
|
+
|
101
|
+
return credentials.stringify_keys if credentials.respond_to? :stringify_keys
|
102
|
+
|
103
|
+
raise ArgumentError, 'Please specify Imgur credentials via a file, string or hash.'
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
|
5
|
+
Gem::Specification.new do |gem|
|
6
|
+
gem.name = 'paperclip-imgur'
|
7
|
+
gem.version = '0.1.0'
|
8
|
+
gem.authors = ['Daniel Cruz Horts']
|
9
|
+
gem.description = %q{Extends Paperclip with Imgur storage}
|
10
|
+
gem.summary = gem.description
|
11
|
+
gem.homepage = 'https://github.com/dncrht/paperclip-imgur'
|
12
|
+
gem.license = 'MIT'
|
13
|
+
|
14
|
+
gem.files = `git ls-files`.split($/)
|
15
|
+
gem.executables = gem.files.grep(%r{^bin/}).map { |f| File.basename(f) }
|
16
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
17
|
+
gem.require_paths = ['lib']
|
18
|
+
|
19
|
+
gem.add_dependency 'imgurapi', '~> 2.0.1'
|
20
|
+
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
require 'paperclip-imgur'
|
2
|
+
require 'active_record'
|
3
|
+
|
4
|
+
class CreateUsers < ActiveRecord::Migration
|
5
|
+
self.verbose = false
|
6
|
+
|
7
|
+
def change
|
8
|
+
create_table :users do |t|
|
9
|
+
t.attachment :avatar
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
describe Paperclip::Storage::Imgur do
|
15
|
+
before(:all) do
|
16
|
+
ActiveRecord::Base.send(:include, Paperclip::Glue)
|
17
|
+
|
18
|
+
FileUtils.rm_rf 'tmp'
|
19
|
+
FileUtils.mkdir_p 'tmp'
|
20
|
+
ActiveRecord::Base.establish_connection('sqlite3:///tmp/foo.sqlite3')
|
21
|
+
CreateUsers.migrate(:up)
|
22
|
+
|
23
|
+
Paperclip.options[:log] = false
|
24
|
+
end
|
25
|
+
|
26
|
+
describe '#parse_credentials' do
|
27
|
+
def set_options(options)
|
28
|
+
stub_const('User', Class.new(ActiveRecord::Base) {
|
29
|
+
has_attached_file :avatar, { :storage => :imgur }.merge(options)
|
30
|
+
})
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'should complain when providing unsuitable credentials' do
|
34
|
+
set_options(:imgur_credentials => 1)
|
35
|
+
expect { User.new.avatar }.to raise_error
|
36
|
+
|
37
|
+
set_options(:imgur_credentials => {})
|
38
|
+
expect { User.new.avatar }.to raise_error
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'should accept a properly formed hash' do
|
42
|
+
set_options(:imgur_credentials => {:app_key => '1', :app_secret => '2', :access_token => '3', :access_token_secret => '4'})
|
43
|
+
expect { User.new.avatar }.to_not raise_error
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'should use config/imgur.yml under a Rails application if we left credentials blank' do
|
47
|
+
stub_const('Rails', Class.new {
|
48
|
+
def self.env
|
49
|
+
'testing'
|
50
|
+
end
|
51
|
+
def self.root
|
52
|
+
Dir.pwd
|
53
|
+
end
|
54
|
+
})
|
55
|
+
|
56
|
+
set_options({})
|
57
|
+
expect { User.new.avatar }.to_not raise_error
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'should accept a file path' do
|
61
|
+
set_options(:imgur_credentials => "#{Dir.pwd}/config/imgur.yml")
|
62
|
+
expect { User.new.avatar }.to_not raise_error
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'should accept a file' do
|
66
|
+
set_options(:imgur_credentials => File.open("#{Dir.pwd}/config/imgur.yml", 'r'))
|
67
|
+
expect { User.new.avatar }.to_not raise_error
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
describe '#url' do
|
72
|
+
before(:each) do
|
73
|
+
stub_const('User', Class.new(ActiveRecord::Base) { has_attached_file :avatar, :storage => :imgur, :imgur_credentials => {:app_key => '1', :app_secret => '2', :access_token => '3', :access_token_secret => '4'} })
|
74
|
+
|
75
|
+
@imgur_hash = 'random_valid_hash'
|
76
|
+
@user = User.create(:avatar_file_name => @imgur_hash)
|
77
|
+
end
|
78
|
+
|
79
|
+
it "should return the missing image path if there's no image" do
|
80
|
+
User.new.avatar.url.should eq('/avatars/original/missing.png')
|
81
|
+
User.new.avatar.url(:random_size).should eq('/avatars/random_size/missing.png')
|
82
|
+
end
|
83
|
+
|
84
|
+
it "should return Imgur's image paths if there's an image" do
|
85
|
+
session = @user.avatar.instance_variable_get(:@imgur_session)
|
86
|
+
|
87
|
+
@user.avatar.url.should eq(session.url(@imgur_hash))
|
88
|
+
@user.avatar.url(:random_size).should eq(session.url(@imgur_hash, :random_size))
|
89
|
+
@user.avatar.url(:small_square).should eq(session.url(@imgur_hash, :small_square))
|
90
|
+
@user.avatar.url(:large_thumbnail).should eq(session.url(@imgur_hash, :large_thumbnail))
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|
metadata
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: paperclip-imgur
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Daniel Cruz Horts
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-07-05 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: imgurapi
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 2.0.1
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 2.0.1
|
27
|
+
description: Extends Paperclip with Imgur storage
|
28
|
+
email:
|
29
|
+
executables: []
|
30
|
+
extensions: []
|
31
|
+
extra_rdoc_files: []
|
32
|
+
files:
|
33
|
+
- ".gitignore"
|
34
|
+
- ".rspec"
|
35
|
+
- Gemfile
|
36
|
+
- LICENSE.txt
|
37
|
+
- README.md
|
38
|
+
- Rakefile
|
39
|
+
- config/imgur.yml
|
40
|
+
- lib/paperclip-imgur.rb
|
41
|
+
- lib/paperclip/imgur.rb
|
42
|
+
- lib/paperclip/storage/imgur.rb
|
43
|
+
- paperclip-imgur.gemspec
|
44
|
+
- spec/paperclip/storage/imgur_spec.rb
|
45
|
+
homepage: https://github.com/dncrht/paperclip-imgur
|
46
|
+
licenses:
|
47
|
+
- MIT
|
48
|
+
metadata: {}
|
49
|
+
post_install_message:
|
50
|
+
rdoc_options: []
|
51
|
+
require_paths:
|
52
|
+
- lib
|
53
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
54
|
+
requirements:
|
55
|
+
- - ">="
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: '0'
|
58
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - ">="
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '0'
|
63
|
+
requirements: []
|
64
|
+
rubyforge_project:
|
65
|
+
rubygems_version: 2.2.2
|
66
|
+
signing_key:
|
67
|
+
specification_version: 4
|
68
|
+
summary: Extends Paperclip with Imgur storage
|
69
|
+
test_files:
|
70
|
+
- spec/paperclip/storage/imgur_spec.rb
|
71
|
+
has_rdoc:
|