Commit aafd59988cfb587e83ccd76fae32d7e01632a8ce
Exists in
master
and in
27 other branches
Merge remote-tracking branch 'origin/master'
Showing
25 changed files
with
92 additions
and
113 deletions
Show diff stats
Gemfile
... | ... | @@ -11,7 +11,6 @@ gem 'will_paginate', '~> 3.0.3' |
11 | 11 | gem 'ruby-feedparser', '~> 0.7' |
12 | 12 | gem 'daemons', '~> 1.1.5' |
13 | 13 | gem 'thin', '~> 1.3.1' |
14 | -gem 'hpricot', '~> 0.8.6' | |
15 | 14 | gem 'nokogiri', '~> 1.5.5' |
16 | 15 | gem 'rake', :require => false |
17 | 16 | gem 'rest-client', '~> 1.6.7' | ... | ... |
INSTALL.md
... | ... | @@ -21,7 +21,7 @@ Noosfero is written in Ruby with the "[Rails framework](http://www.rubyonrails.o |
21 | 21 | You need to install some packages Noosfero depends on. On Debian GNU/Linux or Debian-based systems, all of these packages are available through the Debian archive. You can install them with the following command: |
22 | 22 | |
23 | 23 | # apt-get install ruby rake po4a libgettext-ruby-util libgettext-ruby1.8 \ |
24 | - libsqlite3-ruby rcov librmagick-ruby libredcloth-ruby libhpricot-ruby \ | |
24 | + libsqlite3-ruby rcov librmagick-ruby libredcloth-ruby \ | |
25 | 25 | libwill-paginate-ruby iso-codes libfeedparser-ruby libdaemons-ruby thin \ |
26 | 26 | tango-icon-theme |
27 | 27 | |
... | ... | @@ -40,7 +40,6 @@ On other systems, they may or may not be available through your regular package |
40 | 40 | * Daemons - http://daemons.rubyforge.org |
41 | 41 | * Thin: http://code.macournoyer.com/thin |
42 | 42 | * tango-icon-theme: http://tango.freedesktop.org/Tango_Icon_Library |
43 | -* Hpricot: http://hpricot.com | |
44 | 43 | |
45 | 44 | If you manage to install Noosfero successfully on other systems than Debian, |
46 | 45 | please feel free to contact the Noosfero development mailing with the | ... | ... |
app/helpers/application_helper.rb
... | ... | @@ -1394,16 +1394,16 @@ module ApplicationHelper |
1394 | 1394 | end |
1395 | 1395 | |
1396 | 1396 | def convert_macro(html, source) |
1397 | - doc = Hpricot(html) | |
1397 | + doc = Nokogiri::HTML.fragment html | |
1398 | 1398 | #TODO This way is more efficient but do not support macro inside of |
1399 | 1399 | # macro. You must parse them from the inside-out in order to enable |
1400 | 1400 | # that. |
1401 | - doc.search('.macro').each do |macro| | |
1401 | + doc.css('.macro').each do |macro| | |
1402 | 1402 | macro_name = macro['data-macro'] |
1403 | 1403 | result = @plugins.parse_macro(macro_name, macro, source) |
1404 | 1404 | macro.inner_html = result.kind_of?(Proc) ? self.instance_exec(&result) : result |
1405 | 1405 | end |
1406 | - doc.html | |
1406 | + doc.to_html | |
1407 | 1407 | end |
1408 | 1408 | |
1409 | 1409 | def default_folder_for_image_upload(profile) | ... | ... |
app/models/article.rb
1 | -require 'hpricot' | |
2 | 1 | |
3 | 2 | class Article < ActiveRecord::Base |
4 | 3 | |
... | ... | @@ -707,7 +706,7 @@ class Article < ActiveRecord::Base |
707 | 706 | end |
708 | 707 | |
709 | 708 | def first_paragraph |
710 | - paragraphs = Hpricot(to_html).search('p') | |
709 | + paragraphs = Nokogiri::HTML.fragment(to_html).css('p') | |
711 | 710 | paragraphs.empty? ? '' : paragraphs.first.to_html |
712 | 711 | end |
713 | 712 | |
... | ... | @@ -729,8 +728,8 @@ class Article < ActiveRecord::Base |
729 | 728 | |
730 | 729 | def body_images_paths |
731 | 730 | require 'uri' |
732 | - Hpricot(self.body.to_s).search('img[@src]').collect do |i| | |
733 | - (self.profile && self.profile.environment) ? URI.join(self.profile.environment.top_url, URI.escape(i.attributes['src'])).to_s : i.attributes['src'] | |
731 | + Nokogiri::HTML.fragment(self.body.to_s).css('img[src]').collect do |i| | |
732 | + (self.profile && self.profile.environment) ? URI.join(self.profile.environment.top_url, URI.escape(i['src'])).to_s : i['src'] | |
734 | 733 | end |
735 | 734 | end |
736 | 735 | |
... | ... | @@ -767,8 +766,8 @@ class Article < ActiveRecord::Base |
767 | 766 | end |
768 | 767 | |
769 | 768 | def first_image |
770 | - img = Hpricot(self.lead.to_s).search('img[@src]').first || Hpricot(self.body.to_s).search('img').first | |
771 | - img.nil? ? '' : img.attributes['src'] | |
769 | + img = Nokogiri::HTML.fragment(self.lead.to_s).css('img[src]').first || Nokogiri::HTML.fragment(self.body.to_s).search('img').first | |
770 | + img.nil? ? '' : img['src'] | |
772 | 771 | end |
773 | 772 | |
774 | 773 | delegate :lat, :lng, :region, :region_id, :environment, :environment_id, :to => :profile, :allow_nil => true | ... | ... |
app/models/external_feed.rb
... | ... | @@ -14,9 +14,9 @@ class ExternalFeed < ActiveRecord::Base |
14 | 14 | |
15 | 15 | def add_item(title, link, date, content) |
16 | 16 | return if content.blank? |
17 | - doc = Hpricot(content) | |
18 | - doc.search('*').each do |p| | |
19 | - if p.instance_of? Hpricot::Elem | |
17 | + doc = Nokogiri::HTML.fragment content | |
18 | + doc.css('*').each do |p| | |
19 | + if p.instance_of? Nokogiri::XML::Element | |
20 | 20 | p.remove_attribute 'style' |
21 | 21 | p.remove_attribute 'class' |
22 | 22 | end |
... | ... | @@ -26,10 +26,10 @@ class ExternalFeed < ActiveRecord::Base |
26 | 26 | article = TinyMceArticle.new |
27 | 27 | article.name = title |
28 | 28 | article.profile = blog.profile |
29 | - article.body = content | |
30 | - article.published_at = date | |
31 | - article.source = link | |
32 | - article.profile = blog.profile | |
29 | + article.body = content | |
30 | + article.published_at = date | |
31 | + article.source = link | |
32 | + article.profile = blog.profile | |
33 | 33 | article.parent = blog |
34 | 34 | article.author_name = self.feed_title |
35 | 35 | unless blog.children.exists?(:slug => article.slug) | ... | ... |
app/models/forum.rb
app/models/text_article.rb
1 | 1 | require 'noosfero/translatable_content' |
2 | 2 | |
3 | -# a base class for all text article types. | |
3 | +# a base class for all text article types. | |
4 | 4 | class TextArticle < Article |
5 | 5 | |
6 | 6 | xss_terminate :only => [ :name ], :on => 'validation' |
... | ... | @@ -26,10 +26,10 @@ class TextArticle < Article |
26 | 26 | before_save :set_relative_path |
27 | 27 | |
28 | 28 | def set_relative_path |
29 | - parsed = Hpricot(self.body.to_s) | |
30 | - parsed.search('img[@src]').map { |i| change_element_path(i, 'src') } | |
31 | - parsed.search('a[@href]').map { |i| change_element_path(i, 'href') } | |
32 | - self.body = parsed.to_s | |
29 | + parsed = Nokogiri::HTML.fragment(self.body.to_s) | |
30 | + parsed.css('img[src]').each { |i| change_element_path(i, 'src') } | |
31 | + parsed.css('a[href]').each { |i| change_element_path(i, 'href') } | |
32 | + self.body = parsed.to_html | |
33 | 33 | end |
34 | 34 | |
35 | 35 | def change_element_path(el, attribute) | ... | ... |
debian/control
lib/noosfero/plugin/macro.rb
... | ... | @@ -35,7 +35,7 @@ class Noosfero::Plugin::Macro |
35 | 35 | def attributes(macro) |
36 | 36 | macro.attributes.to_hash. |
37 | 37 | select {|key, value| key[0..10] == 'data-macro-'}. |
38 | - inject({}){|result, a| result.merge({a[0][11..-1] => a[1]})}. | |
38 | + inject({}){|result, a| result.merge({a[0][11..-1] => a[1].to_s})}. | |
39 | 39 | with_indifferent_access |
40 | 40 | end |
41 | 41 | ... | ... |
plugins/comment_group/lib/ext/article.rb
... | ... | @@ -9,7 +9,7 @@ class Article |
9 | 9 | def not_empty_group_comments_removed |
10 | 10 | if body && body_changed? |
11 | 11 | groups_with_comments = Comment.find(:all, :select => 'distinct group_id', :conditions => {:source_id => self.id}).map(&:group_id).compact |
12 | - groups = Hpricot(body.to_s).search('.macro').collect{|element| element['data-macro-group_id'].to_i} | |
12 | + groups = Nokogiri::HTML.fragment(body.to_s).css('.macro').collect{|element| element['data-macro-group_id'].to_i} | |
13 | 13 | errors[:base] << (N_('Not empty group comment cannot be removed')) unless (groups_with_comments-groups).empty? |
14 | 14 | end |
15 | 15 | end | ... | ... |
plugins/community_track/lib/community_track_plugin/track.rb
... | ... | @@ -59,7 +59,7 @@ class CommunityTrackPlugin::Track < Folder |
59 | 59 | |
60 | 60 | def first_paragraph |
61 | 61 | return '' if body.blank? |
62 | - paragraphs = Hpricot(body).search('p') | |
62 | + paragraphs = Nokogiri::HTML.fragment(body).css('p') | |
63 | 63 | paragraphs.empty? ? '' : paragraphs.first.to_html |
64 | 64 | end |
65 | 65 | ... | ... |
script/install-dependencies/debian-squeeze.sh
... | ... | @@ -5,7 +5,7 @@ run sudo apt-get -y install $runtime_dependencies |
5 | 5 | sudo apt-get -y install iceweasel || sudo apt-get -y install firefox |
6 | 6 | |
7 | 7 | # needed for development |
8 | -run sudo apt-get -y install libtidy-ruby libhpricot-ruby libmocha-ruby imagemagick po4a xvfb libxml2-dev libxslt-dev postgresql openjdk-6-jre | |
8 | +run sudo apt-get -y install libtidy-ruby libmocha-ruby imagemagick po4a xvfb libxml2-dev libxslt-dev postgresql openjdk-6-jre | |
9 | 9 | gem which bundler >/dev/null 2>&1 || gem_install bundler |
10 | 10 | setup_rubygems_path |
11 | 11 | run bundle install | ... | ... |
test/functional/cms_controller_test.rb
... | ... | @@ -663,8 +663,8 @@ class CmsControllerTest < ActionController::TestCase |
663 | 663 | should 'be able to add image with alignment' do |
664 | 664 | post :new, :type => 'TinyMceArticle', :profile => profile.identifier, :article => { :name => 'image-alignment', :body => "the text of the article with image <img src='#' align='right'/> right align..." } |
665 | 665 | saved = TinyMceArticle.find_by_name('image-alignment') |
666 | - assert_match /<img.*src="#".*\/>/, saved.body | |
667 | - assert_match /<img.*align="right".*\/>/, saved.body | |
666 | + assert_match /<img.*src="#".*>/, saved.body | |
667 | + assert_match /<img.*align="right".*>/, saved.body | |
668 | 668 | end |
669 | 669 | |
670 | 670 | should 'be able to add image with alignment when textile' do | ... | ... |
test/functional/profile_editor_controller_test.rb
... | ... | @@ -500,7 +500,7 @@ class ProfileEditorControllerTest < ActionController::TestCase |
500 | 500 | xhr :get, :update_categories, :profile => profile.identifier, :category_id => top.id |
501 | 501 | assert_template 'shared/update_categories' |
502 | 502 | assert_equal top, assigns(:current_category) |
503 | - assert_equal [c1, c2], assigns(:categories) | |
503 | + assert_equivalent [c1, c2], assigns(:categories) | |
504 | 504 | end |
505 | 505 | |
506 | 506 | should 'display manage my groups button for person' do | ... | ... |
test/test_helper.rb
... | ... | @@ -3,7 +3,6 @@ ENV["RAILS_ENV"] = "test" |
3 | 3 | require File.expand_path(File.dirname(__FILE__) + "/../config/environment") |
4 | 4 | require 'rails/test_help' |
5 | 5 | require 'mocha' |
6 | -require 'hpricot' | |
7 | 6 | |
8 | 7 | require 'noosfero/test' |
9 | 8 | require 'authenticated_test_helper' | ... | ... |
test/unit/application_helper_test.rb
... | ... | @@ -261,7 +261,7 @@ class ApplicationHelperTest < ActionView::TestCase |
261 | 261 | fast_create(Community, :is_template => true, :environment_id => environment.id) |
262 | 262 | environment.community_default_template= community |
263 | 263 | environment.save |
264 | - | |
264 | + | |
265 | 265 | assert_tag_in_string template_options(:communities, 'community'), :tag => 'input', |
266 | 266 | :attributes => { :name => "community[template_id]", :value => community.id, :checked => true } |
267 | 267 | end |
... | ... | @@ -273,7 +273,7 @@ class ApplicationHelperTest < ActionView::TestCase |
273 | 273 | fast_create(Person, :is_template => true, :environment_id => environment.id) |
274 | 274 | environment.person_default_template= person |
275 | 275 | environment.save |
276 | - | |
276 | + | |
277 | 277 | assert_tag_in_string template_options(:people, 'profile_data'), :tag => 'input', |
278 | 278 | :attributes => { :name => "profile_data[template_id]", :value => person.id, :checked => true } |
279 | 279 | end |
... | ... | @@ -287,7 +287,7 @@ class ApplicationHelperTest < ActionView::TestCase |
287 | 287 | environment.enterprise_default_template= enterprise |
288 | 288 | environment.save |
289 | 289 | environment.reload |
290 | - | |
290 | + | |
291 | 291 | assert_tag_in_string template_options(:enterprises, 'create_enterprise'), :tag => 'input', |
292 | 292 | :attributes => { :name => "create_enterprise[template_id]", :value => enterprise.id, :checked => true } |
293 | 293 | end |
... | ... | @@ -734,16 +734,16 @@ class ApplicationHelperTest < ActionView::TestCase |
734 | 734 | <div class='macro nonEdit' data-macro='unexistent' data-macro-param='987'></div> |
735 | 735 | " |
736 | 736 | parsed_html = convert_macro(html, mock()) |
737 | - parsed_divs = Hpricot(parsed_html).search('div') | |
738 | - expected_divs = Hpricot(" | |
739 | - <div data-macro='#{macro1_name}' class='parsed-macro #{macro1_name}'>Test1</div> | |
740 | - <div data-macro='#{macro2_name}' class='parsed-macro #{macro2_name}'>Test2</div> | |
737 | + parsed_divs = Nokogiri::HTML.fragment(parsed_html).css('div') | |
738 | + expected_divs = Nokogiri::HTML.fragment(" | |
739 | + <div class='parsed-macro #{macro1_name}' data-macro='#{macro1_name}'>Test1</div> | |
740 | + <div class='parsed-macro #{macro2_name}' data-macro='#{macro2_name}'>Test2</div> | |
741 | 741 | <div data-macro='unexistent' class='failed-macro unexistent'>Unsupported macro unexistent!</div> |
742 | - ").search('div') | |
742 | + ").css('div') | |
743 | 743 | |
744 | 744 | # comparing div attributes between parsed and expected html |
745 | 745 | parsed_divs.each_with_index do |div, i| |
746 | - assert_equal expected_divs[i].attributes.to_hash, div.attributes.to_hash | |
746 | + assert_equal expected_divs[i].attributes.to_xml, div.attributes.to_xml | |
747 | 747 | assert_equal expected_divs[i].inner_text, div.inner_text |
748 | 748 | end |
749 | 749 | end | ... | ... |
test/unit/comment_helper_test.rb
... | ... | @@ -137,7 +137,7 @@ class CommentHelperTest < ActiveSupport::TestCase |
137 | 137 | plugin_action = {:link => 'plugin_action', :action_bar => true} |
138 | 138 | @plugins.stubs(:dispatch).returns([plugin_action]) |
139 | 139 | html = comment_actions(comment) |
140 | - assert_match /plugin_action/, Hpricot(html).search('.comments-action-bar').html | |
140 | + assert_match /plugin_action/, Nokogiri::HTML.fragment(html).css('.comments-action-bar').to_html | |
141 | 141 | end |
142 | 142 | |
143 | 143 | def link_to_function(content, url, options = {}) | ... | ... |
test/unit/external_feed_test.rb
... | ... | @@ -166,7 +166,7 @@ class ExternalFeedTest < ActiveSupport::TestCase |
166 | 166 | next if a.kind_of?(RssFeed) |
167 | 167 | dd << a.body.to_s.strip.gsub(/\s+/, ' ') |
168 | 168 | end |
169 | - assert_equal '<img src="noosfero.png" /><p>Html content 1.</p><p>Html content 2.</p>', dd.sort.join | |
169 | + assert_equal '<img src="noosfero.png"><p>Html content 1.</p><p>Html content 2.</p>', dd.sort.join | |
170 | 170 | end |
171 | 171 | |
172 | 172 | should 'use feed title as author name' do | ... | ... |
test/unit/macro_test.rb
... | ... | @@ -15,7 +15,7 @@ class MacroTest < ActiveSupport::TestCase |
15 | 15 | |
16 | 16 | def setup |
17 | 17 | @macro = Plugin1::Macro.new |
18 | - @macro_element = Hpricot(MACRO).search('.macro').first | |
18 | + @macro_element = Nokogiri::HTML.fragment(MACRO).css('.macro').first | |
19 | 19 | end |
20 | 20 | |
21 | 21 | attr_reader :macro, :macro_element | ... | ... |
test/unit/text_article_test.rb
1 | 1 | require_relative "../test_helper" |
2 | 2 | |
3 | 3 | class TextArticleTest < ActiveSupport::TestCase |
4 | - | |
4 | + | |
5 | 5 | # mostly dummy test. Can be removed when (if) there are real tests for this |
6 | - # this class. | |
6 | + # this class. | |
7 | 7 | should 'inherit from Article' do |
8 | 8 | assert_kind_of Article, TextArticle.new |
9 | 9 | end |
... | ... | @@ -44,7 +44,7 @@ class TextArticleTest < ActiveSupport::TestCase |
44 | 44 | env = Environment.default |
45 | 45 | article.body = "<img src=\"http://#{env.default_hostname}/test.png\" />" |
46 | 46 | article.save! |
47 | - assert_equal "<img src=\"/test.png\" />", article.body | |
47 | + assert_equal "<img src=\"/test.png\">", article.body | |
48 | 48 | end |
49 | 49 | |
50 | 50 | should 'change link to relative path' do |
... | ... | @@ -60,18 +60,18 @@ class TextArticleTest < ActiveSupport::TestCase |
60 | 60 | person = create_user('testuser').person |
61 | 61 | article = TextArticle.new(:profile => person, :name => 'test') |
62 | 62 | env = Environment.default |
63 | - article.body = "<img src=\"https://#{env.default_hostname}/test.png\" />" | |
63 | + article.body = "<img src=\"https://#{env.default_hostname}/test.png\">" | |
64 | 64 | article.save! |
65 | - assert_equal "<img src=\"/test.png\" />", article.body | |
65 | + assert_equal "<img src=\"/test.png\">", article.body | |
66 | 66 | end |
67 | 67 | |
68 | 68 | should 'change image path to relative for domain with port' do |
69 | 69 | person = create_user('testuser').person |
70 | 70 | article = TextArticle.new(:profile => person, :name => 'test') |
71 | 71 | env = Environment.default |
72 | - article.body = "<img src=\"http://#{env.default_hostname}:3000/test.png\" />" | |
72 | + article.body = "<img src=\"http://#{env.default_hostname}:3000/test.png\">" | |
73 | 73 | article.save! |
74 | - assert_equal "<img src=\"/test.png\" />", article.body | |
74 | + assert_equal "<img src=\"/test.png\">", article.body | |
75 | 75 | end |
76 | 76 | |
77 | 77 | should 'change image path to relative for domain with www' do |
... | ... | @@ -80,16 +80,16 @@ class TextArticleTest < ActiveSupport::TestCase |
80 | 80 | env = Environment.default |
81 | 81 | env.force_www = true |
82 | 82 | env.save! |
83 | - article.body = "<img src=\"http://#{env.default_hostname}:3000/test.png\" />" | |
83 | + article.body = "<img src=\"http://#{env.default_hostname}:3000/test.png\">" | |
84 | 84 | article.save! |
85 | - assert_equal "<img src=\"/test.png\" />", article.body | |
85 | + assert_equal "<img src=\"/test.png\">", article.body | |
86 | 86 | end |
87 | 87 | |
88 | 88 | should 'not be translatable if there is no language available on environment' do |
89 | 89 | environment = fast_create(Environment) |
90 | 90 | environment.languages = nil |
91 | 91 | profile = fast_create(Person, :environment_id => environment.id) |
92 | - | |
92 | + | |
93 | 93 | text = TextArticle.new(:profile => profile) |
94 | 94 | |
95 | 95 | assert !text.translatable? |
... | ... | @@ -102,11 +102,10 @@ class TextArticleTest < ActiveSupport::TestCase |
102 | 102 | text = fast_create(TextArticle, :profile_id => profile.id) |
103 | 103 | |
104 | 104 | assert !text.translatable? |
105 | - | |
106 | 105 | |
107 | 106 | environment.languages = ['en','pt','fr'] |
108 | 107 | environment.save |
109 | - text.reload | |
108 | + text.reload | |
110 | 109 | assert text.translatable? |
111 | 110 | end |
112 | 111 | ... | ... |
test/unit/tiny_mce_article_test.rb
... | ... | @@ -9,7 +9,7 @@ class TinyMceArticleTest < ActiveSupport::TestCase |
9 | 9 | end |
10 | 10 | attr_reader :profile |
11 | 11 | |
12 | - # this test can be removed when we get real tests for TinyMceArticle | |
12 | + # this test can be removed when we get real tests for TinyMceArticle | |
13 | 13 | should 'be an article' do |
14 | 14 | assert_subclass TextArticle, TinyMceArticle |
15 | 15 | end |
... | ... | @@ -44,11 +44,6 @@ class TinyMceArticleTest < ActiveSupport::TestCase |
44 | 44 | assert(article.body.is_utf8?, "%s expected to be valid UTF-8 content" % article.body.inspect) |
45 | 45 | end |
46 | 46 | |
47 | - should 'fix tinymce mess with itheora comments for IE from tiny mce article body' do | |
48 | - article = create(TinyMceArticle, :profile => profile, :name => 'article', :abstract => 'abstract', :body => "the <!--–-[if IE]--> just for ie... <!--[endif]-->") | |
49 | - assert_equal "the <!–-[if IE]> just for ie... <![endif]-–>", article.body.html_safe | |
50 | - end | |
51 | - | |
52 | 47 | should 'remove iframe if it is not from a trusted site' do |
53 | 48 | article = create(TinyMceArticle, :profile => profile, :name => 'article', :abstract => 'abstract', :body => "<iframe src='http://anything/videos.ogg'></iframe>") |
54 | 49 | assert_equal "", article.body |
... | ... | @@ -94,12 +89,6 @@ class TinyMceArticleTest < ActiveSupport::TestCase |
94 | 89 | assert_equal '', article.body |
95 | 90 | end |
96 | 91 | |
97 | - #TinymMCE convert config={"key":(.*)} in config={"key":(.*)} | |
98 | - should 'not replace " with &quot; when adding an Archive.org video' do | |
99 | - article = create(TinyMceArticle, :profile => profile, :name => 'article', :abstract => 'abstract', :body => "<embed flashvars='config={"key":"\#$b6eb72a0f2f1e29f3d4"}'> </embed>") | |
100 | - assert_equal "<embed flashvars=\"config={"key":"\#$b6eb72a0f2f1e29f3d4"}\"> </embed>", article.body | |
101 | - end | |
102 | - | |
103 | 92 | should 'not sanitize html comments' do |
104 | 93 | article = TinyMceArticle.new |
105 | 94 | article.body = '<p><!-- <asdf> << aasdfa >>> --> <h1> Wellformed html code </h1>' | ... | ... |
vendor/cardmagic-contacts-f66219e6589ccaf3ab9e3574fdd41225d0dd5073/lib/contacts/aol.rb
... | ... | @@ -8,20 +8,19 @@ class Hash |
8 | 8 | end |
9 | 9 | |
10 | 10 | class Contacts |
11 | - require 'hpricot' | |
12 | 11 | class Aol < Base |
13 | 12 | URL = "http://www.aol.com/" |
14 | 13 | LOGIN_URL = "https://my.screenname.aol.com/_cqr/login/login.psp" |
15 | 14 | LOGIN_REFERER_URL = "http://webmail.aol.com/" |
16 | 15 | LOGIN_REFERER_PATH = "sitedomain=sns.webmail.aol.com&lang=en&locale=us&authLev=0&uitype=mini&loginId=&redirType=js&xchk=false" |
17 | 16 | AOL_NUM = "29970-343" # this seems to change each time they change the protocol |
18 | - | |
17 | + | |
19 | 18 | CONTACT_LIST_URL = "http://webmail.aol.com/#{AOL_NUM}/aim-2/en-us/Lite/ContactList.aspx?folder=Inbox&showUserFolders=False" |
20 | 19 | CONTACT_LIST_CSV_URL = "http://webmail.aol.com/#{AOL_NUM}/aim-2/en-us/Lite/ABExport.aspx?command=all" |
21 | 20 | PROTOCOL_ERROR = "AOL has changed its protocols, please upgrade this library first. If that does not work, dive into the code and submit a patch at http://github.com/cardmagic/contacts" |
22 | - | |
21 | + | |
23 | 22 | def real_connect |
24 | - | |
23 | + | |
25 | 24 | postdata = { |
26 | 25 | "loginId" => login, |
27 | 26 | "password" => password, |
... | ... | @@ -62,15 +61,15 @@ class Contacts |
62 | 61 | until forward.nil? |
63 | 62 | data, resp, cookies, forward, old_url = get(forward, cookies, old_url) + [forward] |
64 | 63 | end |
65 | - | |
64 | + | |
66 | 65 | data, resp, cookies, forward, old_url = get("#{LOGIN_URL}?#{LOGIN_REFERER_PATH}", cookies) + [LOGIN_REFERER_URL] |
67 | 66 | until forward.nil? |
68 | 67 | data, resp, cookies, forward, old_url = get(forward, cookies, old_url) + [forward] |
69 | 68 | end |
70 | 69 | |
71 | - doc = Hpricot(data) | |
72 | - (doc/:input).each do |input| | |
73 | - postdata["usrd"] = input.attributes["value"] if input.attributes["name"] == "usrd" | |
70 | + doc = Nokogiri::HTML.fragment data | |
71 | + doc.css('input').each do |input| | |
72 | + postdata["usrd"] = input["value"] if input["name"] == "usrd" | |
74 | 73 | end |
75 | 74 | # parse data for <input name="usrd" value="2726212" type="hidden"> and add it to the postdata |
76 | 75 | |
... | ... | @@ -78,13 +77,13 @@ class Contacts |
78 | 77 | postdata["SNS_LDC"] = cookie_hash_from_string(cookies)["SNS_LDC"] |
79 | 78 | postdata["LTState"] = cookie_hash_from_string(cookies)["LTState"] |
80 | 79 | # raise data.inspect |
81 | - | |
80 | + | |
82 | 81 | data, resp, cookies, forward, old_url = post(LOGIN_URL, postdata.to_query_string, cookies, LOGIN_REFERER_URL) + [LOGIN_REFERER_URL] |
83 | - | |
82 | + | |
84 | 83 | until forward.nil? |
85 | 84 | data, resp, cookies, forward, old_url = get(forward, cookies, old_url) + [forward] |
86 | 85 | end |
87 | - | |
86 | + | |
88 | 87 | if data.index("Invalid Screen Name or Password.") |
89 | 88 | raise AuthenticationError, "Username and password do not match" |
90 | 89 | elsif data.index("Required field must not be blank") |
... | ... | @@ -113,19 +112,19 @@ class Contacts |
113 | 112 | until forward.nil? |
114 | 113 | data, resp, cookies, forward, old_url = get(forward, cookies, old_url) + [forward] |
115 | 114 | end |
116 | - | |
115 | + | |
117 | 116 | if resp.code_type != Net::HTTPOK |
118 | 117 | raise ConnectionError, self.class.const_get(:PROTOCOL_ERROR) |
119 | 118 | end |
120 | 119 | |
121 | 120 | # parse data and grab <input name="user" value="8QzMPIAKs2" type="hidden"> |
122 | - doc = Hpricot(data) | |
123 | - (doc/:input).each do |input| | |
124 | - postdata["user"] = input.attributes["value"] if input.attributes["name"] == "user" | |
121 | + doc = Nokogiri::HTML.fragment data | |
122 | + doc.css('input').each do |input| | |
123 | + postdata["user"] = input["value"] if input["name"] == "user" | |
125 | 124 | end |
126 | - | |
125 | + | |
127 | 126 | data, resp, cookies, forward, old_url = get(CONTACT_LIST_CSV_URL, @cookies, CONTACT_LIST_URL) + [CONTACT_LIST_URL] |
128 | - | |
127 | + | |
129 | 128 | if forward.nil? |
130 | 129 | parse data |
131 | 130 | else |
... | ... | @@ -134,15 +133,15 @@ class Contacts |
134 | 133 | end |
135 | 134 | end |
136 | 135 | private |
137 | - | |
136 | + | |
138 | 137 | def parse(data, options={}) |
139 | 138 | data = CSV.parse(data) |
140 | 139 | col_names = data.shift |
141 | 140 | @contacts = data.map do |person| |
142 | 141 | ["#{person[0]} #{person[1]}", person[4]] unless person[4].empty? |
143 | 142 | end.compact |
144 | - end | |
143 | + end | |
145 | 144 | end |
146 | 145 | |
147 | 146 | TYPES[:aol] = Aol |
148 | -end | |
149 | 147 | \ No newline at end of file |
148 | +end | ... | ... |
vendor/plugins/ruby_bosh/Rakefile
vendor/plugins/ruby_bosh/lib/ruby_bosh.rb
... | ... | @@ -2,10 +2,10 @@ require 'rest_client' |
2 | 2 | require 'builder' |
3 | 3 | require 'rexml/document' |
4 | 4 | require 'base64' |
5 | -require 'hpricot' | |
5 | +require 'nokogiri' | |
6 | 6 | require 'timeout' |
7 | 7 | |
8 | -class RubyBOSH | |
8 | +class RubyBOSH | |
9 | 9 | BOSH_XMLNS = 'http://jabber.org/protocol/httpbind' |
10 | 10 | TLS_XMLNS = 'urn:ietf:params:xml:ns:xmpp-tls' |
11 | 11 | SASL_XMLNS = 'urn:ietf:params:xml:ns:xmpp-sasl' |
... | ... | @@ -24,12 +24,12 @@ class RubyBOSH |
24 | 24 | end |
25 | 25 | |
26 | 26 | attr_accessor :jid, :rid, :sid, :success |
27 | - def initialize(jid, pw, service_url, opts={}) | |
27 | + def initialize(jid, pw, service_url, opts={}) | |
28 | 28 | @service_url = service_url |
29 | 29 | @jid, @pw = jid, pw |
30 | 30 | @host = jid.split("@").last |
31 | 31 | @success = false |
32 | - @timeout = opts[:timeout] || 3 #seconds | |
32 | + @timeout = opts[:timeout] || 3 #seconds | |
33 | 33 | @headers = {"Content-Type" => "text/xml; charset=utf-8", |
34 | 34 | "Accept" => "text/xml"} |
35 | 35 | @wait = opts[:wait] || 5 |
... | ... | @@ -47,7 +47,7 @@ class RubyBOSH |
47 | 47 | |
48 | 48 | def connect |
49 | 49 | initialize_bosh_session |
50 | - if send_auth_request | |
50 | + if send_auth_request | |
51 | 51 | send_restart_request |
52 | 52 | request_resource_binding |
53 | 53 | @success = send_session_request |
... | ... | @@ -55,12 +55,12 @@ class RubyBOSH |
55 | 55 | |
56 | 56 | raise RubyBOSH::AuthFailed, "could not authenticate #{@jid}" unless success? |
57 | 57 | @rid += 1 #updates the rid for the next call from the browser |
58 | - | |
58 | + | |
59 | 59 | [@jid, @sid, @rid] |
60 | 60 | end |
61 | 61 | |
62 | 62 | private |
63 | - def initialize_bosh_session | |
63 | + def initialize_bosh_session | |
64 | 64 | response = deliver(construct_body(:wait => @wait, :to => @host, |
65 | 65 | :hold => @hold, :window => @window, |
66 | 66 | "xmpp:version" => '1.0')) |
... | ... | @@ -72,7 +72,7 @@ class RubyBOSH |
72 | 72 | |
73 | 73 | builder = Builder::XmlMarkup.new |
74 | 74 | parameters = {:rid => @rid, :xmlns => BOSH_XMLNS, |
75 | - "xmpp:version" => "1.0", | |
75 | + "xmpp:version" => "1.0", | |
76 | 76 | "xmlns:xmpp" => "urn:xmpp:xbosh"}.merge(params) |
77 | 77 | |
78 | 78 | if block_given? |
... | ... | @@ -82,10 +82,10 @@ class RubyBOSH |
82 | 82 | end |
83 | 83 | end |
84 | 84 | |
85 | - def send_auth_request | |
85 | + def send_auth_request | |
86 | 86 | request = construct_body(:sid => @sid) do |body| |
87 | - auth_string = "#{@jid}\x00#{@jid.split("@").first.strip}\x00#{@pw}" | |
88 | - body.auth(Base64.encode64(auth_string).gsub(/\s/,''), | |
87 | + auth_string = "#{@jid}\x00#{@jid.split("@").first.strip}\x00#{@pw}" | |
88 | + body.auth(Base64.encode64(auth_string).gsub(/\s/,''), | |
89 | 89 | :xmlns => SASL_XMLNS, :mechanism => 'PLAIN') |
90 | 90 | end |
91 | 91 | |
... | ... | @@ -100,16 +100,16 @@ class RubyBOSH |
100 | 100 | |
101 | 101 | def request_resource_binding |
102 | 102 | request = construct_body(:sid => @sid) do |body| |
103 | - body.iq(:id => "bind_#{rand(100000)}", :type => "set", | |
103 | + body.iq(:id => "bind_#{rand(100000)}", :type => "set", | |
104 | 104 | :xmlns => "jabber:client") do |iq| |
105 | 105 | iq.bind(:xmlns => BIND_XMLNS) do |bind| |
106 | 106 | bind.resource("bosh_#{rand(10000)}") |
107 | 107 | end |
108 | 108 | end |
109 | 109 | end |
110 | - | |
110 | + | |
111 | 111 | response = deliver(request) |
112 | - response.include?("<jid>") | |
112 | + response.include?("<jid>") | |
113 | 113 | end |
114 | 114 | |
115 | 115 | def send_session_request |
... | ... | @@ -117,16 +117,16 @@ class RubyBOSH |
117 | 117 | body.iq(:xmlns => CLIENT_XMLNS, :type => "set", |
118 | 118 | :id => "sess_#{rand(100000)}") do |iq| |
119 | 119 | iq.session(:xmlns => SESSION_XMLNS) |
120 | - end | |
120 | + end | |
121 | 121 | end |
122 | 122 | |
123 | 123 | response = deliver(request) |
124 | - response.include?("body") | |
124 | + response.include?("body") | |
125 | 125 | end |
126 | 126 | |
127 | 127 | def parse(_response) |
128 | - doc = Hpricot(_response.to_s) | |
129 | - doc.search("//body").each do |body| | |
128 | + doc = Nokogiri::HTML.fragment(_response.to_s) | |
129 | + doc.search("body").each do |body| | |
130 | 130 | @sid = body.attributes["sid"].to_s |
131 | 131 | end |
132 | 132 | _response |
... | ... | @@ -156,6 +156,6 @@ end |
156 | 156 | |
157 | 157 | |
158 | 158 | if __FILE__ == $0 |
159 | - p RubyBOSH.initialize_session(ARGV[0], ARGV[1], | |
159 | + p RubyBOSH.initialize_session(ARGV[0], ARGV[1], | |
160 | 160 | "http://localhost:5280/http-bind") |
161 | 161 | end | ... | ... |
vendor/plugins/ruby_bosh/ruby_bosh.gemspec
... | ... | @@ -24,18 +24,15 @@ Gem::Specification.new do |s| |
24 | 24 | if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then |
25 | 25 | s.add_runtime_dependency(%q<builder>, [">= 0"]) |
26 | 26 | s.add_runtime_dependency(%q<adamwiggins-rest-client>, [">= 0"]) |
27 | - s.add_runtime_dependency(%q<hpricot>, [">= 0"]) | |
28 | 27 | s.add_runtime_dependency(%q<SystemTimer>, [">= 0"]) |
29 | 28 | else |
30 | 29 | s.add_dependency(%q<builder>, [">= 0"]) |
31 | 30 | s.add_dependency(%q<adamwiggins-rest-client>, [">= 0"]) |
32 | - s.add_dependency(%q<hpricot>, [">= 0"]) | |
33 | 31 | s.add_dependency(%q<SystemTimer>, [">= 0"]) |
34 | 32 | end |
35 | 33 | else |
36 | 34 | s.add_dependency(%q<builder>, [">= 0"]) |
37 | 35 | s.add_dependency(%q<adamwiggins-rest-client>, [">= 0"]) |
38 | - s.add_dependency(%q<hpricot>, [">= 0"]) | |
39 | 36 | s.add_dependency(%q<SystemTimer>, [">= 0"]) |
40 | 37 | end |
41 | 38 | end | ... | ... |