asker-tool 2.1.5 → 2.2.1
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 +4 -4
- data/README.md +13 -17
- data/bin/asker +2 -1
- data/lib/asker/ai/ai.rb +10 -3
- data/lib/asker/ai/ai_calculate.rb +20 -6
- data/lib/asker/ai/code/base_code_ai.rb +104 -0
- data/lib/asker/{code/ai → ai/code}/code_ai_factory.rb +11 -1
- data/lib/asker/{code/ai → ai/code}/javascript_code_ai.rb +2 -5
- data/lib/asker/ai/code/problem_code_ai.rb +176 -0
- data/lib/asker/{code/ai → ai/code}/python_code_ai.rb +2 -5
- data/lib/asker/{code/ai → ai/code}/ruby_code_ai.rb +14 -7
- data/lib/asker/{code/ai → ai/code}/sql_code_ai.rb +2 -5
- data/lib/asker/ai/concept_ai.rb +13 -3
- data/lib/asker/ai/question.rb +28 -6
- data/lib/asker/ai/stages/base_stage.rb +45 -6
- data/lib/asker/ai/stages/stage_b.rb +100 -50
- data/lib/asker/ai/stages/stage_d.rb +75 -90
- data/lib/asker/ai/stages/stage_f.rb +64 -36
- data/lib/asker/ai/stages/stage_i.rb +79 -92
- data/lib/asker/ai/stages/stage_s.rb +41 -36
- data/lib/asker/ai/stages/stage_t.rb +149 -108
- data/lib/asker/application.rb +19 -11
- data/lib/asker/cli.rb +31 -44
- data/lib/asker/data/code.rb +62 -0
- data/lib/asker/data/column.rb +31 -21
- data/lib/asker/data/concept.rb +109 -65
- data/lib/asker/data/data_field.rb +14 -0
- data/lib/asker/data/project_data.rb +63 -0
- data/lib/asker/data/row.rb +75 -52
- data/lib/asker/data/table.rb +91 -42
- data/lib/asker/data/template.rb +3 -1
- data/lib/asker/data/world.rb +51 -35
- data/lib/asker/displayer/code_displayer.rb +7 -0
- data/lib/asker/displayer/concept_ai_displayer.erb +10 -0
- data/lib/asker/displayer/concept_ai_displayer.rb +74 -53
- data/lib/asker/displayer/concept_displayer.rb +16 -9
- data/lib/asker/displayer/stats_displayer.rb +12 -3
- data/lib/asker/exporter/concept_ai_gift_exporter.rb +19 -11
- data/lib/asker/exporter/concept_ai_moodle_exporter.rb +44 -0
- data/lib/asker/exporter/concept_ai_yaml_exporter.rb +13 -6
- data/lib/asker/exporter/concept_doc_exporter.rb +14 -1
- data/lib/asker/exporter/data_gift_exporter.rb +29 -0
- data/lib/asker/exporter/output_file_exporter.rb +9 -6
- data/lib/asker/files/{config.ini → asker.ini} +48 -1
- data/lib/asker/files/example-concept.haml +0 -1
- data/lib/asker/files/language/du/connectors.yaml +81 -0
- data/lib/asker/{lang/locales/fr → files/language/du}/mistakes.yaml +1 -1
- data/lib/asker/files/language/du/templates.yaml +29 -0
- data/lib/asker/{lang/locales → files/language}/en/connectors.yaml +0 -0
- data/lib/asker/{lang/locales → files/language}/en/mistakes.yaml +0 -0
- data/lib/asker/files/language/en/templates.yaml +29 -0
- data/lib/asker/{lang/locales → files/language}/es/connectors.yaml +0 -0
- data/lib/asker/files/language/es/mistakes.yaml +84 -0
- data/lib/asker/files/language/es/templates.yaml +29 -0
- data/lib/asker/files/language/fr/connectors.yaml +76 -0
- data/lib/asker/{lang/locales/es → files/language/fr}/mistakes.yaml +0 -0
- data/lib/asker/files/language/fr/templates.yaml +29 -0
- data/lib/asker/{lang/locales → files/language}/javascript/connectors.yaml +0 -0
- data/lib/asker/{lang/locales → files/language}/javascript/mistakes.yaml +0 -0
- data/lib/asker/{lang/locales → files/language}/javascript/templates.yaml +0 -0
- data/lib/asker/{lang/locales → files/language}/math/connectors.yaml +0 -0
- data/lib/asker/{lang/locales → files/language}/math/mistakes.yaml +0 -0
- data/lib/asker/{lang/locales → files/language}/math/templates.yaml +0 -0
- data/lib/asker/{lang/locales → files/language}/python/connectors.yaml +0 -0
- data/lib/asker/{lang/locales → files/language}/python/mistakes.yaml +0 -0
- data/lib/asker/{lang/locales → files/language}/python/templates.yaml +0 -0
- data/lib/asker/{lang/locales → files/language}/ruby/connectors.yaml +0 -0
- data/lib/asker/{lang/locales → files/language}/ruby/mistakes.yaml +0 -0
- data/lib/asker/{lang/locales → files/language}/ruby/templates.yaml +0 -0
- data/lib/asker/{lang/locales → files/language}/sql/connectors.yaml +0 -0
- data/lib/asker/{lang/locales → files/language}/sql/mistakes.yaml +0 -0
- data/lib/asker/{lang/locales → files/language}/sql/templates.yaml +0 -0
- data/lib/asker/formatter/concept_doc_formatter.rb +0 -4
- data/lib/asker/formatter/concept_string_formatter.rb +7 -4
- data/lib/asker/formatter/moodle/matching.erb +38 -0
- data/lib/asker/formatter/moodle/multichoice.erb +49 -0
- data/lib/asker/formatter/moodle/shortanswer.erb +30 -0
- data/lib/asker/formatter/moodle/truefalse.erb +47 -0
- data/lib/asker/formatter/question_gift_formatter.rb +30 -20
- data/lib/asker/formatter/question_moodle_formatter.rb +27 -0
- data/lib/asker/{checker.rb → input_checker.rb} +126 -49
- data/lib/asker/lang/lang.rb +17 -10
- data/lib/asker/lang/lang_factory.rb +32 -5
- data/lib/asker/lang/text_actions.rb +87 -69
- data/lib/asker/loader/code_loader.rb +4 -4
- data/lib/asker/loader/content_loader.rb +21 -19
- data/lib/asker/loader/directory_loader.rb +1 -8
- data/lib/asker/loader/embedded_file.rb +42 -0
- data/lib/asker/loader/file_loader.rb +3 -14
- data/lib/asker/loader/haml_loader.rb +15 -0
- data/lib/asker/loader/image_url_loader.rb +8 -12
- data/lib/asker/loader/input_loader.rb +13 -15
- data/lib/asker/loader/project_loader.rb +25 -15
- data/lib/asker/logger.rb +36 -9
- data/lib/asker/skeleton.rb +23 -13
- data/lib/asker.rb +76 -42
- metadata +53 -54
- data/lib/asker/code/ai/base_code_ai.rb +0 -48
- data/lib/asker/code/code.rb +0 -53
- data/lib/asker/lang/locales/du/templates.yaml +0 -50
- data/lib/asker/lang/locales/en/templates.yaml +0 -29
- data/lib/asker/lang/locales/es/templates.yaml +0 -29
- data/lib/asker/lang/locales/fr/connectors.yaml +0 -92
- data/lib/asker/lang/locales/fr/templates.yaml +0 -29
- data/lib/asker/project.rb +0 -172
|
@@ -1,170 +1,211 @@
|
|
|
1
|
-
#
|
|
1
|
+
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require 'set'
|
|
4
4
|
require_relative 'base_stage'
|
|
5
5
|
require_relative '../question'
|
|
6
6
|
|
|
7
|
+
##
|
|
8
|
+
# StageT create questions based con Table data
|
|
9
|
+
# range t1-t9
|
|
10
|
+
# rubocop:disable Metrics/ClassLength
|
|
7
11
|
class StageT < BaseStage
|
|
8
|
-
#
|
|
9
|
-
|
|
10
|
-
|
|
12
|
+
# process_tableXfields
|
|
13
|
+
# rubocop:disable Metrics/MethodLength
|
|
14
|
+
# rubocop:disable Metrics/AbcSize
|
|
15
|
+
def run(table, row, list)
|
|
11
16
|
questions = []
|
|
12
|
-
return questions unless type==
|
|
13
|
-
|
|
14
|
-
if
|
|
15
|
-
questions
|
|
16
|
-
elsif
|
|
17
|
-
questions
|
|
18
|
-
questions
|
|
19
|
-
elsif
|
|
20
|
-
questions
|
|
21
|
-
questions
|
|
22
|
-
questions
|
|
17
|
+
return questions unless concept.type == 'text'
|
|
18
|
+
|
|
19
|
+
if table.fields.count == 2
|
|
20
|
+
questions += process_table2fields(table, row, list, 0, 1)
|
|
21
|
+
elsif table.fields.count == 3
|
|
22
|
+
questions += process_table2fields(table, row, list, 0, 1)
|
|
23
|
+
questions += process_table2fields(table, row, list, 0, 2)
|
|
24
|
+
elsif table.fields.count == 4
|
|
25
|
+
questions += process_table2fields(table, row, list, 0, 1)
|
|
26
|
+
questions += process_table2fields(table, row, list, 0, 2)
|
|
27
|
+
questions += process_table2fields(table, row, list, 0, 3)
|
|
23
28
|
end
|
|
24
29
|
|
|
25
|
-
|
|
30
|
+
questions
|
|
26
31
|
end
|
|
32
|
+
# rubocop:enable Metrics/MethodLength
|
|
33
|
+
# rubocop:enable Metrics/AbcSize
|
|
34
|
+
|
|
35
|
+
private
|
|
27
36
|
|
|
28
|
-
|
|
29
|
-
|
|
37
|
+
# rubocop:disable Metrics/MethodLength
|
|
38
|
+
# rubocop:disable Metrics/AbcSize
|
|
39
|
+
# rubocop:disable Metrics/CyclomaticComplexity
|
|
40
|
+
# rubocop:disable Metrics/PerceivedComplexity
|
|
41
|
+
def process_table2fields(table, row, list, col1, col2)
|
|
30
42
|
questions = []
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
q
|
|
41
|
-
q.
|
|
42
|
-
q.
|
|
43
|
+
lang = concept.lang
|
|
44
|
+
# create questions
|
|
45
|
+
|
|
46
|
+
# Question choice: Using the column #0
|
|
47
|
+
s = Set.new [row[:data][col1], lang.text_for(:none)]
|
|
48
|
+
list.each { |i| s.add(i[:data][col1]) }
|
|
49
|
+
a = s.to_a
|
|
50
|
+
|
|
51
|
+
if s.count > 3
|
|
52
|
+
q = Question.new
|
|
53
|
+
q.name = "#{name}-#{num}-t1table-#{table.name}"
|
|
54
|
+
q.text = random_image_for(name) \
|
|
55
|
+
+ lang.text_for(:t1table, name, table.fields[col1].capitalize, \
|
|
56
|
+
table.fields[col2].capitalize, row[:data][col2])
|
|
57
|
+
q.good = row[:data][col1]
|
|
43
58
|
q.bads << lang.text_for(:none)
|
|
44
59
|
q.bads << a[2]
|
|
45
60
|
q.bads << a[3]
|
|
46
61
|
questions << q
|
|
47
62
|
end
|
|
48
63
|
|
|
49
|
-
s=Set.new [
|
|
50
|
-
|
|
51
|
-
a=s.to_a
|
|
52
|
-
|
|
53
|
-
if s.count>4
|
|
54
|
-
q=Question.new
|
|
55
|
-
q.name="#{name}-#{num
|
|
56
|
-
q.text=
|
|
57
|
-
|
|
64
|
+
s = Set.new [row[:data][col1], lang.text_for(:none)]
|
|
65
|
+
list.each { |i| s.add(i[:data][col1]) }
|
|
66
|
+
a = s.to_a
|
|
67
|
+
|
|
68
|
+
if s.count > 4
|
|
69
|
+
q = Question.new
|
|
70
|
+
q.name = "#{name}-#{num}-t2table-#{table.name}"
|
|
71
|
+
q.text = random_image_for(name) \
|
|
72
|
+
+ lang.text_for(:t2table, name, table.fields[col1].capitalize, \
|
|
73
|
+
table.fields[col2].capitalize, row[:data][col2])
|
|
74
|
+
q.good = lang.text_for(:none)
|
|
58
75
|
q.bads << a[2]
|
|
59
76
|
q.bads << a[3]
|
|
60
77
|
q.bads << a[4]
|
|
61
78
|
questions << q
|
|
62
79
|
end
|
|
63
80
|
|
|
64
|
-
# Using the column #1
|
|
65
|
-
s=Set.new [
|
|
66
|
-
|
|
67
|
-
a=s.to_a
|
|
68
|
-
|
|
69
|
-
if s.count>3
|
|
70
|
-
q=Question.new
|
|
71
|
-
q.name="#{name}-#{num
|
|
72
|
-
q.text=
|
|
73
|
-
|
|
81
|
+
# Question choice: Using the column #1
|
|
82
|
+
s = Set.new [row[:data][col2], lang.text_for(:none)]
|
|
83
|
+
list.each { |i| s.add(i[:data][col2]) }
|
|
84
|
+
a = s.to_a
|
|
85
|
+
|
|
86
|
+
if s.count > 3
|
|
87
|
+
q = Question.new
|
|
88
|
+
q.name = "#{name}-#{num}-t3table-#{table.name}"
|
|
89
|
+
q.text = random_image_for(name) \
|
|
90
|
+
+ lang.text_for(:t3table, name, table.fields[col1].capitalize, \
|
|
91
|
+
row[:data][col1], table.fields[col2].capitalize)
|
|
92
|
+
q.good = a[0]
|
|
74
93
|
q.bads << lang.text_for(:none)
|
|
75
94
|
q.bads << a[2]
|
|
76
95
|
q.bads << a[3]
|
|
77
96
|
questions << q
|
|
78
97
|
end
|
|
79
98
|
|
|
80
|
-
s=Set.new [
|
|
81
|
-
|
|
82
|
-
a=s.to_a
|
|
83
|
-
|
|
84
|
-
if s.count>4
|
|
85
|
-
q=Question.new
|
|
86
|
-
q.name="#{name}-#{num
|
|
87
|
-
q.text=
|
|
88
|
-
|
|
99
|
+
s = Set.new [row[:data][col2], lang.text_for(:none)]
|
|
100
|
+
list.each { |i| s.add(i[:data][col2]) }
|
|
101
|
+
a = s.to_a
|
|
102
|
+
|
|
103
|
+
if s.count > 4
|
|
104
|
+
q = Question.new
|
|
105
|
+
q.name = "#{name}-#{num}-t4table-#{table.name}"
|
|
106
|
+
q.text = random_image_for(name) \
|
|
107
|
+
+ lang.text_for(:t4table, name, table.fields[col1].capitalize, \
|
|
108
|
+
row[:data][col1], table.fields[col2].capitalize)
|
|
109
|
+
q.good = lang.text_for(:none)
|
|
89
110
|
q.bads << a[2]
|
|
90
111
|
q.bads << a[3]
|
|
91
112
|
q.bads << a[4]
|
|
92
113
|
questions << q
|
|
93
114
|
end
|
|
94
115
|
|
|
95
|
-
# Boolean
|
|
96
|
-
q=Question.new
|
|
116
|
+
# Question Boolean: TRUE
|
|
117
|
+
q = Question.new
|
|
97
118
|
q.set_boolean
|
|
98
|
-
q.name="#{name}-#{num
|
|
99
|
-
q.text=
|
|
100
|
-
|
|
119
|
+
q.name = "#{name}-#{num}t5table-#{table.name}"
|
|
120
|
+
q.text = random_image_for(name) \
|
|
121
|
+
+ lang.text_for(:t5table, name, table.fields[col1].capitalize, \
|
|
122
|
+
row[:data][col1], table.fields[col2].capitalize, row[:data][col2])
|
|
123
|
+
q.good = 'TRUE'
|
|
101
124
|
questions << q
|
|
102
125
|
|
|
103
|
-
# Boolean
|
|
104
|
-
s=Set.new [
|
|
105
|
-
|
|
106
|
-
a=s.to_a
|
|
126
|
+
# Question Boolean: FALSE
|
|
127
|
+
s = Set.new [row[:data][col2]]
|
|
128
|
+
list.each { |i| s.add(i[:data][col2]) }
|
|
129
|
+
a = s.to_a
|
|
107
130
|
|
|
108
|
-
if s.count>1
|
|
109
|
-
q=Question.new
|
|
131
|
+
if s.count > 1
|
|
132
|
+
q = Question.new
|
|
110
133
|
q.set_boolean
|
|
111
|
-
q.name="#{name}-#{num
|
|
112
|
-
q.text=
|
|
113
|
-
|
|
134
|
+
q.name = "#{name}-#{num}-t6table-#{table.name}"
|
|
135
|
+
q.text = random_image_for(name) \
|
|
136
|
+
+ lang.text_for(:t6table, name, table.fields[col1].capitalize, \
|
|
137
|
+
row[:data][col1], table.fields[col2].capitalize, a[1])
|
|
138
|
+
q.good = 'FALSE'
|
|
114
139
|
questions << q
|
|
115
140
|
end
|
|
116
141
|
|
|
117
|
-
s=Set.new [
|
|
118
|
-
|
|
119
|
-
a=s.to_a
|
|
142
|
+
s = Set.new [row[:data][col1]]
|
|
143
|
+
list.each { |i| s.add(i[:data][col1]) }
|
|
144
|
+
a = s.to_a
|
|
120
145
|
|
|
121
|
-
if s.count>1
|
|
122
|
-
q=Question.new
|
|
146
|
+
if s.count > 1
|
|
147
|
+
q = Question.new
|
|
123
148
|
q.set_boolean
|
|
124
|
-
q.name="#{name}-#{num
|
|
125
|
-
q.text=
|
|
126
|
-
|
|
149
|
+
q.name = "#{name}-#{num}t7table-#{table.name}"
|
|
150
|
+
q.text = random_image_for(name) \
|
|
151
|
+
+ lang.text_for(:t7table, name, table.fields[col1].capitalize, \
|
|
152
|
+
a[1], table.fields[col2].capitalize, row[:data][col2])
|
|
153
|
+
q.good = 'FALSE'
|
|
127
154
|
questions << q
|
|
128
155
|
end
|
|
129
156
|
|
|
130
|
-
# Short
|
|
131
|
-
if lang.count_words(
|
|
132
|
-
q=Question.new
|
|
157
|
+
# Question Short: column #0, 1 word
|
|
158
|
+
if lang.count_words(row[:data][col1]) == 1
|
|
159
|
+
q = Question.new
|
|
133
160
|
q.set_short
|
|
134
|
-
q.name="#{name}-#{num
|
|
135
|
-
q.text=
|
|
136
|
-
|
|
137
|
-
|
|
161
|
+
q.name = "#{name}-#{num}t8table-#{table.name}"
|
|
162
|
+
q.text = random_image_for(name) \
|
|
163
|
+
+ lang.text_for(:t8table, name, table.fields[col2].capitalize, \
|
|
164
|
+
row[:data][col2], table.fields[col1].capitalize)
|
|
165
|
+
q.shorts << row[:data][col1]
|
|
166
|
+
q.shorts << row[:data][col1].gsub('-', ' ').gsub('_', ' ')
|
|
138
167
|
questions << q
|
|
139
|
-
elsif lang.count_words(
|
|
140
|
-
q=Question.new
|
|
168
|
+
elsif lang.count_words(row[:data][col1]) == 2
|
|
169
|
+
q = Question.new
|
|
141
170
|
q.set_short
|
|
142
|
-
q.name="#{name}-#{num
|
|
143
|
-
q.text=
|
|
144
|
-
|
|
145
|
-
|
|
171
|
+
q.name = "#{name}-#{num}t9table-#{table.name}"
|
|
172
|
+
q.text = random_image_for(name) \
|
|
173
|
+
+ lang.text_for(:t9table, name, table.fields[col2].capitalize, \
|
|
174
|
+
row[:data][col2], table.fields[col1].capitalize, \
|
|
175
|
+
"[#{lang.hide_text(row[:data][col1])}]", lang.count_words(row[:data][col1]))
|
|
176
|
+
q.shorts << row[:data][col1]
|
|
177
|
+
q.shorts << row[:data][col1].gsub('-', ' ').gsub('_', ' ')
|
|
146
178
|
questions << q
|
|
147
179
|
end
|
|
148
180
|
|
|
149
|
-
# Short
|
|
150
|
-
if lang.count_words(
|
|
151
|
-
q=Question.new
|
|
181
|
+
# Question Short: column #1, 1 word
|
|
182
|
+
if lang.count_words(row[:data][col2]) == 1
|
|
183
|
+
q = Question.new
|
|
152
184
|
q.set_short
|
|
153
|
-
q.name="#{name}-#{num
|
|
154
|
-
q.text=
|
|
155
|
-
|
|
156
|
-
|
|
185
|
+
q.name = "#{name}-#{num}t8table-#{table.name}"
|
|
186
|
+
q.text = random_image_for(name) \
|
|
187
|
+
+ lang.text_for(:t8table, name, table.fields[col1].capitalize, \
|
|
188
|
+
row[:data][col1], table.fields[col2].capitalize)
|
|
189
|
+
q.shorts << row[:data][col2]
|
|
190
|
+
q.shorts << row[:data][col2].gsub('-', ' ').gsub('_', ' ')
|
|
157
191
|
questions << q
|
|
158
|
-
elsif lang.count_words(
|
|
159
|
-
q=Question.new
|
|
192
|
+
elsif lang.count_words(row[:data][col2]) == 2
|
|
193
|
+
q = Question.new
|
|
160
194
|
q.set_short
|
|
161
|
-
q.name="#{name}-#{num
|
|
162
|
-
q.text=
|
|
163
|
-
|
|
164
|
-
|
|
195
|
+
q.name = "#{name}-#{num}t9table-#{table.name}"
|
|
196
|
+
q.text = random_image_for(name) \
|
|
197
|
+
+ lang.text_for(:t9table, name, table.fields[col1].capitalize, \
|
|
198
|
+
row[:data][col1], table.fields[col2].capitalize, \
|
|
199
|
+
"[#{lang.hide_text(row[:data][col2])}]", lang.count_words(row[:data][col2]))
|
|
200
|
+
q.shorts << row[:data][col2]
|
|
201
|
+
q.shorts << row[:data][col2].gsub('-', ' ').gsub('_', ' ')
|
|
165
202
|
questions << q
|
|
166
203
|
end
|
|
167
|
-
|
|
204
|
+
questions
|
|
168
205
|
end
|
|
169
|
-
|
|
206
|
+
# rubocop:enable Metrics/MethodLength
|
|
207
|
+
# rubocop:enable Metrics/AbcSize
|
|
208
|
+
# rubocop:enable Metrics/CyclomaticComplexity
|
|
209
|
+
# rubocop:enable Metrics/PerceivedComplexity
|
|
170
210
|
end
|
|
211
|
+
# rubocop:enable Metrics/ClassLength
|
data/lib/asker/application.rb
CHANGED
|
@@ -2,29 +2,37 @@
|
|
|
2
2
|
|
|
3
3
|
require 'singleton'
|
|
4
4
|
require 'inifile'
|
|
5
|
+
require 'rainbow'
|
|
5
6
|
|
|
6
7
|
# Global parameters
|
|
7
8
|
class Application
|
|
8
9
|
include Singleton
|
|
9
10
|
|
|
10
|
-
VERSION = '2.1
|
|
11
|
-
NAME = 'asker'
|
|
12
|
-
GEM = 'asker-tool'
|
|
11
|
+
VERSION = '2.2.1'
|
|
12
|
+
NAME = 'asker'
|
|
13
|
+
GEM = 'asker-tool'
|
|
14
|
+
CONFIGFILE = 'asker.ini'
|
|
13
15
|
attr_reader :config
|
|
14
16
|
|
|
15
|
-
##
|
|
16
|
-
# Initialize Application singleton
|
|
17
17
|
def initialize
|
|
18
18
|
reset
|
|
19
19
|
end
|
|
20
20
|
|
|
21
|
-
##
|
|
22
|
-
# Initialize config values from external "config.ini" file.
|
|
23
21
|
def reset
|
|
24
|
-
filename = File.join(Dir.pwd,
|
|
25
|
-
unless File.exist? filename
|
|
26
|
-
|
|
22
|
+
filename = File.join(Dir.pwd, CONFIGFILE)
|
|
23
|
+
filename = File.join(File.dirname(__FILE__), 'files', CONFIGFILE) unless File.exist? filename
|
|
24
|
+
|
|
25
|
+
begin
|
|
26
|
+
@config = IniFile.load(filename)
|
|
27
|
+
rescue StandardError => e
|
|
28
|
+
puts e.display
|
|
29
|
+
puts Rainbow('[ERROR] Revise configuration file:').red.bright
|
|
30
|
+
puts Rainbow(" #{filename}").red.bright
|
|
31
|
+
exit 1
|
|
27
32
|
end
|
|
28
|
-
|
|
33
|
+
stages = @config['questions']['stages'].split(',')
|
|
34
|
+
@config['questions']['stages'] = stages.map(&:to_sym)
|
|
35
|
+
Rainbow.enabled = false
|
|
36
|
+
Rainbow.enabled = true if @config['global']['color'].downcase == 'yes'
|
|
29
37
|
end
|
|
30
38
|
end
|
data/lib/asker/cli.rb
CHANGED
|
@@ -8,66 +8,38 @@ require_relative '../asker'
|
|
|
8
8
|
##
|
|
9
9
|
# Command Line User Interface
|
|
10
10
|
class CLI < Thor
|
|
11
|
-
map ['
|
|
11
|
+
map ['--help'] => 'help'
|
|
12
12
|
|
|
13
|
-
map ['
|
|
13
|
+
map ['--version'] => 'version'
|
|
14
14
|
desc 'version', 'Show the program version'
|
|
15
|
-
##
|
|
16
|
-
# Show current version
|
|
17
15
|
def version
|
|
18
|
-
|
|
19
|
-
puts " (version #{Rainbow(Application::VERSION).green})"
|
|
16
|
+
puts "#{Application::NAME} version #{Application::VERSION}"
|
|
20
17
|
end
|
|
21
18
|
|
|
22
19
|
map ['f', '-f', '--file'] => 'file'
|
|
23
|
-
desc 'file
|
|
24
|
-
option :color, type: :boolean
|
|
20
|
+
desc '[file] FILEPATH', 'Build output files, from HAML/XML input file.'
|
|
25
21
|
long_desc <<-LONGDESC
|
|
26
|
-
Create output files, from input file (HAML/XML format).
|
|
27
22
|
|
|
28
23
|
Build questions about contents defined into input file specified.
|
|
29
24
|
|
|
30
|
-
|
|
25
|
+
Create output files, from input file (HAML/XML format).
|
|
31
26
|
|
|
32
|
-
|
|
27
|
+
Examples:
|
|
33
28
|
|
|
34
|
-
(
|
|
29
|
+
(1) #{Rainbow('asker input/foo/foo.haml').aqua}, Build questions from HAML file.
|
|
35
30
|
|
|
36
|
-
(
|
|
31
|
+
(2) #{Rainbow('asker input/foo/foo.xml').aqua}, Build questions from XML file.
|
|
37
32
|
|
|
38
|
-
(
|
|
33
|
+
(3) #{Rainbow('asker projects/foo/foo.yaml').aqua}, Build questions from YAML project file.
|
|
39
34
|
|
|
40
35
|
LONGDESC
|
|
41
|
-
##
|
|
42
|
-
# Create questions from input file
|
|
43
|
-
# @param filename (String) Path to input file
|
|
44
36
|
def file(filename)
|
|
45
|
-
# Enable/disable color output
|
|
46
|
-
Rainbow.enabled = false if options['color'] == false
|
|
47
37
|
# Asker start processing input file
|
|
48
38
|
Asker.start(filename)
|
|
49
39
|
end
|
|
50
40
|
|
|
51
|
-
map ['
|
|
52
|
-
desc '
|
|
53
|
-
##
|
|
54
|
-
# Create default INI config file
|
|
55
|
-
def init
|
|
56
|
-
src = File.join(File.dirname(__FILE__), 'files', 'config.ini')
|
|
57
|
-
dst = File.join(Dir.pwd, 'config.ini')
|
|
58
|
-
if File.exist? dst
|
|
59
|
-
puts "[WARN] Exists file! => #{Rainbow(File.basename(dst)).yellow.bright}"
|
|
60
|
-
else
|
|
61
|
-
FileUtils.cp(src, dst)
|
|
62
|
-
puts "[ OK ] Create file => #{Rainbow(File.basename(dst)).green}"
|
|
63
|
-
end
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
map ['c', '-c', '--check'] => 'check'
|
|
67
|
-
desc 'check', 'Check input HAML file syntax'
|
|
68
|
-
##
|
|
69
|
-
# Check input file syntax
|
|
70
|
-
# @param filename (String) Path to input file
|
|
41
|
+
map ['--check'] => 'check'
|
|
42
|
+
desc 'check FILEPATH', 'Check input HAML file syntax'
|
|
71
43
|
def check(filename)
|
|
72
44
|
# Enable/disable color output
|
|
73
45
|
Rainbow.enabled = false if options['color'] == false
|
|
@@ -75,14 +47,19 @@ class CLI < Thor
|
|
|
75
47
|
Asker.check(filename)
|
|
76
48
|
end
|
|
77
49
|
|
|
78
|
-
map ['
|
|
79
|
-
desc '
|
|
50
|
+
map ['--init'] => 'init'
|
|
51
|
+
desc 'init', 'Create default INI config file'
|
|
52
|
+
def init
|
|
53
|
+
Asker.init
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
map ['new','--new'] => 'new_input'
|
|
57
|
+
desc 'new DIRPATH', 'Create Asker demo input files'
|
|
80
58
|
##
|
|
81
59
|
# Create Asker demo input files
|
|
82
60
|
# @param dirname (String) Path to folder
|
|
83
|
-
def
|
|
84
|
-
|
|
85
|
-
Asker.create_skeleton(dirname)
|
|
61
|
+
def new_input(dirname)
|
|
62
|
+
Asker.new_input(dirname)
|
|
86
63
|
end
|
|
87
64
|
|
|
88
65
|
##
|
|
@@ -92,4 +69,14 @@ class CLI < Thor
|
|
|
92
69
|
def method_missing(method, *_args, &_block)
|
|
93
70
|
file(method.to_s)
|
|
94
71
|
end
|
|
72
|
+
|
|
73
|
+
def respond_to_missing?(_method_name)
|
|
74
|
+
true
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
##
|
|
78
|
+
# Thor stop and show messages on screen on failure
|
|
79
|
+
def self.exit_on_failure?
|
|
80
|
+
true
|
|
81
|
+
end
|
|
95
82
|
end
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative '../ai/code/code_ai_factory'
|
|
4
|
+
|
|
5
|
+
class Code
|
|
6
|
+
attr_reader :dirname, :filename, :type
|
|
7
|
+
attr_accessor :process, :features
|
|
8
|
+
attr_reader :lines, :questions
|
|
9
|
+
|
|
10
|
+
def initialize(dirname, filename, type)
|
|
11
|
+
@dirname = dirname
|
|
12
|
+
@filename = filename
|
|
13
|
+
@type = type
|
|
14
|
+
@filepath = File.join(@dirname, @filename)
|
|
15
|
+
@process = false
|
|
16
|
+
@features = []
|
|
17
|
+
@lines = load(@filepath)
|
|
18
|
+
@questions = []
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def process?
|
|
22
|
+
@process
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def lines_to_s(lines)
|
|
26
|
+
out = ''
|
|
27
|
+
lines.each_with_index do |line, index|
|
|
28
|
+
out << format("%2d| #{line}\n", (index + 1))
|
|
29
|
+
end
|
|
30
|
+
out
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
private
|
|
34
|
+
|
|
35
|
+
def load(filepath)
|
|
36
|
+
return if filepath.nil?
|
|
37
|
+
|
|
38
|
+
unless File.exist? filepath
|
|
39
|
+
puts Rainbow("[ERROR] Unkown file #{filepath}").red.bright
|
|
40
|
+
return
|
|
41
|
+
end
|
|
42
|
+
content = File.read(filepath)
|
|
43
|
+
encode_and_split(content)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def encode_and_split(text, encoding = :default)
|
|
47
|
+
# Convert text to UTF-8 deleting unknown chars
|
|
48
|
+
text ||= '' # Ensure text is not nil
|
|
49
|
+
flag = [:default, 'UTF-8'].include? encoding
|
|
50
|
+
return text.encode('UTF-8', invalid: :replace).split("\n") if flag
|
|
51
|
+
|
|
52
|
+
# Convert text from input ENCODING to UTF-8
|
|
53
|
+
ec = Encoding::Converter.new(encoding.to_s, 'UTF-8')
|
|
54
|
+
begin
|
|
55
|
+
text = ec.convert(text)
|
|
56
|
+
rescue StandardError => e
|
|
57
|
+
puts "[ERROR] Encoding: #{e}"
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
text.split("\n")
|
|
61
|
+
end
|
|
62
|
+
end
|
data/lib/asker/data/column.rb
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
-
# encoding: utf-8
|
|
3
2
|
|
|
4
3
|
# Contain data information for every column
|
|
5
4
|
# Params:
|
|
@@ -9,10 +8,15 @@
|
|
|
9
8
|
class Column
|
|
10
9
|
attr_reader :row, :index, :id, :raw, :lang, :type, :simple
|
|
11
10
|
|
|
11
|
+
##
|
|
12
|
+
# initialize Column
|
|
13
|
+
# @param row (Row)
|
|
14
|
+
# @param index (Integer)
|
|
15
|
+
# @param xml_data (XMLdata)
|
|
12
16
|
def initialize(row, index, xml_data)
|
|
13
17
|
@row = row
|
|
14
18
|
@index = index
|
|
15
|
-
@id = @row.id
|
|
19
|
+
@id = "#{@row.id}.#{@index}"
|
|
16
20
|
@raw = ''
|
|
17
21
|
@lang = @row.langs[@index]
|
|
18
22
|
@type = @row.types[@index]
|
|
@@ -28,35 +32,41 @@ class Column
|
|
|
28
32
|
return "<img src=\"#{raw}\" alt\=\"image\">"
|
|
29
33
|
when 'textfile_path'
|
|
30
34
|
return "<pre>#{raw}</pre>"
|
|
31
|
-
else
|
|
32
|
-
return "ERROR type #{@type}"
|
|
33
35
|
end
|
|
36
|
+
"ERROR type #{@type}"
|
|
34
37
|
end
|
|
35
38
|
|
|
36
39
|
private
|
|
37
40
|
|
|
38
41
|
def read_data_from_xml(xml_data)
|
|
39
|
-
raise '[ERROR] Column
|
|
42
|
+
raise '[ERROR] Column with elements!' if xml_data.elements.count.positive?
|
|
40
43
|
|
|
41
44
|
@raw = xml_data.text.strip.to_s
|
|
42
45
|
|
|
43
46
|
# read attributes from XML input data
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
@lang = LangFactory.instance.get(code)
|
|
48
|
-
@simple[:lang] = false
|
|
49
|
-
@row.simple_off(:lang)
|
|
50
|
-
end
|
|
51
|
-
end
|
|
47
|
+
read_lang_from_xml(xml_data)
|
|
48
|
+
read_type_from_xml(xml_data)
|
|
49
|
+
end
|
|
52
50
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
51
|
+
def read_lang_from_xml(xml_data)
|
|
52
|
+
return unless xml_data.attributes['lang']
|
|
53
|
+
|
|
54
|
+
code = xml_data.attributes['lang'].strip
|
|
55
|
+
return if code == @lang.code
|
|
56
|
+
|
|
57
|
+
@lang = LangFactory.instance.get(code)
|
|
58
|
+
@simple[:lang] = false
|
|
59
|
+
@row.simple_off(:lang)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def read_type_from_xml(xml_data)
|
|
63
|
+
return unless xml_data.attributes['type']
|
|
64
|
+
|
|
65
|
+
type = xml_data.attributes['type'].strip
|
|
66
|
+
return if type == @type.to_s
|
|
67
|
+
|
|
68
|
+
@type = type
|
|
69
|
+
@simple[:type] = false
|
|
70
|
+
@row.simple_off(:type)
|
|
61
71
|
end
|
|
62
72
|
end
|