paperclip-dropbox 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,17 @@
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
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source :rubygems
2
+
3
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Janko Marohnić
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,90 @@
1
+ # Dropbox
2
+
3
+ This gem extends [Paperclip](https://github.com/thoughtbot/paperclip) with Dropbox storage.
4
+
5
+ ## Installation
6
+
7
+ Put it in your `Gemfile`:
8
+
9
+ ```ruby
10
+ gem "paperclip-dropbox"
11
+ ```
12
+
13
+ And run `bundle install`.
14
+
15
+ ## Usage
16
+
17
+ Example:
18
+
19
+ ```ruby
20
+ class User < ActiveRecord::Base
21
+ has_attached_file :avatar,
22
+ :storage => :dropbox,
23
+ :dropbox_settings => "#{Rails.root}/config/dropbox.yml"
24
+ end
25
+ ```
26
+
27
+ Valid options for `#has_attached_file` are:
28
+
29
+ - `:dropbox_settings` – A `Hash`, a `File`, or a path to the file where your
30
+ Dropbox configuration is located
31
+
32
+ - `:dropbox_options` – This can be used to overrride `:dropbox_settings` (for example,
33
+ you have configuration in your YAML file, but you want to override some things
34
+ that are specific for a certain attribute)
35
+
36
+ ## Configuration
37
+
38
+ Example (`config/dropbox.yaml`):
39
+
40
+ ```erb
41
+ app_key: <%= ENV["DROPBOX_APP_KEY"] %>
42
+ app_secret: <%= ENV["DROPBOX_APP_SECRET"] %>
43
+ access_token: <%= ENV["DROPBOX_ACCESS_TOKEN"] %>
44
+ access_token_secret: <%= ENV["DROPBOX_ACCESS_TOKEN_SECRET"] %>
45
+ ```
46
+
47
+ You can also namespace them inside of `development`, `testing` and `production` environments
48
+ (just like you do with your `database.yml`).
49
+
50
+ There are 3 more **optional** configurations:
51
+
52
+ - `:access_type` – This is either `"app_folder"` or `"dropbox"` (defaults to `"app_folder"`)
53
+ - `:path` - Similar to Paperclip's `:path` option (defaults to `"<filename>"`)
54
+ - `:environment` - Here you can set your environment if you're in a non-Rails application
55
+
56
+ ### The `:path` option
57
+
58
+ Let's say we've set `:path` to `"<table_name>/<record_id>_<attachment_name>_<filename>"`. If a user with the ID of 13
59
+ uploads `photo.jpg` for his avatar, the file would be saved to
60
+
61
+ ```
62
+ users/13_avatar_photo.jpg
63
+ ```
64
+
65
+ The keywords are: `<filename>`, `<table_name>`, `<model_name>`,
66
+ `<attachment_name>` and `<style>`. Additionally, if you want to use a record's attribute, just
67
+ prefix it with `record_` (like the `<record_id>` above).
68
+
69
+ Filenames in Dropbox inside a folder have to be unique, otherwise exception
70
+ `Paperclip::Storage::Dropbox::FileExists` is thrown. To help you with that, you
71
+ can pass in `:unique_filename => true` to Dropbox configuration, which will
72
+ ensure uniqueness of filenames (this is the same as passing `:path => "<model_name>_<record_id>_<attachment_name>"`).
73
+
74
+ ### Obtaining the access token
75
+
76
+ To obtain the access token, you can use the following rake task:
77
+
78
+ ```
79
+ $ rake dropbox:authorize APP_KEY=your_app_key APP_SECRET=your_app_secret
80
+ ```
81
+
82
+ And just follow the instructions.
83
+
84
+ ## Credits
85
+
86
+ I found some solutions to my problems in **@dripster82**'s [paperclipdropbox](https://github.com/dripster82/paperclipdropbox) gem.
87
+
88
+ ## License
89
+
90
+ [MIT](https://github.com/janko-m/paperclip-dropbox/blob/master/LICENSE)
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
@@ -0,0 +1,11 @@
1
+ module Paperclip
2
+ module Storage
3
+ module Dropbox
4
+ class Railtie < Rails::Railtie
5
+ rake_tasks do
6
+ load "tasks/paperclip-dropbox.rake"
7
+ end
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,125 @@
1
+ require 'dropbox_sdk'
2
+ require 'active_support/core_ext/hash/keys'
3
+ require 'active_support/inflector/methods'
4
+ require 'yaml'
5
+ require 'erb'
6
+
7
+ module Paperclip
8
+ module Storage
9
+ module Dropbox
10
+ attr_reader :dropbox_client
11
+
12
+ def self.extended(base)
13
+ base.instance_eval do
14
+ @dropbox_settings = parse_settings(@options[:dropbox_settings] || {})
15
+ @dropbox_settings.update(@options[:dropbox_options] || {})
16
+
17
+ session = DropboxSession.new(@dropbox_settings[:app_key], @dropbox_settings[:app_secret])
18
+ session.set_access_token(@dropbox_settings[:access_token], @dropbox_settings[:access_token_secret])
19
+
20
+ @dropbox_client = DropboxClient.new(session, @dropbox_settings[:access_type] || :app_folder)
21
+
22
+ @dropbox_keywords = Hash.new do |hash, key|
23
+ if key =~ /^\<record_.+\>$/
24
+ attribute = key.match(/^\<record_(.+)\>$/)[1]
25
+ hash[key] = lambda { |style| instance.send(attribute) }
26
+ end
27
+ end
28
+ @dropbox_keywords.update(
29
+ "<model_name>" => lambda { |style| instance.class.table_name.singularize },
30
+ "<table_name>" => lambda { |style| instance.class.table_name },
31
+ "<filename>" => lambda { |style| original_filename.match(/\.\w{3,4}$/).pre_match },
32
+ "<attachment_name>" => lambda { |style| name },
33
+ "<style>" => lambda { |style| style }
34
+ )
35
+ end
36
+ end
37
+
38
+ def flush_writes
39
+ @queued_for_write.each do |style, file|
40
+ unless exists?(style)
41
+ response = dropbox_client.put_file(path(style), file.read)
42
+ else
43
+ raise FileExists, "\"#{path(style)}\" already exists on Dropbox"
44
+ end
45
+ end
46
+
47
+ after_flush_writes
48
+ @queued_for_write = {}
49
+ end
50
+
51
+ def flush_deletes
52
+ @queued_for_delete.each do |path|
53
+ dropbox_client.file_delete(path)
54
+ end
55
+ @queued_for_delete = []
56
+ end
57
+
58
+ def exists?(style)
59
+ !!url(style)
60
+ end
61
+
62
+ def url(*args)
63
+ style = args.first.is_a?(Symbol) ? args.first : default_style
64
+ options = args.last.is_a?(Hash) ? args.last : {}
65
+ query = options[:download] ? "?dl=1" : ""
66
+
67
+ dropbox_client.media(path(style))["url"] + query
68
+
69
+ rescue DropboxError
70
+ nil
71
+ end
72
+
73
+ def path(style)
74
+ extension = original_filename[/\.\w{3,4}$/]
75
+ result = file_path
76
+ file_path.scan(/\<\w+\>/).each do |keyword|
77
+ result.sub!(keyword, @dropbox_keywords[keyword].call(style).to_s)
78
+ end
79
+ style_suffix = style != default_style ? "_#{style}" : ""
80
+ result = "#{result}#{style_suffix}#{extension}"
81
+ end
82
+
83
+ def copy_to_local_file(style, destination_path)
84
+ local_file = File.open(destination_path, "wb")
85
+ local_file.write(dropbox_client.get_file(path(style)))
86
+ local_file.close
87
+ end
88
+
89
+ private
90
+
91
+ def file_path
92
+ return @dropbox_settings[:path] if @dropbox_settings[:path]
93
+
94
+ if @dropbox_settings[:unique_filename]
95
+ "<model_name>_<record_id>_<attachment_name>"
96
+ else
97
+ "<filename>"
98
+ end
99
+ end
100
+
101
+ def parse_settings(settings)
102
+ settings = settings.respond_to?(:call) ? settings.call : settings
103
+ settings = get_settings(settings).stringify_keys
104
+ environment = defined?(Rails) ? Rails.env : @dropbox_settings[:environment].to_s
105
+ (settings[environment] || settings).symbolize_keys
106
+ end
107
+
108
+ def get_settings(settings)
109
+ case settings
110
+ when File
111
+ YAML.load(ERB.new(File.read(settings.path)).result)
112
+ when String, Pathname
113
+ YAML.load(ERB.new(File.read(settings)).result)
114
+ when Hash
115
+ settings
116
+ else
117
+ raise ArgumentError, "settings are not a path, file, or hash."
118
+ end
119
+ end
120
+
121
+ class FileExists < RuntimeError
122
+ end
123
+ end
124
+ end
125
+ end
@@ -0,0 +1,2 @@
1
+ require "paperclip/storage/dropbox"
2
+ require "paperclip/storage/dropbox/railtie" if defined?(Rails)
@@ -0,0 +1,16 @@
1
+ require 'rake'
2
+ require 'dropbox_sdk'
3
+
4
+ namespace :dropbox do
5
+ desc "Obtain your access token"
6
+ task :authorize do
7
+ session = DropboxSession.new(ENV["APP_KEY"], ENV["APP_SECRET"])
8
+ puts "Visit this URL: #{session.get_authorize_url}"
9
+ print "And after you approved the authorization confirm it here (y/n): "
10
+ answer = STDIN.gets.strip
11
+ exit if answer == "n"
12
+ session.get_access_token
13
+ puts "Access token: #{session.access_token.key}"
14
+ puts "Access token secret: #{session.access_token.secret}"
15
+ end
16
+ end
@@ -0,0 +1,19 @@
1
+ # encoding: utf-8
2
+
3
+ Gem::Specification.new do |gem|
4
+ gem.name = "paperclip-dropbox"
5
+ gem.version = "0.0.1"
6
+
7
+ gem.authors = ["Janko Marohnić"]
8
+ gem.email = ["janko.marohnic@gmail.com"]
9
+ gem.description = %q{Extends Paperclip with Dropbox storage.}
10
+ gem.summary = gem.description
11
+ gem.homepage = "https://github.com/janko-m/paperclip-dropbox"
12
+
13
+ gem.files = `git ls-files`.split($\)
14
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
15
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
16
+ gem.require_paths = ["lib"]
17
+
18
+ gem.add_dependency "dropbox-sdk", "~> 1.3"
19
+ end
metadata ADDED
@@ -0,0 +1,72 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: paperclip-dropbox
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Janko Marohnić
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-08-28 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: dropbox-sdk
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '1.3'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: '1.3'
30
+ description: Extends Paperclip with Dropbox storage.
31
+ email:
32
+ - janko.marohnic@gmail.com
33
+ executables: []
34
+ extensions: []
35
+ extra_rdoc_files: []
36
+ files:
37
+ - .gitignore
38
+ - Gemfile
39
+ - LICENSE
40
+ - README.md
41
+ - Rakefile
42
+ - lib/paperclip-dropbox.rb
43
+ - lib/paperclip/storage/dropbox.rb
44
+ - lib/paperclip/storage/dropbox/railtie.rb
45
+ - lib/tasks/paperclip-dropbox.rake
46
+ - paperclip-dropbox.gemspec
47
+ homepage: https://github.com/janko-m/paperclip-dropbox
48
+ licenses: []
49
+ post_install_message:
50
+ rdoc_options: []
51
+ require_paths:
52
+ - lib
53
+ required_ruby_version: !ruby/object:Gem::Requirement
54
+ none: false
55
+ requirements:
56
+ - - ! '>='
57
+ - !ruby/object:Gem::Version
58
+ version: '0'
59
+ required_rubygems_version: !ruby/object:Gem::Requirement
60
+ none: false
61
+ requirements:
62
+ - - ! '>='
63
+ - !ruby/object:Gem::Version
64
+ version: '0'
65
+ requirements: []
66
+ rubyforge_project:
67
+ rubygems_version: 1.8.23
68
+ signing_key:
69
+ specification_version: 3
70
+ summary: Extends Paperclip with Dropbox storage.
71
+ test_files: []
72
+ has_rdoc: