tumblr_client 0.6.11 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/.gitignore CHANGED
@@ -1,2 +1,11 @@
1
1
  *.gem
2
- .DS_Store
2
+ .DS_Store
3
+
4
+ *.swp
5
+ *.swo
6
+
7
+ tmp
8
+ coverage
9
+ .rspec
10
+
11
+ Gemfile.lock
data/.travis.yml ADDED
@@ -0,0 +1,10 @@
1
+ script: 'rspec spec'
2
+ notifications:
3
+ email:
4
+ - john.crepezzi@gmail.com
5
+ branches:
6
+ only:
7
+ - master
8
+ rvm:
9
+ - 1.9.2
10
+ - 1.9.3
data/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # Tumblr Ruby Gem
2
2
 
3
+ [![Build Status](https://secure.travis-ci.org/codingjester/tumblr_client.png)](http://travis-ci.org/codingjester/tumblr_client)
4
+
3
5
  This is a ruby wrapper for the Tumblr v2 API. There should be support for all endpoints
4
6
  currently available on the [Tumblr API](http://www.tumblr.com/docs/en/api/v2).
5
7
 
@@ -18,10 +20,10 @@ your life easier when using the v2 api. If you need to do the full oauth workflo
18
20
  Configuration for the gem is actually pretty easy:
19
21
 
20
22
  Tumblr.configure do |config|
21
- config.consumer_key = "consumer_key"
22
- config.consumer_secret = "consumer_secret"
23
- config.oauth_token = "access_token"
24
- config.oauth_token_secret = "access_token_secret"
23
+ config.consumer_key = "consumer_key"
24
+ config.consumer_secret = "consumer_secret"
25
+ config.oauth_token = "access_token"
26
+ config.oauth_token_secret = "access_token_secret"
25
27
  end
26
28
 
27
29
  Once you have your configuration squared away it's time to make some requests!
@@ -33,27 +35,31 @@ That's it! You now have a client that can make any request to the Tumblr API.
33
35
  ### Some quick examples
34
36
 
35
37
  Getting user information:
36
-
38
+
37
39
  >> client.info
38
40
 
39
41
  Getting a specific blog's posts and type:
40
-
42
+
41
43
  #Grabbing a specific blogs posts
42
44
  >> client.posts("codingjester.tumblr.com")
43
-
44
- #Grabbing only the last 10 photos off the blog
45
+
46
+ #Grabbing only the last 10 photos off the blog
45
47
  >> client.posts("codingjester.tumblr.com", :type => "photo", :limit => 10)
46
48
 
47
49
 
48
50
  Posting some photos to Tumblr:
49
51
 
50
- #Uploads a great photoset
52
+ # Uploads a great photoset
51
53
  >> client.photo("codingjester.tumblr.com", {:data => ['/path/to/pic.jpg', '/path/to/pic.jpg']})
52
54
 
55
+ # You can also post with the raw data
56
+ >> raw = File.open('/path/to/pic.jpg', 'rb').read
57
+ >> client.photo('codingjester.tumblr.com', :data_raw => [raw]
58
+
53
59
  ### The irb Console
54
60
 
55
61
  Finally, there is an irb console packaged with the gem that should help you test any calls you want to make.
56
- The magic here is that you have a ```.tumblr``` file in your home directory. Inside this file it's just a basic
62
+ The magic here is that you have a `.tumblr` file in your home directory. Inside this file it's just a basic
57
63
  YAML layout with four lines:
58
64
 
59
65
  consumer_key: "your_consumer_key"
@@ -61,12 +67,25 @@ YAML layout with four lines:
61
67
  oauth_token: "your_access_token"
62
68
  oauth_token_secret: "your_access_token_secret"
63
69
 
64
- From there, you should be able to run any of the above commands, with no problem! Just fire off the command ```tumblr``
70
+ From there, you should be able to run any of the above commands, with no problem! Just fire off the command `tumblr`
65
71
  from the terminal and you should be dropped into a console.
66
72
 
73
+ ---
74
+
75
+ The first time that you go to use the irb console, if you have no `.tumblr`
76
+ file, it will walk you through the process of generating one. You will
77
+ be prompted for your consumer_key and consumer_secret (which you can get
78
+ here: http://www.tumblr.com/oauth/register) and then sent out to the site
79
+ to verify your account. Once you verify, you will be redirected to your
80
+ redirect URL (localhost by default) and copy the `oauth_verifier` back into the
81
+ console. Then you're all set!
67
82
 
68
83
  ### Contributions and Pull Requests
69
84
 
70
85
  No request is too small and I encourage everyone to get involved. As you can see, we're sorely lacking in tests! So
71
86
  please if you would like to contribute, let me know and throw me a pull request!
72
87
 
88
+
89
+ ### Requirements
90
+
91
+ * Ruby >= 1.9.2
data/lib/tumblr/blog.rb CHANGED
@@ -1,73 +1,59 @@
1
1
  module Tumblr
2
- class Client
3
- module Blog
4
-
5
- @@standard_options = [:type, :id, :tag, :limit, :offset, :reblog_info, :notes_info, :filter]
6
- #
7
- #Gets the info about the blog
8
- #
9
- def blog_info(blog_name)
10
- get("v2/blog/#{blog_name}/info", {:api_key => @consumer_key})
11
- end
2
+ module Blog
12
3
 
13
- #
14
- # Gets the avatar URL of specified size
15
- #
16
- def avatar(blog_name, size = nil)
17
- response = get_response("v2/blog/#{blog_name}/avatar", :size => size)
18
- if response.status == 301
19
- response.headers['Location']
20
- end
21
- end
4
+ # Gets the info about the blog
5
+ def blog_info(blog_name)
6
+ get("v2/blog/#{blog_name}/info", :api_key => @consumer_key)
7
+ end
22
8
 
23
- #
24
- # Gets the list of followers for the blog
25
- #
26
- def followers(blog_name, options={})
27
- if valid_options([:limit, :offset], options)
28
- get("v2/blog/#{blog_name}/followers", options)
29
- end
30
- end
31
-
32
- #
33
- # Gets the list of likes for the blog
34
- #
35
- def blog_likes(blog_name, options={})
36
- if valid_options([:limit, :offset], options)
37
- url = "v2/blog/#{blog_name}/likes"
38
- params = {:api_key => @consumer_key}
39
- unless options.empty?
40
- params.merge!(options)
41
- end
42
- get(url, params)
43
- end
44
- end
9
+ # Gets the avatar URL of specified size
10
+ def avatar(blog_name, size = nil)
11
+ url = "v2/blog/#{blog_name}/avatar"
12
+ url = "#{url}/#{size}" if size
13
+ get_redirect_url(url)
14
+ end
45
15
 
46
- def posts(blog_name, options={})
47
- url = "v2/blog/#{blog_name}/posts"
48
-
49
- if options.has_key?(:type)
50
- url = "#{url}/#{options[:type]}"
51
- end
52
-
53
- params = {:api_key => @consumer_key}
54
- unless options.empty?
55
- params.merge!(options)
56
- end
57
- get(url, params)
58
- end
16
+ # Gets the list of followers for the blog
17
+ def followers(blog_name, options = {})
18
+ validate_options([:limit, :offset], options)
19
+ get("v2/blog/#{blog_name}/followers", options)
20
+ end
59
21
 
60
- def queue(blog_name)
61
- get("v2/blog/#{blog_name}/posts/queue", {})
62
- end
63
-
64
- def draft(blog_name)
65
- get("v2/blog/#{blog_name}/posts/draft", {})
66
- end
67
-
68
- def submissions(blog_name)
69
- get("v2/blog/#{blog_name}/posts/submission", {})
22
+ # Gets the list of likes for the blog
23
+ def blog_likes(blog_name, options = {})
24
+ validate_options([:limit, :offset], options)
25
+ url = "v2/blog/#{blog_name}/likes"
26
+
27
+ params = { :api_key => @consumer_key }
28
+ params.merge! options
29
+ get(url, params)
30
+ end
31
+
32
+ def posts(blog_name, options = {})
33
+ url = "v2/blog/#{blog_name}/posts"
34
+ if options.has_key?(:type)
35
+ url = "#{url}/#{options[:type]}"
70
36
  end
37
+
38
+ params = { :api_key => @consumer_key }
39
+ params.merge! options
40
+ get(url, params)
41
+ end
42
+
43
+ def queue(blog_name, options = {})
44
+ validate_options([:limit, :offset], options)
45
+ get("v2/blog/#{blog_name}/posts/queue", options)
71
46
  end
47
+
48
+ def draft(blog_name, options = {})
49
+ validate_options([:limit, :offset], options)
50
+ get("v2/blog/#{blog_name}/posts/draft", options)
51
+ end
52
+
53
+ def submissions(blog_name, options = {})
54
+ validate_options([:limit, :offset], options)
55
+ get("v2/blog/#{blog_name}/posts/submission", options)
56
+ end
57
+
72
58
  end
73
59
  end
data/lib/tumblr/client.rb CHANGED
@@ -8,14 +8,15 @@ require 'tumblr/helpers'
8
8
 
9
9
  module Tumblr
10
10
  class Client
11
+
11
12
  include Tumblr::Request
12
- include Tumblr::Client::Blog
13
- include Tumblr::Client::User
14
- include Tumblr::Client::Post
15
- include Tumblr::Client::Tagged
16
- include Tumblr::Client::Helper
13
+ include Tumblr::Blog
14
+ include Tumblr::User
15
+ include Tumblr::Post
16
+ include Tumblr::Tagged
17
+ include Tumblr::Helper
17
18
  include Tumblr::Connection
18
-
19
+
19
20
  def initialize(attrs= {})
20
21
  attrs = Tumblr.options.merge(attrs)
21
22
  Config::VALID_OPTIONS_KEYS.each do |key|
@@ -35,5 +36,6 @@ module Tumblr
35
36
  :token_secret => @oauth_token_secret
36
37
  }
37
38
  end
39
+
38
40
  end
39
41
  end
data/lib/tumblr/config.rb CHANGED
@@ -1,5 +1,4 @@
1
1
  module Tumblr
2
-
3
2
  module Config
4
3
 
5
4
  VALID_OPTIONS_KEYS = [
@@ -8,29 +7,28 @@ module Tumblr
8
7
  :oauth_token,
9
8
  :oauth_token_secret
10
9
  ]
11
-
10
+
12
11
  attr_accessor *VALID_OPTIONS_KEYS
13
12
 
14
13
  def configure
15
14
  yield self
16
15
  self
17
16
  end
18
-
17
+
19
18
  def options
20
19
  options = {}
21
- VALID_OPTIONS_KEYS.each{ |k| options[k] = send(k) }
20
+ VALID_OPTIONS_KEYS.each{ |pname| options[pname] = send(pname) }
22
21
  options
23
22
  end
24
23
 
25
24
  def credentials
26
25
  {
27
- :consumer_key => consumer_key,
28
- :consumer_secret => consumer_secret,
29
- :token => oauth_token,
30
- :token_secret => oauth_token_secret
26
+ :consumer_key => consumer_key,
27
+ :consumer_secret => consumer_secret,
28
+ :token => oauth_token,
29
+ :token_secret => oauth_token_secret
31
30
  }
32
31
  end
33
32
 
34
33
  end
35
-
36
34
  end
@@ -4,21 +4,26 @@ require 'tumblr/request/oauth'
4
4
 
5
5
  module Tumblr
6
6
  module Connection
7
+
7
8
  def connection(options={})
9
+ host = api_host
8
10
  default_options = {
9
11
  :headers => {
10
- :accept => "application/json",
11
- :user_agent => "Tumblr v1.0"
12
+ :accept => 'application/json',
13
+ :user_agent => "tumblr_client (ruby) - #{Tumblr::VERSION}"
12
14
  },
13
- :url => "http://#{api_host}/"
15
+ :url => "http://#{host}/"
14
16
  }
15
- Faraday.new("http://#{api_host}/", default_options.merge(options)) do |builder|
16
- data = { :api_host => api_host }.merge(credentials)
17
- builder.use Tumblr::Request::TumblrOAuth, data unless credentials.empty?
17
+ Faraday.new("http://#{host}/", default_options.merge(options)) do |builder|
18
+ data = { :api_host => host }.merge(credentials)
19
+ unless credentials.empty?
20
+ builder.use Tumblr::Request::TumblrOAuth, data
21
+ end
18
22
  builder.use Faraday::Request::UrlEncoded
19
- builder.use FaradayMiddleware::ParseJson, :content_type => "application/json"
23
+ builder.use FaradayMiddleware::ParseJson, :content_type => 'application/json'
20
24
  builder.use Faraday::Adapter::NetHttp
21
25
  end
22
26
  end
27
+
23
28
  end
24
29
  end
@@ -1,14 +1,19 @@
1
1
  module Tumblr
2
- class Client
3
- module Helper
4
-
5
- def valid_options(valid_opts, opts)
6
- bad_opts = opts.select { |val| !valid_opts.include?(val) }
7
- if !bad_opts.empty?
8
- raise Exception, "Invalid options passed, Only #{valid_opts} allowed."
9
- end
10
- return true
2
+ module Helper
3
+
4
+ def validate_options(valid_opts, opts)
5
+ bad_opts = opts.select { |val| !valid_opts.include?(val) }
6
+ if bad_opts.any?
7
+ raise ArgumentError.new "Invalid options (#{bad_opts.keys.join(', ')}) passed, only #{valid_opts} allowed."
11
8
  end
12
9
  end
10
+
11
+ def validate_no_collision(options, attributes)
12
+ count = attributes.count { |attr| options.has_key?(attr) }
13
+ if count > 1
14
+ raise ArgumentError.new "Can only use one of: #{attributes.join(', ')} (Found #{count})"
15
+ end
16
+ end
17
+
13
18
  end
14
19
  end
data/lib/tumblr/post.rb CHANGED
@@ -1,113 +1,110 @@
1
1
  module Tumblr
2
- class Client
3
- module Post
4
-
5
- @@standard_post_options = [:state, :tags, :tweet, :date, :markdown, :slug, :format]
6
-
7
- def edit(blog_name, options={})
8
- post("v2/blog/#{blog_name}/post/edit", options)
9
- end
2
+ module Post
10
3
 
11
- #Don't be lazy and create a nice interface
12
- def reblog(blog_name, options={})
13
- post("v2/blog/#{blog_name}/post/reblog", options)
14
- end
15
-
16
- def delete(blog_name, id)
17
- post("v2/blog/#{blog_name}/post/delete", {:id => id})
18
- end
4
+ STANDARD_POST_OPTIONS = [:state, :tags, :tweet, :date, :markdown, :slug, :format]
19
5
 
20
- def photo(blog_name, options={})
21
- valid_opts = @@standard_post_options + [:caption, :link, :data, :source, :photoset_layout]
22
- if valid_options(valid_opts, options)
23
- options[:type] = "photo"
24
- if (options.has_key?(:data) && options.has_key?(:source))
25
- raise Exception, "You can only use one parameter, either source or data."
26
- end
27
- if options.has_key?(:source) && options[:source].kind_of?(Array)
28
- count = 0
29
- options[:source].each do |src|
30
- options["source[#{count}]"] = src
31
- count += 1
32
- end
33
- options.delete(:source)
34
- end
35
- if options.has_key?(:data)
36
- #Probably can be refactored
37
- if options[:data].kind_of?(Array)
38
- count = 0
39
- options[:data].each do |filepath|
40
- options["data[#{count}]"] = File.open(filepath, 'rb').read()
41
- count += 1
42
- end
43
- options.delete(:data)
44
- else
45
- options[:data] = File.open(options[:data],'rb').read()
46
- end
47
- end
48
- post("v2/blog/#{blog_name}/post", options)
49
- end
50
- end
51
-
52
- def quote(blog_name, options={})
53
- valid_opts = @@standard_post_options + [:quote, :source]
54
- if valid_options(valid_opts, options)
55
- options[:type] = "quote"
56
- post("v2/blog/#{blog_name}/post", options)
57
- end
58
- end
6
+ def edit(blog_name, options = {})
7
+ post("v2/blog/#{blog_name}/post/edit", options)
8
+ end
59
9
 
60
- def text(blog_name, options={})
61
- valid_opts = @@standard_post_options + [:title, :body]
62
- if valid_options(valid_opts, options)
63
- options[:type] = "text"
64
- post("v2/blog/#{blog_name}/post", options)
65
- end
66
- end
10
+ def reblog(blog_name, options = {})
11
+ post("v2/blog/#{blog_name}/post/reblog", options)
12
+ end
67
13
 
68
- def link(blog_name, options={})
69
- valid_opts = @@standard_post_options + [:title, :url, :description]
70
- if valid_options(valid_opts, options)
71
- options[:type] = "link"
72
- post("v2/blog/#{blog_name}/post", options)
73
- end
74
- end
14
+ def delete(blog_name, id)
15
+ post("v2/blog/#{blog_name}/post/delete", :id => id)
16
+ end
17
+
18
+ def photo(blog_name, options = {})
19
+ valid_opts = STANDARD_POST_OPTIONS + [:caption, :link, :data, :data_raw, :source, :photoset_layout]
20
+ validate_options(valid_opts, options)
21
+ validate_no_collision options, [:data, :source]
75
22
 
76
- def chat(blog_name, options={})
77
- valid_opts = @@standard_post_options + [:title, :conversation]
78
- if valid_options(valid_opts, options)
79
- options[:type] = "chat"
80
- post("v2/blog/#{blog_name}/post", options)
23
+ # Allow source to be passed as an Array
24
+ if options.has_key?(:source) && options[:source].kind_of?(Array)
25
+ options[:source].each.with_index do |src, idx|
26
+ options["source[#{idx}]"] = src
81
27
  end
28
+ options.delete(:source)
82
29
  end
83
30
 
84
- def audio(blog_name, options={})
85
- valid_opts = @@standard_post_options + [:data, :caption, :external_url]
86
- if valid_options(valid_opts, options)
87
- options[:type] = "audio"
88
- if (options.has_key?(:data) && options.has_key?(:external_url))
89
- raise Exception, "You can only use one parameter, either data or external url."
90
- end
91
- if(options.has_key?(:data))
92
- options[:data] = File.open(options[:data],'rb').read()
93
- end
94
- post("v2/blog/#{blog_name}/post", options)
31
+ options[:type] = 'photo'
32
+ extract_data!(options)
33
+ post("v2/blog/#{blog_name}/post", options)
34
+ end
35
+
36
+ def quote(blog_name, options = {})
37
+ valid_opts = STANDARD_POST_OPTIONS + [:quote, :source]
38
+ validate_options(valid_opts, options)
39
+
40
+ options[:type] = 'quote'
41
+ post("v2/blog/#{blog_name}/post", options)
42
+ end
43
+
44
+ def text(blog_name, options = {})
45
+ valid_opts = STANDARD_POST_OPTIONS + [:title, :body]
46
+ validate_options(valid_opts, options)
47
+
48
+ options[:type] = 'text'
49
+ post("v2/blog/#{blog_name}/post", options)
50
+ end
51
+
52
+ def link(blog_name, options = {})
53
+ valid_opts = STANDARD_POST_OPTIONS + [:title, :url, :description]
54
+ validate_options(valid_opts, options)
55
+
56
+ options[:type] = 'link'
57
+ post("v2/blog/#{blog_name}/post", options)
58
+ end
59
+
60
+ def chat(blog_name, options = {})
61
+ valid_opts = STANDARD_POST_OPTIONS + [:title, :conversation]
62
+ validate_options(valid_opts, options)
63
+
64
+ options[:type] = 'chat'
65
+ post("v2/blog/#{blog_name}/post", options)
66
+ end
67
+
68
+ def audio(blog_name, options = {})
69
+ valid_opts = STANDARD_POST_OPTIONS + [:data, :data_raw, :caption, :external_url]
70
+ validate_options(valid_opts, options)
71
+ validate_no_collision options, [:data, :external_url]
72
+
73
+ options[:type] = 'audio'
74
+ extract_data!(options)
75
+ post("v2/blog/#{blog_name}/post", options)
76
+ end
77
+
78
+ def video(blog_name, options = {})
79
+ valid_opts = STANDARD_POST_OPTIONS + [:data, :data_raw, :embed, :caption]
80
+ validate_options(valid_opts, options)
81
+ validate_no_collision options, [:data, :embed]
82
+
83
+ options[:type] = 'video'
84
+ extract_data!(options)
85
+ post("v2/blog/#{blog_name}/post", options)
86
+ end
87
+
88
+ private
89
+
90
+ # Look for the various ways that data can be passed, and normalize
91
+ # the result in this hash
92
+ def extract_data!(options)
93
+ validate_no_collision options, [:data, :data_raw]
94
+ if options.has_key?(:data)
95
+ data = options.delete :data
96
+ data = [data] unless Array === data
97
+ data.each.with_index do |filepath, idx|
98
+ options["data[#{idx}]"] = File.open(filepath, 'rb').read
95
99
  end
96
- end
97
-
98
- def video(blog_name, options={})
99
- valid_opts = @@standard_post_options + [:data, :embed, :caption]
100
- if valid_options(valid_opts, options)
101
- options[:type] = "video"
102
- if (options.has_key?(:data) && options.has_key?(:embed))
103
- raise Exception, "You can only use one parameter, either data or embed."
104
- end
105
- if(options.has_key?(:data))
106
- options[:data] = File.open(options[:data],'rb').read()
107
- end
108
- post("v2/blog/#{blog_name}/post", options)
100
+ elsif options.has_key?(:data_raw)
101
+ data_raw = options.delete :data_raw
102
+ data_raw = [data_raw] unless Array === data_raw
103
+ data_raw.each.with_index do |dr, idx|
104
+ options["data[#{idx}]"] = dr
109
105
  end
110
106
  end
111
107
  end
112
- end
108
+
109
+ end
113
110
  end