asker-tool 2.1.5 → 2.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (105) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +13 -17
  3. data/bin/asker +2 -1
  4. data/lib/asker/ai/ai.rb +10 -3
  5. data/lib/asker/ai/ai_calculate.rb +20 -6
  6. data/lib/asker/ai/code/base_code_ai.rb +104 -0
  7. data/lib/asker/{code/ai → ai/code}/code_ai_factory.rb +11 -1
  8. data/lib/asker/{code/ai → ai/code}/javascript_code_ai.rb +2 -5
  9. data/lib/asker/ai/code/problem_code_ai.rb +176 -0
  10. data/lib/asker/{code/ai → ai/code}/python_code_ai.rb +2 -5
  11. data/lib/asker/{code/ai → ai/code}/ruby_code_ai.rb +14 -7
  12. data/lib/asker/{code/ai → ai/code}/sql_code_ai.rb +2 -5
  13. data/lib/asker/ai/concept_ai.rb +13 -3
  14. data/lib/asker/ai/question.rb +28 -6
  15. data/lib/asker/ai/stages/base_stage.rb +45 -6
  16. data/lib/asker/ai/stages/stage_b.rb +100 -50
  17. data/lib/asker/ai/stages/stage_d.rb +75 -90
  18. data/lib/asker/ai/stages/stage_f.rb +64 -36
  19. data/lib/asker/ai/stages/stage_i.rb +79 -92
  20. data/lib/asker/ai/stages/stage_s.rb +41 -36
  21. data/lib/asker/ai/stages/stage_t.rb +149 -108
  22. data/lib/asker/application.rb +19 -11
  23. data/lib/asker/cli.rb +31 -44
  24. data/lib/asker/data/code.rb +62 -0
  25. data/lib/asker/data/column.rb +31 -21
  26. data/lib/asker/data/concept.rb +109 -65
  27. data/lib/asker/data/data_field.rb +14 -0
  28. data/lib/asker/data/project_data.rb +63 -0
  29. data/lib/asker/data/row.rb +75 -52
  30. data/lib/asker/data/table.rb +91 -42
  31. data/lib/asker/data/template.rb +3 -1
  32. data/lib/asker/data/world.rb +51 -35
  33. data/lib/asker/displayer/code_displayer.rb +7 -0
  34. data/lib/asker/displayer/concept_ai_displayer.erb +10 -0
  35. data/lib/asker/displayer/concept_ai_displayer.rb +74 -53
  36. data/lib/asker/displayer/concept_displayer.rb +16 -9
  37. data/lib/asker/displayer/stats_displayer.rb +12 -3
  38. data/lib/asker/exporter/concept_ai_gift_exporter.rb +19 -11
  39. data/lib/asker/exporter/concept_ai_moodle_exporter.rb +44 -0
  40. data/lib/asker/exporter/concept_ai_yaml_exporter.rb +13 -6
  41. data/lib/asker/exporter/concept_doc_exporter.rb +14 -1
  42. data/lib/asker/exporter/data_gift_exporter.rb +29 -0
  43. data/lib/asker/exporter/output_file_exporter.rb +9 -6
  44. data/lib/asker/files/{config.ini → asker.ini} +48 -1
  45. data/lib/asker/files/example-concept.haml +0 -1
  46. data/lib/asker/files/language/du/connectors.yaml +81 -0
  47. data/lib/asker/{lang/locales/fr → files/language/du}/mistakes.yaml +1 -1
  48. data/lib/asker/files/language/du/templates.yaml +29 -0
  49. data/lib/asker/{lang/locales → files/language}/en/connectors.yaml +0 -0
  50. data/lib/asker/{lang/locales → files/language}/en/mistakes.yaml +0 -0
  51. data/lib/asker/files/language/en/templates.yaml +29 -0
  52. data/lib/asker/{lang/locales → files/language}/es/connectors.yaml +0 -0
  53. data/lib/asker/files/language/es/mistakes.yaml +84 -0
  54. data/lib/asker/files/language/es/templates.yaml +29 -0
  55. data/lib/asker/files/language/fr/connectors.yaml +76 -0
  56. data/lib/asker/{lang/locales/es → files/language/fr}/mistakes.yaml +0 -0
  57. data/lib/asker/files/language/fr/templates.yaml +29 -0
  58. data/lib/asker/{lang/locales → files/language}/javascript/connectors.yaml +0 -0
  59. data/lib/asker/{lang/locales → files/language}/javascript/mistakes.yaml +0 -0
  60. data/lib/asker/{lang/locales → files/language}/javascript/templates.yaml +0 -0
  61. data/lib/asker/{lang/locales → files/language}/math/connectors.yaml +0 -0
  62. data/lib/asker/{lang/locales → files/language}/math/mistakes.yaml +0 -0
  63. data/lib/asker/{lang/locales → files/language}/math/templates.yaml +0 -0
  64. data/lib/asker/{lang/locales → files/language}/python/connectors.yaml +0 -0
  65. data/lib/asker/{lang/locales → files/language}/python/mistakes.yaml +0 -0
  66. data/lib/asker/{lang/locales → files/language}/python/templates.yaml +0 -0
  67. data/lib/asker/{lang/locales → files/language}/ruby/connectors.yaml +0 -0
  68. data/lib/asker/{lang/locales → files/language}/ruby/mistakes.yaml +0 -0
  69. data/lib/asker/{lang/locales → files/language}/ruby/templates.yaml +0 -0
  70. data/lib/asker/{lang/locales → files/language}/sql/connectors.yaml +0 -0
  71. data/lib/asker/{lang/locales → files/language}/sql/mistakes.yaml +0 -0
  72. data/lib/asker/{lang/locales → files/language}/sql/templates.yaml +0 -0
  73. data/lib/asker/formatter/concept_doc_formatter.rb +0 -4
  74. data/lib/asker/formatter/concept_string_formatter.rb +7 -4
  75. data/lib/asker/formatter/moodle/matching.erb +38 -0
  76. data/lib/asker/formatter/moodle/multichoice.erb +49 -0
  77. data/lib/asker/formatter/moodle/shortanswer.erb +30 -0
  78. data/lib/asker/formatter/moodle/truefalse.erb +47 -0
  79. data/lib/asker/formatter/question_gift_formatter.rb +30 -20
  80. data/lib/asker/formatter/question_moodle_formatter.rb +27 -0
  81. data/lib/asker/{checker.rb → input_checker.rb} +126 -49
  82. data/lib/asker/lang/lang.rb +17 -10
  83. data/lib/asker/lang/lang_factory.rb +32 -5
  84. data/lib/asker/lang/text_actions.rb +87 -69
  85. data/lib/asker/loader/code_loader.rb +4 -4
  86. data/lib/asker/loader/content_loader.rb +21 -19
  87. data/lib/asker/loader/directory_loader.rb +1 -8
  88. data/lib/asker/loader/embedded_file.rb +42 -0
  89. data/lib/asker/loader/file_loader.rb +3 -14
  90. data/lib/asker/loader/haml_loader.rb +15 -0
  91. data/lib/asker/loader/image_url_loader.rb +8 -12
  92. data/lib/asker/loader/input_loader.rb +13 -15
  93. data/lib/asker/loader/project_loader.rb +25 -15
  94. data/lib/asker/logger.rb +36 -9
  95. data/lib/asker/skeleton.rb +23 -13
  96. data/lib/asker.rb +76 -42
  97. metadata +53 -54
  98. data/lib/asker/code/ai/base_code_ai.rb +0 -48
  99. data/lib/asker/code/code.rb +0 -53
  100. data/lib/asker/lang/locales/du/templates.yaml +0 -50
  101. data/lib/asker/lang/locales/en/templates.yaml +0 -29
  102. data/lib/asker/lang/locales/es/templates.yaml +0 -29
  103. data/lib/asker/lang/locales/fr/connectors.yaml +0 -92
  104. data/lib/asker/lang/locales/fr/templates.yaml +0 -29
  105. data/lib/asker/project.rb +0 -172
