mechanize 2.7.6 → 2.12.2

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.
Files changed (157) hide show
  1. checksums.yaml +5 -5
  2. data/.github/dependabot.yml +11 -0
  3. data/.github/workflows/ci.yml +43 -0
  4. data/.github/workflows/upstream.yml +51 -0
  5. data/.yardopts +8 -0
  6. data/{CHANGELOG.rdoc → CHANGELOG.md} +221 -96
  7. data/EXAMPLES.rdoc +1 -24
  8. data/Gemfile +10 -4
  9. data/{LICENSE.rdoc → LICENSE.txt} +4 -0
  10. data/README.md +77 -0
  11. data/Rakefile +18 -3
  12. data/examples/latest_user_agents.rb +100 -0
  13. data/examples/rubygems.rb +2 -2
  14. data/examples/wikipedia_links_to_philosophy.rb +5 -6
  15. data/lib/mechanize/chunked_termination_error.rb +1 -0
  16. data/lib/mechanize/content_type_error.rb +1 -0
  17. data/lib/mechanize/cookie.rb +3 -15
  18. data/lib/mechanize/cookie_jar.rb +13 -9
  19. data/lib/mechanize/directory_saver.rb +1 -0
  20. data/lib/mechanize/download.rb +2 -1
  21. data/lib/mechanize/element_matcher.rb +1 -0
  22. data/lib/mechanize/element_not_found_error.rb +1 -0
  23. data/lib/mechanize/file.rb +2 -1
  24. data/lib/mechanize/file_connection.rb +5 -3
  25. data/lib/mechanize/file_request.rb +1 -0
  26. data/lib/mechanize/file_response.rb +4 -1
  27. data/lib/mechanize/file_saver.rb +1 -0
  28. data/lib/mechanize/form/button.rb +1 -0
  29. data/lib/mechanize/form/check_box.rb +1 -0
  30. data/lib/mechanize/form/field.rb +1 -0
  31. data/lib/mechanize/form/file_upload.rb +1 -0
  32. data/lib/mechanize/form/hidden.rb +1 -0
  33. data/lib/mechanize/form/image_button.rb +1 -0
  34. data/lib/mechanize/form/keygen.rb +1 -0
  35. data/lib/mechanize/form/multi_select_list.rb +2 -1
  36. data/lib/mechanize/form/option.rb +1 -0
  37. data/lib/mechanize/form/radio_button.rb +1 -0
  38. data/lib/mechanize/form/reset.rb +1 -0
  39. data/lib/mechanize/form/select_list.rb +1 -0
  40. data/lib/mechanize/form/submit.rb +1 -0
  41. data/lib/mechanize/form/text.rb +1 -0
  42. data/lib/mechanize/form/textarea.rb +1 -0
  43. data/lib/mechanize/form.rb +5 -13
  44. data/lib/mechanize/headers.rb +1 -0
  45. data/lib/mechanize/history.rb +1 -0
  46. data/lib/mechanize/http/agent.rb +83 -10
  47. data/lib/mechanize/http/auth_challenge.rb +1 -0
  48. data/lib/mechanize/http/auth_realm.rb +1 -0
  49. data/lib/mechanize/http/auth_store.rb +1 -0
  50. data/lib/mechanize/http/content_disposition_parser.rb +15 -4
  51. data/lib/mechanize/http/www_authenticate_parser.rb +3 -3
  52. data/lib/mechanize/http.rb +1 -0
  53. data/lib/mechanize/image.rb +1 -0
  54. data/lib/mechanize/page/base.rb +1 -0
  55. data/lib/mechanize/page/frame.rb +1 -0
  56. data/lib/mechanize/page/image.rb +1 -0
  57. data/lib/mechanize/page/label.rb +1 -0
  58. data/lib/mechanize/page/link.rb +8 -1
  59. data/lib/mechanize/page/meta_refresh.rb +1 -0
  60. data/lib/mechanize/page.rb +6 -8
  61. data/lib/mechanize/parser.rb +1 -0
  62. data/lib/mechanize/pluggable_parsers.rb +2 -1
  63. data/lib/mechanize/prependable.rb +1 -0
  64. data/lib/mechanize/redirect_limit_reached_error.rb +1 -0
  65. data/lib/mechanize/redirect_not_get_or_head_error.rb +1 -0
  66. data/lib/mechanize/response_code_error.rb +2 -1
  67. data/lib/mechanize/response_read_error.rb +1 -0
  68. data/lib/mechanize/robots_disallowed_error.rb +1 -0
  69. data/lib/mechanize/test_case/bad_chunking_servlet.rb +1 -0
  70. data/lib/mechanize/test_case/basic_auth_servlet.rb +1 -0
  71. data/lib/mechanize/test_case/content_type_servlet.rb +1 -0
  72. data/lib/mechanize/test_case/digest_auth_servlet.rb +1 -0
  73. data/lib/mechanize/test_case/file_upload_servlet.rb +1 -0
  74. data/lib/mechanize/test_case/form_servlet.rb +1 -0
  75. data/lib/mechanize/test_case/gzip_servlet.rb +4 -3
  76. data/lib/mechanize/test_case/header_servlet.rb +1 -0
  77. data/lib/mechanize/test_case/http_refresh_servlet.rb +1 -0
  78. data/lib/mechanize/test_case/infinite_redirect_servlet.rb +1 -0
  79. data/lib/mechanize/test_case/infinite_refresh_servlet.rb +1 -0
  80. data/lib/mechanize/test_case/many_cookies_as_string_servlet.rb +1 -0
  81. data/lib/mechanize/test_case/many_cookies_servlet.rb +1 -0
  82. data/lib/mechanize/test_case/modified_since_servlet.rb +1 -0
  83. data/lib/mechanize/test_case/ntlm_servlet.rb +1 -0
  84. data/lib/mechanize/test_case/one_cookie_no_spaces_servlet.rb +1 -0
  85. data/lib/mechanize/test_case/one_cookie_servlet.rb +1 -0
  86. data/lib/mechanize/test_case/quoted_value_cookie_servlet.rb +1 -0
  87. data/lib/mechanize/test_case/redirect_servlet.rb +1 -0
  88. data/lib/mechanize/test_case/referer_servlet.rb +1 -0
  89. data/lib/mechanize/test_case/refresh_with_empty_url.rb +1 -0
  90. data/lib/mechanize/test_case/refresh_without_url.rb +1 -0
  91. data/lib/mechanize/test_case/response_code_servlet.rb +1 -0
  92. data/lib/mechanize/test_case/robots_txt_servlet.rb +1 -0
  93. data/lib/mechanize/test_case/send_cookies_servlet.rb +1 -0
  94. data/lib/mechanize/test_case/server.rb +1 -0
  95. data/lib/mechanize/test_case/servlets.rb +1 -0
  96. data/lib/mechanize/test_case/verb_servlet.rb +5 -6
  97. data/lib/mechanize/test_case.rb +34 -34
  98. data/lib/mechanize/unauthorized_error.rb +1 -0
  99. data/lib/mechanize/unsupported_scheme_error.rb +1 -0
  100. data/lib/mechanize/util.rb +2 -1
  101. data/lib/mechanize/version.rb +2 -1
  102. data/lib/mechanize/xml_file.rb +1 -0
  103. data/lib/mechanize.rb +56 -37
  104. data/mechanize.gemspec +43 -35
  105. data/test/htdocs/dir with spaces/foo.html +1 -0
  106. data/test/htdocs/tc_links.html +1 -1
  107. data/test/test_mechanize.rb +21 -8
  108. data/test/test_mechanize_cookie.rb +38 -26
  109. data/test/test_mechanize_cookie_jar.rb +87 -54
  110. data/test/test_mechanize_directory_saver.rb +1 -0
  111. data/test/test_mechanize_download.rb +14 -1
  112. data/test/test_mechanize_element_not_found_error.rb +1 -0
  113. data/test/test_mechanize_file.rb +11 -0
  114. data/test/test_mechanize_file_connection.rb +23 -4
  115. data/test/test_mechanize_file_request.rb +1 -0
  116. data/test/test_mechanize_file_response.rb +26 -1
  117. data/test/test_mechanize_file_saver.rb +1 -0
  118. data/test/test_mechanize_form.rb +14 -1
  119. data/test/test_mechanize_form_check_box.rb +1 -0
  120. data/test/test_mechanize_form_encoding.rb +2 -1
  121. data/test/test_mechanize_form_field.rb +1 -0
  122. data/test/test_mechanize_form_file_upload.rb +1 -0
  123. data/test/test_mechanize_form_image_button.rb +1 -0
  124. data/test/test_mechanize_form_keygen.rb +2 -0
  125. data/test/test_mechanize_form_multi_select_list.rb +1 -0
  126. data/test/test_mechanize_form_option.rb +1 -0
  127. data/test/test_mechanize_form_radio_button.rb +1 -0
  128. data/test/test_mechanize_form_select_list.rb +1 -0
  129. data/test/test_mechanize_form_textarea.rb +1 -0
  130. data/test/test_mechanize_headers.rb +1 -0
  131. data/test/test_mechanize_history.rb +1 -0
  132. data/test/test_mechanize_http_agent.rb +187 -26
  133. data/test/test_mechanize_http_auth_challenge.rb +1 -0
  134. data/test/test_mechanize_http_auth_realm.rb +1 -0
  135. data/test/test_mechanize_http_auth_store.rb +1 -0
  136. data/test/test_mechanize_http_content_disposition_parser.rb +28 -0
  137. data/test/test_mechanize_http_www_authenticate_parser.rb +1 -0
  138. data/test/test_mechanize_image.rb +1 -0
  139. data/test/test_mechanize_link.rb +25 -0
  140. data/test/test_mechanize_page.rb +15 -0
  141. data/test/test_mechanize_page_encoding.rb +33 -5
  142. data/test/test_mechanize_page_frame.rb +1 -0
  143. data/test/test_mechanize_page_image.rb +1 -0
  144. data/test/test_mechanize_page_link.rb +27 -23
  145. data/test/test_mechanize_page_meta_refresh.rb +1 -0
  146. data/test/test_mechanize_parser.rb +1 -0
  147. data/test/test_mechanize_pluggable_parser.rb +1 -0
  148. data/test/test_mechanize_redirect_limit_reached_error.rb +1 -0
  149. data/test/test_mechanize_redirect_not_get_or_head_error.rb +1 -0
  150. data/test/test_mechanize_response_read_error.rb +1 -0
  151. data/test/test_mechanize_subclass.rb +1 -0
  152. data/test/test_mechanize_util.rb +4 -3
  153. data/test/test_mechanize_xml_file.rb +1 -0
  154. data/test/test_multi_select.rb +1 -0
  155. metadata +106 -86
  156. data/.travis.yml +0 -36
  157. data/README.rdoc +0 -77
