├── VERSION
├── .travis.yml
├── .document
├── spec
├── stubs
│ ├── error
│ │ ├── 400
│ │ ├── 401
│ │ ├── 404-find
│ │ ├── 422-bookmark
│ │ ├── 422-bookmarks
│ │ └── 404-update
│ ├── account
│ │ ├── stats
│ │ ├── create
│ │ ├── update
│ │ └── show
│ ├── gift_card
│ │ ├── show
│ │ └── redeem
│ └── drop
│ │ ├── update
│ │ ├── delete
│ │ ├── create
│ │ ├── show
│ │ ├── show-private
│ │ ├── new
│ │ ├── new-private
│ │ └── index
├── cloudapp_api_spec.rb
├── spec_helper.rb
├── cloudapp_gift_card_spec.rb
├── fakeweb_helper.rb
├── cloudapp_client_spec.rb
├── cloudapp_response_error_spec.rb
├── cloudapp_account_spec.rb
├── cloudapp_item_spec.rb
└── cloudapp_drop_spec.rb
├── .gitignore
├── lib
├── cloudapp
│ ├── core_ext.rb
│ ├── httparty.rb
│ ├── response_error.rb
│ ├── multipart.rb
│ ├── gift_card.rb
│ ├── base.rb
│ ├── client.rb
│ ├── account.rb
│ └── drop.rb
└── cloudapp_api.rb
├── Gemfile
├── Rakefile
├── LICENSE
├── Gemfile.lock
├── cloudapp_api.gemspec
└── README.md
/VERSION:
--------------------------------------------------------------------------------
1 | 0.5.0
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: ruby
2 |
3 | rvm:
4 | - 2.0.0
5 | - 1.9.3
6 |
--------------------------------------------------------------------------------
/.document:
--------------------------------------------------------------------------------
1 | README.rdoc
2 | lib/**/*.rb
3 | bin/*
4 | features/**/*.feature
5 | LICENSE
6 |
--------------------------------------------------------------------------------
/spec/stubs/error/404-find:
--------------------------------------------------------------------------------
1 | HTTP/1.1 404 Not Found
2 | Status: 404
3 | Content-Type: text/html; charset=utf-8
4 |
5 |
Not Found
--------------------------------------------------------------------------------
/spec/stubs/error/422-bookmark:
--------------------------------------------------------------------------------
1 | HTTP/1.1 422
2 | Status: 422
3 | Content-Type: application/json; charset=utf-8
4 |
5 | ["URL can't be blank"]
--------------------------------------------------------------------------------
/spec/stubs/error/422-bookmarks:
--------------------------------------------------------------------------------
1 | HTTP/1.1 422
2 | Status: 422
3 | Content-Type: application/json; charset=utf-8
4 |
5 | [["URL can't be blank"]]
--------------------------------------------------------------------------------
/spec/stubs/error/401:
--------------------------------------------------------------------------------
1 | HTTP/1.1 401 Unauthorized
2 | Status: 401
3 | Content-Type: text/plain; charset=utf-8
4 |
5 | HTTP Digest: "Access denied."
--------------------------------------------------------------------------------
/spec/stubs/account/stats:
--------------------------------------------------------------------------------
1 | HTTP/1.1 200 OK
2 | Status: 200
3 | Content-Type: application/json; charset=utf-8
4 |
5 | {
6 | "items": 42,
7 | "views": 31337
8 | }
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ## MAC OS
2 | .DS_Store
3 |
4 | ## TEXTMATE
5 | *.tmproj
6 | tmtags
7 |
8 | ## EMACS
9 | *~
10 | \#*
11 | .\#*
12 |
13 | ## VIM
14 | *.swp
15 |
16 | ## PROJECT::GENERAL
17 | .autotest
18 | .ruby-*
19 | .yardoc
20 | coverage
21 | doc
22 | rdoc
23 | pkg
24 |
25 | ## PROJECT::SPECIFIC
26 | test/test_config.yml
27 |
--------------------------------------------------------------------------------
/spec/stubs/error/400:
--------------------------------------------------------------------------------
1 | HTTP/1.1 400 Bad Request
2 | Status: 400
3 | Content-Type: application/xml
4 |
5 |
6 | MalformedPOSTRequestThe body of your POST request is not well-formed multipart/form-data.1BD4C1A789889BA49i/ZNBBvYD+KKoHBRUU6/9uqu/0XvFkNmvBiiLhn/hEZXOes/xVRrHim//JC9mmi
--------------------------------------------------------------------------------
/lib/cloudapp/core_ext.rb:
--------------------------------------------------------------------------------
1 | class Hash #:nodoc:
2 |
3 | # Return a new hash with all keys converted to symbols.
4 | def symbolize_keys
5 | inject({}) do |options, (key, value)|
6 | options[(key.to_sym rescue key) || key] = value
7 | options
8 | end
9 | end
10 |
11 | # Destructively convert all keys to symbols.
12 | def symbolize_keys!
13 | self.replace(self.symbolize_keys)
14 | end
15 |
16 | end
17 |
--------------------------------------------------------------------------------
/Gemfile:
--------------------------------------------------------------------------------
1 | source "http://rubygems.org"
2 |
3 | # Add dependencies required to use your gem here.
4 | gem "httparty", "~> 0.13.5"
5 | gem "mime-types"
6 |
7 | # Add dependencies to develop your gem here.
8 | # Include everything needed to run rake, tests, features, etc.
9 | group :development do
10 | gem "rspec"
11 | gem 'coveralls', :require => false
12 | gem "fakeweb"
13 | gem "yard"
14 | gem "bluecloth"
15 | gem "cucumber"
16 | end
17 |
--------------------------------------------------------------------------------
/spec/stubs/gift_card/show:
--------------------------------------------------------------------------------
1 | HTTP/1.1 200 OK
2 | Status: 200
3 | Content-Type: application/json; charset=utf-8
4 |
5 | {
6 | "id": 1,
7 | "code": "ABC123",
8 | "plan": "pro",
9 | "months": 12,
10 | "href": "https://my.cl.ly/gift_cards/ABC123",
11 | "created_at": "2011-01-08T20:11:26Z",
12 | "updated_at": "2011-01-08T20:11:26Z",
13 | "redeemed_at": null,
14 | "effective_at": null,
15 | "expires_at": null
16 | }
--------------------------------------------------------------------------------
/spec/stubs/account/create:
--------------------------------------------------------------------------------
1 | HTTP/1.1 201 Created
2 | Status: 201
3 | Content-Type: application/json; charset=utf-8
4 |
5 | {
6 | "id": 1,
7 | "email": "arthur@dent.com",
8 | "domain": null,
9 | "domain_home_page": null,
10 | "private_items": true,
11 | "subscribed": false,
12 | "alpha": false,
13 | "created_at": "2010-12-10T17:07:01Z",
14 | "updated_at": "2010-12-10T17:07:01Z",
15 | "activated_at": null
16 | }
--------------------------------------------------------------------------------
/spec/stubs/gift_card/redeem:
--------------------------------------------------------------------------------
1 | HTTP/1.1 200 OK
2 | Status: 200
3 | Content-Type: application/json; charset=utf-8
4 |
5 | {
6 | "id": 1,
7 | "code": "ABC123",
8 | "plan": "pro",
9 | "months": 12,
10 | "href": "https://my.cl.ly/gift_cards/ABC123",
11 | "created_at": "2011-01-08T20:11:26Z",
12 | "updated_at": "2011-01-08T21:26:26Z",
13 | "redeemed_at": "2011-01-08T21:26:26Z",
14 | "effective_at": "2011-01-10",
15 | "expires_at": "2012-01-10"
16 | }
--------------------------------------------------------------------------------
/spec/stubs/account/update:
--------------------------------------------------------------------------------
1 | HTTP/1.1 200 OK
2 | Status: 200
3 | Content-Type: application/json; charset=utf-8
4 |
5 | {
6 | "id": 1,
7 | "email": "ford@prefect.com",
8 | "domain": "dent.com",
9 | "domain_home_page": "http://hhgproject.org",
10 | "private_items": false,
11 | "subscribed": false,
12 | "alpha": false,
13 | "created_at": "2010-12-10T17:07:01Z",
14 | "updated_at": "2010-12-10T20:33:38Z",
15 | "activated_at": "2010-12-10T17:12:51Z"
16 | }
--------------------------------------------------------------------------------
/spec/stubs/account/show:
--------------------------------------------------------------------------------
1 | HTTP/1.1 200 OK
2 | Status: 200
3 | Content-Type: application/json; charset=utf-8
4 |
5 | {
6 | "id": 1,
7 | "email": "arthur@dent.com",
8 | "domain": null,
9 | "domain_home_page": null,
10 | "private_items": true,
11 | "subscribed": true,
12 | "subscription_expires_at": "2012-05-21",
13 | "alpha": false,
14 | "created_at": "2010-12-10T17:07:01Z",
15 | "updated_at": "2010-12-10T17:12:51Z",
16 | "activated_at": "2010-12-10T17:12:51Z"
17 | }
18 |
--------------------------------------------------------------------------------
/spec/cloudapp_api_spec.rb:
--------------------------------------------------------------------------------
1 | require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2 |
3 | describe CloudApp do
4 |
5 | it "should set correct headers" do
6 | CloudApp::HEADERS['User-Agent'].should == "Ruby.CloudApp.API"
7 | CloudApp::HEADERS['Accept'].should == "application/json"
8 | CloudApp::HEADERS['Content-Type'].should == "application/json"
9 | end
10 |
11 | it "should be authenticatable" do
12 | auth = {
13 | :username => "testuser@test.com",
14 | :password => "password"
15 | }
16 | CloudApp.authenticate(auth[:username], auth[:password]).should == auth
17 | end
18 |
19 | end
20 |
21 |
--------------------------------------------------------------------------------
/Rakefile:
--------------------------------------------------------------------------------
1 | require 'rubygems'
2 | require 'bundler'
3 | begin
4 | Bundler.setup(:default, :development)
5 | rescue Bundler::BundlerError => e
6 | $stderr.puts e.message
7 | $stderr.puts "Run `bundle install` to install missing gems"
8 | exit e.status_code
9 | end
10 | require 'rake'
11 |
12 | Bundler::GemHelper.install_tasks
13 |
14 | require 'rspec/core'
15 | require 'rspec/core/rake_task'
16 | RSpec::Core::RakeTask.new(:spec) do |spec|
17 | spec.pattern = FileList['spec/**/*_spec.rb']
18 | spec.verbose
19 | end
20 |
21 | require 'cucumber/rake/task'
22 | Cucumber::Rake::Task.new(:features)
23 |
24 | task :default => :spec
25 |
26 | require 'yard'
27 | YARD::Rake::YardocTask.new
28 |
--------------------------------------------------------------------------------
/spec/spec_helper.rb:
--------------------------------------------------------------------------------
1 | $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2 | $LOAD_PATH.unshift(File.dirname(__FILE__))
3 | require 'rspec'
4 | require 'fakeweb_helper.rb'
5 | require 'cloudapp_api'
6 | require 'coveralls'
7 | Coveralls.wear!
8 |
9 | # Requires supporting files with custom matchers and macros, etc,
10 | # in ./support/ and its subdirectories.
11 | Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
12 |
13 | RSpec.configure do |config|
14 | config.color_enabled = true
15 |
16 | config.before :suite do
17 | FakeWeb.allow_net_connect = false
18 | end
19 |
20 | config.after :suite do
21 | FakeWeb.allow_net_connect = true
22 | end
23 | end
24 |
--------------------------------------------------------------------------------
/spec/stubs/drop/update:
--------------------------------------------------------------------------------
1 | HTTP/1.1 200 OK
2 | Status: 200
3 | Content-Type: application/json; charset=utf-8
4 |
5 | {
6 | "href": "http://my.cl.ly/items/1912565",
7 | "name": "CloudApp",
8 | "private": false,
9 | "url": "http://cl.ly/2wt6",
10 | "content_url": "http://cl.ly/2wt6/content",
11 | "item_type": "bookmark",
12 | "view_counter": 0,
13 | "icon": "http://my.cl.ly/images/item_types/bookmark.png",
14 | "remote_url": null,
15 | "redirect_url": "http://getcloudapp.com",
16 | "source": "Cloud/1.5.1 CFNetwork/520.0.13 Darwin/11.0.0 (x86_64) (MacBookPro5%2C5)",
17 | "created_at": "2010-10-23T21:15:21Z",
18 | "updated_at": "2010-10-23T21:17:04Z",
19 | "deleted_at": null
20 | }
21 |
--------------------------------------------------------------------------------
/spec/stubs/drop/delete:
--------------------------------------------------------------------------------
1 | HTTP/1.1 200 OK
2 | Status: 200
3 | Content-Type: application/json; charset=utf-8
4 |
5 | {
6 | "href": "http://my.cl.ly/items/1912565",
7 | "name": "CloudApp",
8 | "private": false,
9 | "url": "http://cl.ly/2wt6",
10 | "content_url": "http://cl.ly/2wt6/content",
11 | "item_type": "bookmark",
12 | "view_counter": 0,
13 | "icon": "http://my.cl.ly/images/item_types/bookmark.png",
14 | "remote_url": null,
15 | "redirect_url": "http://getcloudapp.com",
16 | "source": "Cloud/1.5.1 CFNetwork/520.0.13 Darwin/11.0.0 (x86_64) (MacBookPro5%2C5)",
17 | "created_at": "2010-10-23T21:15:21Z",
18 | "updated_at": "2010-10-23T21:17:04Z",
19 | "deleted_at": "2010-10-25T14:37:43Z"
20 | }
21 |
--------------------------------------------------------------------------------
/spec/stubs/drop/create:
--------------------------------------------------------------------------------
1 | HTTP/1.1 200 OK
2 | Status: 200
3 | Content-Type: application/json; charset=utf-8
4 |
5 | {
6 | "href": "http://my.cl.ly/items/1912565",
7 | "name": "CloudApp",
8 | "private": true,
9 | "url": "http://cl.ly/4febbfdfb185c63d5e14",
10 | "content_url": "http://cl.ly/4febbfdfb185c63d5e14/content",
11 | "item_type": "bookmark",
12 | "view_counter": 0,
13 | "icon": "http://my.cl.ly/images/item_types/bookmark.png",
14 | "remote_url": null,
15 | "redirect_url": "http://getcloudapp.com",
16 | "source": "Cloud/1.5.1 CFNetwork/520.0.13 Darwin/11.0.0 (x86_64) (MacBookPro5%2C5)",
17 | "created_at": "2010-10-23T19:50:24Z",
18 | "updated_at": "2010-10-23T19:50:39Z",
19 | "deleted_at": null
20 | }
21 |
--------------------------------------------------------------------------------
/spec/stubs/drop/show:
--------------------------------------------------------------------------------
1 | HTTP/1.1 200 OK
2 | Status: 200
3 | Content-Type: application/json; charset=utf-8
4 |
5 | {
6 | "href": "http://my.cl.ly/items/1912559",
7 | "name": "CloudApp Logo.png",
8 | "private": false,
9 | "url": "http://cl.ly/2wr4",
10 | "content_url": "http://cl.ly/2wr4/CloudApp_Logo.png",
11 | "item_type": "image",
12 | "view_counter": 42,
13 | "icon": "http://my.cl.ly/images/item_types/image.png",
14 | "remote_url": "http://f.cl.ly/items/7c7aea1395c3db0aee18/CloudApp%20Logo.png",
15 | "redirect_url": null,
16 | "source": "Cloud/1.5.1 CFNetwork/520.0.13 Darwin/11.0.0 (x86_64) (MacBookPro5%2C5)",
17 | "created_at": "2010-10-23T19:50:13Z",
18 | "updated_at": "2010-10-23T19:50:38Z",
19 | "deleted_at": null
20 | }
21 |
--------------------------------------------------------------------------------
/spec/stubs/drop/show-private:
--------------------------------------------------------------------------------
1 | HTTP/1.1 200 OK
2 | Status: 200
3 | Content-Type: application/json; charset=utf-8
4 |
5 | {
6 | "href": "http://my.cl.ly/items/1912559",
7 | "name": "CloudApp Logo.png",
8 | "private": true,
9 | "url": "http://cl.ly/2wr4",
10 | "content_url": "http://cl.ly/2wr4/CloudApp_Logo.png",
11 | "item_type": "image",
12 | "view_counter": 42,
13 | "icon": "http://my.cl.ly/images/item_types/image.png",
14 | "remote_url": "http://f.cl.ly/items/7c7aea1395c3db0aee18/CloudApp%20Logo.png",
15 | "redirect_url": null,
16 | "source": "Cloud/1.5.1 CFNetwork/520.0.13 Darwin/11.0.0 (x86_64) (MacBookPro5%2C5)",
17 | "created_at": "2010-10-23T19:50:13Z",
18 | "updated_at": "2010-10-23T19:50:38Z",
19 | "deleted_at": null
20 | }
21 |
--------------------------------------------------------------------------------
/spec/stubs/drop/new:
--------------------------------------------------------------------------------
1 | HTTP/1.1 200 OK
2 | Status: 200
3 | Content-Type: application/json; charset=utf-8
4 |
5 | {
6 | "uploads_remaining": 10,
7 | "max_upload_size": 26214400,
8 | "url": "http://f.cl.ly",
9 | "params": {
10 | "AWSAccessKeyId": "AKIAIDPUZISHSBEOFS6Q",
11 | "key": "items/qL/${filename}",
12 | "acl": "public-read",
13 | "success_action_redirect": "http://my.cl.ly/items/s3",
14 | "signature": "2vRWmaSy46WGs0MDUdLHAqjSL8k=",
15 | "policy": "eyJleHBpcmF0aW9uIjoiMjAxMC0wNC0wMVQwMDowMDowMFoiLCJjb25kaXRpb25zIjpbeyJidWNrZXQiOiJsaW5lYnJlYWstdGVzdCJ9LHsiYWNsIjoicHVibGljLXJlYWQifSx7InN1Y2Nlc3NfYWN0aW9uX3JlZGlyZWN0IjoiaHR0cDovL215LmNsb3VkYXBwLmxvY2FsL3VwbG9hZHMvczMifSxbInN0YXJ0cy13aXRoIiwiJGtleSIsInVwbG9hZHMvcUwvIl1dfQ=="
16 | }
17 | }
--------------------------------------------------------------------------------
/spec/stubs/drop/new-private:
--------------------------------------------------------------------------------
1 | HTTP/1.1 200 OK
2 | Status: 200
3 | Content-Type: application/json; charset=utf-8
4 |
5 | {
6 | "uploads_remaining": 10,
7 | "max_upload_size": 26214400,
8 | "url": "http://f.cl.ly",
9 | "params": {
10 | "AWSAccessKeyId": "AKIAIDPUZISHSBEOFS6Q",
11 | "key": "items/qL/${filename}",
12 | "acl": "public-read",
13 | "success_action_redirect": "http://my.cl.ly/items/s3?item[private]=true",
14 | "signature": "2vRWmaSy46WGs0MDUdLHAqjSL8k=",
15 | "policy": "eyJleHBpcmF0aW9uIjoiMjAxMC0wNC0wMVQwMDowMDowMFoiLCJjb25kaXRpb25zIjpbeyJidWNrZXQiOiJsaW5lYnJlYWstdGVzdCJ9LHsiYWNsIjoicHVibGljLXJlYWQifSx7InN1Y2Nlc3NfYWN0aW9uX3JlZGlyZWN0IjoiaHR0cDovL215LmNsb3VkYXBwLmxvY2FsL3VwbG9hZHMvczMifSxbInN0YXJ0cy13aXRoIiwiJGtleSIsInVwbG9hZHMvcUwvIl1dfQ=="
16 | }
17 | }
--------------------------------------------------------------------------------
/spec/stubs/error/404-update:
--------------------------------------------------------------------------------
1 | HTTP/1.1 404 Not Found
2 | Status: 404
3 | Content-Type: text/html; charset=utf-8
4 |
5 |
6 |
7 |
8 | The page you were looking for doesn't exist (404)
9 |
21 |
22 |
23 |
24 |
25 |
26 |
The page you were looking for doesn't exist.
27 |
You may have mistyped the address or the page may have moved.
28 |
29 |
30 |
--------------------------------------------------------------------------------
/lib/cloudapp_api.rb:
--------------------------------------------------------------------------------
1 | require "httparty"
2 | require "yaml" unless defined?(YAML)
3 | YAML::ENGINE.yamler = "syck" if defined?(YAML::ENGINE) && RUBY_VERSION < "2.0.0"
4 |
5 | ["base", "drop", "account", "gift_card", "client", "multipart", "httparty", "core_ext", "response_error"].each do |inc|
6 | require File.join(File.dirname(__FILE__), "cloudapp", inc)
7 | end
8 |
9 | # A simple Ruby wrapper for the CloudApp API. Uses HTTParty and provides
10 | # two alternative interfaces for interracting with the API.
11 | # An ActiveResource-like interface is provided alongside a simple client interface.
12 | module CloudApp
13 |
14 | # Version number
15 | VERSION = "0.3.1"
16 |
17 | # Sets the authentication credentials in a class variable
18 | #
19 | # @param [String] email cl.ly username
20 | # @param [String] password cl.ly password
21 | # @return [Hash] authentication credentials
22 | def CloudApp.authenticate(email, password)
23 | Base.authenticate(email, password)
24 | end
25 |
26 | end
27 |
--------------------------------------------------------------------------------
/lib/cloudapp/httparty.rb:
--------------------------------------------------------------------------------
1 | require "json"
2 |
3 | module HTTParty #:nodoc:
4 |
5 | class Response < ::BasicObject #:nodoc:
6 | def ok?
7 | [200, 201, 202].include?(self.code)
8 | end
9 | end
10 |
11 | class Request #:nodoc:
12 |
13 | private
14 |
15 | def body
16 | options[:body].is_a?(Hash) ? options[:body].to_json : options[:body]
17 | end
18 |
19 | def setup_raw_request
20 | # This is a cloudapp hack to ensure the correct headers are set on redirect from S3
21 | if @redirect
22 | options[:headers] = CloudApp::HEADERS
23 | options[:query] = {}
24 | options[:body] = {}
25 | end
26 | @raw_request = http_method.new(uri.request_uri)
27 | @raw_request.body = body if body
28 | @raw_request.initialize_http_header(options[:headers])
29 | @raw_request.basic_auth(username, password) if options[:basic_auth]
30 | setup_digest_auth if options[:digest_auth]
31 | end
32 |
33 | end
34 |
35 | end
36 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2010 Aaron Russell
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining
4 | a copy of this software and associated documentation files (the
5 | "Software"), to deal in the Software without restriction, including
6 | without limitation the rights to use, copy, modify, merge, publish,
7 | distribute, sublicense, and/or sell copies of the Software, and to
8 | permit persons to whom the Software is furnished to do so, subject to
9 | the following conditions:
10 |
11 | The above copyright notice and this permission notice shall be
12 | included in all copies or substantial portions of the Software.
13 |
14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/lib/cloudapp/response_error.rb:
--------------------------------------------------------------------------------
1 | module CloudApp
2 |
3 | # Error raised on a bad response
4 | class ResponseError < StandardError
5 |
6 | attr_reader :response, :code, :errors
7 |
8 | # Instantiate an instance of CloudApp::ResponseError
9 | #
10 | # Only used internally
11 | #
12 | # @param [HTTParty::Response] res
13 | # @return [CloudApp::ResponseError]
14 | def initialize(res)
15 | @response = res.response
16 | @code = res.code
17 | begin
18 | @errors = parse_errors(res.parsed_response)
19 | rescue JSON::ParserError => ex
20 | @errors = [res.response.body]
21 | end
22 | end
23 |
24 | # Returns error code and message
25 | #
26 | # @return [String]
27 | def to_s
28 | "#{code.to_s} #{response.msg}".strip
29 | end
30 |
31 | private
32 |
33 | def parse_errors(errors)
34 | return case errors
35 | when Hash
36 | errors.collect{|k,v| "#{k}: #{v}"}
37 | when String
38 | [errors]
39 | when Array
40 | errors
41 | else []
42 | end
43 | end
44 |
45 | end
46 |
47 | end
48 |
--------------------------------------------------------------------------------
/Gemfile.lock:
--------------------------------------------------------------------------------
1 | GEM
2 | remote: http://rubygems.org/
3 | specs:
4 | bluecloth (2.2.0)
5 | builder (3.2.2)
6 | colorize (0.5.8)
7 | coveralls (0.6.7)
8 | colorize
9 | multi_json (~> 1.3)
10 | rest-client
11 | simplecov (>= 0.7)
12 | thor
13 | cucumber (1.3.2)
14 | builder (>= 2.1.2)
15 | diff-lcs (>= 1.1.3)
16 | gherkin (~> 2.12.0)
17 | multi_json (~> 1.3)
18 | diff-lcs (1.2.4)
19 | fakeweb (1.3.0)
20 | gherkin (2.12.0)
21 | multi_json (~> 1.3)
22 | httparty (0.13.5)
23 | json (~> 1.8)
24 | multi_xml (>= 0.5.2)
25 | json (1.8.2)
26 | mime-types (1.23)
27 | multi_json (1.7.7)
28 | multi_xml (0.5.5)
29 | rest-client (1.6.7)
30 | mime-types (>= 1.16)
31 | rspec (2.13.0)
32 | rspec-core (~> 2.13.0)
33 | rspec-expectations (~> 2.13.0)
34 | rspec-mocks (~> 2.13.0)
35 | rspec-core (2.13.1)
36 | rspec-expectations (2.13.0)
37 | diff-lcs (>= 1.1.3, < 2.0)
38 | rspec-mocks (2.13.1)
39 | simplecov (0.7.1)
40 | multi_json (~> 1.0)
41 | simplecov-html (~> 0.7.1)
42 | simplecov-html (0.7.1)
43 | thor (0.18.1)
44 | yard (0.8.6.1)
45 |
46 | PLATFORMS
47 | ruby
48 |
49 | DEPENDENCIES
50 | bluecloth
51 | coveralls
52 | cucumber
53 | fakeweb
54 | httparty (~> 0.13.5)
55 | mime-types
56 | rspec
57 | yard
58 |
--------------------------------------------------------------------------------
/lib/cloudapp/multipart.rb:
--------------------------------------------------------------------------------
1 | require "mime/types"
2 |
3 | module CloudApp
4 |
5 | # TODO - Document the Multipart Class
6 | class Multipart #:nodoc:
7 |
8 | EOL = "\r\n" #:nodoc:
9 |
10 | def initialize(params)
11 | @params = params
12 | file = @params.delete(:file)
13 | bound = "--#{boundary}"
14 | @body = bound + EOL
15 | @params.each do |key, val|
16 | @body += create_regular_field(key, val)
17 | @body += EOL + bound + EOL
18 | end
19 | @body += create_file_field(file)
20 | @body += EOL + bound + "--#{EOL}"
21 | end
22 |
23 | def payload #:nodoc:
24 | {
25 | :headers => {"User-Agent" => "Ruby.CloudApp.API",
26 | "Content-Type" => "multipart/form-data; boundary=#{boundary}"},
27 | :body => @body
28 | }
29 | end
30 |
31 | def boundary #:nodoc:
32 | @boundary ||= "#{HEADERS["User-Agent"]}.#{Array.new(16/2) { rand(256) }.pack("C*").unpack("H*").first}"
33 | end
34 |
35 | def create_regular_field(key, val) #:nodoc:
36 | %Q{Content-Disposition: form-data; name="#{key}"} + EOL + EOL + val
37 | end
38 |
39 | def create_file_field(file) #:nodoc:
40 | %Q{Content-Disposition: form-data; name="file"; filename="#{File.basename(file.path)}"} + EOL +
41 | "Content-Type: #{mime_for(file.path)}" + EOL + EOL +
42 | file.read
43 | end
44 |
45 | def mime_for(path) #:nodoc:
46 | (MIME::Types.type_for(path)[0] || MIME::Types["application/octet-stream"][0]).simplified
47 | end
48 |
49 | end
50 |
51 | end
52 |
--------------------------------------------------------------------------------
/lib/cloudapp/gift_card.rb:
--------------------------------------------------------------------------------
1 | module CloudApp
2 |
3 | # An ActiveResource-like interface through which to interract with CloudApp gift cards.
4 | #
5 | #
6 | # @example Gets started by Authenticating
7 | # CloudApp.authenticate "username", "password"
8 | #
9 | # @example Usage via the GiftCard class
10 | # # View gift card details
11 | # @gift = CloudApp::GiftCard.find "ABC123"
12 | #
13 | # # Apply the gift card
14 | # CloudApp::GiftCard.redeem "ABC123"
15 | # # or
16 | # @gift.redeem
17 | #
18 | class GiftCard < Base
19 |
20 | # Get the details of an unredeemed gift card.
21 | #
22 | # Requires authentication.
23 | #
24 | # @param [String] code Gift card code
25 | # @return [CloudApp::GiftCard]
26 | def self.find(code)
27 | res = get "/gift_cards/#{code}", :digest_auth => @@auth
28 | res.ok? ? GiftCard.new(res) : bad_response(res)
29 | end
30 |
31 | # Apply a gift card to the authenticated account.
32 | #
33 | # Requires authentication.
34 | #
35 | # @param [String] code Gift card code
36 | # @return [CloudApp::GiftCard]
37 | def self.redeem(code)
38 | res = put "/gift_cards/#{code}", {:body => {}, :digest_auth => @@auth}
39 | res.ok? ? GiftCard.new(res) : bad_response(res)
40 | end
41 |
42 | attr_reader :id, :code, :plan, :months, :href,
43 | :created_at, :updated_at, :redeemed_at, :effective_at, :expires_at
44 |
45 | # Apply the gift card to the authenticated account.
46 | #
47 | # @return [CloudApp::GiftCard]
48 | def redeem
49 | self.class.redeem code
50 | end
51 |
52 | end
53 |
54 | end
--------------------------------------------------------------------------------
/spec/cloudapp_gift_card_spec.rb:
--------------------------------------------------------------------------------
1 | require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2 |
3 | describe CloudApp::GiftCard do
4 |
5 | before(:each) do
6 | fake_it_all
7 | @gift = CloudApp::GiftCard.find "ABC123"
8 | end
9 |
10 | it "should be a GiftCard object" do
11 | @gift.should be_a_kind_of CloudApp::GiftCard
12 | end
13 |
14 | it "should return an id" do
15 | @gift.id.should == 1
16 | end
17 |
18 | it "should return a code" do
19 | @gift.code.should == "ABC123"
20 | end
21 |
22 | it "should return a plan" do
23 | @gift.plan.should == "pro"
24 | end
25 |
26 | it "should return a months attribute" do
27 | @gift.months.should == 12
28 | end
29 |
30 | it "should return the gift card url" do
31 | @gift.href.should == "https://my.cl.ly/gift_cards/ABC123"
32 | end
33 |
34 | it "should return timestamps" do
35 | @gift.created_at.should be_a_kind_of Time
36 | @gift.updated_at.should be_a_kind_of Time
37 | @gift.redeemed_at.should == nil
38 | @gift.effective_at.should == nil
39 | @gift.expires_at.should == nil
40 | end
41 |
42 | it "should return the raw data hash" do
43 | @gift.data.should be_a_kind_of Hash
44 | @gift.data['code'].should == "ABC123"
45 | end
46 |
47 | end
48 |
49 | describe "Redeem gift card" do
50 |
51 | before(:each) do
52 | fake_it_all
53 | @gift = CloudApp::GiftCard.redeem "ABC123"
54 | end
55 |
56 | it "should be a GiftCard object" do
57 | @gift.should be_a_kind_of CloudApp::GiftCard
58 | end
59 |
60 | it "should have a redeemed at time" do
61 | @gift.redeemed_at.should be_a_kind_of Time
62 | end
63 |
64 | it "should have an effective at date" do
65 | @gift.effective_at.should be_a_kind_of Date
66 | end
67 |
68 | it "should have an expires at date" do
69 | @gift.expires_at.should be_a_kind_of Date
70 | end
71 |
72 | end
73 |
--------------------------------------------------------------------------------
/spec/stubs/drop/index:
--------------------------------------------------------------------------------
1 | HTTP/1.1 200 OK
2 | Status: 200
3 | Content-Type: application/json; charset=utf-8
4 |
5 | [{
6 | "href": "http://my.cl.ly/items/1912729",
7 | "name": "My CloudApp",
8 | "private": true,
9 | "url": "http://cl.ly/40b6ab341aca432a34ee",
10 | "content_url": "http://cl.ly/40b6ab341aca432a34ee/content",
11 | "item_type": "bookmark",
12 | "view_counter": 0,
13 | "icon": "http://my.cl.ly/images/item_types/bookmark.png",
14 | "remote_url": null,
15 | "redirect_url": "http://my.cl.ly",
16 | "source": "Cloud/1.5.1 CFNetwork/520.0.13 Darwin/11.0.0 (x86_64) (MacBookPro5%2C5)",
17 | "created_at": "2010-10-23T20:10:37Z",
18 | "updated_at": "2010-10-23T20:10:41Z",
19 | "deleted_at": null
20 | }, {
21 | "href": "http://my.cl.ly/items/1912565",
22 | "name": "CloudApp",
23 | "private": false,
24 | "url": "http://cl.ly/2wt6",
25 | "content_url": "http://cl.ly/2wt6/content",
26 | "item_type": "bookmark",
27 | "view_counter": 2,
28 | "icon": "http://my.cl.ly/images/item_types/bookmark.png",
29 | "remote_url": null,
30 | "redirect_url": "http://getcloudapp.com",
31 | "source": "Cloud/1.5.1 CFNetwork/520.0.13 Darwin/11.0.0 (x86_64) (MacBookPro5%2C5)",
32 | "created_at": "2010-10-23T19:50:24Z",
33 | "updated_at": "2010-10-23T19:50:39Z",
34 | "deleted_at": null
35 | }, {
36 | "href": "http://my.cl.ly/items/1912559",
37 | "name": "CloudApp Logo.png",
38 | "private": false,
39 | "url": "http://cl.ly/2wr4",
40 | "content_url": "http://cl.ly/2wr4/content",
41 | "item_type": "image",
42 | "view_counter": 2,
43 | "icon": "http://my.cl.ly/images/item_types/image.png",
44 | "remote_url": "http://f.cl.ly/items/7c7aea1395c3db0aee18/CloudApp%20Logo.png",
45 | "redirect_url": null,
46 | "source": "Cloud/1.5.1 CFNetwork/520.0.13 Darwin/11.0.0 (x86_64) (MacBookPro5%2C5)",
47 | "created_at": "2010-10-23T19:50:13Z",
48 | "updated_at": "2010-10-23T19:50:38Z",
49 | "deleted_at": null
50 | }]
51 |
--------------------------------------------------------------------------------
/lib/cloudapp/base.rb:
--------------------------------------------------------------------------------
1 | require "httparty"
2 |
3 | module CloudApp
4 |
5 | # Globally set request headers
6 | HEADERS = {
7 | "User-Agent" => "Ruby.CloudApp.API",
8 | "Accept" => "application/json",
9 | "Content-Type" => "application/json"
10 | }
11 |
12 | # Base class for setting HTTParty configurations globally
13 | class Base
14 |
15 | include HTTParty
16 | base_uri "my.cl.ly"
17 | headers HEADERS
18 | format :json
19 |
20 | # Define empty auth hash
21 | @@auth = {}
22 |
23 | # Sets the authentication credentials in a class variable.
24 | #
25 | # @param [String] email cl.ly email
26 | # @param [String] password cl.ly password
27 | # @return [Hash] authentication credentials
28 | def self.authenticate(email, password)
29 | @@auth = {:username => email, :password => password}
30 | end
31 |
32 | # Examines a bad response and raises an approriate exception
33 | #
34 | # @param [HTTParty::Response] response
35 | def self.bad_response(response)
36 | if response.class == HTTParty::Response
37 | raise ResponseError, response
38 | end
39 | raise StandardError, "Unknown error"
40 | end
41 |
42 | attr_reader :data
43 |
44 | # Create a new CloudApp::Base object.
45 | #
46 | # Only used internally
47 | #
48 | # @param [Hash] attributes
49 | # @return [CloudApp::Base]
50 | def initialize(attributes = {})
51 | @data = attributes
52 | load(@data)
53 | end
54 |
55 | private
56 |
57 | # Sets the attributes for object.
58 | #
59 | # @param [Hash] attributes
60 | def load(attributes = {})
61 | attributes.each do |key, val|
62 | if key =~ /^.*_at$/ and val
63 | # if this is a date/time key and it's not nil, try to parse it first
64 | # as DateTime, then as Date only
65 | begin
66 | dt = DateTime.strptime(val, "%Y-%m-%dT%H:%M:%SZ")
67 | newval = Time.utc(dt.year, dt.month, dt.day, dt.hour, dt.min, dt.sec)
68 | rescue ArgumentError => ex
69 | newval = DateTime.strptime(val, "%Y-%m-%d")
70 | end
71 | self.instance_variable_set("@#{key}", newval)
72 | else
73 | self.instance_variable_set("@#{key}", val)
74 | end
75 | end
76 | end
77 |
78 | end
79 |
80 | end
81 |
--------------------------------------------------------------------------------
/spec/fakeweb_helper.rb:
--------------------------------------------------------------------------------
1 | require 'fakeweb'
2 |
3 | def stub_file(stub)
4 | File.join(File.dirname(__FILE__), 'stubs', stub)
5 | end
6 |
7 | def fake_it_all
8 | FakeWeb.clean_registry
9 | FakeWeb.register_uri :head, %r{http://(my.|f.)?cl.ly(/items)?}, :status => ["200", "OK"]
10 | FakeWeb.register_uri :post, 'http://f.cl.ly', :status => ["303"], :location => "http://my.cl.ly/items/s3"
11 | FakeWeb.register_uri :post, 'http://my.cl.ly/reset', :status => ["200", "OK"]
12 | {
13 | # GET URLs
14 | :get => {
15 | %r{http://cl.ly/\w+} => File.join('drop', 'show'),
16 | 'http://my.cl.ly/items' => File.join('drop', 'index'),
17 | 'http://my.cl.ly/items/new' => File.join('drop', 'new'),
18 | 'http://my.cl.ly/items/new?item[private]=true' => File.join('drop', 'new-private'),
19 | 'http://my.cl.ly/items/s3' => File.join('drop', 'show'),
20 | 'http://my.cl.ly/items/s3?item[private]=true' => File.join('drop', 'show-private'),
21 | 'http://my.cl.ly/account' => File.join('account', 'show'),
22 | 'http://my.cl.ly/account/stats' => File.join('account', 'stats'),
23 | %r{http://my.cl.ly/gift_cards/\w+} => File.join('gift_card', 'show')
24 | },
25 | # POST URLs
26 | :post => {
27 | 'http://my.cl.ly/items' => File.join('drop', 'create'),
28 | 'http://my.cl.ly/register' => File.join('account', 'create')
29 | },
30 | # PUT URLs
31 | :put => {
32 | %r{http://my.cl.ly/items/\d+} => File.join('drop', 'update'),
33 | 'http://my.cl.ly/account' => File.join('account', 'update'),
34 | %r{http://my.cl.ly/gift_cards/\w+} => File.join('gift_card', 'redeem')
35 | },
36 | # DELETE URLs
37 | :delete => {
38 | %r{http://my.cl.ly/items/\d+} => File.join('drop', 'delete')
39 | }
40 | }.
41 | each do |method, requests|
42 | requests.each do |url, response|
43 | FakeWeb.register_uri(method, url, :response => stub_file(response))
44 | end
45 | end
46 | end
47 |
48 | def fake_it_all_with_errors
49 | FakeWeb.clean_registry
50 | FakeWeb.register_uri :head, %r{http://(my.|f.)?cl.ly(/items)?}, :status => ["200", "OK"]
51 | {
52 | :get => {
53 | 'http://my.cl.ly/items' => File.join('error', '401'),
54 | %r{http://cl.ly/\w+} => File.join('error', '404-find'),
55 | 'http://my.cl.ly/items/new' => File.join('drop', 'new')
56 | },
57 | :put => {
58 | %r{http://my.cl.ly/items/\d+} => File.join('error', '404-update')
59 | }
60 | }.each do |method, requests|
61 | requests.each do |url, response|
62 | FakeWeb.register_uri(method, url, :response => stub_file(response))
63 | end
64 | end
65 | end
66 |
--------------------------------------------------------------------------------
/cloudapp_api.gemspec:
--------------------------------------------------------------------------------
1 | # Generated by jeweler
2 | # DO NOT EDIT THIS FILE DIRECTLY
3 | # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4 | # -*- encoding: utf-8 -*-
5 | # stub: cloudapp_api 0.5.0 ruby lib
6 |
7 | Gem::Specification.new do |s|
8 | s.name = "cloudapp_api"
9 | s.version = "0.5.0"
10 |
11 | s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
12 | s.require_paths = ["lib"]
13 | s.authors = ["Aaron Russell"]
14 | s.date = "2015-06-01"
15 | s.description = "A simple Ruby wrapper for the CloudApp API. Uses HTTParty with a simple ActiveResource-like interface."
16 | s.email = "aaron@gc4.co.uk"
17 | s.extra_rdoc_files = [
18 | "LICENSE",
19 | "README.md"
20 | ]
21 | s.files = [
22 | ".document",
23 | ".travis.yml",
24 | "Gemfile",
25 | "Gemfile.lock",
26 | "LICENSE",
27 | "README.md",
28 | "Rakefile",
29 | "VERSION",
30 | "cloudapp_api.gemspec",
31 | "lib/cloudapp/account.rb",
32 | "lib/cloudapp/base.rb",
33 | "lib/cloudapp/client.rb",
34 | "lib/cloudapp/core_ext.rb",
35 | "lib/cloudapp/drop.rb",
36 | "lib/cloudapp/gift_card.rb",
37 | "lib/cloudapp/httparty.rb",
38 | "lib/cloudapp/multipart.rb",
39 | "lib/cloudapp/response_error.rb",
40 | "lib/cloudapp_api.rb",
41 | "spec/cloudapp_account_spec.rb",
42 | "spec/cloudapp_api_spec.rb",
43 | "spec/cloudapp_client_spec.rb",
44 | "spec/cloudapp_drop_spec.rb",
45 | "spec/cloudapp_gift_card_spec.rb",
46 | "spec/cloudapp_item_spec.rb",
47 | "spec/cloudapp_response_error_spec.rb",
48 | "spec/fakeweb_helper.rb",
49 | "spec/spec_helper.rb",
50 | "spec/stubs/account/create",
51 | "spec/stubs/account/show",
52 | "spec/stubs/account/stats",
53 | "spec/stubs/account/update",
54 | "spec/stubs/drop/create",
55 | "spec/stubs/drop/delete",
56 | "spec/stubs/drop/index",
57 | "spec/stubs/drop/new",
58 | "spec/stubs/drop/new-private",
59 | "spec/stubs/drop/show",
60 | "spec/stubs/drop/show-private",
61 | "spec/stubs/drop/update",
62 | "spec/stubs/error/400",
63 | "spec/stubs/error/401",
64 | "spec/stubs/error/404-find",
65 | "spec/stubs/error/404-update",
66 | "spec/stubs/error/422-bookmark",
67 | "spec/stubs/error/422-bookmarks",
68 | "spec/stubs/gift_card/redeem",
69 | "spec/stubs/gift_card/show"
70 | ]
71 | s.homepage = "http://github.com/aaronrussell/cloudapp_api"
72 | s.rubygems_version = "2.4.4"
73 | s.summary = "A simple Ruby wrapper for the CloudApp API. Uses HTTParty with a simple ActiveResource-like interface."
74 |
75 | s.add_runtime_dependency 'httparty', "~> 0.13.5"
76 | s.add_runtime_dependency 'mime-types', ">= 1.16"
77 | s.add_development_dependency 'rspec', "~> 2.13.0"
78 | s.add_development_dependency 'coveralls', "~> 0.6.7"
79 | s.add_development_dependency 'fakeweb', "~> 1.3.0"
80 | s.add_development_dependency 'yard', "~> 0.8.6.1"
81 | s.add_development_dependency 'bluecloth', "~> 2.2.0"
82 | s.add_development_dependency 'cucumber', "~> 1.3.2"
83 | end
84 |
85 |
--------------------------------------------------------------------------------
/spec/cloudapp_client_spec.rb:
--------------------------------------------------------------------------------
1 | require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2 |
3 | describe CloudApp::Client do
4 |
5 | before(:each) do
6 | fake_it_all
7 | CloudApp.authenticate "testuser@test.com", "password"
8 | @client = CloudApp::Client.new
9 | end
10 |
11 | it "should be reautheticatable" do
12 | username = "joe.bloggs@testing.com"
13 | password = "password"
14 | auth = @client.authenticate username, password
15 | auth[:username].should == username
16 | end
17 |
18 | it "should find an drop" do
19 | drop = @client.drop "2wr4"
20 | drop.should be_a_kind_of CloudApp::Drop
21 | end
22 |
23 | it "should list all drops" do
24 | drops = @client.drops
25 | drops.should be_a_kind_of Array
26 | drops.each do |drop|
27 | drop.should be_a_kind_of CloudApp::Drop
28 | end
29 | end
30 |
31 | it "should bookmark an drop" do
32 | name = "CloudApp"
33 | drop = @client.bookmark "http://getcloudapp.com", name
34 | drop.should be_a_kind_of CloudApp::Drop
35 | drop.name.should == name
36 | end
37 |
38 | it "should bookmark multiple drops" do
39 | # overwrite the normal fake uri for this spec
40 | FakeWeb.register_uri :post, 'http://my.cl.ly/items', :response => stub_file(File.join('drop', 'index'))
41 | bookmarks = [
42 | { :name => "Authur Dent", :redirect_url => "http://en.wikipedia.org/wiki/Arthur_Dent" },
43 | { :name => "Ford Prefect", :redirect_url => "http://en.wikipedia.org/wiki/Ford_Prefect_(character)"},
44 | { :name => "Zaphod Beeblebrox", :redirect_url => "http://en.wikipedia.org/wiki/Zaphod_Beeblebrox" }
45 | ]
46 | drops = @client.bookmark bookmarks
47 | drops.should be_a_kind_of Array
48 | drops.each do |drop|
49 | drop.should be_a_kind_of CloudApp::Drop
50 | end
51 | end
52 |
53 | it "should upload a file" do
54 | drop = @client.upload "README.md"
55 | drop.should be_a_kind_of CloudApp::Drop
56 | drop.item_type.should == "image"
57 | end
58 |
59 | it "should upload a file with specific privacy" do
60 | # override the upload fakeweb uri
61 | FakeWeb.register_uri :post, 'http://f.cl.ly', :status => ["303"], :location => "http://my.cl.ly/items/s3?item[private]=true"
62 | drop = @client.upload "README.md", :private => true
63 | drop.should be_a_kind_of CloudApp::Drop
64 | drop.private.should == true
65 | end
66 |
67 | it "should rename an drop" do
68 | name = "CloudApp"
69 | drop = @client.rename "2wr4", name
70 | drop.should be_a_kind_of CloudApp::Drop
71 | drop.name.should == name
72 | end
73 |
74 | it "should set an drops privacy" do
75 | drop = @client.privacy "2wr4", false
76 | drop.should be_a_kind_of CloudApp::Drop
77 | drop.private.should == false
78 | end
79 |
80 | it "should delete an drop" do
81 | drop = @client.delete "2wr4"
82 | drop.should be_a_kind_of CloudApp::Drop
83 | drop.deleted_at.should be_a_kind_of Time
84 | end
85 |
86 | it "should recover an drop" do
87 | drop = @client.recover "2wr4"
88 | drop.should be_a_kind_of CloudApp::Drop
89 | drop.deleted_at.should == nil
90 | end
91 |
92 | end
93 |
--------------------------------------------------------------------------------
/spec/cloudapp_response_error_spec.rb:
--------------------------------------------------------------------------------
1 | require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2 |
3 | describe CloudApp::ResponseError, "when not logged in" do
4 |
5 | before(:each) do
6 | fake_it_all_with_errors
7 | @error = lambda { CloudApp::Drop.all }
8 | end
9 |
10 | it "should raise a 401" do
11 | @error.should raise_error(CloudApp::ResponseError, "401 Unauthorized")
12 | end
13 |
14 | it "should return a code and error messages" do
15 | @error.should raise_error{|e|
16 | e.code.should == 401
17 | e.errors[0].should == "HTTP Digest: \"Access denied.\""
18 | }
19 | end
20 |
21 | end
22 |
23 |
24 | describe CloudApp::ResponseError, "when item doesn't exist" do
25 |
26 | before(:each) do
27 | fake_it_all_with_errors
28 | @error = lambda { CloudApp::Drop.find "12345" }
29 | end
30 |
31 | it "should raise a 404" do
32 | @error.should raise_error(CloudApp::ResponseError, "404 Not Found")
33 | end
34 |
35 | it "should return a code and error messages" do
36 | @error.should raise_error{|e|
37 | e.code.should == 404
38 | e.errors[0].should == "Not Found
"
39 | }
40 | end
41 |
42 | end
43 |
44 |
45 | describe CloudApp::ResponseError, "when updating someone elses item" do
46 |
47 | before(:each) do
48 | fake_it_all_with_errors
49 | @error = lambda { CloudApp::Drop.update "http://my.cl.ly/items/12345" }
50 | end
51 |
52 | it "should raise a 404" do
53 | @error.should raise_error(CloudApp::ResponseError, "404 Not Found")
54 | end
55 |
56 | it "should return a code and error messages" do
57 | @error.should raise_error{|e|
58 | e.code.should == 404
59 | }
60 | end
61 |
62 | end
63 |
64 |
65 | describe "when recovering an unrecoverable item" do
66 |
67 | before(:each) do
68 | fake_it_all_with_errors
69 | @error = lambda { CloudApp::Drop.recover "http://my.cl.ly/items/12345" }
70 | end
71 |
72 | it "should raise a 404" do
73 | @error.should raise_error(CloudApp::ResponseError, "404 Not Found")
74 | end
75 |
76 | it "should return a code and error messages" do
77 | @error.should raise_error{|e|
78 | e.code.should == 404
79 | }
80 | end
81 |
82 | end
83 |
84 |
85 | describe CloudApp::ResponseError, "badly formatted bookmark" do
86 |
87 | before(:each) do
88 | fake_it_all_with_errors
89 | FakeWeb.register_uri :post, 'http://my.cl.ly/items', :response => stub_file(File.join('error', '422-bookmark'))
90 | CloudApp.authenticate "testuser@test.com", "password"
91 | @error = lambda { CloudApp::Drop.create :bookmark }
92 | end
93 |
94 | it "should raise a 422" do
95 | @error.should raise_error(CloudApp::ResponseError, "422")
96 | end
97 |
98 | it "should return an array of error messages" do
99 | @error.should raise_error{|e|
100 | e.errors.should be_a_kind_of(Array)
101 | e.errors[0].should == "URL can't be blank"
102 | }
103 | end
104 |
105 | end
106 |
107 |
108 | describe CloudApp::ResponseError, "badly formatted bookmarks" do
109 |
110 | before(:each) do
111 | fake_it_all_with_errors
112 | FakeWeb.register_uri :post, 'http://my.cl.ly/items', :response => stub_file(File.join('error', '422-bookmarks'))
113 | CloudApp.authenticate "testuser@test.com", "password"
114 | @error = lambda { CloudApp::Drop.create :bookmarks, [{}] }
115 | end
116 |
117 | it "should raise a 422" do
118 | @error.should raise_error(CloudApp::ResponseError, "422")
119 | end
120 |
121 | it "should return a nested array of error messages" do
122 | @error.should raise_error{|e|
123 | e.errors.should be_a_kind_of(Array)
124 | e.errors[0].should be_a_kind_of(Array)
125 | e.errors[0][0].should == "URL can't be blank"
126 | }
127 | end
128 |
129 | end
130 |
131 |
--------------------------------------------------------------------------------
/spec/cloudapp_account_spec.rb:
--------------------------------------------------------------------------------
1 | require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2 |
3 | describe CloudApp::Account do
4 |
5 | before(:each) do
6 | fake_it_all
7 | CloudApp.authenticate "testuser@test.com", "password"
8 | @account = CloudApp::Account.find
9 | end
10 |
11 | it "should be a Account object" do
12 | @account.should be_a_kind_of CloudApp::Account
13 | end
14 |
15 | it "should return an id" do
16 | @account.id.should == 1
17 | end
18 |
19 | it "should return an email" do
20 | @account.email.should == "arthur@dent.com"
21 | end
22 |
23 | it "should return a blank domain" do
24 | @account.domain.should == nil
25 | end
26 |
27 | it "should return a blank domain home page" do
28 | @account.domain_home_page.should == nil
29 | end
30 |
31 | it "should return a private items booleans" do
32 | @account.private_items.should == true
33 | end
34 |
35 | it "should return a subscribed boolean" do
36 | @account.subscribed.should == true
37 | end
38 |
39 | it "should return a subscription expiration date" do
40 | @account.subscription_expires_at == "2012-05-21"
41 | end
42 |
43 | it "should return a alpha boolean" do
44 | @account.alpha.should == false
45 | end
46 |
47 | it "should return timestamps" do
48 | @account.created_at.should be_a_kind_of Time
49 | @account.updated_at.should be_a_kind_of Time
50 | @account.activated_at.should be_a_kind_of Time
51 | end
52 |
53 | it "should return the raw data hash" do
54 | @account.data.should be_a_kind_of Hash
55 | @account.data['email'].should == "arthur@dent.com"
56 | end
57 |
58 | end
59 |
60 |
61 | describe "Change default security" do
62 |
63 | before(:each) do
64 | fake_it_all
65 | CloudApp.authenticate "testuser@test.com", "password"
66 | @account = CloudApp::Account.update :private_items => false
67 | end
68 |
69 | it "should be a Account object" do
70 | @account.should be_a_kind_of CloudApp::Account
71 | end
72 |
73 | it "should have private items set to false" do
74 | @account.private_items.should == false
75 | end
76 |
77 | end
78 |
79 |
80 | describe "Change email" do
81 |
82 | before(:each) do
83 | fake_it_all
84 | CloudApp.authenticate "testuser@test.com", "password"
85 | @email = "ford@prefect.com"
86 | @account = CloudApp::Account.update :email => @email, :current_password => "towel"
87 | end
88 |
89 | it "should be a Account object" do
90 | @account.should be_a_kind_of CloudApp::Account
91 | end
92 |
93 | it "should have the new email address" do
94 | @account.email.should == @email
95 | end
96 |
97 | end
98 |
99 |
100 | describe "Change password" do
101 |
102 | before(:each) do
103 | fake_it_all
104 | CloudApp.authenticate "testuser@test.com", "password"
105 | @account = CloudApp::Account.update :password => "hoopy frood", :current_password => "towel"
106 | end
107 |
108 | it "should be a Account object" do
109 | @account.should be_a_kind_of CloudApp::Account
110 | end
111 |
112 | end
113 |
114 |
115 | describe "Reset password" do
116 |
117 | before(:each) do
118 | fake_it_all
119 | @response = CloudApp::Account.reset :email => "arthur@dent.com"
120 | end
121 |
122 | it "should return true" do
123 | @response.should == true
124 | end
125 |
126 | end
127 |
128 |
129 | describe "Register account" do
130 |
131 | before(:each) do
132 | fake_it_all
133 | @email = "arthur@dent.com"
134 | @account = CloudApp::Account.create :email => @email, :current_password => "towel", :accept_tos => true
135 | end
136 |
137 | it "should be a Account object" do
138 | @account.should be_a_kind_of CloudApp::Account
139 | end
140 |
141 | it "should have the same email" do
142 | @account.email.should == @email
143 | end
144 |
145 | end
146 |
147 |
148 | describe "Set custom domain" do
149 |
150 | before(:each) do
151 | fake_it_all
152 | CloudApp.authenticate "testuser@test.com", "password"
153 | @domain = "dent.com"
154 | @dhp = "http://hhgproject.org"
155 | @account = CloudApp::Account.update :domain => @domain, :domain_home_page => @dhp
156 | end
157 |
158 | it "should be a Account object" do
159 | @account.should be_a_kind_of CloudApp::Account
160 | end
161 |
162 | it "should have the same domain" do
163 | @account.domain.should == @domain
164 | end
165 |
166 | it "should have the same domain home page" do
167 | @account.domain_home_page.should == @dhp
168 | end
169 |
170 | end
171 |
172 |
173 | describe "View account statistics" do
174 |
175 | before(:each) do
176 | fake_it_all
177 | CloudApp.authenticate "testuser@test.com", "password"
178 | @account = CloudApp::Account.find
179 | @stats = @account.stats
180 | end
181 |
182 | it "should be a Hash object" do
183 | @stats.should be_a_kind_of Hash
184 | end
185 |
186 | it "should have a number of items" do
187 | @stats[:items].should be_true
188 | @stats[:items].should be_a_kind_of Integer
189 | end
190 |
191 | it "should have a number of views" do
192 | @stats[:views].should be_true
193 | @stats[:views].should be_a_kind_of Integer
194 | end
195 |
196 | end
197 |
--------------------------------------------------------------------------------
/lib/cloudapp/client.rb:
--------------------------------------------------------------------------------
1 | module CloudApp
2 |
3 | # A client interface through which to interract with the CloudApp API.
4 | #
5 | # @example Creating a client instance and set authentication credentials
6 | # @client = CloudApp::Client.new
7 | # @client.authenticate "username", "password"
8 | #
9 | # @example Creating editing and deleting drops
10 | # # Find a single drop by it's slug
11 | # drop = @client.drop "2wr4"
12 | #
13 | # # Get a list of all drops
14 | # drops = @client.all
15 | #
16 | # # Create a new bookmark
17 | # drop = @client.bookmark "http://getcloudapp.com", "CloudApp"
18 | #
19 | # # Create multiple new bookmarks
20 | # bookmarks = [
21 | # { :name => "Authur Dent", :redirect_url => "http://en.wikipedia.org/wiki/Arthur_Dent" },
22 | # { :name => "Zaphod Beeblebrox", :redirect_url => "http://en.wikipedia.org/wiki/Zaphod_Beeblebrox" }
23 | # ]
24 | # drops = @client.bookmark bookmarks
25 | #
26 | # # Upload a file
27 | # drop = @client.upload "/path/to/image.png"
28 | # drop = @client.upload "/path/to/image.png", :private => true
29 | #
30 | # # Rename a file
31 | # @client.rename "2wr4", "Big Screenshot"
32 | #
33 | # # Set a drop's privacy
34 | # @client.privacy "2wr4", true
35 | #
36 | # # Delete an drop
37 | # @client.delete "2wr4"
38 | #
39 | # # Recover a deleted drop
40 | # @client.recover "2wr4"
41 | #
42 | class Client
43 |
44 | # Creates a new CloudApp::Client instance.
45 | #
46 | # You can pass +:username+ and +:password+ parameters to the call.
47 | #
48 | # @param [Hash] opts authentication credentials.
49 | # @option opts [String] :username cl.ly username
50 | # @option opts [String] :password cl.ly username
51 | # @return [CloudApp::Client]
52 | def initialize(opts = {})
53 | if opts[:username] && opts[:password]
54 | Base.authenticate(opts[:username], opts[:password])
55 | end
56 | end
57 |
58 | # Sets the authentication credentials in a class variable.
59 | #
60 | # @param [String] username cl.ly username
61 | # @param [String] password cl.ly password
62 | # @return [Hash] authentication credentials
63 | def authenticate(username, password)
64 | Base.authenticate(username, password)
65 | end
66 |
67 | # Get metadata about a cl.ly URL like name, type, or view count.
68 | #
69 | # Finds the drop by it's slug id, for example "2wr4".
70 | #
71 | # @param [String] id cl.ly slug id
72 | # @return [CloudApp::Drop]
73 | def drop(id)
74 | Drop.find(id)
75 | end
76 |
77 | alias_method :item, :drop
78 |
79 | # Page through your drops.
80 | #
81 | # Requires authentication.
82 | #
83 | # @param [Hash] opts options parameters
84 | # @option opts [Integer] :page (1) Page number starting at 1
85 | # @option opts [Integer] :per_page (5) Number of items per page
86 | # @option opts [String] :type ('image') Filter items by type (image, bookmark, text, archive, audio, video, or unknown)
87 | # @option opts [Boolean] :deleted (true) Show trashed drops
88 | # @return [Array[CloudApp::Drop]]
89 | def drops(opts = {})
90 | Drop.all(opts)
91 | end
92 |
93 | alias_method :items, :drops
94 |
95 | # Create one or more new bookmark drops.
96 | #
97 | # Requires authentication.
98 | #
99 | # @overload bookmark(url, name = "")
100 | # @param [String] url url to bookmark
101 | # @param [String] name name of bookmark
102 | # @overload bookmark(opts)
103 | # @param [Array] opts array of bookmark option parameters (containing +:name+ and +:redirect_url+)
104 | # @return [CloudApp::Drop]
105 | def bookmark(*args)
106 | if args[0].is_a? Array
107 | Drop.create(:bookmarks, args)
108 | else
109 | url, name = args[0], (args[1] || "")
110 | Drop.create(:bookmark, {:name => name, :redirect_url => url})
111 | end
112 | end
113 |
114 | # Create a new drop by uploading a file.
115 | #
116 | # Requires authentication.
117 | #
118 | # @param [String] file local path to file
119 | # @param [optional, Hash] opts options paramaters
120 | # @option opts [Boolean] :private override the account default privacy setting
121 | # @return [CloudApp::Drop]
122 | def upload(file, opts = {})
123 | Drop.create(:upload, opts.merge(:file => file))
124 | end
125 |
126 | # Change the name of the drop.
127 | #
128 | # Finds the drop by it's slug id, for example "2wr4".
129 | #
130 | # Requires authentication.
131 | #
132 | # @param [String] id drop id
133 | # @param [String] name new drop name
134 | # @return [CloudApp::Drop]
135 | def rename(id, name = "")
136 | drop = Drop.find(id)
137 | drop.update(:name => name)
138 | end
139 |
140 | # Modify a drop with a private URL to have a public URL or vice versa.
141 | #
142 | # Finds the drop by it's slug id, for example "2wr4".
143 | #
144 | # Requires authentication.
145 | #
146 | # @param [String] id drop id
147 | # @param [Boolean] privacy privacy setting
148 | # @return [CloudApp::Drop]
149 | def privacy(id, privacy = false)
150 | drop = Drop.find(id)
151 | drop.update(:private => privacy)
152 | end
153 |
154 | # Send the drop to the trash.
155 | #
156 | # Finds the drop by it's slug id, for example "2wr4".
157 | #
158 | # Requires authentication.
159 | #
160 | # @param [String] id drop id
161 | # @return [CloudApp::Drop]
162 | def delete(id)
163 | drop = Drop.find(id)
164 | drop.delete
165 | end
166 |
167 | # Recover a deleted drop from the trash.
168 | #
169 | # Finds the drop by it's slug id, for example "2wr4".
170 | #
171 | # Requires authentication.
172 | #
173 | # @param [String] id drop id
174 | # @return [CloudApp::Drop]
175 | def recover(id)
176 | drop = Drop.find(id)
177 | drop.recover
178 | end
179 |
180 | end
181 |
182 | end
183 |
--------------------------------------------------------------------------------
/lib/cloudapp/account.rb:
--------------------------------------------------------------------------------
1 | module CloudApp
2 |
3 | # An ActiveResource-like interface through which to interract with CloudApp accounts.
4 | #
5 | # @example Create a CloudApp account
6 | # CloudApp::Account.create :email => "arthur@dent.com", :password => "towel"
7 | #
8 | # @example Most other account actions require authentication first
9 | # CloudApp.authenticate "username", "password"
10 | #
11 | # @example Usage via the Account class
12 | # # View account details
13 | # @account = CloudApp::Account.find
14 | #
15 | # # Change default security
16 | # CloudApp::Account.update :private_items => false
17 | #
18 | # # Change email
19 | # CloudApp::Account.update :email => "ford@prefect.com", :current_password => "towel"
20 | #
21 | # # Change password
22 | # CloudApp::Account.update :password => "happy frood", :current_password => "towel"
23 | #
24 | # # Set custom domain
25 | # CloudApp::Account.update :domain => "dent.com", :domain_home_page => "http://hhgproject.org"
26 | #
27 | # # Forgot password
28 | # CloudApp::Account.reset :email => "arthur@dent.com"
29 | #
30 | # # View account stats
31 | # CloudApp::Account.stats
32 | #
33 | # @example Usage via the class instance
34 | # # Change default security
35 | # @account.update :private_items => false
36 | #
37 | # # Change email
38 | # @account.update :email => "ford@prefect.com", :current_password => "towel"
39 | #
40 | # # Change password
41 | # @account.update :password => "happy frood", :current_password => "towel"
42 | #
43 | # # Set custom domain
44 | # @account.update :domain => "dent.com", :domain_home_page => "http://hhgproject.org"
45 | #
46 | # # Forgot password
47 | # @account.reset
48 | #
49 | # # View account stats
50 | # @account.stats
51 | #
52 | class Account < Base
53 |
54 | # Get the basic details of the authenticated account.
55 | #
56 | # Requires authentication.
57 | #
58 | # @return [CloudApp::Account]
59 | def self.find
60 | res = get "/account", :digest_auth => @@auth
61 | res.ok? ? Account.new(res) : bad_response(res)
62 | end
63 |
64 | # Create a CloudApp account.
65 | #
66 | # @param [Hash] opts options parameters
67 | # @option opts [String] :email Account email address
68 | # @option opts [String] :password Account password
69 | # @option opts [Boolean] :accept_tos Accept CloudApp terms of service
70 | # @return [CloudApp::Account]
71 | def self.create(opts = {})
72 | res = post "/register", :body => {:user => opts}
73 | res.ok? ? Account.new(res) : bad_response(res)
74 | end
75 |
76 | # Modify the authenticated accounts details. Can change the default security of newly
77 | # created drops, the accounts email address, password, and custom domain details.
78 | #
79 | # Note that when changing email address or password, the current password is required.
80 | # Also note that to change custom domains requires an account with a Pro subscription.
81 | #
82 | # Requires authentication
83 | #
84 | # @param [Hash] opts options parameters
85 | # @option opts [Boolean] :private_items Change default security of new drops
86 | # @option opts [String] :email Change email address
87 | # @option opts [String] :password Change password
88 | # @option opts [String] :current_password Current account password
89 | # @option opts [String] :domain Set custom domain
90 | # @option opts [String] :domain_home_page URL to redirect visitors to custom domain's root
91 | # @return [CloudApp::Account]
92 | def self.update(opts = {})
93 | res = put "/account", {:body => {:user => opts}, :digest_auth => @@auth}
94 | res.ok? ? Account.new(res) : bad_response(res)
95 | end
96 |
97 | # Dispatch an email containing a link to reset the account's password.
98 | #
99 | # @param [Hash] opts options parameters
100 | # @option opts [String] :email Account email address
101 | # @return [Boolean]
102 | def self.reset(opts = {})
103 | res = post "/reset", :body => {:user => opts}
104 | res.ok? ? true : bad_response(res)
105 | end
106 |
107 | # Get the total number of drops created and total views for all drops.
108 | #
109 | # Requires authentication.
110 | #
111 | # @return [Hash]
112 | def self.stats
113 | res = get "/account/stats", :digest_auth => @@auth
114 | res.ok? ? res.symbolize_keys! : bad_response(res)
115 | end
116 |
117 | attr_reader :id, :email, :domain, :domain_home_page, :private_items,
118 | :subscribed, :subscription_expires_at, :alpha,
119 | :created_at, :updated_at, :activated_at
120 |
121 | # Modify the authenticated accounts details. Can change the default security of newly
122 | # created drops, the accounts email address, password, and custom domain details.
123 | #
124 | # Note that when changing email address or password, the current password is required.
125 | # Also note that to change custom domains requires an account with a Pro subscription.
126 | #
127 | # @param [Hash] opts options parameters
128 | # @option opts [Boolean] :private_items Change default security of new drops
129 | # @option opts [String] :email Change email address
130 | # @option opts [String] :password Change password
131 | # @option opts [String] :current_password Current account password
132 | # @option opts [String] :domain Set custom domain
133 | # @option opts [String] :domain_home_page URL to redirect visitors to custom domain's root
134 | # @return [CloudApp::Account]
135 | def update(opts = {})
136 | self.class.update opts
137 | end
138 |
139 | # Dispatch an email containing a link to reset the account's password.
140 | #
141 | # @param [Hash] opts options parameters
142 | # @option opts [String] :email Account email address
143 | # @return [Boolean]
144 | def reset
145 | self.class.reset :email => self.email
146 | end
147 |
148 | # Get the total number of drops created and total views for all drops.
149 | #
150 | # @return [Hash]
151 | def stats
152 | self.class.stats
153 | end
154 |
155 | end
156 |
157 | end
158 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # CloudApp API
2 |
3 | [](https://travis-ci.org/aaronrussell/cloudapp_api)
4 | [](https://codeclimate.com/github/aaronrussell/cloudapp_api)
5 | [](https://coveralls.io/r/aaronrussell/cloudapp_api)
6 |
7 | A simple Ruby wrapper for the [CloudApp API](http://support.getcloudapp.com/faqs/developers/api). Uses [HTTParty](http://github.com/jnunemaker/httparty) with a simple ActiveResource-like interface.
8 |
9 | Two interfaces are provided for interacting with the CloudApp API. The first is a ActiveResource-like interface, directly calling methods on the Drop and Account classes. The second option is to interact through a Client interface.
10 |
11 | * [Familiarise yourself with the documentation](http://rubydoc.info/github/aaronrussell/cloudapp_api/)
12 |
13 | ## Installation
14 |
15 | To install as a Gem:
16 |
17 | sudo gem install cloudapp_api
18 |
19 | **(Version 0.5.0 ends compaitibility with Ruby 1.8.7. If you need 1.8.7 support, you can still use version 0.4.0 of this gem.)**
20 |
21 | ## Authentication
22 |
23 | Authentication is necessary for most actions, the only exceptions being when creating a new Account or querying a specific Drop.
24 |
25 | CloudApp.authenticate "email@address.com", "password"
26 |
27 | ## Drops
28 |
29 | * Documentation - {CloudApp::Drop}
30 |
31 | ---
32 |
33 | ### Usage via the Drop class
34 |
35 | # Find a single drop by it's slug
36 | @drop = CloudApp::Drop.find "2wr4"
37 |
38 | # Get a list of all drops
39 | @drops = CloudApp::Drop.all
40 |
41 | # Create a new bookmark
42 | @drop = CloudApp::Drop.create :bookmark, :name => "CloudApp", :redirect_url => "http://getcloudapp.com"
43 |
44 | # Create multiple bookmarks
45 | bookmarks = [
46 | { :name => "Authur Dent", :redirect_url => "http://en.wikipedia.org/wiki/Arthur_Dent" },
47 | { :name => "Zaphod Beeblebrox", :redirect_url => "http://en.wikipedia.org/wiki/Zaphod_Beeblebrox" }
48 | ]
49 | @drops = CloudApp::Drop.create :bookmarks, bookmarks
50 |
51 | # Upload a file
52 | @drop = CloudApp::Drop.create :upload, :file => "/path/to/image.png"
53 | @drop = CloudApp::Drop.create :upload, :file => "/path/to/image.png", :private => true
54 |
55 | # Rename a file
56 | CloudApp::Drop.update "http://my.cl.ly/items/1912565", :name => "Big Screenshot"
57 |
58 | # Set a drop's privacy
59 | CloudApp::Drop.update "http://my.cl.ly/items/1912565", :private => true
60 |
61 | # Delete a drop
62 | CloudApp::Drop.delete "http://my.cl.ly/items/1912565"
63 |
64 | # Recover a deleted drop
65 | CloudApp::Drop.recover "http://my.cl.ly/items/1912565"
66 |
67 | ### Usage via the class instance
68 |
69 | # Rename a file
70 | @drop.update :name => "Big Screenshot"
71 |
72 | # Set the drop's privacy
73 | @drop.update :private => true
74 |
75 | # Delete a drop
76 | @drop.delete
77 |
78 | # Recover a deleted drop
79 | @drop.recover
80 |
81 | ## Drops via a Client instance
82 |
83 | * Documentation - {CloudApp::Client}
84 |
85 | ---
86 |
87 | # Find a single drop by it's slug
88 | drop = @client.drop "2wr4"
89 |
90 | # Get a list of all drops
91 | drops = @client.all
92 |
93 | # Create a new bookmark
94 | drop = @client.bookmark "http://getcloudapp.com", "CloudApp"
95 |
96 | # Create multiple new bookmarks
97 | bookmarks = [
98 | { :name => "Authur Dent", :redirect_url => "http://en.wikipedia.org/wiki/Arthur_Dent" },
99 | { :name => "Zaphod Beeblebrox", :redirect_url => "http://en.wikipedia.org/wiki/Zaphod_Beeblebrox" }
100 | ]
101 | drops = @client.bookmark bookmarks
102 |
103 | # Upload a file
104 | drop = @client.upload "/path/to/image.png"
105 | drop = @client.upload "/path/to/image.png", :private => true
106 |
107 | # Rename a file
108 | @client.rename "2wr4", "Big Screenshot"
109 |
110 | # Set a drop's privacy
111 | @client.privacy "2wr4", true
112 |
113 | # Delete an drop
114 | @client.delete "2wr4"
115 |
116 | # Recover a deleted drop
117 | @client.recover "2wr4"
118 |
119 | ## Account examples
120 |
121 | * Documentation - {CloudApp::Account}
122 |
123 | ---
124 |
125 | # Create a CloudApp account
126 | @account = CloudApp::Account.create :email => "arthur@dent.com", :password => "towel"
127 |
128 | # View account details
129 | @account = CloudApp::Account.find
130 |
131 | # Forgot password
132 | CloudApp::Account.reset :email => "arthur@dent.com"
133 |
134 | # Change default security
135 | @account.update :private_items => false
136 |
137 | # Change email
138 | @account.update :email => "ford@prefect.com", :current_password => "towel"
139 |
140 | # Change password
141 | @account.update :password => "happy frood", :current_password => "towel"
142 |
143 | # Set custom domain
144 | @account.update :domain => "dent.com", :domain_home_page => "http://hhgproject.org"
145 |
146 | # View account stats
147 | @account.stats
148 |
149 | ## Gift cards
150 |
151 | * Documentation - {CloudApp::GiftCard}
152 |
153 | ---
154 |
155 | # View gift card details
156 | @gift = CloudApp::GiftCard.find "ABC123"
157 |
158 | # Apply the gift card
159 | CloudApp::GiftCard.redeem "ABC123"
160 | # or
161 | @gift.redeem
162 |
163 | ## What's next on the to-do list?
164 |
165 | * Refactor the Client interface so can be used with all of the API
166 |
167 | ## Note on Patches/Pull Requests
168 |
169 | * Fork the project.
170 | * Make your feature addition or bug fix.
171 | * Add tests for it. This is important so I don't break it in a future version unintentionally.
172 | * Commit, do not mess with rakefile, version, or history.
173 | (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
174 | * Send me a pull request. Bonus points for topic branches.
175 |
176 | ## Author & Contributors
177 |
178 | * [Aaron Russell](http://www.aaronrussell.co.uk)
179 | * [Christian Nicolai](https://github.com/cmur2)
180 |
181 | ## Copyright
182 |
183 | Copyright (c) 2010 Aaron Russell. See LICENSE for details.
184 |
--------------------------------------------------------------------------------
/spec/cloudapp_item_spec.rb:
--------------------------------------------------------------------------------
1 | # For legacy purpose still test director on the Item object
2 | # Item is deprecated and should not be used. Instead use the Drop object.
3 |
4 | require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
5 |
6 | describe CloudApp::Item do
7 |
8 | before(:each) do
9 | fake_it_all
10 | @item = CloudApp::Item.find "2wr4"
11 | end
12 |
13 | it "should be a Item object" do
14 | @item.should be_a_kind_of CloudApp::Drop
15 | end
16 |
17 | it "should return a name" do
18 | @item.name.should == "CloudApp Logo.png"
19 | end
20 |
21 | it "should return an href" do
22 | @item.href.should == "http://my.cl.ly/items/1912559"
23 | end
24 |
25 | it "should return a privacy boolean" do
26 | @item.private.should == false
27 | end
28 |
29 | it "should return a url" do
30 | @item.url.should == "http://cl.ly/2wr4"
31 | end
32 |
33 | it "should return a content url" do
34 | @item.content_url.should == "http://cl.ly/2wr4/CloudApp_Logo.png"
35 | end
36 |
37 | it "should return a item type" do
38 | @item.item_type.should == "image"
39 | end
40 |
41 | it "should return a view counter" do
42 | @item.view_counter.should == 42
43 | end
44 |
45 | it "should return an icon url" do
46 | @item.icon.should == "http://my.cl.ly/images/item_types/image.png"
47 | end
48 |
49 | it "should return a remote url" do
50 | @item.remote_url == "http://f.cl.ly/items/7c7aea1395c3db0aee18/CloudApp%20Logo.png"
51 | end
52 |
53 | it "should not return a redirect url" do
54 | @item.redirect_url == nil
55 | end
56 |
57 | it "should return timestamps" do
58 | @item.created_at.should be_a_kind_of Time
59 | @item.updated_at.should be_a_kind_of Time
60 | @item.deleted_at.should == nil
61 | end
62 |
63 | end
64 |
65 |
66 | describe "Bookmark link" do
67 |
68 | before(:each) do
69 | fake_it_all
70 | CloudApp.authenticate "testuser@test.com", "password"
71 | @name = "CloudApp"
72 | @redirect_url = "http://getcloudapp.com"
73 | @item = CloudApp::Item.create :bookmark, {:name => @name, :redirect_url => @redirect_url}
74 | end
75 |
76 | it "should be a Item object" do
77 | @item.should be_a_kind_of CloudApp::Drop
78 | end
79 |
80 | it "should return the same name" do
81 | @item.name.should == @name
82 | end
83 |
84 | it "should return the same redirect_url" do
85 | @item.redirect_url.should == @redirect_url
86 | end
87 |
88 | end
89 |
90 |
91 | describe "Bookmark multiple links" do
92 |
93 | before(:each) do
94 | fake_it_all
95 | # overwrite the normal fake uri for this spec
96 | FakeWeb.register_uri :post, 'http://my.cl.ly/items', :response => stub_file(File.join('drop', 'index'))
97 | CloudApp.authenticate "testuser@test.com", "password"
98 | @bookmarks = [
99 | { :name => "Authur Dent", :redirect_url => "http://en.wikipedia.org/wiki/Arthur_Dent" },
100 | { :name => "Ford Prefect", :redirect_url => "http://en.wikipedia.org/wiki/Ford_Prefect_(character)"},
101 | { :name => "Zaphod Beeblebrox", :redirect_url => "http://en.wikipedia.org/wiki/Zaphod_Beeblebrox" }
102 | ]
103 | @items = CloudApp::Item.create :bookmarks, @bookmarks
104 | end
105 |
106 | it "should be an Array" do
107 | @items.should be_a_kind_of Array
108 | end
109 |
110 | it "should contain Item objects" do
111 | @items.each do |item|
112 | item.should be_a_kind_of CloudApp::Drop
113 | end
114 | end
115 |
116 | end
117 |
118 |
119 | describe "Change security of an item" do
120 |
121 | before(:each) do
122 | fake_it_all
123 | CloudApp.authenticate "testuser@test.com", "password"
124 | @item = CloudApp::Item.update "http://my.cl.ly/items/1912565", {:private => false}
125 | end
126 |
127 | it "should be an Item object" do
128 | @item.should be_a_kind_of CloudApp::Drop
129 | end
130 |
131 | it "should not be private" do
132 | @item.private.should == false
133 | end
134 |
135 | end
136 |
137 |
138 |
139 | describe "Delete an item" do
140 |
141 | before(:each) do
142 | fake_it_all
143 | CloudApp.authenticate "testuser@test.com", "password"
144 | @item = CloudApp::Item.delete "http://my.cl.ly/items/1912565"
145 | end
146 |
147 | it "should be an Item object" do
148 | @item.should be_a_kind_of CloudApp::Drop
149 | end
150 |
151 | it "should have a deleted_at timestamp" do
152 | @item.deleted_at.should be_a_kind_of Time
153 | end
154 |
155 | end
156 |
157 |
158 | describe "Empty trash" do
159 | end
160 |
161 |
162 | describe "List items" do
163 |
164 | before(:each) do
165 | fake_it_all
166 | CloudApp.authenticate "testuser@test.com", "password"
167 | @items = CloudApp::Item.all
168 | end
169 |
170 | it "should be an Array" do
171 | @items.should be_a_kind_of Array
172 | end
173 |
174 | it "should contain Item objects" do
175 | @items.each do |item|
176 | item.should be_a_kind_of CloudApp::Drop
177 | end
178 | end
179 |
180 | end
181 |
182 |
183 | describe "Recover deleted item" do
184 |
185 | before(:each) do
186 | fake_it_all
187 | CloudApp.authenticate "testuser@test.com", "password"
188 | @item = CloudApp::Item.recover "http://my.cl.ly/items/1912565"
189 | end
190 |
191 | it "should be an Item object" do
192 | @item.should be_a_kind_of CloudApp::Drop
193 | end
194 |
195 | it "should not have a deleted_at timestamp" do
196 | @item.deleted_at.should == nil
197 | end
198 |
199 | end
200 |
201 |
202 | describe "Rename item" do
203 |
204 | before(:each) do
205 | fake_it_all
206 | CloudApp.authenticate "testuser@test.com", "password"
207 | @name = "CloudApp"
208 | @item = CloudApp::Item.update "http://my.cl.ly/items/1912565", {:name => @name}
209 | end
210 |
211 | it "should be an Item object" do
212 | @item.should be_a_kind_of CloudApp::Drop
213 | end
214 |
215 | it "should be have the same name" do
216 | @item.name.should == @name
217 | end
218 |
219 | end
220 |
221 |
222 | describe "Upload file" do
223 |
224 | before(:each) do
225 | fake_it_all
226 | CloudApp.authenticate "testuser@test.com", "password"
227 | @item = CloudApp::Item.create :upload, {:file => "README.md"}
228 | end
229 |
230 | it "should be an Item object" do
231 | @item.should be_a_kind_of CloudApp::Drop
232 | end
233 |
234 | it "should return a item type" do
235 | @item.item_type.should == "image"
236 | end
237 |
238 | end
239 |
240 |
241 | describe "Upload file with specific privacy" do
242 |
243 | before(:each) do
244 | fake_it_all
245 | # override the upload fakeweb uri
246 | FakeWeb.register_uri :post, 'http://f.cl.ly', :status => ["303"], :location => "http://my.cl.ly/items/s3?item[private]=true"
247 | CloudApp.authenticate "testuser@test.com", "password"
248 | @item = CloudApp::Item.create :upload, {:file => "README.md", :private => true}
249 | end
250 |
251 | it "should be an Item object" do
252 | @item.should be_a_kind_of CloudApp::Drop
253 | end
254 |
255 | it "should return as private" do
256 | @item.private.should == true
257 | end
258 |
259 | end
260 |
261 |
262 |
--------------------------------------------------------------------------------
/spec/cloudapp_drop_spec.rb:
--------------------------------------------------------------------------------
1 | require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2 |
3 | describe CloudApp::Drop do
4 |
5 | before(:each) do
6 | fake_it_all
7 | @drop = CloudApp::Drop.find "2wr4"
8 | end
9 |
10 | it "should be a Drop object" do
11 | @drop.should be_a_kind_of CloudApp::Drop
12 | end
13 |
14 | it "should return a name" do
15 | @drop.name.should == "CloudApp Logo.png"
16 | end
17 |
18 | it "should return an href" do
19 | @drop.href.should == "http://my.cl.ly/items/1912559"
20 | end
21 |
22 | it "should return a privacy boolean" do
23 | @drop.private.should == false
24 | end
25 |
26 | it "should return a url" do
27 | @drop.url.should == "http://cl.ly/2wr4"
28 | end
29 |
30 | it "should return a content url" do
31 | @drop.content_url.should == "http://cl.ly/2wr4/CloudApp_Logo.png"
32 | end
33 |
34 | it "should return a drop type" do
35 | @drop.item_type.should == "image"
36 | end
37 |
38 | it "should return a view counter" do
39 | @drop.view_counter.should == 42
40 | end
41 |
42 | it "should return an icon url" do
43 | @drop.icon.should == "http://my.cl.ly/images/item_types/image.png"
44 | end
45 |
46 | it "should return a remote url" do
47 | @drop.remote_url == "http://f.cl.ly/items/7c7aea1395c3db0aee18/CloudApp%20Logo.png"
48 | end
49 |
50 | it "should not return a redirect url" do
51 | @drop.redirect_url == nil
52 | end
53 |
54 | it "should return a source" do
55 | @drop.source == "Cloud/1.5.1 CFNetwork/520.0.13 Darwin/11.0.0 (x86_64) (MacBookPro5%2C5)"
56 | end
57 |
58 | it "should return timestamps" do
59 | @drop.created_at.should be_a_kind_of Time
60 | @drop.updated_at.should be_a_kind_of Time
61 | @drop.deleted_at.should == nil
62 | end
63 |
64 | it "should return the raw data hash" do
65 | @drop.data.should be_a_kind_of Hash
66 | @drop.data['name'].should == "CloudApp Logo.png"
67 | end
68 |
69 | end
70 |
71 |
72 | describe "Bookmark link" do
73 |
74 | before(:each) do
75 | fake_it_all
76 | CloudApp.authenticate "testuser@test.com", "password"
77 | @name = "CloudApp"
78 | @redirect_url = "http://getcloudapp.com"
79 | @drop = CloudApp::Drop.create :bookmark, {:name => @name, :redirect_url => @redirect_url}
80 | end
81 |
82 | it "should be a Drop object" do
83 | @drop.should be_a_kind_of CloudApp::Drop
84 | end
85 |
86 | it "should return the same name" do
87 | @drop.name.should == @name
88 | end
89 |
90 | it "should return the same redirect_url" do
91 | @drop.redirect_url.should == @redirect_url
92 | end
93 |
94 | end
95 |
96 |
97 | describe "Bookmark multiple links" do
98 |
99 | before(:each) do
100 | fake_it_all
101 | # overwrite the normal fake uri for this spec
102 | FakeWeb.register_uri :post, 'http://my.cl.ly/items', :response => stub_file(File.join('drop', 'index'))
103 | CloudApp.authenticate "testuser@test.com", "password"
104 | @bookmarks = [
105 | { :name => "Authur Dent", :redirect_url => "http://en.wikipedia.org/wiki/Arthur_Dent" },
106 | { :name => "Ford Prefect", :redirect_url => "http://en.wikipedia.org/wiki/Ford_Prefect_(character)"},
107 | { :name => "Zaphod Beeblebrox", :redirect_url => "http://en.wikipedia.org/wiki/Zaphod_Beeblebrox" }
108 | ]
109 | @drops = CloudApp::Drop.create :bookmarks, @bookmarks
110 | end
111 |
112 | it "should be an Array" do
113 | @drops.should be_a_kind_of Array
114 | end
115 |
116 | it "should contain Drop objects" do
117 | @drops.each do |drop|
118 | drop.should be_a_kind_of CloudApp::Drop
119 | end
120 | end
121 |
122 | end
123 |
124 |
125 | describe "Change security of an drop" do
126 |
127 | before(:each) do
128 | fake_it_all
129 | CloudApp.authenticate "testuser@test.com", "password"
130 | @drop = CloudApp::Drop.update "http://my.cl.ly/items/1912565", {:private => false}
131 | end
132 |
133 | it "should be an Drop object" do
134 | @drop.should be_a_kind_of CloudApp::Drop
135 | end
136 |
137 | it "should not be private" do
138 | @drop.private.should == false
139 | end
140 |
141 | end
142 |
143 |
144 |
145 | describe "Delete a drop" do
146 |
147 | before(:each) do
148 | fake_it_all
149 | CloudApp.authenticate "testuser@test.com", "password"
150 | @drop = CloudApp::Drop.delete "http://my.cl.ly/items/1912565"
151 | end
152 |
153 | it "should be an Drop object" do
154 | @drop.should be_a_kind_of CloudApp::Drop
155 | end
156 |
157 | it "should have a deleted_at timestamp" do
158 | @drop.deleted_at.should be_a_kind_of Time
159 | end
160 |
161 | end
162 |
163 |
164 | describe "Empty trash" do
165 | end
166 |
167 |
168 | describe "List drops" do
169 |
170 | before(:each) do
171 | fake_it_all
172 | CloudApp.authenticate "testuser@test.com", "password"
173 | @drops = CloudApp::Drop.all
174 | end
175 |
176 | it "should be an Array" do
177 | @drops.should be_a_kind_of Array
178 | end
179 |
180 | it "should contain Drop objects" do
181 | @drops.each do |drop|
182 | drop.should be_a_kind_of CloudApp::Drop
183 | end
184 | end
185 |
186 | end
187 |
188 |
189 | describe "Recover deleted drop" do
190 |
191 | before(:each) do
192 | fake_it_all
193 | CloudApp.authenticate "testuser@test.com", "password"
194 | @drop = CloudApp::Drop.recover "http://my.cl.ly/items/1912565"
195 | end
196 |
197 | it "should be an Drop object" do
198 | @drop.should be_a_kind_of CloudApp::Drop
199 | end
200 |
201 | it "should not have a deleted_at timestamp" do
202 | @drop.deleted_at.should == nil
203 | end
204 |
205 | end
206 |
207 |
208 | describe "Rename drop" do
209 |
210 | before(:each) do
211 | fake_it_all
212 | CloudApp.authenticate "testuser@test.com", "password"
213 | @name = "CloudApp"
214 | @drop = CloudApp::Drop.update "http://my.cl.ly/items/1912565", {:name => @name}
215 | end
216 |
217 | it "should be an Drop object" do
218 | @drop.should be_a_kind_of CloudApp::Drop
219 | end
220 |
221 | it "should be have the same name" do
222 | @drop.name.should == @name
223 | end
224 |
225 | end
226 |
227 |
228 | describe "Upload file" do
229 |
230 | before(:each) do
231 | fake_it_all
232 | CloudApp.authenticate "testuser@test.com", "password"
233 | @drop = CloudApp::Drop.create :upload, {:file => "README.md"}
234 | end
235 |
236 | it "should be an Drop object" do
237 | @drop.should be_a_kind_of CloudApp::Drop
238 | end
239 |
240 | it "should return a drop type" do
241 | @drop.item_type.should == "image"
242 | end
243 |
244 | end
245 |
246 |
247 | describe "Upload file with specific privacy" do
248 |
249 | before(:each) do
250 | fake_it_all
251 | # override the upload fakeweb uri
252 | FakeWeb.register_uri :post, 'http://f.cl.ly', :status => ["303"], :location => "http://my.cl.ly/items/s3?item[private]=true"
253 | CloudApp.authenticate "testuser@test.com", "password"
254 | @drop = CloudApp::Drop.create :upload, {:file => "README.md", :private => true}
255 | end
256 |
257 | it "should be an Drop object" do
258 | @drop.should be_a_kind_of CloudApp::Drop
259 | end
260 |
261 | it "should return as private" do
262 | @drop.private.should == true
263 | end
264 |
265 | end
266 |
--------------------------------------------------------------------------------
/lib/cloudapp/drop.rb:
--------------------------------------------------------------------------------
1 | module CloudApp
2 |
3 | # An ActiveResource-like interface through which to interract with CloudApp drops.
4 | #
5 | # @example Gets started by Authenticating
6 | # CloudApp.authenticate "username", "password"
7 | #
8 | # @example Usage via the Drop class
9 | # # Find a single drop by it's slug
10 | # @drop = CloudApp::Drop.find "2wr4"
11 | #
12 | # # Get a list of all drops
13 | # @drops = CloudApp::Drop.all
14 | #
15 | # # Create a new bookmark
16 | # @drop = CloudApp::Drop.create :bookmark, :name => "CloudApp", :redirect_url => "http://getcloudapp.com"
17 | #
18 | # # Create multiple bookmarks
19 | # bookmarks = [
20 | # { :name => "Authur Dent", :redirect_url => "http://en.wikipedia.org/wiki/Arthur_Dent" },
21 | # { :name => "Zaphod Beeblebrox", :redirect_url => "http://en.wikipedia.org/wiki/Zaphod_Beeblebrox" }
22 | # ]
23 | # @drops = CloudApp::Drop.create :bookmarks, bookmarks
24 | #
25 | # # Upload a file
26 | # @drop = CloudApp::Drop.create :upload, :file => "/path/to/image.png"
27 | # @drop = CloudApp::Drop.create :upload, :file => "/path/to/image.png", :private => true
28 | #
29 | # # Rename a file
30 | # CloudApp::Drop.update "http://my.cl.ly/items/1912565", :name => "Big Screenshot"
31 | #
32 | # # Set a drop's privacy
33 | # CloudApp::Drop.update "http://my.cl.ly/items/1912565", :private => true
34 | #
35 | # # Delete a drop
36 | # CloudApp::Drop.delete "http://my.cl.ly/items/1912565"
37 | #
38 | # # Recover a deleted drop
39 | # CloudApp::Drop.recover "http://my.cl.ly/items/1912565"
40 | #
41 | # @example Usage via the class instance
42 | # # Rename a file
43 | # @drop.update :name => "Big Screenshot"
44 | #
45 | # # Set the drop's privacy
46 | # @drop.update :private => true
47 | #
48 | # # Delete a drop
49 | # @drop.delete
50 | #
51 | # # Recover a deleted drop
52 | # @drop.recover
53 | #
54 | class Drop < Base
55 |
56 | # Get metadata about a cl.ly URL like name, type, or view count.
57 | #
58 | # Finds the drop by it's slug id, for example "2wr4".
59 | #
60 | # @param [String] id cl.ly slug id
61 | # @return [CloudApp::Drop]
62 | def self.find(id)
63 | res = get "http://cl.ly/#{id}"
64 | res.ok? ? Drop.new(res) : bad_response(res)
65 | end
66 |
67 | # Page through your drops.
68 | #
69 | # Requires authentication.
70 | #
71 | # @param [Hash] opts options parameters
72 | # @option opts [Integer] :page Page number starting at 1
73 | # @option opts [Integer] :per_page Number of items per page
74 | # @option opts [String] :type Filter items by type (image, bookmark, text, archive, audio, video, or unknown)
75 | # @option opts [Boolean] :deleted Show trashed drops
76 | # @return [Array[CloudApp::Drop]]
77 | def self.all(opts = {})
78 | res = get "/items", {:query => (opts.empty? ? nil : opts), :digest_auth => @@auth}
79 | res.ok? ? res.collect{|i| Drop.new(i)} : bad_response(res)
80 | end
81 |
82 | # Create a new drop. Multiple bookmarks can be created at once by
83 | # passing an array of bookmark options parameters.
84 | #
85 | # Requires authentication.
86 | #
87 | # @param [Symbol] kind type of drop (can be +:bookmark+, +:bookmarks+ or +:upload+)
88 | # @overload self.create(:bookmark, opts = {})
89 | # @param [Hash] opts options paramaters
90 | # @option opts [String] :name Name of bookmark (only required for +:bookmark+ kind)
91 | # @option opts [String] :redirect_url Redirect URL (only required for +:bookmark+ kind)
92 | # @overload self.create(:bookmarks, bookmarks)
93 | # @param [Array] bookmarks array of bookmark option parameters (containing +:name+ and +:redirect_url+)
94 | # @overload self.create(:upload, opts = {})
95 | # @param [Hash] opts options paramaters
96 | # @option opts [String] :file Path to file (only required for +:upload+ kind)
97 | # @option opts [Boolean] :private override the account default privacy setting
98 | # @return [CloudApp::Drop]
99 | def self.create(kind, opts = {})
100 | case kind
101 | when :bookmark
102 | res = post "/items", {:body => {:item => opts}, :digest_auth => @@auth}
103 | when :bookmarks
104 | res = post "/items", {:body => {:items => opts}, :digest_auth => @@auth}
105 | when :upload
106 | r = get "/items/new", {:query => ({:item => {:private => opts[:private]}} if opts.has_key?(:private)), :digest_auth => @@auth}
107 | return bad_response(r) unless r.ok?
108 | res = post r['url'], Multipart.new(r['params'].merge!(:file => File.new(opts[:file]))).payload.merge!(:digest_auth => @@auth)
109 | else
110 | # TODO raise an error
111 | return false
112 | end
113 | res.ok? ? (res.is_a?(Array) ? res.collect{|i| Drop.new(i)} : Drop.new(res)) : bad_response(res)
114 | end
115 |
116 | # Modify a drop. Can currently modify it's name or security setting by passing parameters.
117 | #
118 | # Requires authentication.
119 | #
120 | # @param [String] href href attribute of drop
121 | # @param [Hash] opts options paramaters
122 | # @option opts [String] :name for renaming the drop
123 | # @option opts [Boolean] :privacy set drop privacy
124 | # @return [CloudApp::Drop]
125 | def self.update(href, opts = {})
126 | res = put href, {:body => {:item => opts}, :digest_auth => @@auth}
127 | res.ok? ? Drop.new(res) : bad_response(res)
128 | end
129 |
130 | # Send a drop to the trash.
131 | #
132 | # Requires authentication.
133 | #
134 | # @param [String] href href attribute of the drop
135 | # @return [CloudApp::Drop]
136 | def self.delete(href)
137 | # Use delete on the Base class to avoid recursion
138 | res = Base.delete href, :digest_auth => @@auth
139 | res.ok? ? Drop.new(res) : bad_response(res)
140 | end
141 |
142 | # Recover a drop from the trash.
143 | #
144 | # Requires authentication.
145 | #
146 | # @param [String] href href attribute of the drop
147 | # @return [CloudApp::Drop]
148 | def self.recover(href)
149 | res = put href, {:body => {:deleted => true, :item => {:deleted_at => nil}}, :digest_auth => @@auth}
150 | res.ok? ? Drop.new(res) : bad_response(res)
151 | end
152 |
153 | attr_reader :href, :name, :private, :url, :content_url, :item_type, :view_counter,
154 | :icon, :remote_url, :redirect_url, :source, :created_at, :updated_at, :deleted_at
155 |
156 | # Modify the drop. Can currently modify it's name or security setting by passing parameters.
157 | #
158 | # @param [Hash] opts options paramaters
159 | # @option opts [String] :name for renaming the drop
160 | # @option opts [Boolean] :privacy set the drop's privacy
161 | # @return [CloudApp::Drop]
162 | def update(opts = {})
163 | self.class.update self.href, opts
164 | end
165 |
166 | # Send the drop to the trash.
167 | #
168 | # @return [CloudApp::Drop]
169 | def delete
170 | self.class.delete self.href
171 | end
172 |
173 | # Recover the drop from the trash.
174 | #
175 | # @return [CloudApp::Drop]
176 | def recover
177 | self.class.recover self.href
178 | end
179 |
180 | # Is the drop an image?
181 | #
182 | # @return [Boolean]
183 | def image?
184 | item_type == 'image'
185 | end
186 |
187 | # Is the drop a bookmark?
188 | #
189 | # @return [Boolean]
190 | def bookmark?
191 | item_type == 'bookmark'
192 | end
193 |
194 | # Is the drop a text file?
195 | #
196 | # @return [Boolean]
197 | def text?
198 | item_type == 'text'
199 | end
200 |
201 | # Is the drop an archive?
202 | #
203 | # @return [Boolean]
204 | def archive?
205 | item_type == 'archive'
206 | end
207 |
208 | # Is the drop an audio file?
209 | #
210 | # @return [Boolean]
211 | def audio?
212 | item_type == 'audio'
213 | end
214 |
215 | # Is the drop a video file?
216 | #
217 | # @return [Boolean]
218 | def video?
219 | item_type == 'video'
220 | end
221 |
222 | # Is the drop an unknown file type?
223 | #
224 | # @return [Boolean]
225 | def unknown?
226 | item_type == 'unknown'
227 | end
228 |
229 | # Return the drops raw data as a string, useful for returning the text of documents
230 | #
231 | # @return [String]
232 | def raw
233 | @raw ||= HTTParty.get(content_url).to_s
234 | end
235 |
236 | private
237 |
238 | def extension
239 | File.extname(content_url)[1..-1].to_s.downcase if content_url
240 | end
241 |
242 | end
243 |
244 | # The Item class is now deprecated in favour of the Drop class.
245 | # For legacy purposes you can still use the Item class but it is recommended you
246 | # update your code to use the Drop class to ensure future compatibility.
247 | class Item < Drop; end
248 |
249 | end
250 |
--------------------------------------------------------------------------------