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.
- checksums.yaml +7 -0
- data/.dockerignore +48 -0
- data/.gitattributes +19 -0
- data/.github/dependabot.yml +12 -0
- data/.github/workflows/ci.yml +90 -0
- data/.rubocop.yml +8 -0
- data/.ruby-version +1 -0
- data/Dockerfile +69 -0
- data/Gemfile +68 -0
- data/README.md +188 -0
- data/Rakefile +6 -0
- data/app/assets/config/manifest.js +5 -0
- data/app/assets/images/.keep +0 -0
- data/app/assets/images/2024-12-30-07:58:34-screenshot.png +0 -0
- data/app/assets/images/facebook/facebook-logo.svg +3 -0
- data/app/assets/images/google/googlelogo_color_272x92dp.png +0 -0
- data/app/assets/images/instagram/app-store.png +0 -0
- data/app/assets/images/instagram/google-play.png +0 -0
- data/app/assets/images/instagram/instagram-logo.png +0 -0
- data/app/assets/images/instagram/screenshot1.png +0 -0
- data/app/assets/images/instagram/screenshot2.png +0 -0
- data/app/assets/images/instagram/screenshot3.png +0 -0
- data/app/assets/images/instagram/screenshot4.png +0 -0
- data/app/assets/images/nauta_etecsa/CUBADEBATE.jpg +0 -0
- data/app/assets/images/nauta_etecsa/CUBAEDUCA.jpg +0 -0
- data/app/assets/images/nauta_etecsa/CUBARTE.jpg +0 -0
- data/app/assets/images/nauta_etecsa/CUBASI.jpg +0 -0
- data/app/assets/images/nauta_etecsa/ECURED.jpg +0 -0
- data/app/assets/images/nauta_etecsa/OFERTAS.jpg +0 -0
- data/app/assets/images/nauta_etecsa/PAPELETA.jpg +0 -0
- data/app/assets/images/nauta_etecsa/contenedor_bg.jpg +0 -0
- data/app/assets/images/nauta_etecsa/etecsa.jpg +0 -0
- data/app/assets/images/nauta_etecsa/nauta_wifi.jpg +0 -0
- data/app/assets/images/nauta_hogar/CUBADEBATE.jpg +0 -0
- data/app/assets/images/nauta_hogar/CUBAEDUCA.jpg +0 -0
- data/app/assets/images/nauta_hogar/CUBARTE.jpg +0 -0
- data/app/assets/images/nauta_hogar/CUBASI.jpg +0 -0
- data/app/assets/images/nauta_hogar/ECURED.jpg +0 -0
- data/app/assets/images/nauta_hogar/OFERTAS.jpg +0 -0
- data/app/assets/images/nauta_hogar/PAPELETA.jpg +0 -0
- data/app/assets/images/nauta_hogar/banner_hogar.png +0 -0
- data/app/assets/images/wibrfake/Breaker-Wallpaper1.jpg +0 -0
- data/app/assets/images/wibrfake/mac-list-parameter.png +0 -0
- data/app/assets/images/wibrfake/wibrfake-100x100.png +0 -0
- data/app/assets/images/wibrfake/wibrfake-32x32.png +0 -0
- data/app/assets/images/wibrfake/wibrfake-48x48.png +0 -0
- data/app/assets/images/wibrfake/wibrfake-apfake-on.png +0 -0
- data/app/assets/images/wibrfake/wibrfake-apfake-set-basic.png +0 -0
- data/app/assets/images/wibrfake/wibrfake-apfake-show.png +0 -0
- data/app/assets/images/wibrfake/wibrfake-help.png +0 -0
- data/app/assets/images/wibrfake/wibrfake-hostpot.png +0 -0
- data/app/assets/images/wibrfake/wibrfake-init.png +0 -0
- data/app/assets/images/wibrfake/wibrfake-init2.png +0 -0
- data/app/assets/images/wibrfake/wibrfake-login-basic.jpg +0 -0
- data/app/assets/images/wibrfake/wibrfake-mac-list.png +0 -0
- data/app/assets/images/wibrfake/wibrfake-mac-ramset-oui.png +0 -0
- data/app/assets/images/wibrfake/wibrfake-mac-ramset.png +0 -0
- data/app/assets/images/wibrfake/wibrfake-mac-set.png +0 -0
- data/app/assets/images/wibrfake/wibrfake-mac-show.png +0 -0
- data/app/assets/images/wibrfake/wibrfake-need-signin.jpg +0 -0
- data/app/assets/images/wibrfake/wibrfake-session-active.png +0 -0
- data/app/assets/images/wibrfake/wibrfake-session-init.png +0 -0
- data/app/assets/images/wibrfake/wibrfake-session-list.png +0 -0
- data/app/assets/images/wibrfake/wibrfake-session-new.png +0 -0
- data/app/assets/images/wibrfake/wibrfake-session-rename.png +0 -0
- data/app/assets/images/wibrfake/wibrfake-session-save.png +0 -0
- data/app/assets/images/wibrfake/wibrfake-web-server-apfake.png +0 -0
- data/app/assets/images/wibrfake/wibrfake-web-server-on.png +0 -0
- data/app/assets/images/wibrfake/wibrfake-web-server-show.png +0 -0
- data/app/assets/images/wibrfake/wibrfake-wkdump-loaded.png +0 -0
- data/app/assets/images/wibrfake/wibrfake-wkdump.png +0 -0
- data/app/assets/images/wibrfake/wibrfake.png +0 -0
- data/app/assets/stylesheets/application.css +15 -0
- data/app/assets/stylesheets/basic/page_basic.css +0 -0
- data/app/assets/stylesheets/facebook/page_facebook.css +93 -0
- data/app/assets/stylesheets/google/page_google.css +137 -0
- data/app/assets/stylesheets/instagram/page_instagram.css +94 -0
- data/app/assets/stylesheets/nauta_etecsa/page_nauta.css +325 -0
- data/app/assets/stylesheets/nauta_hogar/page_nauta.css +469 -0
- data/app/assets/stylesheets/wibrfake/page_wibrfake.css +1181 -0
- data/app/assets/stylesheets/wibrfake/page_wibrfake_about.css +486 -0
- data/app/channels/application_cable/channel.rb +4 -0
- data/app/channels/application_cable/connection.rb +4 -0
- data/app/controllers/application_controller.rb +15 -0
- data/app/controllers/concerns/.keep +0 -0
- data/app/controllers/sessions_controller.rb +111 -0
- data/app/helpers/application_helper.rb +2 -0
- data/app/helpers/sessions_helper.rb +2 -0
- data/app/javascript/application.js +3 -0
- data/app/javascript/bootstrap.bundle.min.js +7 -0
- data/app/javascript/controllers/application.js +9 -0
- data/app/javascript/controllers/hello_controller.js +7 -0
- data/app/javascript/controllers/index.js +4 -0
- data/app/javascript/google/page_google.js +50 -0
- data/app/javascript/incorrect3.js +29 -0
- data/app/javascript/page_wibrfake.js +50 -0
- data/app/javascript/page_wibrfake_about.js +147 -0
- data/app/jobs/application_job.rb +7 -0
- data/app/mailers/application_mailer.rb +4 -0
- data/app/models/application_record.rb +3 -0
- data/app/models/concerns/.keep +0 -0
- data/app/models/user.rb +6 -0
- data/app/views/layouts/application.html.erb +33 -0
- data/app/views/layouts/mailer.html.erb +13 -0
- data/app/views/layouts/mailer.text.erb +1 -0
- data/app/views/pwa/manifest.json.erb +22 -0
- data/app/views/pwa/service-worker.js +26 -0
- data/app/views/sessions/basic/basic.html.erb +21 -0
- data/app/views/sessions/facebook/facebook.html.erb +132 -0
- data/app/views/sessions/google/google.html.erb +72 -0
- data/app/views/sessions/index.html.erb +11 -0
- data/app/views/sessions/instagram/instagram.html.erb +69 -0
- data/app/views/sessions/nauta_etecsa/nauta_etecsa.html.erb +97 -0
- data/app/views/sessions/nauta_hogar/nauta_hogar.html.erb +135 -0
- data/app/views/sessions/wibrfake/about/about.html.erb +164 -0
- data/app/views/sessions/wibrfake/wibrfake.html.erb +417 -0
- data/bin/.names.rb.swp +0 -0
- data/bin/brakeman +7 -0
- data/bin/bundle +114 -0
- data/bin/docker-entrypoint +13 -0
- data/bin/google.wkdump +3 -0
- data/bin/importmap +4 -0
- data/bin/rails +4 -0
- data/bin/rake +4 -0
- data/bin/rubocop +8 -0
- data/bin/setup +37 -0
- data/bin/wibrfake +20 -0
- data/config/application.rb +26 -0
- data/config/boot.rb +4 -0
- data/config/cable.yml +10 -0
- data/config/credentials.yml.enc +1 -0
- data/config/database.yml +16 -0
- data/config/environment.rb +5 -0
- data/config/environments/development.rb +85 -0
- data/config/environments/production.rb +105 -0
- data/config/environments/test.rb +67 -0
- data/config/icons/application-x-wkdump.xml +13 -0
- data/config/icons/hicolor/16x16/mimetypes/application-x-wkdump.png +0 -0
- data/config/icons/hicolor/32x32/mimetypes/application-x-wkdump.png +0 -0
- data/config/icons/hicolor/48x48/mimetypes/application-x-wkdump.png +0 -0
- data/config/icons/hicolor/icon-theme.cache +0 -0
- data/config/icons/hicolor/index.theme +20 -0
- data/config/icons/wkdump.desktop +5 -0
- data/config/importmap.rb +7 -0
- data/config/initializers/assets.rb +12 -0
- data/config/initializers/content_security_policy.rb +25 -0
- data/config/initializers/devise.rb +313 -0
- data/config/initializers/filter_parameter_logging.rb +8 -0
- data/config/initializers/inflections.rb +16 -0
- data/config/initializers/permissions_policy.rb +13 -0
- data/config/locales/devise.en.yml +65 -0
- data/config/locales/en.yml +31 -0
- data/config/puma.rb +35 -0
- data/config/routes.rb +12 -0
- data/config/storage.yml +34 -0
- data/config.ru +6 -0
- data/db/development.sqlite3 +0 -0
- data/db/schema.rb +14 -0
- data/ext/wibrfake/extconf.rb +3 -0
- data/ext/wibrfake/wibrfake.h +0 -0
- data/images/ouilist.png +0 -0
- data/images/wibrfakehelp.png +0 -0
- data/images/wibrfakeinit.png +0 -0
- data/lib/assets/.keep +0 -0
- data/lib/tasks/.keep +0 -0
- data/lib/wibrfake/Config/ipaddr.rb +71 -0
- data/lib/wibrfake/Config/options.rb +98 -0
- data/lib/wibrfake/Config/security_wpa.rb +43 -0
- data/lib/wibrfake/DataBase/howuis.db +0 -0
- data/lib/wibrfake/DataBase/ouis.db +0 -0
- data/lib/wibrfake/DataBase/ouis.rb +24 -0
- data/lib/wibrfake/DataBase/rename.rb +15 -0
- data/lib/wibrfake/DataBase/show.rb +18 -0
- data/lib/wibrfake/Dnsmasq/dhcp.rb +149 -0
- data/lib/wibrfake/Dnsmasq/dhcp_prueba.rb +135 -0
- data/lib/wibrfake/Dnsmasq/dns.rb +34 -0
- data/lib/wibrfake/Dnsmasq/dns_prueba.rb +36 -0
- data/lib/wibrfake/Dnsmasq/dnsmasq.rb +33 -0
- data/lib/wibrfake/Listing/apfake.rb +28 -0
- data/lib/wibrfake/Listing/clients.rb +76 -0
- data/lib/wibrfake/Listing/ouis.rb +53 -0
- data/lib/wibrfake/Listing/process.rb +14 -0
- data/lib/wibrfake/Listing/sessions.rb +47 -0
- data/lib/wibrfake/Listing/web_server.rb +17 -0
- data/lib/wibrfake/Listing/wireless.rb +30 -0
- data/lib/wibrfake/Logs/credentials.log +59 -0
- data/lib/wibrfake/NetworkInterface/ip-routing.rb +99 -0
- data/lib/wibrfake/NetworkInterface/mac.rb +114 -0
- data/lib/wibrfake/NetworkInterface/monitor.rb +44 -0
- data/lib/wibrfake/NetworkInterface/ouis.db +0 -0
- data/lib/wibrfake/Process/id.rb +11 -0
- data/lib/wibrfake/Process/pids.log +5 -0
- data/lib/wibrfake/Process/pkill.rb +124 -0
- data/lib/wibrfake/Process/processes.rb +76 -0
- data/lib/wibrfake/Rails/login.rb +20 -0
- data/lib/wibrfake/Rails/routes.rb +76 -0
- data/lib/wibrfake/Rails/service.rb +58 -0
- data/lib/wibrfake/Rails/service_usage.rb +46 -0
- data/lib/wibrfake/Sessions/session.rb +188 -0
- data/lib/wibrfake/String/string.rb +109 -0
- data/lib/wibrfake/Tmp/config.yml +1 -0
- data/lib/wibrfake/config.rb +24 -0
- data/lib/wibrfake/help.rb +107 -0
- data/lib/wibrfake/optionpr.rb +68 -0
- data/lib/wibrfake/run.rb +9 -0
- data/lib/wibrfake/ty/apld.rb +110 -0
- data/lib/wibrfake/ty/prompt/answers_collector.rb +78 -0
- data/lib/wibrfake/ty/prompt/block_paginator.rb +59 -0
- data/lib/wibrfake/ty/prompt/choice.rb +147 -0
- data/lib/wibrfake/ty/prompt/choices.rb +129 -0
- data/lib/wibrfake/ty/prompt/confirm_question.rb +158 -0
- data/lib/wibrfake/ty/prompt/const.rb +17 -0
- data/lib/wibrfake/ty/prompt/converter_dsl.rb +21 -0
- data/lib/wibrfake/ty/prompt/converter_registry.rb +69 -0
- data/lib/wibrfake/ty/prompt/converters.rb +182 -0
- data/lib/wibrfake/ty/prompt/distance.rb +49 -0
- data/lib/wibrfake/ty/prompt/enum_list.rb +433 -0
- data/lib/wibrfake/ty/prompt/errors.rb +31 -0
- data/lib/wibrfake/ty/prompt/evaluator.rb +29 -0
- data/lib/wibrfake/ty/prompt/expander.rb +321 -0
- data/lib/wibrfake/ty/prompt/keypress.rb +98 -0
- data/lib/wibrfake/ty/prompt/list.rb +589 -0
- data/lib/wibrfake/ty/prompt/mask_question.rb +96 -0
- data/lib/wibrfake/ty/prompt/multi_list.rb +224 -0
- data/lib/wibrfake/ty/prompt/multiline.rb +72 -0
- data/lib/wibrfake/ty/prompt/paginator.rb +111 -0
- data/lib/wibrfake/ty/prompt/question/checks.rb +105 -0
- data/lib/wibrfake/ty/prompt/question/modifier.rb +96 -0
- data/lib/wibrfake/ty/prompt/question/validation.rb +72 -0
- data/lib/wibrfake/ty/prompt/question.rb +391 -0
- data/lib/wibrfake/ty/prompt/result.rb +42 -0
- data/lib/wibrfake/ty/prompt/selected_choices.rb +77 -0
- data/lib/wibrfake/ty/prompt/slider.rb +286 -0
- data/lib/wibrfake/ty/prompt/statement.rb +55 -0
- data/lib/wibrfake/ty/prompt/suggestion.rb +113 -0
- data/lib/wibrfake/ty/prompt/symbols.rb +89 -0
- data/lib/wibrfake/ty/prompt/test.rb +36 -0
- data/lib/wibrfake/ty/prompt/timer.rb +75 -0
- data/lib/wibrfake/ty/prompt/utils.rb +42 -0
- data/lib/wibrfake/ty/prompt/version.rb +7 -0
- data/lib/wibrfake/ty/prompt.rb +589 -0
- data/lib/wibrfake/version.rb +5 -0
- data/lib/wibrfake/wibrfake_cli.rb +683 -0
- data/log/.keep +0 -0
- data/pruebas/daemon1.pid +1 -0
- data/pruebas/daemon2.pid +1 -0
- data/pruebas/daemons.rb +44 -0
- data/public/404.html +67 -0
- data/public/406-unsupported-browser.html +66 -0
- data/public/422.html +67 -0
- data/public/500.html +66 -0
- data/public/icon.png +0 -0
- data/public/icon.svg +3 -0
- data/public/robots.txt +1 -0
- data/storage/.keep +0 -0
- data/test/application_system_test_case.rb +5 -0
- data/test/channels/application_cable/connection_test.rb +13 -0
- data/test/controllers/.keep +0 -0
- data/test/controllers/sessions_controller_test.rb +7 -0
- data/test/fixtures/files/.keep +0 -0
- data/test/fixtures/users.yml +11 -0
- data/test/helpers/.keep +0 -0
- data/test/integration/.keep +0 -0
- data/test/mailers/.keep +0 -0
- data/test/models/.keep +0 -0
- data/test/models/user_test.rb +7 -0
- data/test/system/.keep +0 -0
- data/test/test_helper.rb +15 -0
- data/tmp/.keep +0 -0
- data/tmp/pids/.keep +0 -0
- data/tmp/storage/.keep +0 -0
- data/vendor/.keep +0 -0
- data/vendor/javascript/.keep +0 -0
- data/wibrfake.gemspec +49 -0
- 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
|