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.
@@ -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: