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

Commit

Permalink
add public / private option for dropbox apps
Browse files Browse the repository at this point in the history
add visibility option to readme
Readme formating
pull extracted classes into their own files
  • Loading branch information
dougbradbury committed Dec 12, 2013
1 parent 9f0dec7 commit a0f77a3
Show file tree
Hide file tree
Showing 8 changed files with 98 additions and 20 deletions.
17 changes: 16 additions & 1 deletion README.md
Expand Up @@ -91,6 +91,7 @@ This is a hash containing any of the following options:
- `:environment` – String, the environment name to use for selecting namespaced
credentials in a non-Rails app


For example:

```ruby
Expand All @@ -104,6 +105,20 @@ end

In Rails you don't need to specify it.

### The `:dropbox_visilbility` option
This is a string "public" (default) or "private".
- "public" - Files will be placed in your "Public" directory in dropbox and will the public urls will be used to access the files (not http request required to get a url for the file)
- "private" - Files can be placed in any dropbox directory (set your :path attachment option) and private, expiring urls (4 hours) will be generated each time you access this file. Private can only be used with the 'dropbox' access type.

```ruby
class User < ActiveRecord::Base
has_attached_file :avatar,
:storage => :dropbox,
:dropbox_credentials => Rails.root.join("config/dropbox.yml"),
:dropbox_visibility: 'public'
end
```

### The `:path` option

To change the path of the file, use Paperclip's `:path` option:
Expand All @@ -112,7 +127,7 @@ To change the path of the file, use Paperclip's `:path` option:
:path => ":style/:id_:filename" # Defaults to ":filename"
```

In "Full Dropbox" mode it will automatically be searched in the `Public` folder,
In "Full Dropbox" mode with "public" visibility it will automatically be searched in the `Public` folder,
so there is not need to specify it.

### URL options
Expand Down
18 changes: 13 additions & 5 deletions lib/paperclip/storage/dropbox.rb
@@ -1,9 +1,10 @@
require "dropbox_sdk"
require "active_support/core_ext/hash/keys"
require "paperclip/storage/dropbox/path_generator"
require "paperclip/storage/dropbox/url_generator"
require "paperclip/storage/dropbox/generator_factory"
require "paperclip/storage/dropbox/credentials"


module Paperclip
module Storage
module Dropbox
Expand All @@ -12,8 +13,10 @@ def self.extended(base)
@options[:dropbox_options] ||= {}
@options[:dropbox_credentials] = fetch_credentials
@options[:path] = nil if @options[:path] == self.class.default_options[:path]
@options[:dropbox_visibility] ||= "public"

@path_generator = PathGenerator.new(self, @options)
@url_generator = UrlGenerator.new(self, @options)
@url_generator = GeneratorFactory.build_url_generator(self, @options)
end
end

Expand All @@ -39,7 +42,9 @@ def url(style_or_options = default_style, options = {})
end

def path(style = default_style)
@path_generator.generate(style)
path = @path_generator.generate(style)
path = File.join("Public", path) if public_dropbox?
path
end

def copy_to_local_file(style = default_style, destination_path)
Expand All @@ -66,8 +71,11 @@ def dropbox_client
end
end

def app_folder?; @options[:dropbox_credentials][:access_type] == "app_folder"; end
def full_dropbox?; @options[:dropbox_credentials][:access_type] == "dropbox"; end
def public_dropbox?
@options[:dropbox_credentials][:access_type] == "dropbox" &&
@options[:dropbox_visibility] == "public"
end


private

Expand Down
18 changes: 18 additions & 0 deletions lib/paperclip/storage/dropbox/generator_factory.rb
@@ -0,0 +1,18 @@
require "paperclip/storage/dropbox/private_url_generator"
require "paperclip/storage/dropbox/public_url_generator"
module Paperclip
module Storage
module Dropbox
module GeneratorFactory
def self.build_url_generator(storage, options)
if options[:dropbox_credentials][:access_type] == "app_folder"
PrivateUrlGenerator.new(storage, options)
elsif options[:dropbox_credentials][:access_type] == "dropbox"
PublicUrlGenerator.new(storage, options)
end
end
end
end
end
end

