ehbrs_ruby_utils 0.42.0 → 0.44.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d257573a9117902808e20c43bf002671f832d16cc40bf676cfb46282435b22f5
4
- data.tar.gz: fa5b446750faae117f1902457683b1b46599f85e64d40b7402451433d007d861
3
+ metadata.gz: 478c8b2a993c8da6facb45e2809c7210b0eaad73ad1379aa9653aba242ab7bb6
4
+ data.tar.gz: d9edd9c0400135a534d1f45077635fa6399d0b536925a4da02a5f9784730a937
5
5
  SHA512:
6
- metadata.gz: 2f5dbbbcffc5213abb54303cc9272e3875f40ba4f80c759298c6ba4d6677e806862b5a221a26fd487f45c26c02f7075decbf1251b424dd15a28ab186c35d9d5c
7
- data.tar.gz: dd456900169ed432a7c2b3aaef91ab93fff318b098eddcade488b5877df89b9babdeb45ec1336eadeb2ecde18d80a1c1b7011a5fa56952ed6427e60f3aab41ea
6
+ metadata.gz: 31f4b15a837c816399ce97cf3cd89bcd0563c2c2b6f4e415221d95b8c50b260efc91489bc7b68e0341a9711238f8247b6e958b44c52f13959fb8eef5dcd5d1f7
7
+ data.tar.gz: e6cc85c4297ddf52ac3f6ba0b0ee5f1c6227b0a17eea3b44977dd91ed180b48b67c1e6956c02932dd17c9f631ca6fe759ff6c30f985be726eed0d2c8bb6ae55e
@@ -47,7 +47,7 @@ module EhbrsRubyUtils
47
47
  end
48
48
 
49
49
  def scroll_down
50
- session.execute_script('window.scrollBy(0, 90)')
50
+ session.scroll_down_by(90)
51
51
  end
52
52
  end