@@ -1,170 +1,211 @@
1
- # encoding: utf-8
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
- #range t1-t9...c1-c9
9
-
10
- def run(pTable, pRow, pList) #process_tableXfields
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=="text"
13
-
14
- if pTable.fields.count>1 then
15
- questions = questions + process_table2fields(pTable, pRow, pList, 0, 1)
16
- elsif pTable.fields.count>2 then
17
- questions = questions + process_table2fields(pTable, pRow, pList, 0, 2)
18
- questions = questions + process_table2fields(pTable, pRow, pList, 1, 2)
19
- elsif pTable.fields.count>3 then
20
- questions = questions + process_table2fields(pTable, pRow, pList, 0, 3)
21
- questions = questions + process_table2fields(pTable, pRow, pList, 1, 3)
22
- questions = questions + process_table2fields(pTable, pRow, pList, 2, 3)
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
- return questions
30
+ questions
26
31
  end
32
+ # rubocop:enable Metrics/MethodLength
33
+ # rubocop:enable Metrics/AbcSize
34
+
35
+ private
27
36
 
28
- private
29
- def process_table2fields(lTable, lRow, pList, pCol1, pCol2)
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
- #create gift questions
32
-
33
- # Using the column #0
34
- s=Set.new [ lRow[:data][0] , lang.text_for(:none) ]
35
- pList.each { |i| s.add( i[:data][0] ) }
36
- a=s.to_a
37
-
38
- if s.count>3 then
39
- q=Question.new
40
- q.name="#{name}-#{num.to_s}-t1table-#{lTable.name}"
41
- q.text=lang.text_for(:t1table, name, lTable.fields[0].capitalize, lTable.fields[1].capitalize, lRow[:data][1])
42
- q.good=lRow[:data][0]
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 [ lRow[:data][0], lang.text_for(:none) ]
50
- pList.each { |i| s.add( i[:data][0] ) }
51
- a=s.to_a
52
-
53
- if s.count>4 then
54
- q=Question.new
55
- q.name="#{name}-#{num.to_s}-t2table-#{lTable.name}"
56
- q.text=lang.text_for(:t2table, name, lTable.fields[0].capitalize, lTable.fields[1].capitalize, lRow[:data][1])
57
- q.good=lang.text_for(:none)
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 [ lRow[:data][1], lang.text_for(:none) ]
66
- pList.each { |i| s.add( i[:data][1] ) }
67
- a=s.to_a
68
-
69
- if s.count>3 then
70
- q=Question.new
71
- q.name="#{name}-#{num.to_s}-t3table-#{lTable.name}"
72
- q.text=lang.text_for(:t3table, name, lTable.fields[0].capitalize, lRow[:data][0], lTable.fields[1].capitalize)
73
- q.good=a[0]
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 [ lRow[:data][1], lang.text_for(:none) ]
81
- pList.each { |i| s.add( i[:data][1] ) }
82
- a=s.to_a
83
-
84
- if s.count>4 then
85
- q=Question.new
86
- q.name="#{name}-#{num.to_s}-t4table-#{lTable.name}"
87
- q.text=lang.text_for(:t4table, name, lTable.fields[0].capitalize, lRow[:data][0], lTable.fields[1].capitalize)
88
- q.good=lang.text_for(:none)
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 association TRUE
96
- q=Question.new
116
+ # Question Boolean: TRUE
117
+ q = Question.new
97
118
  q.set_boolean
98
- q.name="#{name}-#{num.to_s}t5table-#{lTable.name}"
99
- q.text=lang.text_for(:t5table, name, lTable.fields[0].capitalize, lRow[:data][0] ,lTable.fields[1].capitalize, lRow[:data][1] )
100
- q.good="TRUE"
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 association FALSE
104
- s=Set.new [ lRow[:data][1] ]
105
- pList.each { |i| s.add( i[:data][1] ) }
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 then
109
- q=Question.new
131
+ if s.count > 1
132
+ q = Question.new
110
133
  q.set_boolean
111
- q.name="#{name}-#{num.to_s}-t6table-#{lTable.name}"
112
- q.text=lang.text_for(:t6table, name, lTable.fields[0].capitalize, lRow[:data][0], lTable.fields[1].capitalize, a[1] )
113
- q.good="FALSE"
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 [ lRow[:data][0] ]
118
- pList.each { |i| s.add( i[:data][0] ) }
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 then
122
- q=Question.new
146
+ if s.count > 1
147
+ q = Question.new
123
148
  q.set_boolean
124
- q.name="#{name}-#{num.to_s}t7table-#{lTable.name}"
125
- q.text=lang.text_for(:t7table, name, lTable.fields[0].capitalize, a[1], lTable.fields[1].capitalize, lRow[:data][1] )
126
- q.good="FALSE"
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 answer with column #0, 1 word
131
- if lang.count_words(lRow[:data][0])==1 then
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.to_s}t8table-#{lTable.name}"
135
- q.text=lang.text_for(:t8table, name, lTable.fields[1].capitalize, lRow[:data][1], lTable.fields[0].capitalize)
136
- q.shorts << lRow[:data][0]
137
- q.shorts << lRow[:data][0].gsub("-"," ").gsub("_"," ")
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(lRow[:data][0])==2 then
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.to_s}t9table-#{lTable.name}"
143
- q.text=lang.text_for(:t9table, name, lTable.fields[1].capitalize, lRow[:data][1], lTable.fields[0].capitalize, "[#{lang.hide_text(lRow[:data][0])}]", lang.count_words(lRow[:data][0]) )
144
- q.shorts << lRow[:data][0]
145
- q.shorts << lRow[:data][0].gsub("-"," ").gsub("_"," ")
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 answer with column #1, 1 word
150
- if lang.count_words(lRow[:data][1])==1 then
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.to_s}t8table-#{lTable.name}"
154
- q.text=lang.text_for(:t8table, name, lTable.fields[0].capitalize, lRow[:data][0], lTable.fields[1].capitalize)
155
- q.shorts << lRow[:data][1]
156
- q.shorts << lRow[:data][1].gsub("-"," ").gsub("_"," ")
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(lRow[:data][1])==2 then
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.to_s}t9table-#{lTable.name}"
162
- q.text=lang.text_for(:t9table, name, lTable.fields[0].capitalize, lRow[:data][0], lTable.fields[1].capitalize, "[#{lang.hide_text(lRow[:data][1])}]", lang.count_words(lRow[:data][1]) )
163
- q.shorts << lRow[:data][1]
164
- q.shorts << lRow[:data][1].gsub("-"," ").gsub("_"," ")
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
- return questions
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
@@ -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.5' # Application version
11
- NAME = 'asker' # Application name
12
- GEM = 'asker-tool' # Gem name
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, 'config.ini')
25
- unless File.exist? filename
26
- filename = File.join(File.dirname(__FILE__), 'files', 'config.ini')
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
- @config = IniFile.load(filename)
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 ['h', '-h', '--help'] => 'help'
11
+ map ['--help'] => 'help'
12
12
 
