ubiquitously 0.0.1.6 → 0.1.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/README.markdown +224 -19
- data/Rakefile +12 -4
- data/bin/u.me +4 -0
- data/lib/ubiquitously.rb +56 -7
- data/lib/ubiquitously/commands/base.rb +118 -0
- data/lib/ubiquitously/commands/post.rb +108 -0
- data/lib/ubiquitously/commands/user.rb +111 -0
- data/lib/ubiquitously/extensions/callbacks.rb +62 -0
- data/lib/ubiquitously/extensions/core.rb +88 -0
- data/lib/ubiquitously/extensions/mechanize.rb +35 -0
- data/lib/ubiquitously/models/base.rb +18 -0
- data/lib/ubiquitously/models/page.rb +28 -0
- data/lib/ubiquitously/models/post.rb +66 -0
- data/lib/ubiquitously/models/service.rb +1 -0
- data/lib/ubiquitously/models/service/account.rb +57 -0
- data/lib/ubiquitously/models/service/account/authorizable.rb +58 -0
- data/lib/ubiquitously/models/service/account/loggable.rb +50 -0
- data/lib/ubiquitously/models/service/account/restful.rb +21 -0
- data/lib/ubiquitously/models/service/post.rb +59 -0
- data/lib/ubiquitously/models/service/post/loggable.rb +64 -0
- data/lib/ubiquitously/models/service/post/ownable.rb +31 -0
- data/lib/ubiquitously/models/service/post/postable.rb +73 -0
- data/lib/ubiquitously/models/service/post/restful.rb +52 -0
- data/lib/ubiquitously/models/user.rb +128 -0
- data/lib/ubiquitously/services/blogger_den.rb +68 -0
- data/lib/ubiquitously/services/chetzit.rb +37 -0
- data/lib/ubiquitously/services/code_project.rb +21 -0
- data/lib/ubiquitously/services/delicious.rb +54 -0
- data/lib/ubiquitously/services/design_bump.rb +41 -0
- data/lib/ubiquitously/services/designgizer.rb +21 -0
- data/lib/ubiquitously/services/designr_fix.rb +21 -0
- data/lib/ubiquitously/services/digg.rb +151 -0
- data/lib/ubiquitously/services/digzign.rb +25 -0
- data/lib/ubiquitously/services/diigo.rb +68 -0
- data/lib/ubiquitously/services/dzone.rb +132 -0
- data/lib/ubiquitously/services/dzone_snippets.rb +39 -0
- data/lib/ubiquitously/services/facebook.rb +42 -0
- data/lib/ubiquitously/services/faves.rb +81 -0
- data/lib/ubiquitously/services/favshare.rb +78 -0
- data/lib/ubiquitously/services/flikode.rb +38 -0
- data/lib/ubiquitously/services/friendfeed.rb +21 -0
- data/lib/ubiquitously/services/gist.rb +52 -0
- data/lib/ubiquitously/services/google_buzz.rb +15 -0
- data/lib/ubiquitously/services/identica.rb +15 -0
- data/lib/ubiquitously/services/jump_tags.rb +21 -0
- data/lib/ubiquitously/services/kailoon.rb +27 -0
- data/lib/ubiquitously/services/meta_filter.rb +26 -0
- data/lib/ubiquitously/services/mixx.rb +94 -0
- data/lib/ubiquitously/services/mmo.rb +22 -0
- data/lib/ubiquitously/services/mvc_forge.rb +37 -0
- data/lib/ubiquitously/services/my_space.rb +25 -0
- data/lib/ubiquitously/services/nestdev.rb +36 -0
- data/lib/ubiquitously/services/newsvine.rb +76 -0
- data/lib/ubiquitously/services/pixel_groovy.rb +22 -0
- data/lib/ubiquitously/services/posterous.rb +24 -0
- data/lib/ubiquitously/services/programmers_heaven.rb +21 -0
- data/lib/ubiquitously/{propeller.rb → services/propeller.rb} +17 -26
- data/lib/ubiquitously/services/queness.rb +38 -0
- data/lib/ubiquitously/services/reddit.rb +62 -0
- data/lib/ubiquitously/services/scribd.rb +21 -0
- data/lib/ubiquitously/services/script_and_style.rb +23 -0
- data/lib/ubiquitously/services/sharebrain.rb +19 -0
- data/lib/ubiquitously/services/shoutwire.rb +34 -0
- data/lib/ubiquitously/services/slideshare.rb +70 -0
- data/lib/ubiquitously/services/smipple.rb +21 -0
- data/lib/ubiquitously/services/snipplr.rb +67 -0
- data/lib/ubiquitously/services/snipt.rb +49 -0
- data/lib/ubiquitously/services/sphinn.rb +24 -0
- data/lib/ubiquitously/services/stumble_upon.rb +67 -0
- data/lib/ubiquitously/services/stumpedia.rb +13 -0
- data/lib/ubiquitously/services/tumblr.rb +28 -0
- data/lib/ubiquitously/services/tweako.rb +53 -0
- data/lib/ubiquitously/services/twitter.rb +60 -0
- data/lib/ubiquitously/services/web_blend.rb +25 -0
- data/lib/ubiquitously/services/webdev5.rb +32 -0
- data/lib/ubiquitously/services/who_freelance.rb +21 -0
- data/lib/ubiquitously/services/wordtaps.rb +36 -0
- data/lib/ubiquitously/services/yahoo_buzz.rb +64 -0
- data/lib/ubiquitously/services/youblr.rb +15 -0
- data/lib/ubiquitously/services/zabox.rb +22 -0
- data/lib/ubiquitously/support/active_record.rb +25 -0
- data/lib/ubiquitously/support/storage.rb +71 -0
- data/test/config/cookies.yml +111 -0
- data/test/config/credentials.yml +7 -0
- data/test/config/secrets.yml +33 -0
- data/test/config/tokens.yml +30 -0
- data/test/meta.html +19 -0
- data/test/test_delicious.rb +37 -0
- data/test/test_digg.rb +57 -0
- data/test/test_dzone.rb +23 -18
- data/test/test_facebook.rb +40 -0
- data/test/test_faves.rb +18 -20
- data/test/test_helper.rb +8 -1
- data/test/test_newsvine.rb +3 -3
- data/test/test_page.rb +21 -0
- data/test/test_post.rb +55 -0
- data/test/test_propeller.rb +2 -2
- data/test/test_reddit.rb +26 -4
- data/test/test_stumble_upon.rb +23 -3
- data/test/test_twitter.rb +33 -0
- data/test/test_user.rb +22 -0
- metadata +199 -24
- data/lib/ext.rb +0 -37
- data/lib/ubiquitously/base.rb +0 -56
- data/lib/ubiquitously/dzone.rb +0 -111
- data/lib/ubiquitously/faves.rb +0 -43
- data/lib/ubiquitously/mister_wong.rb +0 -11
- data/lib/ubiquitously/mixins/resourceful.rb +0 -50
- data/lib/ubiquitously/mixx.rb +0 -66
- data/lib/ubiquitously/newsvine.rb +0 -54
- data/lib/ubiquitously/reddit.rb +0 -46
- data/lib/ubiquitously/sphinn.rb +0 -11
- data/lib/ubiquitously/stumble_upon.rb +0 -61
- data/test/config.yml +0 -18
@@ -0,0 +1,81 @@
|
|
1
|
+
module Ubiquitously
|
2
|
+
module Faves
|
3
|
+
class Account < Ubiquitously::Service::Account
|
4
|
+
def login
|
5
|
+
page = agent.get("https://secure.faves.com/signIn")
|
6
|
+
form = page.forms.detect {|form| form.form_node["id"] == "signInBox"}
|
7
|
+
form["rUsername"] = username
|
8
|
+
form["rPassword"] = password
|
9
|
+
form["action"] = "Sign In"
|
10
|
+
page = form.submit
|
11
|
+
|
12
|
+
authorize!(page.title !~ /Sign In/i)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
class Post < Ubiquitously::Service::Post
|
17
|
+
def create
|
18
|
+
page = agent.get("http://faves.com/createdot.aspx")
|
19
|
+
form = page.form_with(:name => "createDotForm")
|
20
|
+
form["noteText"] = description
|
21
|
+
form["urlText"] = url
|
22
|
+
form["subjectText"] = title
|
23
|
+
form["tagsText"] = tags.join(", ")
|
24
|
+
form.field_with(:name => "rateSelect").options.each do |option|
|
25
|
+
option.select if option.value.to_s == "5"
|
26
|
+
end
|
27
|
+
form.field_with(:name => "shareSelect").options.each do |option|
|
28
|
+
option.select if option.value.to_s.downcase == "public"
|
29
|
+
end
|
30
|
+
# hidden fields they fill out with javascript
|
31
|
+
# form["imageUrl"] = "http://s3.amazonaws.com/github/ribbons/forkme_right_white_ffffff.png"
|
32
|
+
# form["imageWidth"] = "149"
|
33
|
+
# form["imageHeight"] = "149"
|
34
|
+
# just before you submit the form they append the current time, so they have a range.
|
35
|
+
# mimic the range of time :)
|
36
|
+
form["authoringExpiry"] = form["authoringExpiry"] + "loadedtime=#{1.minute.ago.to_i * 1000}publishedtime=#{Time.now.to_i * 1000}"
|
37
|
+
headers = {
|
38
|
+
"Accept" => "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
|
39
|
+
"Keep-Alive" => "115",
|
40
|
+
"Accept-Encoding" => "gzip,deflate"
|
41
|
+
}
|
42
|
+
|
43
|
+
unless debug?
|
44
|
+
page = form.submit(nil, headers)
|
45
|
+
end
|
46
|
+
|
47
|
+
self
|
48
|
+
end
|
49
|
+
|
50
|
+
class << self
|
51
|
+
def find(options = {})
|
52
|
+
result = []
|
53
|
+
user = options[:user]
|
54
|
+
user_url = "http://faves.com/users/#{user.username_for(self)}"
|
55
|
+
html = Nokogiri::HTML(open(user_url).read)
|
56
|
+
|
57
|
+
html.css(".userDotList li").each do |node|
|
58
|
+
next if node["id"].blank?
|
59
|
+
url = node.css(".note > a").first["href"]
|
60
|
+
title = node.css(".note > p").first.text
|
61
|
+
tags = []
|
62
|
+
node.xpath("a").each do |tag|
|
63
|
+
tags << tag.text if tag["class"].blank?
|
64
|
+
end
|
65
|
+
record = new(
|
66
|
+
:title => title,
|
67
|
+
:url => url,
|
68
|
+
:tags => tags
|
69
|
+
)
|
70
|
+
if options[:url] && options[:url] == record.url
|
71
|
+
return record
|
72
|
+
end
|
73
|
+
result << record
|
74
|
+
end
|
75
|
+
|
76
|
+
options[:url] ? nil : result
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
module Ubiquitously
|
2
|
+
module Favshare
|
3
|
+
class Account < Ubiquitously::Service::Account
|
4
|
+
def login
|
5
|
+
page = agent.get("http://favshare.net/login.php")
|
6
|
+
form = page.forms.detect {|form| form.form_node["id"] == "thisform"}
|
7
|
+
form["username"] = username
|
8
|
+
form["password"] = password
|
9
|
+
form["persistent"] = "persistent"
|
10
|
+
form["processlogin"] = "1"
|
11
|
+
page = form.submit
|
12
|
+
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
# see your posts here: http://favshare.net/user/history/viatropos/
|
17
|
+
class Post < Ubiquitously::Service::Post
|
18
|
+
|
19
|
+
# max tags == 40 chars
|
20
|
+
def tokenize
|
21
|
+
super.merge(:tags => tags.taggify(" ", ", ", 40))
|
22
|
+
end
|
23
|
+
|
24
|
+
def create
|
25
|
+
page = agent.get("http://favshare.net/submit.php")
|
26
|
+
form = page.forms.detect {|form| form.form_node["id"] == "thisform"}
|
27
|
+
|
28
|
+
form["url"] = url
|
29
|
+
|
30
|
+
page = form.submit
|
31
|
+
form = page.forms.detect {|form| form.form_node["id"] == "thisform"}
|
32
|
+
|
33
|
+
form["title"] = title
|
34
|
+
form["bodytext"] = description # 350 chars max
|
35
|
+
form["summarytext"] = description
|
36
|
+
# MALFORMATTED HTML: select box is outside of the form
|
37
|
+
#form.fields_with(:name => "category").first.options.each do |option|
|
38
|
+
# option.select if option.value.to_s == "3"
|
39
|
+
#end
|
40
|
+
# b/c of malformedness...
|
41
|
+
form["category"] = "3"
|
42
|
+
form["url"] = url
|
43
|
+
form["phase"] = "2"
|
44
|
+
form["randkey"] = page.parser.css("input[@name='randkey']").first["value"]
|
45
|
+
form["id"] = page.parser.css("input[@name='id']").first["value"]
|
46
|
+
|
47
|
+
form["tags"] = token[:tags] # comma separated with space
|
48
|
+
|
49
|
+
iframe_url = page.parser.css("noscript iframe").first["src"]
|
50
|
+
params = iframe_url.split("?").last
|
51
|
+
captcha_iframe = agent.click(page.iframes.first)
|
52
|
+
captcha_form = captcha_iframe.forms.first
|
53
|
+
captcha_image = captcha_iframe.parser.css("img").first["src"]
|
54
|
+
# open browser with captcha image
|
55
|
+
system("open", "http://api.recaptcha.net/#{captcha_image}")
|
56
|
+
# enter captcha response in terminal
|
57
|
+
captcha_says = ask("Enter Captcha from Browser Image: ") { |q| q.echo = true }
|
58
|
+
captcha_form["recaptcha_response_field"] = captcha_says
|
59
|
+
# submit captcha
|
60
|
+
captcha_form.action = "http://www.google.com/recaptcha/api/noscript?#{params}"
|
61
|
+
captcha_response = captcha_form.submit
|
62
|
+
# grab secret
|
63
|
+
captcha_response = captcha_response.parser.css("textarea").first.text
|
64
|
+
|
65
|
+
form["recaptcha_challenge_field"] = captcha_response
|
66
|
+
form["recaptcha_response_field"] = "manual_challenge"
|
67
|
+
page = form.submit
|
68
|
+
|
69
|
+
unless debug?
|
70
|
+
form = page.forms.detect {|form| form.form_node["id"] == "thisform"}
|
71
|
+
page = form.submit
|
72
|
+
end
|
73
|
+
|
74
|
+
true
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Ubiquitously
|
2
|
+
module Flikode
|
3
|
+
class Account < Ubiquitously::Service::Account
|
4
|
+
def login
|
5
|
+
page = agent.get("http://flikode.com/login")
|
6
|
+
form = page.form_with(:name => "login")
|
7
|
+
form["username"] = username
|
8
|
+
form["password"] = password
|
9
|
+
page = form.submit
|
10
|
+
|
11
|
+
authorize!(page.uri != "http://flikode.com/login")
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
class Post < Ubiquitously::Service::Post
|
16
|
+
def create
|
17
|
+
page = agent.get("http://flikode.com/snippet")
|
18
|
+
form = page.form_with(:name => "snippet")
|
19
|
+
|
20
|
+
form["title"] = token[:title]
|
21
|
+
form["description"] = token[:description]
|
22
|
+
form["tags"] = token[:tags]
|
23
|
+
|
24
|
+
form.field_with(:name => "language").options.each do |option|
|
25
|
+
option.select if option.text.to_s.strip.downcase =~ /#{format}/
|
26
|
+
end
|
27
|
+
|
28
|
+
form.radiobuttons_with(:name => "choose").last.check
|
29
|
+
|
30
|
+
form["snippet"] = token[:body]
|
31
|
+
|
32
|
+
page = form.submit
|
33
|
+
|
34
|
+
true
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Ubiquitously
|
2
|
+
module Friendfeed
|
3
|
+
class Account < Ubiquitously::Service::Account
|
4
|
+
def login
|
5
|
+
page = agent.get("http://service.com/login")
|
6
|
+
form = page.form_with(:name => "loginform")
|
7
|
+
form["username"] = username
|
8
|
+
form["password"] = password
|
9
|
+
page = form.submit
|
10
|
+
|
11
|
+
authorized?(page.title =~ /Some title/i)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
class Post < Ubiquitously::Service::Post
|
16
|
+
def create
|
17
|
+
page = agent.get("")
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module Ubiquitously
|
2
|
+
module Gist
|
3
|
+
class Account < Ubiquitously::Service::Account
|
4
|
+
def login
|
5
|
+
page = agent.get("https://gist.github.com/login")
|
6
|
+
form = page.form_with(:action => "/session")
|
7
|
+
form["login"] = username
|
8
|
+
form["password"] = password
|
9
|
+
page = form.submit
|
10
|
+
|
11
|
+
authorize!(page.uri != "https://gist.github.com/session")
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
class Post < Ubiquitously::Service::Post
|
16
|
+
validates_presence_of :format, :extension
|
17
|
+
|
18
|
+
def tokenize
|
19
|
+
super.merge(
|
20
|
+
# make sure we have the extension
|
21
|
+
:title => self.title.gsub(/(?:\.#{self.extension})?$/, ".#{self.extension}")
|
22
|
+
)
|
23
|
+
end
|
24
|
+
|
25
|
+
def create
|
26
|
+
page = agent.get("http://gist.github.com/")
|
27
|
+
form = page.form_with(:action => "/gists")
|
28
|
+
|
29
|
+
form.field_with(:name => "file_ext[gistfile1]").options.each do |option|
|
30
|
+
if format == extension || format == option.text.to_s.downcase.strip
|
31
|
+
option.select
|
32
|
+
break
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
form["file_name[gistfile1]"] = token[:title]
|
37
|
+
form["file_contents[gistfile1]"] = token[:description]
|
38
|
+
|
39
|
+
if public?
|
40
|
+
button = form.buttons.last
|
41
|
+
else
|
42
|
+
form["action_button"] = "private"
|
43
|
+
button = form.buttons.first
|
44
|
+
end
|
45
|
+
|
46
|
+
page = form.submit(button)
|
47
|
+
|
48
|
+
true
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Ubiquitously
|
2
|
+
module GoogleBuzz
|
3
|
+
class Account < Ubiquitously::Service::Account
|
4
|
+
end
|
5
|
+
|
6
|
+
class Post < Ubiquitously::Service::Post
|
7
|
+
validates_presence_of :url, :title, :description, :tags
|
8
|
+
|
9
|
+
def save(options = {})
|
10
|
+
return false unless valid?
|
11
|
+
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Ubiquitously
|
2
|
+
module Identica
|
3
|
+
class Account < Ubiquitously::Service::Account
|
4
|
+
end
|
5
|
+
|
6
|
+
class Post < Ubiquitously::Service::Post
|
7
|
+
validates_presence_of :url, :title, :description, :tags
|
8
|
+
|
9
|
+
def save(options = {})
|
10
|
+
return false unless valid?
|
11
|
+
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Ubiquitously
|
2
|
+
module JumpTags
|
3
|
+
class Account < Ubiquitously::Service::Account
|
4
|
+
def login
|
5
|
+
page = agent.get("http://service.com/login")
|
6
|
+
form = page.form_with(:name => "loginform")
|
7
|
+
form["username"] = username
|
8
|
+
form["password"] = password
|
9
|
+
page = form.submit
|
10
|
+
|
11
|
+
authorized?(page.title =~ /Some title/i)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
class Post < Ubiquitously::Service::Post
|
16
|
+
def create
|
17
|
+
page = agent.get("")
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Ubiquitously
|
2
|
+
module Kailoon
|
3
|
+
class Account < Ubiquitously::Service::Account
|
4
|
+
def login
|
5
|
+
return true
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
class Post < Ubiquitously::Service::Post
|
10
|
+
def create
|
11
|
+
page = agent.get("http://kailoon.com/web-design-news/")
|
12
|
+
form = page.forms.detect { |form| form.form_node["id"] == "commentform" }
|
13
|
+
|
14
|
+
# weird, but this is how they're doing it
|
15
|
+
form["author"] = title
|
16
|
+
form["url"] = url
|
17
|
+
form["email"] = user.email
|
18
|
+
# 200 word max
|
19
|
+
form["comment"] = description
|
20
|
+
|
21
|
+
page = form.submit
|
22
|
+
|
23
|
+
true
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Ubiquitously
|
2
|
+
module MetaFilter
|
3
|
+
class Account < Ubiquitously::Service::Account
|
4
|
+
def login
|
5
|
+
page = agent.get("https://login.metafilter.com/")
|
6
|
+
form = page.forms.first
|
7
|
+
form["user_name"] = username
|
8
|
+
form["user_pass"] = password
|
9
|
+
page = form.submit
|
10
|
+
|
11
|
+
authorize!(page.uri != "https://login.metafilter.com/logging-in.mefi")
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
# You cannot post to the front page at this time.
|
16
|
+
# This can be due to one of several things.
|
17
|
+
# You may not have been a member long enough (1 week),
|
18
|
+
# you may not have posted enough comments (at least 3),
|
19
|
+
# or you may have already posted a link in the past 24 hours.
|
20
|
+
class Post < Ubiquitously::Service::Post
|
21
|
+
def create
|
22
|
+
page = agent.get("http://www.metafilter.com/")
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
module Ubiquitously
|
2
|
+
module Mixx
|
3
|
+
class Account < Ubiquitously::Service::Account
|
4
|
+
def login
|
5
|
+
page = agent.get("https://www.mixx.com/")
|
6
|
+
form = page.form_with(:action => "https://www.mixx.com/save_login")
|
7
|
+
form["user[loginid]"] = username
|
8
|
+
form["user[password]"] = password
|
9
|
+
page = form.submit
|
10
|
+
|
11
|
+
authorize!(page.body !~ /login was unsuccessful/i)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
class Post < Ubiquitously::Service::Post
|
16
|
+
def create
|
17
|
+
page = agent.get("http://www.mixx.com/submit")
|
18
|
+
form = page.form_with(:action => "http://www.mixx.com/submit/step2")
|
19
|
+
form["thingy[page_url]"] = token[:url]
|
20
|
+
page = form.submit
|
21
|
+
|
22
|
+
already_submitted = page.parser.css(".flash.notice").first.text rescue ""
|
23
|
+
if (already_submitted =~ /already submitted/i)
|
24
|
+
form = page.forms.detect { |form| form.form_node["class"] =~ /vote-for/ }
|
25
|
+
form.submit
|
26
|
+
|
27
|
+
form = page.forms.detect { |form| form.form_node["id"] == "thingy_comment_form" }
|
28
|
+
form["comment[body]"] = token[:description]
|
29
|
+
form.submit
|
30
|
+
else
|
31
|
+
# last page
|
32
|
+
form = page.form_with(:action => "http://www.mixx.com/submit/save")
|
33
|
+
|
34
|
+
# captcha
|
35
|
+
iframe_url = page.parser.css("li.captcha iframe").first["src"]
|
36
|
+
params = iframe_url.split("?").last
|
37
|
+
captcha_iframe = agent.click(page.iframes.first)
|
38
|
+
captcha_form = captcha_iframe.forms.first
|
39
|
+
captcha_image = captcha_iframe.parser.css("img").first["src"]
|
40
|
+
# open browser with captcha image
|
41
|
+
system("open", "http://api.recaptcha.net/#{captcha_image}")
|
42
|
+
# enter captcha response in terminal
|
43
|
+
captcha_says = ask("Enter Captcha from Browser Image: ") { |q| q.echo = true }
|
44
|
+
captcha_form["recaptcha_response_field"] = captcha_says
|
45
|
+
# submit captcha
|
46
|
+
captcha_form.action = "http://www.google.com/recaptcha/api/noscript?#{params}"
|
47
|
+
captcha_response = captcha_form.submit
|
48
|
+
# grab secret
|
49
|
+
captcha_response = captcha_response.parser.css("textarea").first.text
|
50
|
+
|
51
|
+
# submit post
|
52
|
+
form = page.form_with(:action => "http://www.mixx.com/submit/save")
|
53
|
+
form["thingy[title]"] = token[:title]
|
54
|
+
form["thingy[description]"] = token[:description]
|
55
|
+
form["thingy[new_tags]"] = token[:tags]
|
56
|
+
form["recaptcha_challenge_field"] = captcha_response
|
57
|
+
form["recaptcha_response_field"] = captcha_says
|
58
|
+
|
59
|
+
form.submit
|
60
|
+
end
|
61
|
+
|
62
|
+
true
|
63
|
+
end
|
64
|
+
|
65
|
+
class << self
|
66
|
+
def find(options = {})
|
67
|
+
records = []
|
68
|
+
user = options[:user]
|
69
|
+
user_url = "http://www.mixx.com/feeds/users/#{user.username_for(self)}"
|
70
|
+
xml = Nokogiri::XML(open(user_url).read)
|
71
|
+
urls = url_permutations(options[:url])
|
72
|
+
|
73
|
+
xml.css("item").each do |node|
|
74
|
+
title = node.css("title").first.text
|
75
|
+
url = node.xpath("mixx:source", {"mixx" => "http://www.mixx.com/mixxrss/"}).first.text
|
76
|
+
description = node.css("description").first.text
|
77
|
+
service_url = node.css("link").first.text
|
78
|
+
record = new(
|
79
|
+
:title => title,
|
80
|
+
:url => url,
|
81
|
+
:description => description,
|
82
|
+
:service_url => service_url,
|
83
|
+
:user => user
|
84
|
+
)
|
85
|
+
return record if urls.include?(record.url)
|
86
|
+
records << record
|
87
|
+
end
|
88
|
+
|
89
|
+
options[:url] ? nil : records
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|