53
53
  end
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'aranha/parsers/html/item_list'
4
+ require 'eac_ruby_utils/core_ext'
5
+
6
+ module EhbrsRubyUtils
7
+ module Booking
8
+ module Parsers
9
+ class List < ::Aranha::Parsers::Html::ItemList
10
+ class << self
11
+ def testid_xpath(value, *suffixes)
12
+ ([".//*[@data-testid='#{value}']"] + suffixes).join('/')
13
+ end
14
+ end
15
+
16
+ ITEMS_XPATH = '//*[@data-testid="property-card"]'
17
+
18
+ field :name, :string, testid_xpath('title', 'text()')
19
+ field :href, :string, testid_xpath('title-link', '@href')
20
+ field :price, :float, testid_xpath('price-and-discounted-price', '/text()')
21
+ field :tax, :float_optional, testid_xpath('taxes-and-charges', 'text()')
22
+ field :address, :string, testid_xpath('address', 'text()')
23
+ field :distance, :distance, testid_xpath('distance', 'text()')
24
+ field :review_score, :float_optional, testid_xpath('review-score', 'div[1]/text()')
25
+ field :review_count, :integer, testid_xpath('review-score', 'div[2]/div[2]/text()')
26
+ field :unit_title, :string_recursive, testid_xpath('recommended-units',
27
+ '/*[@role="link"]')
28
+
29
+ def data
30
+ { accommodations: items_data, declared_count: declared_count }
31
+ end
32
+
33
+ # @return [Integer]
34
+ def declared_count
35
+ node_parser.integer_value(nokogiri, '//h1/text()')
36
+ end
37
+
38
+ def items_xpath
39
+ ITEMS_XPATH
40
+ end
41
+
42
+ def node_parser
43
+ r = super
44
+ r.extend(NodeParserExtra)
45
+ r
46
+ end
47
+
48
+ module NodeParserExtra
49
+ DISTANCE_PARSER = /\A(\d+)(?:,(\d+))? (m|km)/.to_parser do |m|
50
+ r = m[1].to_f + m[2].if_present(0) { |v| v.to_f / 10.pow(v.length) }
51
+ r /= 1000 if m[3] == 'm'
52
+ r
53
+ end
54
+
55
+ def distance_value(node, xpath)
56
+ s = string_value(node, xpath)
57
+ DISTANCE_PARSER.parse!(s)
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_ruby_utils/core_ext'
4
+
5
+ module EhbrsRubyUtils
6
+ module Booking
7
+ module Processors
8
+ class List
9
+ class BuildAccommodation
10
+ acts_as_instance_method
11
+ common_constructor :list, :data
12
+
13
+ TOTAL_VALUE = '=index($A:$ZZZ;row();column()-2)+index($A:$ZZZ;row();column()-1)'
14
+
15
+ def result
16
+ %i[link total].inject(data) do |a, e|
17
+ a.merge(e => send("#{e}_value"))
18
+ end
19
+ end
20
+
21
+ # @return [String]
22
+ def link_value
23
+ "=HYPERLINK(\"#{data.fetch(:href)}\";\"#{data.fetch(:name)}\")"
24
+ end
25
+
26
+ # @return [String]
27
+ def total_value
28
+ TOTAL_VALUE
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,82 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'aranha/selenium/session'
4
+ require 'ehbrs_ruby_utils/booking/parsers/list'
5
+ require 'eac_ruby_utils/core_ext'
6
+
7
+ module EhbrsRubyUtils
8
+ module Booking
9
+ module Processors
10
+ class List
11
+ enable_simple_cache
12
+ common_constructor :url
13
+
14
+ CLOSE_BANNER_XPATH = '//button[@aria-label = "Ignorar informações de login."]'
15
+ MORE_RESULTS_XPATH = '//*[text() = "Ver mais resultados"]'
16
+ SCROLL_DOWN_STEP = 500
17
+
18
+ # @return [Array]
19
+ def accommodations
20
+ data.fetch(:accommodations).map { |a| build_accommodation(a) }
21
+ end
22
+
23
+ # @return [Integer]
24
+ def declared_count
25
+ data.fetch(:declared_count)
26
+ end
27
+
28
+ protected
29
+
30
+ # @return [Boolean]
31
+ def all_accommodations_reached?
32
+ p = parser
33
+ p.data.fetch(:accommodations).count >= p.data.fetch(:declared_count)
34
+ end
35
+
36
+ def click_more_results
37
+ more_results_button.click
38
+ end
39
+
40
+ def close_banner
41
+ close_banner_button.click
42
+ end
43
+
44
+ # @return [Aranha::Selenium::Session::Element]
45
+ def close_banner_button
46
+ session.element(xpath: CLOSE_BANNER_XPATH)
47
+ end
48
+
49
+ def data_uncached
50
+ session.navigate.to url
51
+ session.wait(5.minutes).until do
52
+ close_banner
53
+ click_more_results
54
+ scroll_down
55
+ all_accommodations_reached?
56
+ end
57
+ parser.data
58
+ end
59
+
60
+ # @return [Aranha::Selenium::Session::Element]
61
+ def more_results_button
62
+ session.element(xpath: MORE_RESULTS_XPATH)
63
+ end
64
+
65
+ def parser
66
+ ::EhbrsRubyUtils::Booking::Parsers::List.from_string(session.current_source)
67
+ end
68
+
69
+ # @return [Aranha::Selenium::Session]
70
+ def session_uncached
71
+ ::Aranha::Selenium::Session.new
72
+ end
73
+
74
+ def scroll_down
75
+ session.scroll_down_by(SCROLL_DOWN_STEP)
76
+ end
77
+
78
+ require_sub __FILE__, require_mode: :kernel
79
+ end
80
+ end
81
+ end
82
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module EhbrsRubyUtils
4
- VERSION = '0.42.0'
4
+ VERSION = '0.44.0'
5
5
  end
