wibrfake-brk 0.0.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 (275) hide show
  1. checksums.yaml +7 -0
  2. data/.dockerignore +48 -0
  3. data/.gitattributes +19 -0
  4. data/.github/dependabot.yml +12 -0
  5. data/.github/workflows/ci.yml +90 -0
  6. data/.rubocop.yml +8 -0
  7. data/.ruby-version +1 -0
  8. data/Dockerfile +69 -0
  9. data/Gemfile +68 -0
  10. data/README.md +188 -0
  11. data/Rakefile +6 -0
  12. data/app/assets/config/manifest.js +5 -0
  13. data/app/assets/images/.keep +0 -0
  14. data/app/assets/images/2024-12-30-07:58:34-screenshot.png +0 -0
  15. data/app/assets/images/facebook/facebook-logo.svg +3 -0
  16. data/app/assets/images/google/googlelogo_color_272x92dp.png +0 -0
  17. data/app/assets/images/instagram/app-store.png +0 -0
  18. data/app/assets/images/instagram/google-play.png +0 -0
  19. data/app/assets/images/instagram/instagram-logo.png +0 -0
  20. data/app/assets/images/instagram/screenshot1.png +0 -0
  21. data/app/assets/images/instagram/screenshot2.png +0 -0
  22. data/app/assets/images/instagram/screenshot3.png +0 -0
  23. data/app/assets/images/instagram/screenshot4.png +0 -0
  24. data/app/assets/images/nauta_etecsa/CUBADEBATE.jpg +0 -0
  25. data/app/assets/images/nauta_etecsa/CUBAEDUCA.jpg +0 -0
  26. data/app/assets/images/nauta_etecsa/CUBARTE.jpg +0 -0
  27. data/app/assets/images/nauta_etecsa/CUBASI.jpg +0 -0
  28. data/app/assets/images/nauta_etecsa/ECURED.jpg +0 -0
  29. data/app/assets/images/nauta_etecsa/OFERTAS.jpg +0 -0
  30. data/app/assets/images/nauta_etecsa/PAPELETA.jpg +0 -0
  31. data/app/assets/images/nauta_etecsa/contenedor_bg.jpg +0 -0
  32. data/app/assets/images/nauta_etecsa/etecsa.jpg +0 -0
  33. data/app/assets/images/nauta_etecsa/nauta_wifi.jpg +0 -0
  34. data/app/assets/images/nauta_hogar/CUBADEBATE.jpg +0 -0
  35. data/app/assets/images/nauta_hogar/CUBAEDUCA.jpg +0 -0
  36. data/app/assets/images/nauta_hogar/CUBARTE.jpg +0 -0
  37. data/app/assets/images/nauta_hogar/CUBASI.jpg +0 -0
  38. data/app/assets/images/nauta_hogar/ECURED.jpg +0 -0
  39. data/app/assets/images/nauta_hogar/OFERTAS.jpg +0 -0
  40. data/app/assets/images/nauta_hogar/PAPELETA.jpg +0 -0
  41. data/app/assets/images/nauta_hogar/banner_hogar.png +0 -0
  42. data/app/assets/images/wibrfake/Breaker-Wallpaper1.jpg +0 -0
  43. data/app/assets/images/wibrfake/mac-list-parameter.png +0 -0
  44. data/app/assets/images/wibrfake/wibrfake-100x100.png +0 -0
  45. data/app/assets/images/wibrfake/wibrfake-32x32.png +0 -0
  46. data/app/assets/images/wibrfake/wibrfake-48x48.png +0 -0
  47. data/app/assets/images/wibrfake/wibrfake-apfake-on.png +0 -0
  48. data/app/assets/images/wibrfake/wibrfake-apfake-set-basic.png +0 -0
  49. data/app/assets/images/wibrfake/wibrfake-apfake-show.png +0 -0
  50. data/app/assets/images/wibrfake/wibrfake-help.png +0 -0
  51. data/app/assets/images/wibrfake/wibrfake-hostpot.png +0 -0
  52. data/app/assets/images/wibrfake/wibrfake-init.png +0 -0
  53. data/app/assets/images/wibrfake/wibrfake-init2.png +0 -0
  54. data/app/assets/images/wibrfake/wibrfake-login-basic.jpg +0 -0
  55. data/app/assets/images/wibrfake/wibrfake-mac-list.png +0 -0
  56. data/app/assets/images/wibrfake/wibrfake-mac-ramset-oui.png +0 -0
  57. data/app/assets/images/wibrfake/wibrfake-mac-ramset.png +0 -0
  58. data/app/assets/images/wibrfake/wibrfake-mac-set.png +0 -0
  59. data/app/assets/images/wibrfake/wibrfake-mac-show.png +0 -0
  60. data/app/assets/images/wibrfake/wibrfake-need-signin.jpg +0 -0
  61. data/app/assets/images/wibrfake/wibrfake-session-active.png +0 -0
  62. data/app/assets/images/wibrfake/wibrfake-session-init.png +0 -0
  63. data/app/assets/images/wibrfake/wibrfake-session-list.png +0 -0
  64. data/app/assets/images/wibrfake/wibrfake-session-new.png +0 -0
  65. data/app/assets/images/wibrfake/wibrfake-session-rename.png +0 -0
  66. data/app/assets/images/wibrfake/wibrfake-session-save.png +0 -0
  67. data/app/assets/images/wibrfake/wibrfake-web-server-apfake.png +0 -0
  68. data/app/assets/images/wibrfake/wibrfake-web-server-on.png +0 -0
  69. data/app/assets/images/wibrfake/wibrfake-web-server-show.png +0 -0
  70. data/app/assets/images/wibrfake/wibrfake-wkdump-loaded.png +0 -0
  71. data/app/assets/images/wibrfake/wibrfake-wkdump.png +0 -0
  72. data/app/assets/images/wibrfake/wibrfake.png +0 -0
  73. data/app/assets/stylesheets/application.css +15 -0
  74. data/app/assets/stylesheets/basic/page_basic.css +0 -0
  75. data/app/assets/stylesheets/facebook/page_facebook.css +93 -0
  76. data/app/assets/stylesheets/google/page_google.css +137 -0
  77. data/app/assets/stylesheets/instagram/page_instagram.css +94 -0
  78. data/app/assets/stylesheets/nauta_etecsa/page_nauta.css +325 -0
  79. data/app/assets/stylesheets/nauta_hogar/page_nauta.css +469 -0
  80. data/app/assets/stylesheets/wibrfake/page_wibrfake.css +1181 -0
  81. data/app/assets/stylesheets/wibrfake/page_wibrfake_about.css +486 -0
  82. data/app/channels/application_cable/channel.rb +4 -0
  83. data/app/channels/application_cable/connection.rb +4 -0
  84. data/app/controllers/application_controller.rb +15 -0
  85. data/app/controllers/concerns/.keep +0 -0
  86. data/app/controllers/sessions_controller.rb +111 -0
  87. data/app/helpers/application_helper.rb +2 -0
  88. data/app/helpers/sessions_helper.rb +2 -0
  89. data/app/javascript/application.js +3 -0
  90. data/app/javascript/bootstrap.bundle.min.js +7 -0
  91. data/app/javascript/controllers/application.js +9 -0
  92. data/app/javascript/controllers/hello_controller.js +7 -0
  93. data/app/javascript/controllers/index.js +4 -0
  94. data/app/javascript/google/page_google.js +50 -0
  95. data/app/javascript/incorrect3.js +29 -0
  96. data/app/javascript/page_wibrfake.js +50 -0
  97. data/app/javascript/page_wibrfake_about.js +147 -0
  98. data/app/jobs/application_job.rb +7 -0
  99. data/app/mailers/application_mailer.rb +4 -0
  100. data/app/models/application_record.rb +3 -0
  101. data/app/models/concerns/.keep +0 -0
  102. data/app/models/user.rb +6 -0
  103. data/app/views/layouts/application.html.erb +33 -0
  104. data/app/views/layouts/mailer.html.erb +13 -0
  105. data/app/views/layouts/mailer.text.erb +1 -0
  106. data/app/views/pwa/manifest.json.erb +22 -0
  107. data/app/views/pwa/service-worker.js +26 -0
  108. data/app/views/sessions/basic/basic.html.erb +21 -0
  109. data/app/views/sessions/facebook/facebook.html.erb +132 -0
  110. data/app/views/sessions/google/google.html.erb +72 -0
  111. data/app/views/sessions/index.html.erb +11 -0
  112. data/app/views/sessions/instagram/instagram.html.erb +69 -0
  113. data/app/views/sessions/nauta_etecsa/nauta_etecsa.html.erb +97 -0
  114. data/app/views/sessions/nauta_hogar/nauta_hogar.html.erb +135 -0
  115. data/app/views/sessions/wibrfake/about/about.html.erb +164 -0
  116. data/app/views/sessions/wibrfake/wibrfake.html.erb +417 -0
  117. data/bin/.names.rb.swp +0 -0
  118. data/bin/brakeman +7 -0
  119. data/bin/bundle +114 -0
  120. data/bin/docker-entrypoint +13 -0
  121. data/bin/google.wkdump +3 -0
  122. data/bin/importmap +4 -0
  123. data/bin/rails +4 -0
  124. data/bin/rake +4 -0
  125. data/bin/rubocop +8 -0
  126. data/bin/setup +37 -0
  127. data/bin/wibrfake +20 -0
  128. data/config/application.rb +26 -0
  129. data/config/boot.rb +4 -0
  130. data/config/cable.yml +10 -0
  131. data/config/credentials.yml.enc +1 -0
  132. data/config/database.yml +16 -0
  133. data/config/environment.rb +5 -0
  134. data/config/environments/development.rb +85 -0
  135. data/config/environments/production.rb +105 -0
  136. data/config/environments/test.rb +67 -0
  137. data/config/icons/application-x-wkdump.xml +13 -0
  138. data/config/icons/hicolor/16x16/mimetypes/application-x-wkdump.png +0 -0
  139. data/config/icons/hicolor/32x32/mimetypes/application-x-wkdump.png +0 -0
  140. data/config/icons/hicolor/48x48/mimetypes/application-x-wkdump.png +0 -0
  141. data/config/icons/hicolor/icon-theme.cache +0 -0
  142. data/config/icons/hicolor/index.theme +20 -0
  143. data/config/icons/wkdump.desktop +5 -0
  144. data/config/importmap.rb +7 -0
  145. data/config/initializers/assets.rb +12 -0
  146. data/config/initializers/content_security_policy.rb +25 -0
  147. data/config/initializers/devise.rb +313 -0
  148. data/config/initializers/filter_parameter_logging.rb +8 -0
  149. data/config/initializers/inflections.rb +16 -0
  150. data/config/initializers/permissions_policy.rb +13 -0
  151. data/config/locales/devise.en.yml +65 -0
  152. data/config/locales/en.yml +31 -0
  153. data/config/puma.rb +35 -0
  154. data/config/routes.rb +12 -0
  155. data/config/storage.yml +34 -0
  156. data/config.ru +6 -0
  157. data/db/development.sqlite3 +0 -0
  158. data/db/schema.rb +14 -0
  159. data/ext/wibrfake/extconf.rb +3 -0
  160. data/ext/wibrfake/wibrfake.h +0 -0
  161. data/images/ouilist.png +0 -0
  162. data/images/wibrfakehelp.png +0 -0
  163. data/images/wibrfakeinit.png +0 -0
  164. data/lib/assets/.keep +0 -0
  165. data/lib/tasks/.keep +0 -0
  166. data/lib/wibrfake/Config/ipaddr.rb +71 -0
  167. data/lib/wibrfake/Config/options.rb +98 -0
  168. data/lib/wibrfake/Config/security_wpa.rb +43 -0
  169. data/lib/wibrfake/DataBase/howuis.db +0 -0
  170. data/lib/wibrfake/DataBase/ouis.db +0 -0
  171. data/lib/wibrfake/DataBase/ouis.rb +24 -0
  172. data/lib/wibrfake/DataBase/rename.rb +15 -0
  173. data/lib/wibrfake/DataBase/show.rb +18 -0
  174. data/lib/wibrfake/Dnsmasq/dhcp.rb +149 -0
  175. data/lib/wibrfake/Dnsmasq/dhcp_prueba.rb +135 -0
  176. data/lib/wibrfake/Dnsmasq/dns.rb +34 -0
  177. data/lib/wibrfake/Dnsmasq/dns_prueba.rb +36 -0
  178. data/lib/wibrfake/Dnsmasq/dnsmasq.rb +33 -0
  179. data/lib/wibrfake/Listing/apfake.rb +28 -0
  180. data/lib/wibrfake/Listing/clients.rb +76 -0
  181. data/lib/wibrfake/Listing/ouis.rb +53 -0
  182. data/lib/wibrfake/Listing/process.rb +14 -0
  183. data/lib/wibrfake/Listing/sessions.rb +47 -0
  184. data/lib/wibrfake/Listing/web_server.rb +17 -0
  185. data/lib/wibrfake/Listing/wireless.rb +30 -0
  186. data/lib/wibrfake/Logs/credentials.log +59 -0
  187. data/lib/wibrfake/NetworkInterface/ip-routing.rb +99 -0
  188. data/lib/wibrfake/NetworkInterface/mac.rb +114 -0
  189. data/lib/wibrfake/NetworkInterface/monitor.rb +44 -0
  190. data/lib/wibrfake/NetworkInterface/ouis.db +0 -0
  191. data/lib/wibrfake/Process/id.rb +11 -0
  192. data/lib/wibrfake/Process/pids.log +5 -0
  193. data/lib/wibrfake/Process/pkill.rb +124 -0
  194. data/lib/wibrfake/Process/processes.rb +76 -0
  195. data/lib/wibrfake/Rails/login.rb +20 -0
  196. data/lib/wibrfake/Rails/routes.rb +76 -0
  197. data/lib/wibrfake/Rails/service.rb +58 -0
  198. data/lib/wibrfake/Rails/service_usage.rb +46 -0
  199. data/lib/wibrfake/Sessions/session.rb +188 -0
  200. data/lib/wibrfake/String/string.rb +109 -0
  201. data/lib/wibrfake/Tmp/config.yml +1 -0
  202. data/lib/wibrfake/config.rb +24 -0
  203. data/lib/wibrfake/help.rb +107 -0
  204. data/lib/wibrfake/optionpr.rb +68 -0
  205. data/lib/wibrfake/run.rb +9 -0
  206. data/lib/wibrfake/ty/apld.rb +110 -0
  207. data/lib/wibrfake/ty/prompt/answers_collector.rb +78 -0
  208. data/lib/wibrfake/ty/prompt/block_paginator.rb +59 -0
  209. data/lib/wibrfake/ty/prompt/choice.rb +147 -0
  210. data/lib/wibrfake/ty/prompt/choices.rb +129 -0
  211. data/lib/wibrfake/ty/prompt/confirm_question.rb +158 -0
  212. data/lib/wibrfake/ty/prompt/const.rb +17 -0
  213. data/lib/wibrfake/ty/prompt/converter_dsl.rb +21 -0
  214. data/lib/wibrfake/ty/prompt/converter_registry.rb +69 -0
  215. data/lib/wibrfake/ty/prompt/converters.rb +182 -0
  216. data/lib/wibrfake/ty/prompt/distance.rb +49 -0
  217. data/lib/wibrfake/ty/prompt/enum_list.rb +433 -0
  218. data/lib/wibrfake/ty/prompt/errors.rb +31 -0
  219. data/lib/wibrfake/ty/prompt/evaluator.rb +29 -0
  220. data/lib/wibrfake/ty/prompt/expander.rb +321 -0
  221. data/lib/wibrfake/ty/prompt/keypress.rb +98 -0
  222. data/lib/wibrfake/ty/prompt/list.rb +589 -0
  223. data/lib/wibrfake/ty/prompt/mask_question.rb +96 -0
  224. data/lib/wibrfake/ty/prompt/multi_list.rb +224 -0
  225. data/lib/wibrfake/ty/prompt/multiline.rb +72 -0
  226. data/lib/wibrfake/ty/prompt/paginator.rb +111 -0
  227. data/lib/wibrfake/ty/prompt/question/checks.rb +105 -0
  228. data/lib/wibrfake/ty/prompt/question/modifier.rb +96 -0
  229. data/lib/wibrfake/ty/prompt/question/validation.rb +72 -0
  230. data/lib/wibrfake/ty/prompt/question.rb +391 -0
  231. data/lib/wibrfake/ty/prompt/result.rb +42 -0
  232. data/lib/wibrfake/ty/prompt/selected_choices.rb +77 -0
  233. data/lib/wibrfake/ty/prompt/slider.rb +286 -0
  234. data/lib/wibrfake/ty/prompt/statement.rb +55 -0
  235. data/lib/wibrfake/ty/prompt/suggestion.rb +113 -0
  236. data/lib/wibrfake/ty/prompt/symbols.rb +89 -0
  237. data/lib/wibrfake/ty/prompt/test.rb +36 -0
  238. data/lib/wibrfake/ty/prompt/timer.rb +75 -0
  239. data/lib/wibrfake/ty/prompt/utils.rb +42 -0
  240. data/lib/wibrfake/ty/prompt/version.rb +7 -0
  241. data/lib/wibrfake/ty/prompt.rb +589 -0
  242. data/lib/wibrfake/version.rb +5 -0
  243. data/lib/wibrfake/wibrfake_cli.rb +683 -0
  244. data/log/.keep +0 -0
  245. data/pruebas/daemon1.pid +1 -0
  246. data/pruebas/daemon2.pid +1 -0
  247. data/pruebas/daemons.rb +44 -0
  248. data/public/404.html +67 -0
  249. data/public/406-unsupported-browser.html +66 -0
  250. data/public/422.html +67 -0
  251. data/public/500.html +66 -0
  252. data/public/icon.png +0 -0
  253. data/public/icon.svg +3 -0
  254. data/public/robots.txt +1 -0
  255. data/storage/.keep +0 -0
  256. data/test/application_system_test_case.rb +5 -0
  257. data/test/channels/application_cable/connection_test.rb +13 -0
  258. data/test/controllers/.keep +0 -0
  259. data/test/controllers/sessions_controller_test.rb +7 -0
  260. data/test/fixtures/files/.keep +0 -0
  261. data/test/fixtures/users.yml +11 -0
  262. data/test/helpers/.keep +0 -0
  263. data/test/integration/.keep +0 -0
  264. data/test/mailers/.keep +0 -0
  265. data/test/models/.keep +0 -0
  266. data/test/models/user_test.rb +7 -0
  267. data/test/system/.keep +0 -0
  268. data/test/test_helper.rb +15 -0
  269. data/tmp/.keep +0 -0
  270. data/tmp/pids/.keep +0 -0
  271. data/tmp/storage/.keep +0 -0
  272. data/vendor/.keep +0 -0
  273. data/vendor/javascript/.keep +0 -0
  274. data/wibrfake.gemspec +49 -0
  275. metadata +743 -0
