ubiquitously 0.0.1.6 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|