13
- map ['v', '-v', '--version'] => 'version'
13
+ map ['--version'] => 'version'
14
14
  desc 'version', 'Show the program version'
15
- ##
16
- # Show current version
17
15
  def version
18
- print Rainbow(Application::NAME).bright.blue
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 NAME', 'Build output files, from HAML/XML input 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
- Examples:
25
+ Create output files, from input file (HAML/XML format).
31
26
 
32
- (1) #{Rainbow('asker input/foo/foo.haml').yellow}, Build questions from HAML file.
27
+ Examples:
33
28
 
34
- (2) #{Rainbow('asker input/foo/foo.xml').yellow}, Build questions from XML file.
29
+ (1) #{Rainbow('asker input/foo/foo.haml').aqua}, Build questions from HAML file.
35
30
 
36
- (3) #{Rainbow('asker file --no-color input/foo/foo.haml').yellow}, Same as (1) but without colors.
31
+ (2) #{Rainbow('asker input/foo/foo.xml').aqua}, Build questions from XML file.
37
32
 
38
- (4) #{Rainbow('asker projects/foo/foo.yaml').yellow}, Build questions from YAML project file.
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 ['i', '-i', '--init'] => 'init'
52
- desc 'init', 'Create default INI config fie'
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 ['n', '-b', '--new', 'new'] => 'create_skeleton'
79
- desc 'new', 'Create Asker demo input files'
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 create_skeleton(dirname)
84
- # Asker start processing input file
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
@@ -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 + '.' + @index.to_s
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 XML data with elements!' if xml_data.elements.count.positive?
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
- if xml_data.attributes['lang']
45
- code = xml_data.attributes['lang'].strip
46
- if code != @lang.code
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
- if xml_data.attributes['type']
54
- type = xml_data.attributes['type'].strip
55
- if type != @type.to_s
56
- @type = type
57
- @simple[:type] = false
58
- @row.simple_off(:type)
59
- end
60
- end
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