data/EXAMPLES.rdoc CHANGED
@@ -24,29 +24,6 @@ example, <code>do ... end.submit</code> is the same as <code>{ ...
24
24
  end
25
25
  end
26
26
 
27
- == Rubyforge
28
-
29
- require 'rubygems'
30
- require 'mechanize'
31
-
32
- a = Mechanize.new
33
- a.get('http://rubyforge.org/') do |page|
34
- # Click the login link
35
- login_page = a.click(page.link_with(:text => /Log In/))
36
-
37
- # Submit the login form
38
- my_page = login_page.form_with(:action => '/account/login.php') do |f|
39
- f.form_loginname = ARGV[0]
40
- f.form_pw = ARGV[1]
41
- end.click_button
42
-
43
- my_page.links.each do |link|
44
- text = link.text.strip
45
- next unless text.length > 0
46
- puts text
47
- end
48
- end
49
-
50
27
  == File Upload
51
28
 
52
29
  Upload a file to flickr.
@@ -129,7 +106,7 @@ This example also demonstrates subclassing Mechanize.
129
106
 
130
107
  class TestMech < Mechanize
131
108
  def process
132
- get 'http://rubyforge.org/'
109
+ get 'http://rubygems.org/'
133
110
  search_form = page.forms.first
134
111
  search_form.words = 'WWW'
135
112
  submit search_form
data/Gemfile CHANGED
@@ -1,6 +1,12 @@
1
- source 'https://rubygems.org'
2
-
3
- # In order to be able to install on 1.9.3 and 2.0.0
4
- ruby RUBY_VERSION
1
+ source "https://rubygems.org"
5
2
 
6
3
  gemspec
4
+
5
+ gem "minitest", "~> 5.14"
6
+ gem "rake", "~> 13.0"
7
+ gem "rdoc", "~> 6.3"
8
+ gem "rubocop", "~> 1.12"
9
+ unless RUBY_PLATFORM == 'java'
10
+ gem 'brotli', '>= 0.5'
11
+ gem 'zstd-ruby', '~> 1.5'
12
+ end
@@ -1,5 +1,9 @@
1
1
  (The MIT License)
2
2
 
3
+ Copyright (c) 2005 by Michael Neumann (mneumann@ntecs.de)
4
+
5
+ Copyright (c) 2006-2021 by Eric Hodel, Akinori MUSHA, Aaron Patterson, Lee Jarvis, Mike Dalessio
6
+
3
7
  Permission is hereby granted, free of charge, to any person obtaining
4
8
  a copy of this software and associated documentation files (the
5
9
  'Software'), to deal in the Software without restriction, including
data/README.md ADDED
@@ -0,0 +1,77 @@
1
+ # Mechanize
2
+
3
+ * https://www.rubydoc.info/gems/mechanize/
4
+ * https://github.com/sparklemotion/mechanize
5
+
6
+ [![Test suite](https://github.com/sparklemotion/mechanize/actions/workflows/ci.yml/badge.svg)](https://github.com/sparklemotion/mechanize/actions/workflows/ci.yml)
7
+
8
+
9
+ ## Description
10
+
11
+ The Mechanize library is used for automating interaction with websites. Mechanize automatically stores and sends cookies, follows redirects, and can follow links and submit forms. Form fields can be populated and submitted. Mechanize also keeps track of the sites that you have visited as a history.
12
+
13
+
14
+ ## Dependencies
15
+
16
+ * Ruby >= 2.6
17
+ * Gems:
18
+ * `addressable`
19
+ * `domain_name`
20
+ * `http-cookie`
21
+ * `mime-types`
22
+ * `net-http-digest_auth`
23
+ * `net-http-persistent`
24
+ * `nokogiri`
25
+ * `rubyntlm`
26
+ * `webrick`
27
+ * `webrobots`
28
+
29
+
30
+ ## Support:
31
+
32
+ The bug tracker is available here:
33
+
34
+ * https://github.com/sparklemotion/mechanize/issues
35
+
36
+
37
+ ## Examples
38
+
39
+ If you are just starting, check out [GUIDE.rdoc](https://github.com/sparklemotion/mechanize/blob/main/GUIDE.rdoc) or [EXAMPLES.rdoc](https://github.com/sparklemotion/mechanize/blob/main/EXAMPLES.rdoc).
40
+
41
+
42
+ ## Developers
43
+
44
+ Use bundler to install dependencies:
45
+
46
+ ```
47
+ bundle install
48
+ ```
49
+
50
+ Run all tests with:
51
+
52
+ ```
53
+ bundle exec rake test
54
+ ```
55
+
56
+ See also Mechanize::TestCase to read about the built-in testing infrastructure.
57
+
58
+
59
+ ## Authors
60
+
61
+ * Eric Hodel
62
+ * Akinori MUSHA
63
+ * Aaron Patterson
64
+ * Lee Jarvis
65
+ * Mike Dalessio
66
+
67
+
68
+ ## Acknowledgments
69
+
70
+ This library was heavily influenced by its namesake in the Perl world. A big
71
+ thanks goes to [Andy Lester](http://petdance.com), the author of the original Perl module WWW::Mechanize which is available [here](http://search.cpan.org/dist/WWW-Mechanize/). Ruby Mechanize would not be around without you!
72
+
73
+ Thank you to Michael Neumann for starting the Ruby version. Thanks to everyone who's helped out in various ways. Finally, thank you to the people using this library!
74
+
75
+ ## License
76
+
77
+ This library is distributed under the MIT license. Please see [LICENSE.txt](https://github.com/sparklemotion/mechanize/blob/main/LICENSE.txt).
data/Rakefile CHANGED
@@ -23,9 +23,9 @@ task('ssl_cert') do |p|
23
23
  end
24
24
 
25
25
  RDoc::Task.new do |rdoc|
26
- rdoc.main = "README.rdoc"
26
+ rdoc.main = "README.md"
27
27
  rdoc.rdoc_dir = 'doc'
28
- rdoc.rdoc_files.include( "CHANGELOG.rdoc", "EXAMPLES.rdoc", "GUIDE.rdoc", "LICENSE.rdoc", "README.rdoc", "lib/**/*.rb")
28
+ rdoc.rdoc_files.include( "CHANGELOG.md", "EXAMPLES.rdoc", "GUIDE.rdoc", "LICENSE.txt", "README.md", "lib/**/*.rb")
29
29
  end
30
30
 
31
31
  desc "Run tests"
@@ -38,4 +38,19 @@ task publish_docs: %w[rdoc] do
38
38
  sh 'rsync', '-avzO', '--delete', 'doc/', 'docs-push.seattlerb.org:/data/www/docs.seattlerb.org/mechanize/'
39
39
  end
40
40
 
41
- task default: :test
41
+ desc "Run rubocop checks"
42
+ task :rubocop => ["rubocop:security", "rubocop:frozen_string_literals"]
43
+
44
+ namespace "rubocop" do
45
+ desc "Run rubocop security check"
46
+ task :security do
47
+ sh "rubocop lib --only Security"
48
+ end
49
+
50
+ desc "Run rubocop string literals check"
51
+ task :frozen_string_literals do
52
+ sh "rubocop lib test --auto-correct-all --only Style/FrozenStringLiteralComment"
53
+ end
54
+ end
55
+
56
+ task default: [:rubocop, :test]
@@ -0,0 +1,100 @@
1
+ require 'mechanize'
2
+ require 'ostruct'
3
+
4
+ # LatestUAFetcher fetches latest user agents from `WhatIsMyBrowser.com`.
5
+ # It can use to update `Mechanize::AGENT_ALIASES`.
6
+ class LatestUAFetcher
7
+ attr_reader :user_agents
8
+
9
+ USER_AGENT_TYPES = OpenStruct.new(
10
+ linux_firefox: "Linux Firefox",
11
+ mac_firefox: "Mac Firefox",
12
+ mac_safari: "Mac Safari",
13
+ windows_chrome: "Windows Chrome",
14
+ windows_edge: "Windows Edge",
15
+ windows_firefox: "Windows Firefox",
16
+ android: "Android",
17
+ iphone: "iPhone",
18
+ ipad: "iPad",
19
+ )
20
+
21
+ BASE_URL = 'https://www.whatismybrowser.com/guides/the-latest-user-agent'
22
+
23
+ def initialize
24
+ @agent = Mechanize.new.tap { |a| a.user_agent_alias = 'Mac Firefox' }
25
+ @user_agents = {}
26
+ end
27
+
28
+ def run
29
+ return unless user_agents.empty?
30
+
31
+ sleep_time = 1
32
+
33
+ fetch_user_agents('chrome')
34
+ fetch_user_agents('firefox')
35
+ fetch_user_agents('safari')
36
+ fetch_user_agents('edge')
37
+ end
38
+
39
+ def ordered_user_agents
40
+ USER_AGENT_TYPES.to_h.values.each_with_object({}) do |type, ordered_user_agents|
41
+ ordered_user_agents[type] = user_agents[type]
42
+ end
43
+ end
44
+
45
+ private
46
+
47
+ def fetch_user_agents(browser_name, sleep_time = 1)
48
+ puts "fetch #{browser_name} UA..."
49
+ send(browser_name)
50
+ puts "sleeping... (#{sleep_time}s)"
51
+ sleep sleep_time
52
+ end
53
+
54
+ def edge
55
+ page = @agent.get("#{BASE_URL}/edge")
56
+
57
+ windows_dom = page.css("h2:contains('Latest Edge on Windows User Agents')")
58
+
59
+ @user_agents[USER_AGENT_TYPES.windows_edge] = windows_dom.css('+ .listing-of-useragents .code').first.text
60
+ end
61
+
62
+ def firefox
63
+ page = @agent.get("#{BASE_URL}/firefox")
64
+
65
+ desktop_dom = page.css("h2:contains('Latest Firefox on Desktop User Agents')")
66
+ table_dom = desktop_dom.css('+ .listing-of-useragents')
67
+
68
+ @user_agents[USER_AGENT_TYPES.linux_firefox] = table_dom.css('td:contains("Linux")').css("+ td .code:contains('Ubuntu; Linux x86_64')").text
69
+ @user_agents[USER_AGENT_TYPES.windows_firefox] = table_dom.css('td:contains("Windows")').css('+ td .code').text
70
+ @user_agents[USER_AGENT_TYPES.mac_firefox] = table_dom.css('td:contains("Macos")').css('+ td .code').text
71
+ end
72
+
73
+ def safari
74
+ page = @agent.get("#{BASE_URL}/safari")
75
+
76
+ macos_dom = page.css("h2:contains('Latest Safari on macOS User Agents')")
77
+ ios_dom = page.css("h2:contains('Latest Safari on iOS User Agents')")
78
+
79
+ @user_agents[USER_AGENT_TYPES.mac_safari] = macos_dom.css('+ .listing-of-useragents .code').first.text
80
+ @user_agents[USER_AGENT_TYPES.iphone] = ios_dom.css('+ .listing-of-useragents').css("tr:contains('Iphone') .code").text
81
+ @user_agents[USER_AGENT_TYPES.ipad] = ios_dom.css('+ .listing-of-useragents').css("tr:contains('Ipad') .code").text
82
+ end
83
+
84
+ def chrome
85
+ page = @agent.get("#{BASE_URL}/chrome")
86
+
87
+ windows_dom = page.css("h2:contains('Latest Chrome on Windows 10 User Agents')")
88
+ android_dom = page.css("h2:contains('Latest Chrome on Android User Agents')")
89
+
90
+ @user_agents[USER_AGENT_TYPES.windows_chrome] = windows_dom.css('+ .listing-of-useragents .code').first.text
91
+ @user_agents[USER_AGENT_TYPES.android] = android_dom.css('+ .listing-of-useragents .code').first.text
92
+ end
93
+ end
94
+
95
+ if $0 == __FILE__
96
+ agent = LatestUAFetcher.new
97
+ agent.run
98
+
99
+ pp agent.ordered_user_agents
100
+ end
data/examples/rubygems.rb CHANGED
@@ -1,4 +1,4 @@
1
- # This example logs a user in to rubyforge and prints out the body of the
1
+ # This example logs a user in to rubygems and prints out the body of the
2
2
  # page after logging the user in.
3
3
  require 'rubygems'
4
4
  require 'mechanize'
@@ -9,7 +9,7 @@ mech = Mechanize.new
9
9
  mech.log = Logger.new $stderr
10
10
  mech.agent.http.debug_output = $stderr
11
11
 
12
- # Load the rubyforge website
12
+ # Load the rubygems website
13
13
  page = mech.get('https://rubygems.org/')
14
14
  page = mech.click page.link_with(:text => /Sign in/) # Click the login link
15
15
  form = page.forms[1] # Select the first form
@@ -58,10 +58,10 @@ class WikipediaLinksToPhilosophy
58
58
  # the article.
59
59
 
60
60
  def follow_first_link
61
- puts @title
61
+ puts "#{@title} (#{@page.uri})"
62
62
 
63
63
  # > p > a rejects italics
64
- links = @page.root.css('.mw-content-ltr > p > a[href^="/wiki/"]')
64
+ links = @page.root.css('.mw-content-ltr p > a[href^="/wiki/"]')
65
65
 
66
66
  # reject disambiguation and special pages, images and files
67
67
  links = links.reject do |link_node|
@@ -74,10 +74,9 @@ class WikipediaLinksToPhilosophy
74
74
 
75
75
  link = links.first
76
76
 
77
- unless link then
78
- # disambiguation page? try the first item in the list
79
- link =
80
- @page.root.css('.mw-content-ltr > ul > li > a[href^="/wiki/"]').first
77
+ if link.nil?
78
+ puts "Could not parse #{@page.uri}"
79
+ exit 1
81
80
  end
82
81
 
83
82
  # convert a Nokogiri HTML element back to a mechanize link
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  ##
2
3
  # Raised when Mechanize detects the chunked transfer-encoding may be
3
4
  # incorrectly terminated.
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  ##
2
3
  # This error is raised when a pluggable parser tries to parse a content type
3
4
  # that it does not know how to handle. For example if Mechanize::Page were to
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  warn 'mechanize/cookie will be deprecated. Please migrate to the http-cookie APIs.' if $VERBOSE
2
3
 
3
4
  require 'http/cookie'
@@ -6,7 +7,7 @@ class Mechanize
6
7
  module CookieDeprecated
7
8
  def __deprecated__(to = nil)
8
9
  $VERBOSE or return
9
- method = caller[0][/([^`]+)(?='$)/]
10
+ method = caller_locations(1,1).first.base_label
10
11
  to ||= method
11
12
  case self
12
13
  when Class
@@ -20,7 +21,7 @@ class Mechanize
20
21
  this = '%s#%s' % [klass, method]
21
22
  that = 'HTTP::%s#%s' % [lname, to]
22
23
  end
23
- warn '%s: The call of %s needs to be fixed to follow the new API (%s).' % [caller[1], this, that]
24
+ warn '%s: The call of %s needs to be fixed to follow the new API (%s).' % [caller_locations(2,1).first, this, that]
24
25
  end
25
26
  private :__deprecated__
26
27
  end
@@ -50,19 +51,6 @@ class Mechanize
50
51
 
51
52
  Cookie = ::HTTP::Cookie
52
53
 
53
- # Compatibility for Ruby 1.8/1.9
54
- unless Cookie.respond_to?(:prepend, true)
55
- require 'mechanize/prependable'
56
-
57
- class Cookie
58
- extend Prependable
59
-
60
- class << self
61
- extend Prependable
62
- end
63
- end
64
- end
65
-
66
54
  class Cookie
67
55
  prepend CookieIMethods
68
56
 
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  warn 'mechanize/cookie_jar will be deprecated. Please migrate to the http-cookie APIs.' if $VERBOSE
2
3
 
3
4
  require 'http/cookie_jar'
@@ -65,7 +66,7 @@ class Mechanize
65
66
  class CookieJar < ::HTTP::CookieJar
66
67
  def save(output, *options)
67
68
  output.respond_to?(:write) or
68
- return open(output, 'w') { |io| save(io, *options) }
69
+ return ::File.open(output, 'w') { |io| save(io, *options) }
69
70
 
70
71
  opthash = {
71
72
  :format => :yaml,
@@ -119,7 +120,7 @@ class Mechanize
119
120
 
120
121
  def load(input, *options)
121
122
  input.respond_to?(:write) or
122
- return open(input, 'r') { |io| load(io, *options) }
123
+ return ::File.open(input, 'r') { |io| load(io, *options) }
123
124
 
124
125
  opthash = {
125
126
  :format => :yaml,
@@ -148,7 +149,7 @@ class Mechanize
148
149
  return super(input, opthash) if opthash[:format] != :yaml
149
150
 
150
151
  begin
151
- data = YAML.load(input)
152
+ data = load_yaml(input)
152
153
  rescue ArgumentError
153
154
  @logger.warn "unloadable YAML cookie data discarded" if @logger
154
155
  return self
@@ -173,14 +174,17 @@ class Mechanize
173
174
  return self
174
175
  end
175
176
  end
176
- end
177
177
 
178
- # Compatibility for Ruby 1.8/1.9
179
- unless ::HTTP::CookieJar.respond_to?(:prepend, true)
180
- require 'mechanize/prependable'
178
+ private
181
179
 
182
- class ::HTTP::CookieJar
183
- extend Prependable
180
+ if YAML.name == "Psych" && Gem::Requirement.new(">= 3.1").satisfied_by?(Gem::Version.new(Psych::VERSION))
181
+ def load_yaml(yaml)
182
+ YAML.safe_load(yaml, aliases: true, permitted_classes: ["Mechanize::Cookie", "Time"])
183
+ end
184
+ else
185
+ def load_yaml(yaml)
186
+ YAML.load(yaml) # rubocop:disable Security/YAMLLoad
187
+ end
184
188
  end
185
189
  end
186
190
 
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  ##
2
3
  # Unlike Mechanize::FileSaver, the directory saver places all downloaded files
3
4
  # in a single pre-specified directory.
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  ##
2
3
  # Download is a pluggable parser for downloading files without loading them
3
4
  # into memory first. You may subclass this class to handle content types you
@@ -71,7 +72,7 @@ class Mechanize::Download
71
72
  dirname = File.dirname filename
72
73
  FileUtils.mkdir_p dirname
73
74
 
74
- open filename, 'wb' do |io|
75
+ ::File.open(filename, 'wb')do |io|
75
76
  until @body_io.eof? do
76
77
  io.write @body_io.read 16384
77
78
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module Mechanize::ElementMatcher
2
3
 
3
4
  def elements_with singular, plural = "#{singular}s"
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  ##
2
3
  # Raised when an an element was not found on the Page
3
4
 
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  ##
2
3
  # This is the base class for the Pluggable Parsers. If Mechanize cannot find
3
4
  # an appropriate class to use for the content type, this class will be used.
@@ -82,7 +83,7 @@ class Mechanize::File
82
83
  dirname = File.dirname filename
83
84
  FileUtils.mkdir_p dirname
84
85
 
85
- open filename, 'wb' do |f|
86
+ ::File.open(filename, 'wb')do |f|
86
87
  f.write body
87
88
  end
88
89
 
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  ##
2
3
  # Wrapper to make a file URI work like an http URI
3
4
 
@@ -10,8 +11,9 @@ class Mechanize::FileConnection
10
11
  end
11
12
 
12
13
  def request uri, request
13
- yield Mechanize::FileResponse.new Mechanize::Util.uri_unescape uri.path
14
+ file_path = uri.select(:host, :path)
15
+ .select { |part| part && (part.length > 0) }
16
+ .join(":")
17
+ yield Mechanize::FileResponse.new(Mechanize::Util.uri_unescape(file_path))
14
18
  end
15
-
16
19
  end
17
-
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  ##
2
3
  # A wrapper for a file URI that makes a request that works like a
3
4
  # Net::HTTPRequest
@@ -1,8 +1,11 @@
1
+ # frozen_string_literal: true
1
2
  ##
2
3
  # Fake response for dealing with file:/// requests
3
4
 
4
5
  class Mechanize::FileResponse
5
6
 
7
+ attr_reader :file_path
8
+
6
9
  def initialize(file_path)
7
10
  @file_path = file_path
8
11
  @uri = nil
@@ -15,7 +18,7 @@ class Mechanize::FileResponse
15
18
  if directory?
16
19
  yield dir_body
17
20
  else
18
- open @file_path, 'rb' do |io|
21
+ ::File.open(@file_path, 'rb') do |io|
19
22
  yield io.read
20
23
  end
21
24
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  ##
2
3
  # This is a pluggable parser that automatically saves every file it
3
4
  # encounters. Unlike Mechanize::DirectorySaver, the file saver saves the
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  ##
2
3
  # A Submit button in a Form
3
4
 
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  ##
2
3
  # This class represents a check box found in a Form. To activate the CheckBox
3
4
  # in the Form, set the checked method to true.
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  ##
2
3
  # This class represents a field in a form. It handles the following input
3
4
  # tags found in a form:
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  # This class represents a file upload field found in a form. To use this
2
3
  # class, set FileUpload#file_data= to the data of the file you want to upload
3
4
  # and FileUpload#mime_type= to the appropriate mime type of the file.
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  class Mechanize::Form::Hidden < Mechanize::Form::Field
2
3
  end
3
4
 
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  ##
2
3
  # This class represents an image button in a form. Use the x and y methods to
3
4
  # set the x and y positions for where the mouse "clicked".
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  ##
2
3
  # This class represents a keygen (public / private key generator) found in a
3
4
  # Form. The field will automatically generate a key pair and compute its own
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  ##
2
3
  # This class represents a select list where multiple values can be selected.
3
4
  # MultiSelectList#value= accepts an array, and those values are used as
@@ -35,7 +36,7 @@ class Mechanize::Form::MultiSelectList < Mechanize::Form::Field
35
36
  # select_list.option_with(:value => '1').value = 'foo'
36
37
 
37
38
  ##
38
- # :mehtod: option_with!(criteria)
39
+ # :method: option_with!(criteria)
39
40
  #
40
41
  # Same as +option_with+ but raises an ElementNotFoundError if no button
41
42
  # matches +criteria+
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  ##
2
3
  # This class contains an option found within SelectList. A SelectList can
3
4
  # have many Option classes associated with it. An option can be selected by
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  ##
2
3
  # This class represents a radio button found in a Form. To activate the
3
4
  # RadioButton in the Form, set the checked method to true.
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  class Mechanize::Form::Reset < Mechanize::Form::Button
2
3
  end
3
4
 
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  # This class represents a select list or drop down box in a Form. Set the
2
3
  # value for the list by calling SelectList#value=. SelectList contains a list
3
4
  # of Option that were found. After finding the correct option, set the select
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  class Mechanize::Form::Submit < Mechanize::Form::Button
2
3
  end
3
4
 
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  class Mechanize::Form::Text < Mechanize::Form::Field
2
3
  end
3
4
 
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  class Mechanize::Form::Textarea < Mechanize::Form::Field
2
3
  end
3
4