doomy_client 0.8.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,59 @@
1
+ module Tumblr
2
+ module Blog
3
+
4
+ # Gets the info about the blog
5
+ def blog_info(blog_name)
6
+ get(blog_path(blog_name, 'info'), :api_key => @consumer_key)
7
+ end
8
+
9
+ # Gets the avatar URL of specified size
10
+ def avatar(blog_name, size = nil)
11
+ url = blog_path(blog_name, 'avatar')
12
+ url = "#{url}/#{size}" if size
13
+ get_redirect_url(url)
14
+ end
15
+
16
+ # Gets the list of followers for the blog
17
+ def followers(blog_name, options = {})
18
+ validate_options([:limit, :offset], options)
19
+ get(blog_path(blog_name, 'followers'), options)
20
+ end
21
+
22
+ # Gets the list of likes for the blog
23
+ def blog_likes(blog_name, options = {})
24
+ validate_options([:limit, :offset, :before, :after], options)
25
+ url = blog_path(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 = blog_path(blog_name, 'posts')
34
+ if options.has_key?(:type)
35
+ url = "#{url}/#{options[:type]}"
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(blog_path(blog_name, 'posts/queue'), options)
46
+ end
47
+
48
+ def draft(blog_name, options = {})
49
+ validate_options([:limit, :offset], options)
50
+ get(blog_path(blog_name, 'posts/draft'), options)
51
+ end
52
+
53
+ def submissions(blog_name, options = {})
54
+ validate_options([:limit, :offset], options)
55
+ get(blog_path(blog_name, 'posts/submission'), options)
56
+ end
57
+
58
+ end
59
+ end
@@ -0,0 +1,51 @@
1
+ require 'tumblr/blog'
2
+ require 'tumblr/user'
3
+ require 'tumblr/request'
4
+ require 'tumblr/connection'
5
+ require 'tumblr/post'
6
+ require 'tumblr/tagged'
7
+ require 'tumblr/helpers'
8
+
9
+ module Tumblr
10
+ class Client
11
+
12
+ class << self
13
+ def default_api_host
14
+ ENV['TUMBLR_API_HOST'] || 'api.tumblr.com'
15
+ end
16
+ end
17
+
18
+ include Tumblr::Request
19
+ include Tumblr::Blog
20
+ include Tumblr::User
21
+ include Tumblr::Post
22
+ include Tumblr::Tagged
23
+ include Tumblr::Helper
24
+ include Tumblr::Connection
25
+
26
+ def initialize(attrs= {})
27
+ attrs = Tumblr.options.merge(attrs)
28
+ Config::VALID_OPTIONS_KEYS.each do |key|
29
+ instance_variable_set("@#{key}".to_sym, attrs[key])
30
+ end
31
+ end
32
+
33
+ def api_host
34
+ self.class.default_api_host
35
+ end
36
+
37
+ def api_scheme
38
+ @api_scheme || 'https'
39
+ end
40
+
41
+ def credentials
42
+ {
43
+ :consumer_key => @consumer_key,
44
+ :consumer_secret => @consumer_secret,
45
+ :token => @oauth_token,
46
+ :token_secret => @oauth_token_secret
47
+ }
48
+ end
49
+
50
+ end
51
+ end
@@ -0,0 +1,36 @@
1
+ module Tumblr
2
+ module Config
3
+
4
+ VALID_OPTIONS_KEYS = [
5
+ :consumer_key,
6
+ :consumer_secret,
7
+ :oauth_token,
8
+ :oauth_token_secret,
9
+ :client,
10
+ :api_scheme
11
+ ]
12
+
13
+ attr_accessor *VALID_OPTIONS_KEYS
14
+
15
+ def configure
16
+ yield self
17
+ self
18
+ end
19
+
20
+ def options
21
+ options = {}
22
+ VALID_OPTIONS_KEYS.each{ |pname| options[pname] = send(pname) }
23
+ options
24
+ end
25
+
26
+ def credentials
27
+ {
28
+ :consumer_key => consumer_key,
29
+ :consumer_secret => consumer_secret,
30
+ :token => oauth_token,
31
+ :token_secret => oauth_token_secret
32
+ }
33
+ end
34
+
35
+ end
36
+ end
@@ -0,0 +1,33 @@
1
+ require 'faraday'
2
+ require 'faraday_middleware'
3
+
4
+ module Tumblr
5
+ module Connection
6
+
7
+ def connection(options={})
8
+ options = options.clone
9
+
10
+ default_options = {
11
+ :headers => {
12
+ :accept => 'application/json',
13
+ :user_agent => "tumblr_client/#{Tumblr::VERSION}"
14
+ },
15
+ :url => "#{api_scheme}://#{api_host}/"
16
+ }
17
+
18
+ client = Faraday.default_adapter
19
+
20
+ Faraday.new(default_options.merge(options)) do |conn|
21
+ data = { :api_host => api_host, :ignore_extra_keys => true}.merge(credentials)
22
+ unless credentials.empty?
23
+ conn.request :oauth, data
24
+ end
25
+ conn.request :multipart
26
+ conn.request :url_encoded
27
+ conn.response :json, :content_type => /\bjson$/
28
+ conn.adapter client
29
+ end
30
+ end
31
+
32
+ end
33
+ end
@@ -0,0 +1,29 @@
1
+ module Tumblr
2
+ module Helper
3
+
4
+ private
5
+
6
+ def blog_path(blog_name, ext)
7
+ "v2/blog/#{full_blog_name(blog_name)}/#{ext}"
8
+ end
9
+
10
+ def full_blog_name(blog_name)
11
+ blog_name.include?('.') ? blog_name : "#{blog_name}.tumblr.com"
12
+ end
13
+
14
+ def validate_options(valid_opts, opts)
15
+ bad_opts = opts.select { |val| !valid_opts.include?(val) }
16
+ if bad_opts.any?
17
+ raise ArgumentError.new "Invalid options (#{bad_opts.keys.join(', ')}) passed, only #{valid_opts} allowed."
18
+ end
19
+ end
20
+
21
+ def validate_no_collision(options, attributes)
22
+ count = attributes.count { |attr| options.has_key?(attr) }
23
+ if count > 1
24
+ raise ArgumentError.new "Can only use one of: #{attributes.join(', ')} (Found #{count})"
25
+ end
26
+ end
27
+
28
+ end
29
+ end
@@ -0,0 +1,147 @@
1
+ require 'mime/types'
2
+
3
+ module Tumblr
4
+ module Post
5
+
6
+ STANDARD_POST_OPTIONS = [:is_private, :state, :tags, :tweet, :date, :markdown, :slug, :format]
7
+ DATA_POST_TYPES = [:audio, :video, :photo]
8
+ VALID_POST_TYPES = DATA_POST_TYPES + [:quote, :text, :link, :chat]
9
+
10
+ def edit(blog_name, options = {})
11
+ convert_source_array :source, options
12
+ extract_data!(options) if DATA_POST_TYPES.include?(options[:type])
13
+
14
+ post(blog_path(blog_name, 'post/edit'), options)
15
+ end
16
+
17
+ def reblog(blog_name, options = {})
18
+ post(blog_path(blog_name, 'post/reblog'), options)
19
+ end
20
+
21
+ def delete(blog_name, id)
22
+ post(blog_path(blog_name, 'post/delete'), :id => id)
23
+ end
24
+
25
+ def photo(blog_name, options = {})
26
+ valid_opts = STANDARD_POST_OPTIONS + [:caption, :link, :data, :source, :photoset_layout]
27
+ validate_options(valid_opts, options)
28
+ validate_no_collision options, [:data, :source]
29
+ convert_source_array :source, options
30
+
31
+ options[:type] = 'photo'
32
+ extract_data!(options)
33
+ post(post_path(blog_name), 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(post_path(blog_name), 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(post_path(blog_name), 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(post_path(blog_name), 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(post_path(blog_name), options)
66
+ end
67
+
68
+ def audio(blog_name, options = {})
69
+ valid_opts = STANDARD_POST_OPTIONS + [:data, :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(post_path(blog_name), options)
76
+ end
77
+
78
+ def video(blog_name, options = {})
79
+ valid_opts = STANDARD_POST_OPTIONS + [:data, :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(post_path(blog_name), options)
86
+ end
87
+
88
+ def create_post(type, blog_name, options = {})
89
+ if VALID_POST_TYPES.include?(type)
90
+ send(type, blog_name, options)
91
+ else
92
+ raise ArgumentError.new "\"#{type}\" is not a valid post type"
93
+ end
94
+ end
95
+
96
+ private
97
+
98
+ def post_path(blog_name)
99
+ blog_path(blog_name, 'post')
100
+ end
101
+
102
+ # Allow source to be passed as an Array
103
+ def convert_source_array(key, options)
104
+ if options.has_key?(key) && options[key].kind_of?(Array)
105
+ options[key].each.with_index do |src, idx|
106
+ options["#{key.to_s}[#{idx}]"] = src
107
+ end
108
+ options.delete(key)
109
+ end
110
+ end
111
+
112
+ # Look for the various ways that data can be passed, and normalize
113
+ # the result in this hash
114
+ def extract_data!(options)
115
+ if options.has_key?(:data)
116
+ data = options.delete :data
117
+
118
+ if Array === data
119
+ data.each.with_index do |filepath, idx|
120
+ if filepath.is_a?(Faraday::UploadIO)
121
+ options["data[#{idx}]"] = filepath
122
+ else
123
+ mime_type = extract_mimetype(filepath)
124
+ options["data[#{idx}]"] = Faraday::UploadIO.new(filepath, mime_type)
125
+ end
126
+ end
127
+ elsif data.is_a?(Faraday::UploadIO)
128
+ options["data"] = data
129
+ else
130
+ mime_type = extract_mimetype(data)
131
+ options["data"] = Faraday::UploadIO.new(data, mime_type)
132
+ end
133
+ end
134
+ end
135
+
136
+ def extract_mimetype(filepath)
137
+ mime = MIME::Types.type_for(filepath)
138
+ if (mime.empty?)
139
+ mime_type = "application/octet-stream"
140
+ else
141
+ mime_type = MIME::Types.type_for(filepath)[0].content_type
142
+ end
143
+ mime_type
144
+ end
145
+
146
+ end
147
+ end
@@ -0,0 +1,54 @@
1
+ require 'json'
2
+
3
+ module Tumblr
4
+ module Request
5
+
6
+ # Perform a get request and return the raw response
7
+ def get_response(path, params = {})
8
+ connection.get do |req|
9
+ req.url path
10
+ req.params = params
11
+ end
12
+ end
13
+
14
+ # get a redirect url
15
+ def get_redirect_url(path, params = {})
16
+ response = get_response path, params
17
+ if response.status == 301
18
+ response.headers['Location']
19
+ else
20
+ response.body['meta']
21
+ end
22
+ end
23
+
24
+ # Performs a get request
25
+ def get(path, params={})
26
+ respond get_response(path, params)
27
+ end
28
+
29
+ # Performs post request
30
+ def post(path, params={})
31
+ if Array === params[:tags]
32
+ params[:tags] = params[:tags].join(',')
33
+ end
34
+ response = connection.post do |req|
35
+ req.url path
36
+ req.body = params unless params.empty?
37
+ end
38
+ #Check for errors and encapsulate
39
+ respond(response)
40
+ end
41
+
42
+ def respond(response)
43
+ if [201, 200].include?(response.status)
44
+ response.body['response']
45
+ else
46
+ # surface the meta alongside response
47
+ res = response.body['meta'] || {}
48
+ res.merge! response.body['response'] if response.body['response'].is_a?(Hash)
49
+ res
50
+ end
51
+ end
52
+
53
+ end
54
+ end
@@ -0,0 +1,13 @@
1
+ module Tumblr
2
+ module Tagged
3
+
4
+ def tagged(tag, options={})
5
+ validate_options([:before, :limit, :filter], options)
6
+
7
+ params = { :tag => tag, :api_key => @consumer_key }
8
+ params.merge!(options)
9
+ get("v2/tagged", params)
10
+ end
11
+
12
+ end
13
+ end
@@ -0,0 +1,41 @@
1
+ module Tumblr
2
+ module User
3
+
4
+ def info
5
+ get('v2/user/info')
6
+ end
7
+
8
+ def dashboard(options = {})
9
+ valid_opts = [:limit, :offset, :type, :since_id, :reblog_info, :notes_info]
10
+ validate_options(valid_opts, options)
11
+ get('v2/user/dashboard', options)
12
+ end
13
+
14
+ def likes(options = {})
15
+ validate_options([:limit, :offset, :before, :after], options)
16
+ get('v2/user/likes', options)
17
+ end
18
+
19
+ def following(options = {})
20
+ validate_options([:limit, :offset], options)
21
+ get('v2/user/following', options)
22
+ end
23
+
24
+ def follow(url)
25
+ post('v2/user/follow', :url => url)
26
+ end
27
+
28
+ def unfollow(url)
29
+ post('v2/user/unfollow', :url => url)
30
+ end
31
+
32
+ def like(id, reblog_key)
33
+ post('v2/user/like', :id => id, :reblog_key => reblog_key)
34
+ end
35
+
36
+ def unlike(id, reblog_key)
37
+ post('v2/user/unlike', :id => id, :reblog_key => reblog_key)
38
+ end
39
+
40
+ end
41
+ end