@@ -0,0 +1,391 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "converters"
4
+ require_relative "evaluator"
5
+ require_relative "question/modifier"
6
+ require_relative "question/validation"
7
+ require_relative "question/checks"
8
+ require_relative "utils"
9
+
10
+ module TTY
11
+ # A class responsible for shell prompt interactions.
12
+ class Prompt
13
+ # A class responsible for gathering user input
14
+ #
15
+ # @api public
16
+ class Question
17
+ include Checks
18
+
19
+ UndefinedSetting = Class.new do
20
+ def to_s
21
+ "undefined"
22
+ end
23
+ alias_method :inspect, :to_s
24
+ end
25
+
26
+ # Store question message
27
+ # @api public
28
+ attr_reader :message
29
+
30
+ attr_reader :modifier
31
+
32
+ attr_reader :validation
33
+
34
+ # Initialize a Question
35
+ #
36
+ # @api public
37
+ def initialize(prompt, **options)
38
+ # Option deprecation
39
+ if options[:validation]
40
+ warn "[DEPRECATION] The `:validation` option is deprecated. Use `:validate` instead."
41
+ options[:validate] = options[:validation]
42
+ end
43
+
44
+ @prompt = prompt
45
+ @prefix = options.fetch(:prefix) { @prompt.prefix }
46
+ @default = options.fetch(:default) { UndefinedSetting }
47
+ @required = options.fetch(:required) { false }
48
+ @echo = options.fetch(:echo) { true }
49
+ @in = options.fetch(:in) { UndefinedSetting }
50
+ @modifier = options.fetch(:modifier) { [] }
51
+ @validation = options.fetch(:validate) { UndefinedSetting }
52
+ @convert = options.fetch(:convert) { UndefinedSetting }
53
+ @active_color = options.fetch(:active_color) { @prompt.active_color }
54
+ @help_color = options.fetch(:help_color) { @prompt.help_color }
55
+ @error_color = options.fetch(:error_color) { :red }
56
+ @value = options.fetch(:value) { UndefinedSetting }
57
+ @quiet = options.fetch(:quiet) { @prompt.quiet }
58
+ @messages = Utils.deep_copy(options.fetch(:messages) { {} })
59
+ @done = false
60
+ @first_render = true
61
+ @input = nil
62
+
63
+ @evaluator = Evaluator.new(self)
64
+
65
+ @evaluator << CheckRequired
66
+ @evaluator << CheckDefault
67
+ @evaluator << CheckRange
68
+ @evaluator << CheckValidation
69
+ @evaluator << CheckModifier
70
+ @evaluator << CheckConversion
71
+ end
72
+
73
+ # Stores all the error messages displayed to user
74
+ # The currently supported messages are:
75
+ # * :range?
76
+ # * :required?
77
+ # * :valid?
78
+ attr_reader :messages
79
+
80
+ # Retrieve message based on the key
81
+ #
82
+ # @param [Symbol] name
83
+ # the name of message key
84
+ #
85
+ # @param [Hash] tokens
86
+ # the tokens to evaluate
87
+ #
88
+ # @return [Array[String]]
89
+ #
90
+ # @api private
91
+ def message_for(name, tokens = nil)
92
+ template = @messages[name]
93
+ if template && !template.match(/\%\{/).nil?
94
+ [template % tokens]
95
+ else
96
+ [template || ""]
97
+ end
98
+ end
99
+
100
+ # Call the question
101
+ #
102
+ # @param [String] message
103
+ #
104
+ # @return [self]
105
+ #
106
+ # @api public
107
+ def call(message = "", &block)
108
+ @message = message
109
+ block.call(self) if block
110
+ @prompt.subscribe(self) do
111
+ render
112
+ end
113
+ end
114
+
115
+ # Read answer and convert to type
116
+ #
117
+ # @api private
118
+ def render
119
+ @errors = []
120
+ until @done
121
+ result = process_input(render_question)
122
+ if result.failure?
123
+ @errors = result.errors
124
+ @prompt.print(render_error(result.errors))
125
+ else
126
+ @done = true
127
+ end
128
+ question = render_question
129
+ input_line = question + result.value.to_s
130
+ total_lines = @prompt.count_screen_lines(input_line)
131
+ @prompt.print(refresh(question.lines.count, total_lines))
132
+ end
133
+ @prompt.print(render_question) unless @quiet
134
+ result.value
135
+ end
136
+
137
+ # Render question
138
+ #
139
+ # @return [String]
140
+ #
141
+ # @api private
142
+ def render_question
143
+ header = []
144
+ if !Utils.blank?(@prefix) || !Utils.blank?(message)
145
+ header << "#{@prefix}#{message} "
146
+ end
147
+ if !echo?
148
+ header
149
+ elsif @done
150
+ header << @prompt.decorate(@input.to_s, @active_color)
151
+ elsif default? && !Utils.blank?(@default)
152
+ header << @prompt.decorate("(#{default})", @help_color) + " "
153
+ end
154
+ header << "\n" if @done
155
+ header.join
156
+ end
157
+
158
+ # Decide how to handle input from user
159
+ #
160
+ # @api private
161
+ def process_input(question)
162
+ @input = read_input(question)
163
+ if Utils.blank?(@input)
164
+ @input = default? ? default : nil
165
+ end
166
+ @evaluator.(@input)
167
+ end
168
+
169
+ # Process input
170
+ #
171
+ # @api private
172
+ def read_input(question)
173
+ options = { echo: echo }
174
+ if value? && @first_render
175
+ options[:value] = @value
176
+ @first_render = false
177
+ end
178
+ @prompt.read_line(question, **options).chomp
179
+ end
180
+
181
+ # Handle error condition
182
+ #
183
+ # @return [String]
184
+ #
185
+ # @api private
186
+ def render_error(errors)
187
+ errors.reduce([]) do |acc, err|
188
+ acc << @prompt.decorate(">>", :red) + " " + err
189
+ acc
190
+ end.join("\n")
191
+ end
192
+
193
+ # Determine area of the screen to clear
194
+ #
195
+ # @param [Integer] lines
196
+ # number of lines to clear
197
+ #
198
+ # @return [String]
199
+ #
200
+ # @api private
201
+ def refresh(lines, lines_to_clear)
202
+ output = []
203
+ if @done
204
+ if @errors.count.zero?
205
+ output << @prompt.cursor.up(lines)
206
+ else
207
+ lines += @errors.count
208
+ lines_to_clear += @errors.count
209
+ end
210
+ else
211
+ output << @prompt.cursor.up(lines)
212
+ end
213
+ output.join + @prompt.clear_lines(lines_to_clear)
214
+ end
215
+
216
+ # Convert value to expected type
217
+ #
218
+ # @param [Object] value
219
+ #
220
+ # @api private
221
+ def convert_result(value)
222
+ if convert? && !Utils.blank?(value)
223
+ case @convert
224
+ when Proc
225
+ @convert.call(value)
226
+ else
227
+ Converters.convert(@convert, value)
228
+ end
229
+ else
230
+ value
231
+ end
232
+ end
233
+
234
+ # Specify answer conversion
235
+ #
236
+ # @api public
237
+ def convert(value = (not_set = true), message = nil)
238
+ messages[:convert?] = message if message
239
+ if not_set
240
+ @convert
241
+ else
242
+ @convert = value
243
+ end
244
+ end
245
+
246
+ # Check if conversion is set
247
+ #
248
+ # @return [Boolean]
249
+ #
250
+ # @api public
251
+ def convert?
252
+ @convert != UndefinedSetting
253
+ end
254
+
255
+ # Set default value.
256
+ #
257
+ # @api public
258
+ def default(value = (not_set = true))
259
+ return @default if not_set
260
+
261
+ @default = value
262
+ end
263
+
264
+ # Check if default value is set
265
+ #
266
+ # @return [Boolean]
267
+ #
268
+ # @api public
269
+ def default?
270
+ @default != UndefinedSetting
271
+ end
272
+
273
+ # Ensure that passed argument is present or not
274
+ #
275
+ # @return [Boolean]
276
+ #
277
+ # @api public
278
+ def required(value = (not_set = true), message = nil)
279
+ messages[:required?] = message if message
280
+ return @required if not_set
281
+
282
+ @required = value
283
+ end
284
+ alias required? required
285
+
286
+ # Set validation rule for an argument
287
+ #
288
+ # @param [Object] value
289
+ #
290
+ # @return [Question]
291
+ #
292
+ # @api public
293
+ def validate(value = nil, message = nil, &block)
294
+ messages[:valid?] = message if message
295
+ @validation = (value || block)
296
+ end
297
+
298
+ # Prepopulate input with custom content
299
+ #
300
+ # @api public
301
+ def value(val)
302
+ return @value if val.nil?
303
+
304
+ @value = val
305
+ end
306
+
307
+ # Check if custom value is present
308
+ #
309
+ # @api private
310
+ def value?
311
+ @value != UndefinedSetting
312
+ end
313
+
314
+ def validation?
315
+ @validation != UndefinedSetting
316
+ end
317
+
318
+ # Modify string according to the rule given.
319
+ #
320
+ # @param [Symbol] rule
321
+ #
322
+ # @api public
323
+ def modify(*rules)
324
+ @modifier = rules
325
+ end
326
+
327
+ # Turn terminal echo on or off. This is used to secure the display so
328
+ # that the entered characters are not echoed back to the screen.
329
+ #
330
+ # @api public
331
+ def echo(value = nil)
332
+ return @echo if value.nil?
333
+
334
+ @echo = value
335
+ end
336
+ alias echo? echo
337
+
338
+ # Turn raw mode on or off. This enables character-based input.
339
+ #
340
+ # @api public
341
+ def raw(value = nil)
342
+ return @raw if value.nil?
343
+
344
+ @raw = value
345
+ end
346
+ alias raw? raw
347
+
348
+ # Set expected range of values
349
+ #
350
+ # @param [String] value
351
+ #
352
+ # @api public
353
+ def in(value = (not_set = true), message = nil)
354
+ messages[:range?] = message if message
355
+ if in? && !@in.is_a?(Range)
356
+ @in = Converters.convert(:range, @in)
357
+ end
358
+ return @in if not_set
359
+
360
+ @in = Converters.convert(:range, value)
361
+ end
362
+
363
+ # Check if range is set
364
+ #
365
+ # @return [Boolean]
366
+ #
367
+ # @api public
368
+ def in?
369
+ @in != UndefinedSetting
370
+ end
371
+
372
+ # Set quiet mode.
373
+ #
374
+ # @api public
375
+ def quiet(value)
376
+ @quiet = value
377
+ end
378
+
379
+ # @api public
380
+ def to_s
381
+ message.to_s
382
+ end
383
+
384
+ # String representation of this question
385
+ # @api public
386
+ def inspect
387
+ "#<#{self.class.name} @message=#{message}, @input=#{@input}>"
388
+ end
389
+ end # Question
390
+ end # Prompt
391
+ end # TTY
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TTY
4
+ class Prompt
5
+ # Accumulates errors
6
+ class Result
7
+ attr_reader :question, :value, :errors
8
+
9
+ def initialize(question, value, errors = [])
10
+ @question = question
11
+ @value = value
12
+ @errors = errors
13
+ end
14
+
15
+ def with(condition = nil, &block)
16
+ validator = (condition || block)
17
+ (new_value, validation_error) = validator.call(question, value)
18
+ accumulated_errors = errors + Array(validation_error)
19
+
20
+ if accumulated_errors.empty?
21
+ Success.new(question, new_value)
22
+ else
23
+ Failure.new(question, new_value, accumulated_errors)
24
+ end
25
+ end
26
+
27
+ def success?
28
+ is_a?(Success)
29
+ end
30
+
31
+ def failure?
32
+ is_a?(Failure)
33
+ end
34
+
35
+ class Success < Result
36
+ end
37
+
38
+ class Failure < Result
39
+ end
40
+ end
41
+ end # Prompt
42
+ end # TTY
@@ -0,0 +1,77 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TTY
4
+ class Prompt
5
+ # @api private
6
+ class SelectedChoices
7
+ include Enumerable
8
+
9
+ attr_reader :size
10
+
11
+ # Create selected choices
12
+ #
13
+ # @param [Array<Choice>] selected
14
+ # @param [Array<Integer>] indexes
15
+ #
16
+ # @api public
17
+ def initialize(selected = [], indexes = [])
18
+ @selected = selected
19
+ @indexes = indexes
20
+ @size = @selected.size
21
+ end
22
+
23
+ # Clear selected choices
24
+ #
25
+ # @api public
26
+ def clear
27
+ @indexes.clear
28
+ @selected.clear
29
+ @size = 0
30
+ end
31
+
32
+ # Iterate over selected choices
33
+ #
34
+ # @api public
35
+ def each(&block)
36
+ return to_enum unless block_given?
37
+
38
+ @selected.each(&block)
39
+ end
40
+
41
+ # Insert choice at index
42
+ #
43
+ # @param [Integer] index
44
+ # @param [Choice] choice
45
+ #
46
+ # @api public
47
+ def insert(index, choice)
48
+ insert_idx = find_index_by { |i| index < @indexes[i] }
49
+ insert_idx ||= -1
50
+ @indexes.insert(insert_idx, index)
51
+ @selected.insert(insert_idx, choice)
52
+ @size += 1
53
+ self
54
+ end
55
+
56
+ # Delete choice at index
57
+ #
58
+ # @return [Choice]
59
+ # the deleted choice
60
+ #
61
+ # @api public
62
+ def delete_at(index)
63
+ delete_idx = @indexes.each_index.find { |i| index == @indexes[i] }
64
+ return nil unless delete_idx
65
+
66
+ @indexes.delete_at(delete_idx)
67
+ choice = @selected.delete_at(delete_idx)
68
+ @size -= 1
69
+ choice
70
+ end
71
+
72
+ def find_index_by(&search)
73
+ (0...@size).bsearch(&search)
74
+ end
75
+ end # SelectedChoices
76
+ end # Prompt
77
+ end # TTY