@@ -16,7 +16,7 @@ module EhbrsRubyUtils
16
16
  end
17
17
 
18
18
  def show(level)
19
- super(level)
19
+ super
20
20
  children.each do |child|
21
21
  child.show(level + 1)
22
22
  end
@@ -25,7 +25,7 @@ module EhbrsRubyUtils
25
25
 
26
26
  class CheckWithProfiles < ::SimpleDelegator
27
27
  def initialize(check)
28
- super(check)
28
+ super
29
29
  @profiles = []
30
30
  end
31
31
 
@@ -23,7 +23,7 @@ module EhbrsRubyUtils
23
23
  MPEG4_EXTRA_UNSUPPORTED = %w[dx50 xvid].freeze
24
24
 
25
25
  def initialize
26
- super()
26
+ super
27
27
  add_check('invalid_extension', '.m4v')
28
28
  end
29
29
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ehbrs_ruby_utils
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.42.0
4
+ version: 0.44.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Eduardo H. Bogoni
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-05-15 00:00:00.000000000 Z
11
+ date: 2024-06-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: aranha
@@ -50,34 +50,28 @@ dependencies:
50
50
  requirements:
51
51
  - - "~>"
52
52
  - !ruby/object:Gem::Version
53
- version: '0.10'
54
- - - ">="
55
- - !ruby/object:Gem::Version
56
- version: 0.10.1
53
+ version: '0.11'
57
54
  type: :runtime
58
55
  prerelease: false
59
56
  version_requirements: !ruby/object:Gem::Requirement
60
57
  requirements:
61
58
  - - "~>"
62
59
  - !ruby/object:Gem::Version
63
- version: '0.10'
64
- - - ">="
65
- - !ruby/object:Gem::Version
66
- version: 0.10.1
60
+ version: '0.11'
67
61
  - !ruby/object:Gem::Dependency
68
62
  name: avm
69
63
  requirement: !ruby/object:Gem::Requirement
70
64
  requirements:
71
65
  - - "~>"
72
66
  - !ruby/object:Gem::Version
73
- version: '0.91'
67
+ version: '0.92'
74
68
  type: :runtime
75
69
  prerelease: false
76
70
  version_requirements: !ruby/object:Gem::Requirement
77
71
  requirements:
78
72
  - - "~>"
79
73
  - !ruby/object:Gem::Version
80
- version: '0.91'
74
+ version: '0.92'
81
75
  - !ruby/object:Gem::Dependency
82
76
  name: dentaku
83
77
  requirement: !ruby/object:Gem::Requirement
@@ -132,34 +126,28 @@ dependencies:
132
126
  requirements:
133
127
  - - "~>"
134
128
  - !ruby/object:Gem::Version
135
- version: '0.121'
129
+ version: '0.122'
136
130
  type: :runtime
137
131
  prerelease: false
138
132
  version_requirements: !ruby/object:Gem::Requirement
139
133
  requirements:
140
134
  - - "~>"
141
135
  - !ruby/object:Gem::Version
142
- version: '0.121'
136
+ version: '0.122'
143
137
  - !ruby/object:Gem::Dependency
144
138
  name: eac_templates
145
139
  requirement: !ruby/object:Gem::Requirement
146
140
  requirements:
147
141
  - - "~>"
148
142
  - !ruby/object:Gem::Version
149
- version: '0.5'
150
- - - ">="
151
- - !ruby/object:Gem::Version
152
- version: 0.5.1
143
+ version: '0.7'
153
144
  type: :runtime
154
145
  prerelease: false
155
146
  version_requirements: !ruby/object:Gem::Requirement
156
147
  requirements:
157
148
  - - "~>"
158
149
  - !ruby/object:Gem::Version
159
- version: '0.5'
160
- - - ">="
161
- - !ruby/object:Gem::Version
162
- version: 0.5.1
150
+ version: '0.7'
163
151
  - !ruby/object:Gem::Dependency
164
152
  name: inifile
165
153
  requirement: !ruby/object:Gem::Requirement
@@ -292,6 +280,9 @@ files:
292
280
  - lib/ehbrs_ruby_utils/bga/urls.rb
293
281
  - lib/ehbrs_ruby_utils/bga/whatsapp_formatter.rb
294
282
  - lib/ehbrs_ruby_utils/bga/whatsapp_formatter/option.rb
283
+ - lib/ehbrs_ruby_utils/booking/parsers/list.rb
284
+ - lib/ehbrs_ruby_utils/booking/processors/list.rb
285
+ - lib/ehbrs_ruby_utils/booking/processors/list/build_accommodation.rb
295
286
  - lib/ehbrs_ruby_utils/circular_list_spreader.rb
296
287
  - lib/ehbrs_ruby_utils/circular_list_spreader/base_level.rb
297
288
  - lib/ehbrs_ruby_utils/circular_list_spreader/group_level.rb
@@ -334,11 +325,6 @@ files:
334
325
  - lib/ehbrs_ruby_utils/music/ous/category.rb
335
326
  - lib/ehbrs_ruby_utils/music/ous/node.rb
336
327
  - lib/ehbrs_ruby_utils/music/sort.rb
337
- - lib/ehbrs_ruby_utils/music/sort/commands.rb
338
- - lib/ehbrs_ruby_utils/music/sort/commands/base.rb
339
- - lib/ehbrs_ruby_utils/music/sort/commands/dump.rb
340
- - lib/ehbrs_ruby_utils/music/sort/commands/load.rb
341
- - lib/ehbrs_ruby_utils/music/sort/commands/shuffle.rb
342
328
  - lib/ehbrs_ruby_utils/music/sort/files.rb
343
329
  - lib/ehbrs_ruby_utils/music/sort/files/base.rb
344
330
  - lib/ehbrs_ruby_utils/music/sort/files/factory.rb
@@ -1,31 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'ehbrs_ruby_utils/core_ext'
4
- require 'ehbrs_ruby_utils/music/sort/files/scanner'
5
-
6
- module EhbrsRubyUtils
7
- module Music
8
- module Sort
9
- module Commands
10
- class Base
11
- enable_speaker
12
- enable_simple_cache
13
- common_constructor :root, :confirm do
14
- self.root = root.to_pathname
15
- run
16
- end
17
-
18
- private
19
-
20
- def config_file
21
- scanner.config_file
22
- end
23
-
24
- def scanner_uncached
25
- ::EhbrsRubyUtils::Music::Sort::Files::Scanner.new(root)
26
- end
27
- end
28
- end
29
- end
30
- end
31
- end
@@ -1,67 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'ehbrs_ruby_utils/core_ext'
4
- require 'ehbrs_ruby_utils/music/sort/commands/base'
5
- require 'ehbrs_ruby_utils/music/sort/files/base'
6
- require 'ehbrs_ruby_utils/music/sort/files/factory'
7
-
8
- module EhbrsRubyUtils
9
- module Music
10
- module Sort
11
- module Commands
12
- class Dump < EhbrsRubyUtils::Music::Sort::Commands::Base
13
- private
14
-
15
- def run
16
- if File.exist?(config_file)
17
- @config = YAML.load_file(config_file)
18
- to_rename.each { |sf| rename(sf) }
19
- else
20
- fatal_error("File \"#{config_file}\" does not exist")
21
- end
22
- end
23
-
24
- def to_rename
25
- r = []
26
- ::EhbrsRubyUtils::Music::Sort::Files::Factory::SECTIONS.each do |section|
27
- i = 1
28
- (@config[section] || []).each do |name|
29
- r << ::EhbrsRubyUtils::Music::Sort::Files::Base.new(section, i, name, nil)
30
- i += 1
31
- end
32
- end
33
- r
34
- end
35
-
36
- def rename(source_file)
37
- o = scanner.search(source_file.name)
38
- if o
39
- rename_on_found(source_file, o)
40
- else
41
- warn("File not found for \"#{source_file}\"")
42
- end
43
- end
44
-
45
- def rename_on_found(source_file, sorted_file)
46
- o = sorted_file.reorder(source_file.section, source_file.order, order_padding)
47
- info("\"#{o.source_basename}\" => \"#{o.target_basename}\"")
48
- confirm_rename(o.source_basename, o.target_basename) if confirm
49
- end
50
-
51
- def confirm_rename(old_basename, new_basename)
52
- op = File.expand_path(old_basename, root)
53
- np = File.expand_path(new_basename, root)
54
- return if np == op
55
- raise "\"#{np}\" (From \"#{op}\") already exists" if File.exist?(np)
56
-
57
- File.rename(op, np)
58
- end
59
-
60
- def order_padding_uncached
61
- scanner.count.to_s.length
62
- end
63
- end
64
- end
65
- end
66
- end
67
- end
@@ -1,36 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'ehbrs_ruby_utils/core_ext'
4
- require 'ehbrs_ruby_utils/music/sort/commands/base'
5
-
6
- module EhbrsRubyUtils
7
- module Music
8
- module Sort
9
- module Commands
10
- class Load < EhbrsRubyUtils::Music::Sort::Commands::Base
11
- private
12
-
13
- def run
14
- info "Reading \"#{root}\"..."
15
- config = build_config
16
- s = config.to_yaml
17
- puts s
18
- if confirm
19
- info("Writing to \"#{config_file}\"...")
20
- File.write(config_file, s)
21
- end
22
- puts 'Done!'.green
23
- end
24
-
25
- def build_config
26
- config = {}
27
- scanner.by_section.each do |section, fs|
28
- config[section] = fs.sort.map(&:name)
29
- end
30
- config
31
- end
32
- end
33
- end
34
- end
35
- end
36
- end
@@ -1,55 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'ehbrs_ruby_utils/core_ext'
4
- require 'ehbrs_ruby_utils/music/sort/commands/base'
5
- require 'ehbrs_ruby_utils/music/sort/files/factory'
6
-
7
- module EhbrsRubyUtils
8
- module Music
9
- module Sort
10
- module Commands
11
- class Shuffle < EhbrsRubyUtils::Music::Sort::Commands::Base
12
- private
13
-
14
- def run
15
- if confirm
16
- load_last_shuffle
17
- else
18
- dump_last_shuffle
19
- end
20
- end
21
-
22
- def dump_last_shuffle
23
- s = build_config.to_yaml
24
- puts s
25
- info("Writing to \"#{last_shuffle_file}\"...")
26
- File.write(last_shuffle_file, s)
27
- puts 'Done!'.green
28
- end
29
-
30
- def load_last_shuffle
31
- if File.exist?(last_shuffle_file)
32
- IO.copy_stream(last_shuffle_file, config_file)
33
- File.unlink(last_shuffle_file)
34
- puts 'Done!'.green
35
- else
36
- fatal_error "File \"#{last_shuffle_file}\" does not exist"
37
- end
38
- end
39
-
40
- def last_shuffle_file
41
- File.join(root, '.last_shuffle')
42
- end
43
-
44
- def build_config
45
- config = {}
46
- config[::EhbrsRubyUtils::Music::Sort::Files::Factory::SECTION_CURRENT] =
47
- scanner.all.to_a.shuffle.map(&:name)
48
- config[::EhbrsRubyUtils::Music::Sort::Files::Factory::SECTION_NEW] = []
49
- config
50
- end
51
- end
52
- end
53
- end
54
- end
55
- end
@@ -1,13 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'ehbrs_ruby_utils/core_ext'
4
-
5
- module EhbrsRubyUtils
6
- module Music
7
- module Sort
8
- module Commands
9
- require_sub __FILE__
10
- end
11
- end
12
- end
13
- end