ehbrs-tools 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (158) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +13 -0
  3. data/exe/ehbrs +6 -0
  4. data/lib/ehbrs.rb +7 -0
  5. data/lib/ehbrs/executables.rb +28 -0
  6. data/lib/ehbrs/tools.rb +9 -0
  7. data/lib/ehbrs/tools/runner.rb +35 -0
  8. data/lib/ehbrs/tools/runner/vg.rb +26 -0
  9. data/lib/ehbrs/tools/runner/vg/ips.rb +90 -0
  10. data/lib/ehbrs/tools/runner/videos.rb +25 -0
  11. data/lib/ehbrs/tools/runner/videos/unsupported.rb +65 -0
  12. data/lib/ehbrs/tools/version.rb +7 -0
  13. data/lib/ehbrs/videos.rb +9 -0
  14. data/lib/ehbrs/videos/convert_job.rb +99 -0
  15. data/lib/ehbrs/videos/file.rb +70 -0
  16. data/lib/ehbrs/videos/profiles/base.rb +35 -0
  17. data/lib/ehbrs/videos/profiles/same_quality.rb +21 -0
  18. data/lib/ehbrs/videos/track.rb +27 -0
  19. data/lib/ehbrs/videos/unsupported/check_result.rb +24 -0
  20. data/lib/ehbrs/videos/unsupported/check_set.rb +43 -0
  21. data/lib/ehbrs/videos/unsupported/check_support.rb +68 -0
  22. data/lib/ehbrs/videos/unsupported/checks.rb +13 -0
  23. data/lib/ehbrs/videos/unsupported/checks/codec_extra_unlisted.rb +27 -0
  24. data/lib/ehbrs/videos/unsupported/checks/codec_extra_unsupported.rb +26 -0
  25. data/lib/ehbrs/videos/unsupported/checks/codec_unlisted.rb +23 -0
  26. data/lib/ehbrs/videos/unsupported/checks/codec_unsupported.rb +25 -0
  27. data/lib/ehbrs/videos/unsupported/checks/invalid_extension.rb +25 -0
  28. data/lib/ehbrs/videos/unsupported/file.rb +50 -0
  29. data/lib/ehbrs/videos/unsupported/file/fix.rb +45 -0
  30. data/lib/ehbrs/videos/unsupported/fix_profile.rb +56 -0
  31. data/lib/ehbrs/videos/unsupported/fixes/supported_codec.rb +36 -0
  32. data/lib/ehbrs/videos/unsupported/fixes/supported_container.rb +17 -0
  33. data/lib/ehbrs/videos/unsupported/profiles.rb +13 -0
  34. data/lib/ehbrs/videos/unsupported/profiles/base.rb +102 -0
  35. data/lib/ehbrs/videos/unsupported/profiles/philco.rb +27 -0
  36. data/lib/ehbrs/videos/unsupported/profiles/samsung.rb +32 -0
  37. data/lib/ehbrs/videos/unsupported/search.rb +72 -0
  38. data/lib/ehbrs/videos/unsupported/track.rb +32 -0
  39. data/vendor/eac_cli/Gemfile +5 -0
  40. data/vendor/eac_cli/eac_cli.gemspec +18 -0
  41. data/vendor/eac_cli/lib/eac_cli.rb +7 -0
  42. data/vendor/eac_cli/lib/eac_cli/default_runner.rb +22 -0
  43. data/vendor/eac_cli/lib/eac_cli/runner.rb +30 -0
  44. data/vendor/eac_cli/lib/eac_cli/runner/argument_option.rb +13 -0
  45. data/vendor/eac_cli/lib/eac_cli/runner/base_option.rb +22 -0
  46. data/vendor/eac_cli/lib/eac_cli/runner/boolean_option.rb +13 -0
  47. data/vendor/eac_cli/lib/eac_cli/runner/definition.rb +60 -0
  48. data/vendor/eac_cli/lib/eac_cli/runner/docopt_doc.rb +65 -0
  49. data/vendor/eac_cli/lib/eac_cli/runner/positional_argument.rb +15 -0
  50. data/vendor/eac_cli/lib/eac_cli/version.rb +5 -0
  51. data/vendor/eac_cli/spec/rubocop_spec.rb +7 -0
  52. data/vendor/eac_cli/spec/spec_helper.rb +100 -0
  53. data/vendor/eac_ruby_utils/Gemfile +16 -0
  54. data/vendor/eac_ruby_utils/MIT-LICENCE +16 -0
  55. data/vendor/eac_ruby_utils/README.rdoc +3 -0
  56. data/vendor/eac_ruby_utils/eac_ruby_utils.gemspec +25 -0
  57. data/vendor/eac_ruby_utils/lib/eac_ruby_utils.rb +23 -0
  58. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/arguments_consumer.rb +81 -0
  59. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/common_constructor.rb +133 -0
  60. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/configs.rb +82 -0
  61. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/configs/file.rb +66 -0
  62. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/console.rb +5 -0
  63. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/console/configs.rb +135 -0
  64. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/console/docopt_runner.rb +39 -0
  65. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/console/docopt_runner/_class_methods.rb +18 -0
  66. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/console/docopt_runner/_doc.rb +25 -0
  67. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/console/docopt_runner/_settings.rb +19 -0
  68. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/console/docopt_runner/_subcommands.rb +139 -0
  69. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/console/speaker.rb +134 -0
  70. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/console/speaker/_class_methods.rb +39 -0
  71. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/console/speaker/list.rb +63 -0
  72. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/console/speaker/node.rb +25 -0
  73. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/contextualizable.rb +16 -0
  74. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/core_ext.rb +5 -0
  75. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/envs.rb +23 -0
  76. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/envs/base_env.rb +28 -0
  77. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/envs/command.rb +155 -0
  78. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/envs/command/extra_options.rb +46 -0
  79. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/envs/executable.rb +51 -0
  80. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/envs/file.rb +22 -0
  81. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/envs/local_env.rb +17 -0
  82. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/envs/process.rb +19 -0
  83. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/envs/ssh_env.rb +72 -0
  84. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/filesystem_cache.rb +53 -0
  85. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/filesystem_traverser.rb +56 -0
  86. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/fs_cache.rb +11 -0
  87. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/listable.rb +17 -0
  88. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/listable/class_methods.rb +14 -0
  89. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/listable/instance_methods.rb +30 -0
  90. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/listable/integer_list.rb +23 -0
  91. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/listable/list.rb +89 -0
  92. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/listable/lists.rb +61 -0
  93. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/listable/string_list.rb +19 -0
  94. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/listable/value.rb +38 -0
  95. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/on_clean_ruby_environment.rb +23 -0
  96. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/options_consumer.rb +62 -0
  97. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/patch.rb +11 -0
  98. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/patches.rb +4 -0
  99. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/patches/class.rb +4 -0
  100. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/patches/class/common_constructor.rb +9 -0
  101. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/patches/hash.rb +5 -0
  102. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/patches/hash/options_consumer.rb +10 -0
  103. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/patches/hash/sym_keys_hash.rb +10 -0
  104. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/patches/module.rb +4 -0
  105. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/patches/module/console_speaker.rb +10 -0
  106. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/patches/module/listable.rb +10 -0
  107. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/patches/module/patch.rb +9 -0
  108. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/patches/module/require_sub.rb +9 -0
  109. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/patches/module/simple_cache.rb +10 -0
  110. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/patches/object.rb +5 -0
  111. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/patches/object/asserts.rb +14 -0
  112. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/patches/object/if_present.rb +12 -0
  113. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/patches/object/template.rb +16 -0
  114. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/paths_hash.rb +95 -0
  115. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/require_sub.rb +11 -0
  116. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/rspec.rb +9 -0
  117. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/rspec/conditional.rb +38 -0
  118. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/rspec/stubbed_ssh.rb +44 -0
  119. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/settings_provider.rb +65 -0
  120. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/simple_cache.rb +42 -0
  121. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/templates.rb +9 -0
  122. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/templates/directory.rb +104 -0
  123. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/templates/file.rb +101 -0
  124. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/templates/searcher.rb +55 -0
  125. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/version.rb +5 -0
  126. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/yaml.rb +13 -0
  127. data/vendor/eac_ruby_utils/spec/lib/eac_ruby_utils/arguments_consumer_spec.rb +17 -0
  128. data/vendor/eac_ruby_utils/spec/lib/eac_ruby_utils/common_constructor_spec.rb +36 -0
  129. data/vendor/eac_ruby_utils/spec/lib/eac_ruby_utils/configs_spec.rb +31 -0
  130. data/vendor/eac_ruby_utils/spec/lib/eac_ruby_utils/console/configs_spec.rb +14 -0
  131. data/vendor/eac_ruby_utils/spec/lib/eac_ruby_utils/console/docopt_runner_spec.rb +136 -0
  132. data/vendor/eac_ruby_utils/spec/lib/eac_ruby_utils/console/speaker_spec.rb +36 -0
  133. data/vendor/eac_ruby_utils/spec/lib/eac_ruby_utils/envs/executable_spec.rb +33 -0
  134. data/vendor/eac_ruby_utils/spec/lib/eac_ruby_utils/envs/ssh_env_spec.rb +25 -0
  135. data/vendor/eac_ruby_utils/spec/lib/eac_ruby_utils/filesystem_cache_spec.rb +32 -0
  136. data/vendor/eac_ruby_utils/spec/lib/eac_ruby_utils/listable_spec.rb +180 -0
  137. data/vendor/eac_ruby_utils/spec/lib/eac_ruby_utils/options_consumer_spec.rb +45 -0
  138. data/vendor/eac_ruby_utils/spec/lib/eac_ruby_utils/patches/hash/options_consumer_spec.rb +17 -0
  139. data/vendor/eac_ruby_utils/spec/lib/eac_ruby_utils/patches/hash/sym_keys_hash_spec.rb +13 -0
  140. data/vendor/eac_ruby_utils/spec/lib/eac_ruby_utils/patches/module/console_speaker_spec.rb +13 -0
  141. data/vendor/eac_ruby_utils/spec/lib/eac_ruby_utils/patches/module/listable_spec.rb +13 -0
  142. data/vendor/eac_ruby_utils/spec/lib/eac_ruby_utils/patches/module/simple_cache_spec.rb +13 -0
  143. data/vendor/eac_ruby_utils/spec/lib/eac_ruby_utils/patches/object/if_present_spec.rb +13 -0
  144. data/vendor/eac_ruby_utils/spec/lib/eac_ruby_utils/patches/object/template_spec.rb +23 -0
  145. data/vendor/eac_ruby_utils/spec/lib/eac_ruby_utils/patches/object/template_spec_files/path/my_stub_with_template +1 -0
  146. data/vendor/eac_ruby_utils/spec/lib/eac_ruby_utils/paths_hash_spec.rb +49 -0
  147. data/vendor/eac_ruby_utils/spec/lib/eac_ruby_utils/settings_provider_spec.rb +46 -0
  148. data/vendor/eac_ruby_utils/spec/lib/eac_ruby_utils/simple_cache_spec.rb +102 -0
  149. data/vendor/eac_ruby_utils/spec/lib/eac_ruby_utils/templates/file_spec.rb +34 -0
  150. data/vendor/eac_ruby_utils/spec/lib/eac_ruby_utils/templates/file_spec_files/expected_content +2 -0
  151. data/vendor/eac_ruby_utils/spec/lib/eac_ruby_utils/templates/file_spec_files/source.template +2 -0
  152. data/vendor/eac_ruby_utils/spec/lib/eac_ruby_utils/templates/searcher_spec.rb +30 -0
  153. data/vendor/eac_ruby_utils/spec/lib/eac_ruby_utils/templates/searcher_spec_files/path1/subdir1/file1.template +1 -0
  154. data/vendor/eac_ruby_utils/spec/lib/eac_ruby_utils/templates/searcher_spec_files/path1/subdir1/file2 +1 -0
  155. data/vendor/eac_ruby_utils/spec/lib/eac_ruby_utils/templates/searcher_spec_files/path2/subdir1/file3.template +1 -0
  156. data/vendor/eac_ruby_utils/spec/locales/pt-BR.yml +38 -0
  157. data/vendor/eac_ruby_utils/spec/spec_helper.rb +12 -0
  158. metadata +227 -0
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EacRubyUtils
4
+ module Envs
5
+ class File
6
+ attr_reader :env, :path
7
+
8
+ def initialize(env, path)
9
+ @env = env
10
+ @path = path
11
+ end
12
+
13
+ def exist?
14
+ env.command('stat', path).execute[:exit_code].zero?
15
+ end
16
+
17
+ def read
18
+ env.command('cat', path).execute!
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_ruby_utils/envs/base_env'
4
+
5
+ module EacRubyUtils
6
+ module Envs
7
+ class LocalEnv < ::EacRubyUtils::Envs::BaseEnv
8
+ def to_s
9
+ 'LOCAL'
10
+ end
11
+
12
+ def command_line(line)
13
+ line
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'open3'
4
+
5
+ module EacRubyUtils
6
+ module Envs
7
+ class Process
8
+ def initialize(command)
9
+ @data = { command: command }
10
+ @data[:stdout], @data[:stderr], @data[:exit_code] = Open3.capture3(command)
11
+ @data[:exit_code] = @data[:exit_code].to_i
12
+ end
13
+
14
+ def to_h
15
+ @data.dup
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,72 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'addressable'
4
+ require 'eac_ruby_utils/envs/base_env'
5
+ require 'net/ssh'
6
+ require 'shellwords'
7
+
8
+ module EacRubyUtils
9
+ module Envs
10
+ class SshEnv < ::EacRubyUtils::Envs::BaseEnv
11
+ USER_PATTERN = /[a-z_][a-z0-9_-]*/.freeze
12
+ HOSTNAME_PATTERN = /[^@]+/.freeze
13
+ USER_HOSTNAME_PATTERN = /\A(?:(#{USER_PATTERN})@)?(#{HOSTNAME_PATTERN})\z/.freeze
14
+
15
+ class << self
16
+ def parse_uri(uri)
17
+ uri_by_url(uri) || uri_by_user_hostname(uri) || raise("URI has no SSH scheme: #{uri}")
18
+ end
19
+
20
+ private
21
+
22
+ def uri_by_url(url)
23
+ r = ::Addressable::URI.parse(url)
24
+ r.scheme == 'ssh' && r.host.present? ? r : nil
25
+ end
26
+
27
+ def uri_by_user_hostname(user_hostname)
28
+ m = USER_HOSTNAME_PATTERN.match(user_hostname)
29
+ m ? ::Addressable::URI.new(scheme: 'ssh', host: m[2], user: m[1]) : nil
30
+ rescue Addressable::URI::InvalidURIError
31
+ nil
32
+ end
33
+ end
34
+
35
+ attr_reader :uri
36
+
37
+ def initialize(uri)
38
+ @uri = self.class.parse_uri(uri).freeze
39
+ end
40
+
41
+ def to_s
42
+ uri.to_s
43
+ end
44
+
45
+ def command_line(line)
46
+ "#{ssh_command_line} #{Shellwords.escape(line)}"
47
+ end
48
+
49
+ private
50
+
51
+ def ssh_command_line
52
+ r = %w[ssh]
53
+ r += ['-p', uri.port] if uri.port.present?
54
+ r += ssh_command_line_options
55
+ r << user_hostname_uri
56
+ r.map { |a| Shellwords.escape(a) }.join(' ')
57
+ end
58
+
59
+ def ssh_command_line_options
60
+ r = []
61
+ uri.query_values&.each { |k, v| r += ['-o', "#{k}=#{v}"] }
62
+ r
63
+ end
64
+
65
+ def user_hostname_uri
66
+ r = uri.host
67
+ r = "#{uri.user}@#{r}" if uri.user.present?
68
+ r
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EacRubyUtils
4
+ class FilesystemCache
5
+ CONTENT_FILE_NAME = '__content__'
6
+
7
+ attr_reader :path
8
+
9
+ def initialize(*path_parts)
10
+ raise ArgumentError, "\"#{path_parts}\" is empty" if path_parts.empty?
11
+
12
+ @path = ::File.expand_path(::File.join(*path_parts.map(&:to_s)))
13
+ end
14
+
15
+ def clear
16
+ return unless cached?
17
+
18
+ ::File.unlink(content_path)
19
+ end
20
+
21
+ def read
22
+ return nil unless cached?
23
+
24
+ ::File.read(content_path)
25
+ end
26
+
27
+ def write(value)
28
+ assert_directory_on_path
29
+ ::File.write(content_path, value)
30
+ value
31
+ end
32
+
33
+ def child(*child_path_parts)
34
+ self.class.new(path, *child_path_parts)
35
+ end
36
+
37
+ def cached?
38
+ ::File.exist?(content_path)
39
+ end
40
+
41
+ def content_path
42
+ ::File.join(path, CONTENT_FILE_NAME)
43
+ end
44
+
45
+ private
46
+
47
+ def assert_directory_on_path
48
+ raise "#{path} is a file" if ::File.file?(path)
49
+
50
+ ::FileUtils.mkdir_p(path)
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EacRubyUtils
4
+ class FilesystemTraverser
5
+ attr_accessor :check_directory, :check_file, :recursive, :hidden_directories
6
+
7
+ def check_path(path)
8
+ path = ::Pathname.new(path.to_s) unless path.is_a?(::Pathname)
9
+ internal_check_path(path, 0)
10
+ end
11
+
12
+ def hidden_directories?
13
+ hidden_directories ? true : false
14
+ end
15
+
16
+ def recursive?
17
+ recursive ? true : false
18
+ end
19
+
20
+ private
21
+
22
+ def process_directory?(level)
23
+ level.zero? || recursive?
24
+ end
25
+
26
+ def inner_check_directory(dir, level)
27
+ return unless process_directory?(level)
28
+
29
+ user_check_directory(dir)
30
+ dir.each_entry do |e|
31
+ next if %(. ..).include?(e.basename.to_s)
32
+ next unless !e.basename.to_s.start_with?('.') || hidden_directories?
33
+
34
+ internal_check_path(dir.join(e), level + 1)
35
+ end
36
+ end
37
+
38
+ def internal_check_path(path, level)
39
+ if path.file?
40
+ user_check_file(path)
41
+ elsif path.directory?
42
+ inner_check_directory(path, level)
43
+ else
44
+ raise "Unknown filesystem object: #{path}"
45
+ end
46
+ end
47
+
48
+ def user_check_file(path)
49
+ check_file&.call(path)
50
+ end
51
+
52
+ def user_check_directory(path)
53
+ check_directory&.call(path)
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_ruby_utils/filesystem_cache'
4
+
5
+ module EacRubyUtils
6
+ class << self
7
+ def fs_cache
8
+ @fs_cache ||= ::EacRubyUtils::FilesystemCache.new(::Dir.tmpdir, 'eac_ruby_utils', '.cache')
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_support/concern'
4
+ Dir["#{__dir__}/#{::File.basename(__FILE__, '.*')}/*.rb"].sort.each do |partial|
5
+ require partial
6
+ end
7
+
8
+ module EacRubyUtils
9
+ module Listable
10
+ extend ActiveSupport::Concern
11
+
12
+ included do
13
+ extend(ClassMethods)
14
+ include(InstanceMethods)
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'i18n'
4
+ require_relative 'lists'
5
+
6
+ module EacRubyUtils
7
+ module Listable
8
+ module ClassMethods
9
+ def lists
10
+ @lists ||= ::EacRubyUtils::Listable::Lists.new(self)
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EacRubyUtils
4
+ module Listable
5
+ module InstanceMethods
6
+ LISTABLE_INSTANCE_VALUE_METHODS = %w[label description].freeze
7
+
8
+ def method_missing(name, *args, &block)
9
+ list, method = parse_method(name)
10
+ list && method ? list.instance_value(self).send(method) : super
11
+ end
12
+
13
+ def respond_to_missing?(name, include_all = false)
14
+ list, method = parse_method(name)
15
+ list && method ? true : super
16
+ end
17
+
18
+ private
19
+
20
+ def parse_method(method)
21
+ self.class.lists.acts_as_listable_items.each do |item, list|
22
+ LISTABLE_INSTANCE_VALUE_METHODS.each do |m|
23
+ return [list, m] if method.to_s == "#{item}_#{m}"
24
+ end
25
+ end
26
+ [nil, nil]
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'list'
4
+
5
+ module EacRubyUtils
6
+ module Listable
7
+ class IntegerList < ::EacRubyUtils::Listable::List
8
+ protected
9
+
10
+ def parse_labels(labels)
11
+ if labels.first.is_a?(Hash)
12
+ Hash[labels.first.map { |k, v| [k.to_i, v.to_s] }]
13
+ else
14
+ Hash[labels.each_with_index.map { |v, i| [i + 1, v.to_s] }]
15
+ end
16
+ end
17
+
18
+ def build_value(index, _key)
19
+ index + 1
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,89 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EacRubyUtils
4
+ module Listable
5
+ class List
6
+ attr_reader :item
7
+
8
+ def initialize(lists, item, labels)
9
+ @lists = lists
10
+ @item = item
11
+ @values = build_values(labels)
12
+ apply_constants
13
+ end
14
+
15
+ def values
16
+ @values.values.map(&:value)
17
+ end
18
+
19
+ def options
20
+ @values.values.map { |v| [v.label, v.value] }
21
+ end
22
+
23
+ def method_missing(name, *args, &block)
24
+ list = find_list_by_method(name)
25
+ list || super
26
+ end
27
+
28
+ def respond_to_missing?(name, include_all = false)
29
+ find_list_by_method(name) || super
30
+ end
31
+
32
+ def i18n_key
33
+ "eac_ruby_utils.listable.#{class_i18n_key}.#{item}"
34
+ end
35
+
36
+ def instance_value(instance)
37
+ v = instance.send(item)
38
+ return @values[v] if @values.key?(v)
39
+
40
+ raise "List value unkown: #{v} (Source: #{@lists.source}, Item: #{item})"
41
+ end
42
+
43
+ def value_valid?(value)
44
+ values.include?(value)
45
+ end
46
+
47
+ def value_validate!(value, error_class = ::StandardError)
48
+ value_valid?(value) ||
49
+ raise(error_class, "Invalid value: \"#{value}\" (Valid: #{values_to_s})")
50
+ end
51
+
52
+ def values_to_s
53
+ values.map { |v| "\"#{v}\"" }.join(', ')
54
+ end
55
+
56
+ private
57
+
58
+ def class_i18n_key
59
+ @lists.source.name.underscore.to_sym
60
+ end
61
+
62
+ def find_list_by_method(method)
63
+ @values.values.each do |v|
64
+ return v if method.to_s == "value_#{v.key}"
65
+ end
66
+ nil
67
+ end
68
+
69
+ def constants
70
+ labels.each_with_index.map { |v, i| ["#{item.upcase}_#{v.upcase}", values[i]] }
71
+ end
72
+
73
+ def apply_constants
74
+ @values.values.each do |v|
75
+ @lists.source.const_set(v.constant_name, v.value)
76
+ end
77
+ end
78
+
79
+ def build_values(labels)
80
+ vs = {}
81
+ parse_labels(labels).each do |value, key|
82
+ v = Value.new(self, value, key)
83
+ vs[v.value] = v
84
+ end
85
+ vs
86
+ end
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,61 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_support/hash_with_indifferent_access'
4
+ require 'active_support/core_ext/string/inflections'
5
+ require_relative 'integer_list'
6
+ require_relative 'string_list'
7
+
8
+ module EacRubyUtils
9
+ module Listable
10
+ class Lists
11
+ attr_reader :source
12
+
13
+ def initialize(source)
14
+ @source = source
15
+ end
16
+
17
+ def add_integer(item, *labels)
18
+ check_acts_as_listable_new_item(item)
19
+ acts_as_listable_items[item] = ::EacRubyUtils::Listable::IntegerList.new(
20
+ self, item, labels
21
+ )
22
+ end
23
+
24
+ def add_string(item, *labels)
25
+ check_acts_as_listable_new_item(item)
26
+ acts_as_listable_items[item] = ::EacRubyUtils::Listable::StringList.new(
27
+ self, item, labels
28
+ )
29
+ end
30
+
31
+ def method_missing(name, *args, &block)
32
+ list = find_list_by_method(name)
33
+ list || super
34
+ end
35
+
36
+ def respond_to_missing?(name, include_all = false)
37
+ find_list_by_method(name) || super
38
+ end
39
+
40
+ def acts_as_listable_items
41
+ @acts_as_listable_items ||= ActiveSupport::HashWithIndifferentAccess.new
42
+ end
43
+
44
+ private
45
+
46
+ def check_acts_as_listable_new_item(item)
47
+ return unless acts_as_listable_items.key?(item)
48
+
49
+ raise "Item já adicionado anteriormente: #{item} em #{self} " \
50
+ "(#{acts_as_listable_items.keys})"
51
+ end
52
+
53
+ def find_list_by_method(method)
54
+ acts_as_listable_items.each do |item, list|
55
+ return list if method.to_sym == item.to_sym
56
+ end
57
+ nil
58
+ end
59
+ end
60
+ end
61
+ end