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 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
- => <WWW::Mechanize::Page...>
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.0
1
+ 0.1.2
data/lib/rubytube.rb CHANGED
@@ -1,7 +1,13 @@
1
1
  $LOAD_PATH.unshift File.dirname(__FILE__)
2
2
 
3
- %w( rubygems mechanize ).each {|lib| require lib }
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
- @required_fiels
26
+ @required_fields
21
27
  end
22
- @required_fiels ||= %w( name title url description duration )
23
28
 
24
- attr_accessor :name, :twitter, :title, :url, :duration, :tags, :description
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
- def fields
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
- def submit!
64
- return unless valid?
65
-
66
- # the reason we're using instance variables is for caching (@agent) and
67
- # so you can easily grab the values of these variables if you need them for debugging
68
- @agent ||= WWW::Mechanize.new {|a| a.user_agent_alias = 'Linux Mozilla' }
69
- @page = @agent.get 'http://rubytu.be/'
70
- @submit_form = @page.forms.find {|form| form.action == '/content' }
71
- @submit_form.set_fields fields
72
- @agent.submit @submit_form
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
@@ -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.fields['content[submitted_by]'].should == screencast.name
65
- screencast.fields['content[submitted_by_twitter]'].should == screencast._twitter_value
66
- screencast.fields['content[title]'].should == screencast.title
67
- screencast.fields['content[url]'].should == screencast.url
68
- screencast.fields['content[tag_list]'].should == screencast._tags_value
69
- screencast.fields['content[duration]'].should == screencast.duration
70
- screencast.fields['content[about]'].should == screencast.description
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
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: remi-rubytube
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - remi