paperclip-imgur 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ nbproject
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color -fs
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in paperclip-imgur.gemspec
4
+ gemspec
@@ -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.
@@ -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
+ ```
@@ -0,0 +1,5 @@
1
+ require 'bundler/gem_tasks'
2
+
3
+ require 'rspec/core/rake_task'
4
+ RSpec::Core::RakeTask.new
5
+ task :default => :spec
@@ -0,0 +1,4 @@
1
+ app_key: 1
2
+ app_secret: 2
3
+ access_token: 3
4
+ access_token_secret: 4
@@ -0,0 +1,2 @@
1
+ require 'paperclip'
2
+ require 'paperclip/imgur'
@@ -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: