remi-rubytube 0.1.0 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +16 -1
- data/VERSION +1 -1
- data/lib/rubytube.rb +124 -22
- data/spec/screencast_spec.rb +8 -7
- metadata +1 -1
data/README.rdoc
CHANGED
@@ -31,4 +31,19 @@ a screencast doesn't sound pleasant ... so I figured I'd automate it.
|
|
31
31
|
=> #<RubyTube::Screencast:0x7fcc8a831c98...>
|
32
32
|
|
33
33
|
>> screencast.submit!
|
34
|
-
=>
|
34
|
+
=> "Thanks for the submission! We'll post it after a quick review!"
|
35
|
+
|
36
|
+
# If you try to submit the same screencast again:
|
37
|
+
|
38
|
+
>> screencast.submit!
|
39
|
+
=> "There was a problem, most likely a wrong or duplicate URL, sorry!"
|
40
|
+
|
41
|
+
After you've called RubyTube::Screencast#submit! you can goto a URL like http://rubytu.be/ruby-basics
|
42
|
+
to see if your screencast was created. It will show up here before it is added to the home page
|
43
|
+
of the site (my guess is that the site owner approves all videos?)
|
44
|
+
|
45
|
+
== Resources
|
46
|
+
|
47
|
+
RubyTube Site:: http://rubytu.be
|
48
|
+
RDoc:: http://remi.github.com/rubytube
|
49
|
+
Code:: http://github.com/remi/rubytube
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
1
|
+
0.1.2
|
data/lib/rubytube.rb
CHANGED
@@ -1,7 +1,13 @@
|
|
1
1
|
$LOAD_PATH.unshift File.dirname(__FILE__)
|
2
2
|
|
3
|
-
|
3
|
+
require 'rubygems'
|
4
4
|
|
5
|
+
begin
|
6
|
+
require 'mechanize'
|
7
|
+
rescue LoadError
|
8
|
+
raise "mechanize failed to load. try: sudo gem install mechanize"
|
9
|
+
end
|
10
|
+
|
5
11
|
module RubyTube #:nodoc:
|
6
12
|
|
7
13
|
# Represents a screencast on http://rubytu.be
|
@@ -9,27 +15,66 @@ module RubyTube #:nodoc:
|
|
9
15
|
# Currently, this is just used to post screencasts to RubyTube,
|
10
16
|
# not to pull them. Unfortunately, RubyTube doesn't appear to
|
11
17
|
# have any kind of an API or easy way to access video information.
|
12
|
-
#
|
13
|
-
# The whole site is 1 page (with pagination) and there's a Feed:
|
14
|
-
# http://feeds.feedburner.com/rubytube?format=xml
|
15
|
-
#
|
16
|
-
# There are tags, but they don't even work!
|
17
18
|
class Screencast
|
18
|
-
|
19
|
+
|
20
|
+
# Returns the required fields/attributes (an Array of strings or symbols)
|
21
|
+
#
|
22
|
+
# #valid? will ensure that each of these attributes is not empty.
|
23
|
+
#
|
24
|
+
# The default fields: DEFAULT_REQUIRED_FIELDS
|
19
25
|
def self.required_fields
|
20
|
-
@
|
26
|
+
@required_fields
|
21
27
|
end
|
22
|
-
@required_fiels ||= %w( name title url description duration )
|
23
28
|
|
24
|
-
|
29
|
+
DEFAULT_REQUIRED_FIELDS = %w( name title url description duration )
|
30
|
+
@required_fields ||= DEFAULT_REQUIRED_FIELDS
|
31
|
+
|
32
|
+
# Your name, eg. 'Bob'
|
33
|
+
attr_accessor :name
|
34
|
+
|
35
|
+
# Your twitter ID, eg. '@coolbob'
|
36
|
+
attr_accessor :twitter
|
37
|
+
|
38
|
+
# The title of this Screencast, eg. 'ActiveRecord Awesomness'
|
39
|
+
attr_accessor :title
|
40
|
+
|
41
|
+
# The absolute path to this Screencast. This should not be a media
|
42
|
+
# URL (eg. a path to a video) nor should it be a URL to a site that
|
43
|
+
# has many videos (eg. 'http://peepcode.com'). Instead, this should
|
44
|
+
# be a link to a page that's specific to this Screencast
|
45
|
+
attr_accessor :url
|
46
|
+
|
47
|
+
# The duration of this Screencast, format: "HH:MM:SS"
|
48
|
+
attr_accessor :duration
|
25
49
|
|
50
|
+
# An Array of tags associated with this screencast, eg: ['Rails', 'ActiveRecord']
|
51
|
+
attr_accessor :tags
|
52
|
+
|
53
|
+
# A short description about this Screencast
|
54
|
+
attr_accessor :description
|
55
|
+
|
56
|
+
# After calling valid?, this is set to an Array which, if the
|
57
|
+
# Screencast isn't valid, will contain messages describing
|
58
|
+
# why the Screencast isn't valid
|
26
59
|
attr_reader :errors
|
27
60
|
|
61
|
+
# Initialized a new Screencast
|
62
|
+
#
|
63
|
+
# Accepts a (standard) Hash or attributes, eg.
|
64
|
+
#
|
65
|
+
# >> @screencast = Screencast.new :name => 'remi', :title => 'Awesome Screencast'
|
66
|
+
#
|
28
67
|
def initialize options = nil
|
29
68
|
@tags ||= []
|
30
69
|
options.each {|k,v| self.send "#{k}=", v } if options
|
31
70
|
end
|
32
71
|
|
72
|
+
# Returns a boolean indicating whether or not this Screencast is valid
|
73
|
+
#
|
74
|
+
# #submit! cannot be called if #valid? doesn't return true
|
75
|
+
#
|
76
|
+
# After calling #valid?, you can check #errors to see messages
|
77
|
+
# describing why this Screencast isn't valid
|
33
78
|
def valid?
|
34
79
|
@errors = []
|
35
80
|
Screencast.required_fields.each do |field|
|
@@ -40,15 +85,67 @@ module RubyTube #:nodoc:
|
|
40
85
|
@errors.empty?
|
41
86
|
end
|
42
87
|
|
88
|
+
# Submits this screencast to http://rubytu.be
|
89
|
+
#
|
90
|
+
# This is the same as going to http://rubytu.be and clicking 'Suggest Video'
|
91
|
+
# and filling out all of the fields
|
92
|
+
#
|
93
|
+
# If you want to preview all of the fields that will be filled out *before*
|
94
|
+
# calling #submit!, see #_fields
|
95
|
+
#
|
96
|
+
# Returns false if the screencast is not valid?, otherwise it returns a
|
97
|
+
# String (taken from the HTML response we get when we submit the form),
|
98
|
+
# describing whether or not the submission/suggestion was successful.
|
99
|
+
def submit!
|
100
|
+
raise "You cannot submit! an invalid Screencast" unless valid?
|
101
|
+
|
102
|
+
# the reason we're using instance variables is for caching (@agent) and
|
103
|
+
# so you can easily grab the values of these variables if you need them for debugging
|
104
|
+
@agent ||= WWW::Mechanize.new {|a| a.user_agent_alias = 'Linux Mozilla' }
|
105
|
+
@page = @agent.get 'http://rubytu.be/'
|
106
|
+
@submit_form = @page.forms.find {|form| form.action == '/content' }
|
107
|
+
@submit_form.set_fields _fields
|
108
|
+
@response = @agent.submit @submit_form
|
109
|
+
|
110
|
+
if @response.at('div.success')
|
111
|
+
@response.at('div.success').text.strip
|
112
|
+
|
113
|
+
elsif @response.at('div.error')
|
114
|
+
@response.at('div.error').text.strip
|
115
|
+
|
116
|
+
else
|
117
|
+
"No success or error message detected? see #_last_response to help with debugging."
|
118
|
+
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
# methods below here should likely be private! but we're keeping them public
|
123
|
+
# and giving them underscore prefixes to indicate that these are private methods
|
124
|
+
|
125
|
+
# [private]
|
126
|
+
#
|
127
|
+
# Returns the raw value to be used for the twitter field in the form we submit
|
128
|
+
#
|
129
|
+
# The user should use the #twitter attribute
|
43
130
|
def _twitter_value
|
44
|
-
(twitter.to_s.strip.empty?) ? '@' : twitter
|
131
|
+
val = (twitter.to_s.strip.empty?) ? '@' : twitter
|
132
|
+
val = "@#{val}" unless val.start_with?('@')
|
133
|
+
val
|
45
134
|
end
|
46
135
|
|
136
|
+
# [private]
|
137
|
+
#
|
138
|
+
# Returns the raw value to be used for the tags field in the form we submit
|
139
|
+
#
|
140
|
+
# The user should use the #tags attribute
|
47
141
|
def _tags_value
|
48
142
|
tags.join(',')
|
49
143
|
end
|
50
144
|
|
51
|
-
|
145
|
+
# [private]
|
146
|
+
#
|
147
|
+
# Returns the raw values to be used for all of the fields in the form we submit
|
148
|
+
def _fields
|
52
149
|
{
|
53
150
|
'content[submitted_by]' => name,
|
54
151
|
'content[submitted_by_twitter]' => _twitter_value,
|
@@ -60,16 +157,21 @@ module RubyTube #:nodoc:
|
|
60
157
|
}
|
61
158
|
end
|
62
159
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
160
|
+
# [private]
|
161
|
+
#
|
162
|
+
# Returns the raw response of the last #submit! call
|
163
|
+
#
|
164
|
+
# This is a WWW::Mechanize::Page object
|
165
|
+
#
|
166
|
+
# To get the raw HTML of the response:
|
167
|
+
#
|
168
|
+
# >> @screencast.last_response.content
|
169
|
+
#
|
170
|
+
# If #submit! hasn't been called on this screencast, this will be nil
|
171
|
+
#
|
172
|
+
# This is really just for debugging!
|
173
|
+
def _last_response
|
174
|
+
@response
|
73
175
|
end
|
74
176
|
|
75
177
|
end
|
data/spec/screencast_spec.rb
CHANGED
@@ -13,6 +13,7 @@ describe RubyTube::Screencast do
|
|
13
13
|
RubyTube::Screencast.gen( :twitter => '@remitaylor' ).twitter.should == '@remitaylor'
|
14
14
|
|
15
15
|
# check the private field that's actually used for form submission
|
16
|
+
RubyTube::Screencast.gen( :twitter => 'remitaylor' )._twitter_value.should == '@remitaylor'
|
16
17
|
RubyTube::Screencast.gen( :twitter => '@remitaylor' )._twitter_value.should == '@remitaylor'
|
17
18
|
RubyTube::Screencast.gen( :twitter => nil )._twitter_value.should == '@'
|
18
19
|
RubyTube::Screencast.gen( :twitter => '' )._twitter_value.should == '@'
|
@@ -61,13 +62,13 @@ describe RubyTube::Screencast do
|
|
61
62
|
:url => 'http://remi.org/some-screencast', :tags => %w( ruby rack ),
|
62
63
|
:duration => '00:02:45'
|
63
64
|
screencast.should be_valid
|
64
|
-
screencast.
|
65
|
-
screencast.
|
66
|
-
screencast.
|
67
|
-
screencast.
|
68
|
-
screencast.
|
69
|
-
screencast.
|
70
|
-
screencast.
|
65
|
+
screencast._fields['content[submitted_by]'].should == screencast.name
|
66
|
+
screencast._fields['content[submitted_by_twitter]'].should == screencast._twitter_value
|
67
|
+
screencast._fields['content[title]'].should == screencast.title
|
68
|
+
screencast._fields['content[url]'].should == screencast.url
|
69
|
+
screencast._fields['content[tag_list]'].should == screencast._tags_value
|
70
|
+
screencast._fields['content[duration]'].should == screencast.duration
|
71
|
+
screencast._fields['content[about]'].should == screencast.description
|
71
72
|
end
|
72
73
|
|
73
74
|
end
|