jamescallmebrent-rumblr 0.0.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/LICENSE.rdoc ADDED
@@ -0,0 +1,24 @@
1
+ = License
2
+
3
+ (The MIT License)
4
+
5
+ Copyright (c) 2009 Brent Hargrave
6
+
7
+ Permission is hereby granted, free of charge, to any person obtaining
8
+ a copy of this software and associated documentation files (the
9
+ "Software"), to deal in the Software without restriction, including
10
+ without limitation the rights to use, copy, modify, merge, publish,
11
+ distribute, sublicense, and/or sell copies of the Software, and to
12
+ permit persons to whom the Software is furnished to do so, subject to
13
+ the following conditions:
14
+
15
+ The above copyright notice and this permission notice shall be
16
+ included in all copies or substantial portions of the Software.
17
+
18
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
22
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,66 @@
1
+ = Rumblr
2
+
3
+ Rumblr is a Ruby client for http://www.tumblr.com XML API. It currently only provides read functionality; you can read User, Tumblelog and Post data.
4
+
5
+ = Overview
6
+
7
+ Rumblr maps the Tumblr API 'authenticate' and 'read' calls. User, Tumblelog and Post models have attributes provided by the API, as well as some convenience methods for common tasks.
8
+
9
+ Please read Tumblr's official documentation (http://tumblr.com/api/) to learn more the API.
10
+
11
+
12
+ == Dependencies
13
+
14
+ * Ruby >= 1.8.6 (not tested with previous versions)
15
+ * libxml-ruby >= 0.8.3
16
+
17
+
18
+ == Download and Installation
19
+
20
+ RubyGems[http://rubyforge.org/projects/rubygems/] is the preferred install method.
21
+ To get the latest version, simply type the following instruction into your command prompt:
22
+
23
+ $ sudo gem install jamescallmebrent-rumblr -s http://gems.github.com
24
+
25
+
26
+ == Getting Started
27
+
28
+ In order to use this library you need a valid Tumblr account.
29
+ Go to http://tumblr.com and register for a new account if you don't already have one.
30
+
31
+
32
+ === Sample usage:
33
+
34
+ require 'rumblr'
35
+ include Rumblr
36
+
37
+ user = User.login({:email => 'name@domain.com', :password => 'pass'})
38
+
39
+ user.tumblelogs.each do |log|
40
+ puts log.name # 'the tumblelogger'
41
+ puts log.type # 'public'
42
+ puts log.url # 'http://tumblelogger.tumblr.com/'
43
+ puts
44
+ end
45
+
46
+ tumblelog = user.primary_tumblelog
47
+
48
+ tumblelog.posts.each do |post|
49
+ puts post.type # 'quote'
50
+ puts post.url # 'http://tumblelogger.tumblr.com/post/12345/my-first-tumblr-post'
51
+ end
52
+
53
+
54
+ == Credits
55
+
56
+ Author:: {Brent Hargrave}[http://brenthargrave.info/] <brent.hargrave@gmail.com>
57
+
58
+
59
+ == FeedBack and Bug reports
60
+
61
+ Please email {Brent Hargrave}[mailto:brent.hargrave@gmail.com] with any questions or feedback.
62
+
63
+
64
+ == License
65
+
66
+ Copyright (c) 2009 Brent Hargrave. Rumblr is released under the MIT license.
data/VERSION.yml ADDED
@@ -0,0 +1,4 @@
1
+ ---
2
+ :major: 0
3
+ :minor: 0
4
+ :patch: 0
@@ -0,0 +1,141 @@
1
+ module Rumblr
2
+
3
+ class Client
4
+ include Singleton
5
+
6
+ # The default set of headers for each request.
7
+ DEFAULT_HEADER = {
8
+ 'User-Agent' => 'Rumblr',
9
+ 'Accept' => 'application/xml'
10
+ }
11
+
12
+ def authenticate(email,password)
13
+ raise ArgumentError unless (email && password)
14
+ user_credentials = { :email => email, :password => password }
15
+ uri = URI::HTTP.build({:path => '/api/authenticate'})
16
+ request = Net::HTTP::Post.new(uri.request_uri, DEFAULT_HEADER)
17
+ request.set_form_data(user_credentials)
18
+
19
+ user_attributes = nil
20
+ complete_request(request) do |response_body|
21
+ user_attributes = parse_user_attributes_from(response_body)
22
+ user_attributes.merge!(user_credentials)
23
+ end
24
+ User.new(user_attributes)
25
+ end
26
+
27
+ def read(options={})
28
+ tumblelog, posts = nil, [] # initialize the return targets
29
+
30
+ uri = URI::HTTP.build({:path => '/api/read'})
31
+ request = Net::HTTP::Post.new(uri.request_uri, DEFAULT_HEADER)
32
+ request.set_form_data(options)
33
+
34
+ raise(ArgumentError) unless (options && options[:url] && !options[:url].empty?)
35
+
36
+ request_url_host = URI.parse(options[:url]).host
37
+ complete_request(request,host=request_url_host) do |response_body|
38
+ parser, parser.string = XML::Parser.new, response_body
39
+ doc = parser.parse
40
+ # parse and map posts
41
+ posts = doc.find('//tumblr/posts/post').inject([]) do |array, element|
42
+ post_attrs = cleanup_hash(element.attributes.to_h)
43
+ # inner elements => sublcass-specific attribute hash
44
+ subclass_attrs = element.children.inject({'tags' => []}) do |hash, child|
45
+ hash['tags'] << child.content if (child.name[/tag/])
46
+ hash[child.name] = child.content
47
+ hash
48
+ end
49
+ # merge hashes, clean out cruft
50
+ inner_attrs = cleanup_hash(subclass_attrs)
51
+ inner_attrs.delete(:text)
52
+ inner_attrs.delete(:tag)
53
+ post_attrs.merge!(inner_attrs)
54
+ # turn attributes into proper model
55
+ klass = case post_attrs[:type]
56
+ when 'regular' then RegularPost
57
+ when 'photo' then PhotoPost
58
+ when 'quote' then QuotePost
59
+ when 'link' then LinkPost
60
+ when 'conversation' then ConversationPost
61
+ when 'video' then VideoPost
62
+ when 'audio' then AudioPost
63
+ else raise 'unknown post type'
64
+ end
65
+ post = klass.new(post_attrs)
66
+ array << post
67
+ array
68
+ end
69
+ # parse and map tumblelog
70
+ tumblelog_element = doc.find_first('//tumblr/tumblelog')
71
+ tumblelog_attrs = cleanup_hash(tumblelog_element.attributes.to_h)
72
+ tumblelog_attrs.merge!(:url => options[:url])
73
+ tumblelog = Tumblelog.new(tumblelog_attrs)
74
+ end
75
+ return tumblelog, posts
76
+ end
77
+
78
+
79
+ protected
80
+
81
+ # Starts and completes the given request. Returns or yields the response body.
82
+ def complete_request(request, host = URI.parse(Rumblr.api_url).host)
83
+ http = Net::HTTP.new(host)
84
+ # Set to debug http output.
85
+ # http.set_debug_output $stderr
86
+ response = http.start { |http| http.request(request) }
87
+
88
+ case response
89
+ when Net::HTTPSuccess then yield response.body if block_given?
90
+ when Net::HTTPBadRequest then raise Rumblr::RequestError, parse_error_message(response)
91
+ when Net::HTTPForbidden then raise Rumblr::AuthorizationError, parse_error_message(response)
92
+ when Net::HTTPNotFound then raise Rumblr::MissingResourceError, parse_error_message(response)
93
+ when Net::HTTPMovedPermanently then raise Rumblr::MovedResourceError, parse_error_message(response)
94
+ when Net::HTTPServerError then raise Rumblr::ServerError, connection_error_message
95
+ else raise "Received an unexpected HTTP response: #{response}"
96
+ end
97
+
98
+ response.body
99
+ end
100
+
101
+ # Extracts the error message from the response for the exception.
102
+ def parse_error_message(response)
103
+ response.body
104
+ end
105
+
106
+ def connection_error_message
107
+ "There was a problem connecting to Tumblr"
108
+ end
109
+
110
+
111
+ private
112
+
113
+ def parse_user_attributes_from(response_body)
114
+ parser, parser.string = XML::Parser.new, response_body
115
+ doc = parser.parse
116
+ tumblelogs = doc.find('//tumblr/tumblelog').inject([]) do |array, element|
117
+ tumblelog_attrs = cleanup_hash(element.attributes.to_h)
118
+ array << Tumblelog.new(tumblelog_attrs)
119
+ array
120
+ end
121
+ raw_user_attributes = doc.find('//tumblr/user').first.attributes.to_h
122
+ user_attributes = cleanup_hash(raw_user_attributes)
123
+ user_attributes.merge!(:tumblelogs => tumblelogs)
124
+ end
125
+
126
+ def cleanup_hash(attrs={})
127
+ clean_attrs = attrs.inject({}) do |hash,(key,value)|
128
+ mapped_key = key.gsub(/-/,'_').to_sym
129
+ mapped_value = case value
130
+ when /($1^|$yes^)/ then true
131
+ when /($0^|$no^)/ then false
132
+ else value
133
+ end
134
+ hash[mapped_key] = mapped_value
135
+ hash
136
+ end
137
+ end
138
+
139
+ end
140
+
141
+ end
@@ -0,0 +1,51 @@
1
+ module Rumblr
2
+
3
+ # for attribute details, see Tumblr's documentation:
4
+ # http://www.tumblr.com/api
5
+ class Post < Resource
6
+ attr_reader :id, :url, :type, :unix_timestamp, :date_gmt, :date, :tags, :private
7
+
8
+ def initialize(attrs={})
9
+ @private = false
10
+ super
11
+ end
12
+
13
+ def private?
14
+ @private
15
+ end
16
+
17
+ def public?
18
+ !self.private?
19
+ end
20
+
21
+ end
22
+
23
+ class RegularPost < Post
24
+ attr_reader :title, :body
25
+ end
26
+
27
+ class PhotoPost < Post
28
+ attr_reader :source, :data, :caption, :click_through_url
29
+ end
30
+
31
+ class QuotePost < Post
32
+ attr_reader :quote, :source
33
+ end
34
+
35
+ class LinkPost < Post
36
+ attr_reader :name, :url, :description
37
+ end
38
+
39
+ class ConversationPost < Post
40
+ attr_reader :title, :conversation
41
+ end
42
+
43
+ class VideoPost < Post
44
+ attr_reader :embed, :data, :title, :caption
45
+ end
46
+
47
+ class AudioPost < Post
48
+ attr_reader :data, :caption
49
+ end
50
+
51
+ end
@@ -0,0 +1,13 @@
1
+ module Rumblr
2
+
3
+ class Resource
4
+
5
+ def initialize(attrs={})
6
+ attrs.each do |key,value|
7
+ self.instance_variable_set(:"@#{key.to_s}", value)
8
+ end
9
+ end
10
+
11
+ end
12
+
13
+ end
@@ -0,0 +1,24 @@
1
+ module Rumblr
2
+
3
+ class Tumblelog < Resource
4
+ attr_reader :name, :timezone, :cname, :title, :url, :avatar_url, :is_primary,
5
+ :type, :private_id
6
+
7
+ def posts
8
+ return [] unless self.url
9
+ log, posts = Client.instance.read(:url => self.url)
10
+ return posts
11
+ end
12
+
13
+ class << self
14
+
15
+ def find_by_url(url)
16
+ log, posts = Client.instance.read(:url => url)
17
+ return log
18
+ end
19
+
20
+ end
21
+
22
+ end
23
+
24
+ end
@@ -0,0 +1,23 @@
1
+ module Rumblr
2
+
3
+ class User < Resource
4
+ attr_reader :email, :password, :can_upload_video, :can_upload_aiff, :vimeo_login_url, :can_upload_audio
5
+
6
+ def tumblelogs
7
+ instance_variable_get(:@tumblelogs) || []
8
+ end
9
+
10
+ def primary_tumblelog
11
+ self.tumblelogs.find { |log| log.is_primary }
12
+ end
13
+
14
+ class << self
15
+ def login(attrs={})
16
+ email, password = attrs[:email], attrs[:password]
17
+ Client.instance.authenticate(email,password)
18
+ end
19
+ end
20
+
21
+ end
22
+
23
+ end
data/lib/rumblr.rb ADDED
@@ -0,0 +1,28 @@
1
+ module Rumblr
2
+
3
+ class MissingResourceError < Exception; end
4
+ class MovedResourceError < Exception; end
5
+ class AuthorizationError < Exception; end
6
+ class RequestError < Exception; end
7
+ class ServerError < Exception; end
8
+
9
+ class << self
10
+ attr_accessor :api_url
11
+ end
12
+ end
13
+
14
+ Rumblr.api_url = "http://www.tumblr.com"
15
+
16
+ require 'rubygems'
17
+ require 'singleton'
18
+ require 'net/http'
19
+ require 'uri'
20
+ gem 'libxml-ruby', '>= 0.8.3'
21
+ require 'xml'
22
+ require 'pp'
23
+
24
+ require 'rumblr/client'
25
+ require 'rumblr/resource'
26
+ require 'rumblr/tumblelog'
27
+ require 'rumblr/user'
28
+ require 'rumblr/post'
@@ -0,0 +1,111 @@
1
+ require File.join(File.dirname(__FILE__), "/../spec_helper" )
2
+
3
+ module Rumblr
4
+
5
+ describe Client do
6
+
7
+ it 'should not be able to be instantiated externally' do
8
+ lambda { Client.new }.should raise_error(NoMethodError)
9
+ end
10
+
11
+ it 'should be able to instantiate itself' do
12
+ lambda { Client.instance }.should_not raise_error
13
+ end
14
+
15
+ end
16
+
17
+ describe Client, "authentication" do
18
+
19
+ before(:each) { mock_successful(:authenticate) }
20
+
21
+ it 'should raise an ArgumentError without email' do
22
+ lambda do
23
+ @client.authenticate('email', nil)
24
+ end.should raise_error(ArgumentError)
25
+ end
26
+
27
+ it 'should raise an ArgumentError without password' do
28
+ lambda do
29
+ @client.authenticate(nil,'password')
30
+ end.should raise_error(ArgumentError)
31
+ end
32
+
33
+ it 'should return a User if successful' do
34
+ result = @client.authenticate('foo@foo.com','password')
35
+ result.should be_an_instance_of(User)
36
+ end
37
+
38
+ it "should include user's existing tumblelogs" do
39
+ user = @client.authenticate('foo@foo.com','password')
40
+ user.tumblelogs.size.should == 2
41
+ end
42
+
43
+ end
44
+
45
+ describe Client, "reading from a public tumblelog" do
46
+
47
+ it 'without a URL should raise an error' do
48
+ mock_successful(:anonymous_read)
49
+ lambda do
50
+ @client.read
51
+ end.should raise_error(ArgumentError)
52
+ end
53
+
54
+ it 'with an empty URL should raise an error' do
55
+ mock_successful(:anonymous_read)
56
+ lambda do
57
+ @client.read(:url => '')
58
+ end.should raise_error(ArgumentError)
59
+ end
60
+
61
+ describe 'without credentials' do
62
+
63
+ before(:each) do
64
+ mock_successful(:anonymous_read)
65
+ @tumblelog, posts = @client.read(:url => 'http://dummylog.tumblr.com/')
66
+ end
67
+
68
+ it 'should yield only posts' do
69
+ @tumblelog.posts.all? {|post| post.kind_of?(Post)}.should be_true
70
+ end
71
+
72
+ it 'should not include all posts, assuming some are private' do
73
+ @tumblelog.posts.size.should == 7
74
+ end
75
+
76
+ it 'should only include public posts' do
77
+ @tumblelog.posts.all? {|post| post.public? }.should be_true
78
+ end
79
+
80
+ it 'should not include any private posts' do
81
+ @tumblelog.posts.any? {|post| post.private? }.should be_false
82
+ end
83
+
84
+ end
85
+
86
+ describe 'with valid credentials' do
87
+
88
+ before(:each) do
89
+ mock_successful(:authenticated_read)
90
+ @tumblelog, posts = @client.read( :url => 'http://dummylog.tumblr.com/',
91
+ :email => 'valid',
92
+ :password => 'valid' )
93
+ end
94
+
95
+ it 'should include all tumblelog posts' do
96
+ @tumblelog.posts.size.should == 14
97
+ end
98
+
99
+ it 'should include all public posts' do
100
+ @tumblelog.posts.find_all {|p| p.public? }.size.should == 7
101
+ end
102
+
103
+ it 'should include private posts' do
104
+ @tumblelog.posts.find_all {|p| p.public? }.size.should == 7
105
+ end
106
+
107
+ end
108
+
109
+ end
110
+
111
+ end
@@ -0,0 +1,25 @@
1
+ require File.join(File.dirname(__FILE__), "/../spec_helper" )
2
+
3
+ module Rumblr
4
+
5
+ describe Post, 'instances' do
6
+
7
+ it 'should have attributes shared by every Post' do
8
+ Post.new.should respond_to(:id, :url, :type, :unix_timestamp, :date_gmt, :date, :tags, :private)
9
+ end
10
+
11
+ it 'private attribute should default to false' do
12
+ Post.new.private.should be_false
13
+ end
14
+
15
+ it 'should provide it private status' do
16
+ Post.new.should respond_to(:private?)
17
+ end
18
+
19
+ it 'should provide it public status (inverse of private status)' do
20
+ Post.new.should respond_to(:public?)
21
+ end
22
+
23
+ end
24
+
25
+ end
@@ -0,0 +1,39 @@
1
+ require File.join(File.dirname(__FILE__), "/../spec_helper" )
2
+
3
+ module Rumblr
4
+
5
+ describe Tumblelog, 'instances' do
6
+
7
+ it 'should have the attributes of a Tumblelog' do
8
+ Tumblelog.new.should respond_to( :name, :timezone, :cname, :title, :url,
9
+ :avatar_url, :is_primary, :type, :private_id)
10
+ end
11
+
12
+ it "' posts should initialize empty" do
13
+ Tumblelog.new.posts.should be_a_kind_of(Array)
14
+ end
15
+
16
+ end
17
+
18
+ describe Tumblelog, 'finder' do
19
+
20
+ describe 'provided a valid URL' do
21
+
22
+ it 'should successfully retrieve a tumblelog' do
23
+ mock_successful(:anonymous_read)
24
+ log = Tumblelog.find_by_url('valid_url')
25
+ log.should be_an_instance_of(Tumblelog)
26
+ end
27
+
28
+ it 'should retrieve a tumblelog with posts' do
29
+ mock_successful(:anonymous_read)
30
+ log = Tumblelog.find_by_url('valid_url')
31
+ log.posts.first.should be_a_kind_of(Post)
32
+ log.posts.first.type.should_not be_nil
33
+ end
34
+
35
+ end
36
+
37
+ end
38
+
39
+ end
@@ -0,0 +1,69 @@
1
+ require File.join(File.dirname(__FILE__), "/../spec_helper" )
2
+
3
+ module Rumblr
4
+
5
+ describe User, 'initializing' do
6
+
7
+ it 'should have the attributes of a User' do
8
+ User.new.should respond_to( :email,
9
+ :password,
10
+ :can_upload_video,
11
+ :can_upload_aiff,
12
+ :vimeo_login_url,
13
+ :can_upload_audio )
14
+ end
15
+
16
+ it 'tumblelogs should initialize empty' do
17
+ User.new.tumblelogs.should be_a_kind_of(Array)
18
+ end
19
+
20
+ end
21
+
22
+ describe User, 'logging in' do
23
+
24
+ before(:each) do
25
+ mock_successful(:authenticate)
26
+ end
27
+
28
+ it 'should login with email and password' do
29
+ user = User.login(:email => 'valid_email', :password => 'valid_password')
30
+ user.should be_an_instance_of(User)
31
+ end
32
+
33
+ it 'should not initialize without email' do
34
+ lambda do
35
+ User.login(:email => nil, :password => 'valid_password')
36
+ end.should raise_error(ArgumentError)
37
+ end
38
+
39
+ it 'should not initialize without password' do
40
+ lambda do
41
+ User.login(:email => 'valid_email', :password => nil)
42
+ end.should raise_error(ArgumentError)
43
+ end
44
+
45
+ end
46
+
47
+ describe User, ', once logged in,' do
48
+
49
+ before(:each) do
50
+ mock_successful(:authenticate)
51
+ @user = User.login(:email => 'valid_email', :password => 'valid_password')
52
+ end
53
+
54
+ it 'should provide one or more tumblelogs' do
55
+ @user.tumblelogs.size.should == 2
56
+ end
57
+
58
+ it 'should provide *only* tumblelogs' do
59
+ @user.tumblelogs.all? { |obj| obj.should be_an_instance_of(Tumblelog) }
60
+ end
61
+
62
+ it 'should provide a primary tumblelog' do
63
+ primary = @user.primary_tumblelog
64
+ primary.is_primary.should be_true
65
+ end
66
+
67
+ end
68
+
69
+ end
@@ -0,0 +1,105 @@
1
+ $: << File.join(File.dirname(__FILE__), "/../lib" )
2
+
3
+ require 'spec'
4
+ require 'rumblr'
5
+
6
+ def mock_successful(request)
7
+ responses_to = {
8
+ :authenticate => successful_authenticate_xml,
9
+ :anonymous_read => successful_anonymous_read_xml,
10
+ :authenticated_read => successful_authenticated_read_xml,
11
+ :authenticated_write => successful_authenticated_write_xml
12
+ }
13
+
14
+ @client = Rumblr::Client.instance
15
+ # yes, this is cheating, but for now just concerned that xml is parsed right
16
+ @client.stub!(:complete_request).and_yield(responses_to[request])
17
+ end
18
+
19
+ def successful_authenticate_xml
20
+ response = <<-EOF
21
+ <?xml version="1.0" encoding="UTF-8"?>
22
+ <tumblr version="1.0">
23
+ <user can-upload-audio="1" can-upload-aiff="1" can-upload-video="0" vimeo-login-url="http://www.vimeo.com/services/foo"/>
24
+ <tumblelog title="" name="foo" url="http://foo.com/" type="public" avatar-url="http://assets.tumblr.com/images/default_avatar_foo.gif" is-primary="yes"/>
25
+ <tumblelog title="bar" private-id="000000" type="private"/>
26
+ </tumblr>
27
+ EOF
28
+ response.strip!
29
+ end
30
+
31
+ def successful_anonymous_read_xml
32
+ response = <<-EOF
33
+ <?xml version="1.0" encoding="UTF-8"?>
34
+ <tumblr version="1.0">
35
+ <tumblelog name="dummylog" timezone="US/Eastern" title="dummy tumblelog title">dummylog description</tumblelog>
36
+ <posts start="0" total="7">
37
+ <post id="78846368" url="http://dummylog.tumblr.com/post/78846368" type="video" date-gmt="2009-02-16 19:11:45 GMT" date="Mon, 16 Feb 2009 14:11:45" unix-timestamp="1234811505">
38
+ <video-caption>public video post caption</video-caption>
39
+ <video-source>http://www.youtube.com/watch?v=rPaWZOM1LnY</video-source>
40
+ <video-player>&lt;object width="400" height="336"&gt;&lt;param name="movie" value="http://www.youtube.com/v/rPaWZOM1LnY&amp;amp;rel=0&amp;amp;egm=0&amp;amp;showinfo=0&amp;amp;fs=1"&gt;&lt;/param&gt;&lt;param name="wmode" value="transparent"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/rPaWZOM1LnY&amp;amp;rel=0&amp;amp;egm=0&amp;amp;showinfo=0&amp;amp;fs=1" type="application/x-shockwave-flash" width="400" height="336" allowFullScreen="true" wmode="transparent"&gt;&lt;/embed&gt;&lt;/object&gt;</video-player>
41
+ <tag>sale</tag>
42
+ <tag>music</tag>
43
+ </post>
44
+ <post id="78846080" url="http://dummylog.tumblr.com/post/78846080" type="audio" date-gmt="2009-02-16 19:10:20 GMT" date="Mon, 16 Feb 2009 14:10:20" unix-timestamp="1234811420" audio-plays="0">
45
+ <audio-caption>public audio post description</audio-caption><audio-player>&lt;embed type="application/x-shockwave-flash" src="http://dummylog.tumblr.com/swf/audio_player.swf?audio_file=http://www.tumblr.com/audio_file/78846080/TofwJxqCAk12g1e0ClxHx7gh&amp;color=FFFFFF" height="27" width="207" quality="best"&gt;&lt;/embed&gt;</audio-player>
46
+ <tag>sale</tag>
47
+ </post>
48
+ <post id="78844911" url="http://dummylog.tumblr.com/post/78844911" type="conversation" date-gmt="2009-02-16 19:04:48 GMT" date="Mon, 16 Feb 2009 14:04:48" unix-timestamp="1234811088">
49
+ <conversation-title>public chat post title</conversation-title>
50
+ <conversation-text>me: public&#13;
51
+ you: chat&#13;
52
+ me: post&#13;
53
+ you: dialogue</conversation-text><conversation><line name="me" label="me:">public&#13;</line><line name="you" label="you:">chat&#13;</line><line name="me" label="me:">post&#13;</line><line name="you" label="you:">dialogue</line></conversation><conversation-line name="me" label="me:" deprecated="conversation-line is deprecated and will soon be removed. Use ./conversation/line.">public&#13;</conversation-line><conversation-line name="you" label="you:" deprecated="conversation-line is deprecated and will soon be removed. Use ./conversation/line.">chat&#13;</conversation-line><conversation-line name="me" label="me:" deprecated="conversation-line is deprecated and will soon be removed. Use ./conversation/line.">post&#13;</conversation-line><conversation-line name="you" label="you:" deprecated="conversation-line is deprecated and will soon be removed. Use ./conversation/line.">dialogue</conversation-line>
54
+ <tag>sale</tag>
55
+ </post>
56
+ <post id="78844351" url="http://dummylog.tumblr.com/post/78844351" type="link" date-gmt="2009-02-16 19:02:00 GMT" date="Mon, 16 Feb 2009 14:02:00" unix-timestamp="1234810920">
57
+ <link-text>public link post name</link-text><link-url>http://www.google.com</link-url>
58
+ <link-description>public link post description</link-description>
59
+ <tag>sale</tag>
60
+ </post>
61
+ <post id="78844076" url="http://dummylog.tumblr.com/post/78844076" type="quote" date-gmt="2009-02-16 19:01:06 GMT" date="Mon, 16 Feb 2009 14:01:06" unix-timestamp="1234810866">
62
+ <quote-text>public quote post content</quote-text>
63
+ <quote-source>public quote post source</quote-source>
64
+ <tag>sale</tag>
65
+ </post>
66
+ <post id="78841604" url="http://dummylog.tumblr.com/post/78841604" type="regular" date-gmt="2009-02-16 18:50:00 GMT" date="Mon, 16 Feb 2009 13:50:00" unix-timestamp="1234810200">
67
+ <regular-title>public text post title</regular-title>
68
+ <regular-body>public text post body</regular-body>
69
+ <tag>sale</tag>
70
+ </post>
71
+ <post id="78841444" url="http://dummylog.tumblr.com/post/78841444" type="photo" date-gmt="2009-02-16 18:49:00 GMT" date="Mon, 16 Feb 2009 13:49:00" unix-timestamp="1234810140">
72
+ <photo-caption>public photo post</photo-caption>
73
+ <photo-url max-width="500">http://21.media.tumblr.com/TofwJxqCAk11p5psVgVhLwzJo1_500.jpg</photo-url>
74
+ <photo-url max-width="400">http://1.media.tumblr.com/TofwJxqCAk11p5psVgVhLwzJo1_400.jpg</photo-url>
75
+ <photo-url max-width="250">http://22.media.tumblr.com/TofwJxqCAk11p5psVgVhLwzJo1_250.jpg</photo-url>
76
+ <photo-url max-width="100">http://19.media.tumblr.com/TofwJxqCAk11p5psVgVhLwzJo1_100.jpg</photo-url>
77
+ <photo-url max-width="75">http://2.media.tumblr.com/TofwJxqCAk11p5psVgVhLwzJo1_75sq.jpg</photo-url>
78
+ <tag>sale</tag>
79
+ </post>
80
+ </posts>
81
+ </tumblr>
82
+ EOF
83
+ response.strip!
84
+ end
85
+
86
+ def successful_authenticated_read_xml
87
+ response = <<-EOF
88
+ <?xml version="1.0" encoding="UTF-8"?>
89
+ <tumblr version="1.0"><tumblelog name="dummylog" timezone="US/Eastern" title="dummy tumblelog title">dummy tumblelog description</tumblelog><posts start="0" total="7"><post id="78846474" url="http://dummylog.tumblr.com/post/78846474" type="video" date-gmt="2009-02-16 19:12:00 GMT" date="Mon, 16 Feb 2009 14:12:00" unix-timestamp="1234811520" private="true"><video-caption>private video post caption</video-caption><video-source>http://www.youtube.com/watch?v=rPaWZOM1LnY</video-source><video-player>&lt;object width="400" height="336"&gt;&lt;param name="movie" value="http://www.youtube.com/v/rPaWZOM1LnY&amp;amp;rel=0&amp;amp;egm=0&amp;amp;showinfo=0&amp;amp;fs=1"&gt;&lt;/param&gt;&lt;param name="wmode" value="transparent"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/rPaWZOM1LnY&amp;amp;rel=0&amp;amp;egm=0&amp;amp;showinfo=0&amp;amp;fs=1" type="application/x-shockwave-flash" width="400" height="336" allowFullScreen="true" wmode="transparent"&gt;&lt;/embed&gt;&lt;/object&gt;</video-player><tag>sale</tag><tag>tag2</tag><tag>music</tag></post><post id="78846368" url="http://dummylog.tumblr.com/post/78846368" type="video" date-gmt="2009-02-16 19:11:00 GMT" date="Mon, 16 Feb 2009 14:11:00" unix-timestamp="1234811460"><video-caption>public video post caption</video-caption><video-source>hilhttp://www.youtube.com/watch?v=rPaWZOM1LnY</video-source><video-player>&lt;object width="400" height="336"&gt;&lt;param name="movie" value="http://www.youtube.com/v/rPaWZOM1LnY&amp;amp;rel=0&amp;amp;egm=0&amp;amp;showinfo=0&amp;amp;fs=1"&gt;&lt;/param&gt;&lt;param name="wmode" value="transparent"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/rPaWZOM1LnY&amp;amp;rel=0&amp;amp;egm=0&amp;amp;showinfo=0&amp;amp;fs=1" type="application/x-shockwave-flash" width="400" height="336" allowFullScreen="true" wmode="transparent"&gt;&lt;/embed&gt;&lt;/object&gt;</video-player><tag>hilarious</tag></post><post id="78846150" url="http://dummylog.tumblr.com/post/78846150" type="audio" date-gmt="2009-02-16 19:10:43 GMT" date="Mon, 16 Feb 2009 14:10:43" unix-timestamp="1234811443" private="true" audio-plays="2"><audio-caption>private audio post description</audio-caption><audio-player>&lt;embed type="application/x-shockwave-flash" src="http://dummylog.tumblr.com/swf/audio_player.swf?audio_file=http://www.tumblr.com/audio_file/78846150/TofwJxqCAk12gje4UYRllUwM&amp;color=FFFFFF" height="27" width="207" quality="best"&gt;&lt;/embed&gt;</audio-player><tag>sale</tag></post><post id="78846080" url="http://dummylog.tumblr.com/post/78846080" type="audio" date-gmt="2009-02-16 19:10:00 GMT" date="Mon, 16 Feb 2009 14:10:00" unix-timestamp="1234811400" audio-plays="0"><audio-caption>public audio post description</audio-caption><audio-player>&lt;embed type="application/x-shockwave-flash" src="http://dummylog.tumblr.com/swf/audio_player.swf?audio_file=http://www.tumblr.com/audio_file/78846080/TofwJxqCAk12g1e0ClxHx7gh&amp;color=FFFFFF" height="27" width="207" quality="best"&gt;&lt;/embed&gt;</audio-player><tag>sale</tag><tag>music</tag></post><post id="78844968" url="http://dummylog.tumblr.com/post/78844968" type="conversation" date-gmt="2009-02-16 19:05:08 GMT" date="Mon, 16 Feb 2009 14:05:08" unix-timestamp="1234811108" private="true"><conversation-title>private chat post title</conversation-title><conversation-text>me: private&#13;
90
+ you: chat&#13;
91
+ me: post&#13;
92
+ you: dialogue</conversation-text><conversation><line name="me" label="me:">private&#13;</line><line name="you" label="you:">chat&#13;</line><line name="me" label="me:">post&#13;</line><line name="you" label="you:">dialogue</line></conversation><conversation-line name="me" label="me:" deprecated="conversation-line is deprecated and will soon be removed. Use ./conversation/line.">private&#13;</conversation-line><conversation-line name="you" label="you:" deprecated="conversation-line is deprecated and will soon be removed. Use ./conversation/line.">chat&#13;</conversation-line><conversation-line name="me" label="me:" deprecated="conversation-line is deprecated and will soon be removed. Use ./conversation/line.">post&#13;</conversation-line><conversation-line name="you" label="you:" deprecated="conversation-line is deprecated and will soon be removed. Use ./conversation/line.">dialogue</conversation-line><tag>sale</tag></post><post id="78844911" url="http://dummylog.tumblr.com/post/78844911" type="conversation" date-gmt="2009-02-16 19:04:48 GMT" date="Mon, 16 Feb 2009 14:04:48" unix-timestamp="1234811088"><conversation-title>public chat post title</conversation-title><conversation-text>me: public&#13;
93
+ you: chat&#13;
94
+ me: post&#13;
95
+ you: dialogue</conversation-text><conversation><line name="me" label="me:">public&#13;</line><line name="you" label="you:">chat&#13;</line><line name="me" label="me:">post&#13;</line><line name="you" label="you:">dialogue</line></conversation><conversation-line name="me" label="me:" deprecated="conversation-line is deprecated and will soon be removed. Use ./conversation/line.">public&#13;</conversation-line><conversation-line name="you" label="you:" deprecated="conversation-line is deprecated and will soon be removed. Use ./conversation/line.">chat&#13;</conversation-line><conversation-line name="me" label="me:" deprecated="conversation-line is deprecated and will soon be removed. Use ./conversation/line.">post&#13;</conversation-line><conversation-line name="you" label="you:" deprecated="conversation-line is deprecated and will soon be removed. Use ./conversation/line.">dialogue</conversation-line><tag>sale</tag></post><post id="78844625" url="http://dummylog.tumblr.com/post/78844625" type="link" date-gmt="2009-02-16 19:03:00 GMT" date="Mon, 16 Feb 2009 14:03:00" unix-timestamp="1234810980" private="true"><link-text>private link post name</link-text><link-url>http://www.google.com</link-url><link-description>private link post description</link-description><tag>sale</tag></post><post id="78844351" url="http://dummylog.tumblr.com/post/78844351" type="link" date-gmt="2009-02-16 19:02:00 GMT" date="Mon, 16 Feb 2009 14:02:00" unix-timestamp="1234810920"><link-text>public link post name</link-text><link-url>http://www.google.com</link-url><link-description>public link post description</link-description><tag>sale</tag></post><post id="78844076" url="http://dummylog.tumblr.com/post/78844076" type="quote" date-gmt="2009-02-16 19:01:06 GMT" date="Mon, 16 Feb 2009 14:01:06" unix-timestamp="1234810866"><quote-text>public quote post content</quote-text><quote-source>public quote post source</quote-source><tag>sale</tag></post><post id="78844136" url="http://dummylog.tumblr.com/post/78844136" type="quote" date-gmt="2009-02-16 19:01:00 GMT" date="Mon, 16 Feb 2009 14:01:00" unix-timestamp="1234810860" private="true"><quote-text>private quote post content</quote-text><quote-source>private quote post content</quote-source><tag>sale</tag></post><post id="78843778" url="http://dummylog.tumblr.com/post/78843778" type="photo" date-gmt="2009-02-16 18:59:40 GMT" date="Mon, 16 Feb 2009 13:59:40" unix-timestamp="1234810780" private="true"><photo-caption>private photo post</photo-caption><photo-url max-width="500">http://7.media.tumblr.com/TofwJxqCAk122bofvQLGsl89o1_500.jpg</photo-url><photo-url max-width="400">http://6.media.tumblr.com/TofwJxqCAk122bofvQLGsl89o1_400.jpg</photo-url><photo-url max-width="250">http://11.media.tumblr.com/TofwJxqCAk122bofvQLGsl89o1_250.jpg</photo-url><photo-url max-width="100">http://11.media.tumblr.com/TofwJxqCAk122bofvQLGsl89o1_100.jpg</photo-url><photo-url max-width="75">http://22.media.tumblr.com/TofwJxqCAk122bofvQLGsl89o1_75sq.jpg</photo-url><tag>sale</tag></post><post id="78843501" url="http://dummylog.tumblr.com/post/78843501" type="regular" date-gmt="2009-02-16 18:58:00 GMT" date="Mon, 16 Feb 2009 13:58:00" unix-timestamp="1234810680" private="true"><regular-title>private text post title</regular-title><regular-body>private text post body</regular-body><tag>sale</tag></post><post id="78841604" url="http://dummylog.tumblr.com/post/78841604" type="regular" date-gmt="2009-02-16 18:50:00 GMT" date="Mon, 16 Feb 2009 13:50:00" unix-timestamp="1234810200"><regular-title>public text post title</regular-title><regular-body>public text post body</regular-body><tag>sale</tag></post><post id="78841444" url="http://dummylog.tumblr.com/post/78841444" type="photo" date-gmt="2009-02-16 18:49:00 GMT" date="Mon, 16 Feb 2009 13:49:00" unix-timestamp="1234810140"><photo-caption>public photo post</photo-caption><photo-url max-width="500">http://21.media.tumblr.com/TofwJxqCAk11p5psVgVhLwzJo1_500.jpg</photo-url><photo-url max-width="400">http://1.media.tumblr.com/TofwJxqCAk11p5psVgVhLwzJo1_400.jpg</photo-url><photo-url max-width="250">http://22.media.tumblr.com/TofwJxqCAk11p5psVgVhLwzJo1_250.jpg</photo-url><photo-url max-width="100">http://19.media.tumblr.com/TofwJxqCAk11p5psVgVhLwzJo1_100.jpg</photo-url><photo-url max-width="75">http://2.media.tumblr.com/TofwJxqCAk11p5psVgVhLwzJo1_75sq.jpg</photo-url><tag>sale</tag></post></posts></tumblr>
96
+ EOF
97
+ response.strip!
98
+ end
99
+
100
+ def successful_authenticated_write_xml
101
+ response = <<-EOF
102
+ <?xml version="1.0" encoding="UTF-8"?>
103
+ EOF
104
+ response.strip!
105
+ end
metadata ADDED
@@ -0,0 +1,78 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: jamescallmebrent-rumblr
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Brent Hargrave
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-02-17 00:00:00 -08:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: libxml-ruby
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 0.8.3
24
+ version:
25
+ description: Ruby client for the Tumblr API
26
+ email: brent.hargrave@gmail.com
27
+ executables: []
28
+
29
+ extensions: []
30
+
31
+ extra_rdoc_files: []
32
+
33
+ files:
34
+ - LICENSE.rdoc
35
+ - README.rdoc
36
+ - VERSION.yml
37
+ - lib/rumblr
38
+ - lib/rumblr/client.rb
39
+ - lib/rumblr/post.rb
40
+ - lib/rumblr/resource.rb
41
+ - lib/rumblr/tumblelog.rb
42
+ - lib/rumblr/user.rb
43
+ - lib/rumblr.rb
44
+ - spec/rumblr
45
+ - spec/rumblr/client_spec.rb
46
+ - spec/rumblr/post_spec.rb
47
+ - spec/rumblr/tumblelog_spec.rb
48
+ - spec/rumblr/user_spec.rb
49
+ - spec/spec_helper.rb
50
+ has_rdoc: true
51
+ homepage: http://github.com/jamescallmebrent/rumblr
52
+ post_install_message:
53
+ rdoc_options:
54
+ - --inline-source
55
+ - --charset=UTF-8
56
+ require_paths:
57
+ - lib
58
+ required_ruby_version: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: "0"
63
+ version:
64
+ required_rubygems_version: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: "0"
69
+ version:
70
+ requirements: []
71
+
72
+ rubyforge_project:
73
+ rubygems_version: 1.2.0
74
+ signing_key:
75
+ specification_version: 2
76
+ summary: Ruby client for the Tumblr API
77
+ test_files: []
78
+