1 change: 0 additions & 1 deletion lib/paperclip/storage/dropbox/path_generator.rb
Expand Up @@ -16,7 +16,6 @@ def generate(style)
else
generate_from_proc(style)
end
path = File.join("Public", path) if @attachment.full_dropbox?
path
end

Expand Down
13 changes: 13 additions & 0 deletions lib/paperclip/storage/dropbox/private_url_generator.rb
@@ -0,0 +1,13 @@
require "paperclip/storage/dropbox/url_generator"
module Paperclip
module Storage
module Dropbox
class PrivateUrlGenerator < UrlGenerator
def file_url(style)
@attachment.dropbox_client.media(@attachment.path(style))["url"]
end
end
end
end
end

16 changes: 16 additions & 0 deletions lib/paperclip/storage/dropbox/public_url_generator.rb
@@ -0,0 +1,16 @@
require "paperclip/storage/dropbox/url_generator"
module Paperclip
module Storage
module Dropbox
class PublicUrlGenerator < UrlGenerator
def file_url(style)
url = URI.parse("https://dl.dropboxusercontent.com/u/#{user_id}/")
path = @attachment.path(style)
path = path.match(/^Public\//).post_match
url.merge!(path)
url.to_s
end
end
end
end
end
16 changes: 3 additions & 13 deletions lib/paperclip/storage/dropbox/url_generator.rb
Expand Up @@ -3,6 +3,7 @@
module Paperclip
module Storage
module Dropbox

class UrlGenerator
def initialize(attachment, attachment_options)
@attachment = attachment
Expand All @@ -11,7 +12,7 @@ def initialize(attachment, attachment_options)

def generate(style, options)
if @attachment.present?
url = @attachment.full_dropbox? ? public_url(style) : private_url(style)
url = file_url(style)
url = URI.parse(url)
url.query = [url.query, "dl=1"].compact.join("&") if options[:download]
url.to_s
Expand All @@ -22,22 +23,11 @@ def generate(style, options)

private

def private_url(style)
@attachment.dropbox_client.media(@attachment.path(style))["url"]
end

def public_url(style)
url = URI.parse("https://dl.dropboxusercontent.com/u/#{user_id}/")
path = @attachment.path(style)
path = path.match(/^Public\//).post_match
url.merge!(path)
url.to_s
end

def user_id
@attachment_options[:dropbox_credentials][:user_id]
end
end

end
end
end
19 changes: 19 additions & 0 deletions spec/lib/paperclip/storage/dropbox_spec.rb
Expand Up @@ -28,6 +28,7 @@ def new_post(options = {})
@options.update(dropbox_credentials: CREDENTIALS[:dropbox].except(:access_type))
expect(new_post.attachment.dropbox_client.root).to eq "dropbox"
end

end

describe "#flush_writes" do
Expand Down Expand Up @@ -81,6 +82,24 @@ def new_post(options = {})
end
end

describe "path" do
it "adds 'Public' to path" do
@options.update(dropbox_visibility: "public")
new_post.attachment.path.include?("Public").should == true
end

it "does not add 'Public' to path" do
@options.update(dropbox_visibility: "private")
new_post.attachment.path.include?("Public").should == false
end

it "does not add 'Public' to app_folder path" do
@options.update(dropbox_credentials: CREDENTIALS[:dropbox].merge(:access_type => "app_folder"))
@options.update(dropbox_visibility: "public")
new_post.attachment.path.include?("Public").should == false
end
end

describe "#copy_to_local_file" do
it "copies file from Dropbox to a local file" do
post = new_post.tap(&:save)
Expand Down

0 comments on commit a0f77a3

Please sign in to comment.