asker-tool 2.1.7 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/{LICENSE.txt → LICENSE} +0 -0
- data/README.md +1 -1
- data/bin/asker +1 -1
- data/lib/asker/ai/ai.rb +6 -3
- data/lib/asker/ai/ai_calculate.rb +20 -6
- data/lib/asker/ai/concept_ai.rb +11 -2
- 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 +114 -73
- data/lib/asker/application.rb +8 -7
- data/lib/asker/checker.rb +6 -8
- data/lib/asker/cli.rb +27 -9
- data/lib/asker/data/code.rb +4 -1
- data/lib/asker/data/concept.rb +67 -21
- data/lib/asker/data/table.rb +2 -0
- data/lib/asker/data/template.rb +3 -1
- data/lib/asker/data/world.rb +7 -4
- 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 +23 -22
- data/lib/asker/displayer/concept_displayer.rb +9 -4
- data/lib/asker/displayer/stats_displayer.rb +8 -0
- data/lib/asker/exporter/concept_ai_gift_exporter.rb +7 -11
- data/lib/asker/exporter/concept_ai_moodle_exporter.rb +44 -0
- data/lib/asker/exporter/concept_ai_yaml_exporter.rb +6 -3
- 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} +14 -4
- data/lib/asker/files/language/du/connectors.yaml +81 -0
- data/lib/asker/files/language/du/mistakes.yaml +82 -0
- data/lib/asker/files/language/du/templates.yaml +28 -49
- data/lib/asker/files/language/en/templates.yaml +19 -19
- data/lib/asker/files/language/es/mistakes.yaml +9 -7
- data/lib/asker/files/language/es/templates.yaml +19 -19
- data/lib/asker/files/language/fr/connectors.yaml +68 -84
- data/lib/asker/files/language/fr/templates.yaml +22 -22
- 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 +21 -19
- data/lib/asker/formatter/question_moodle_formatter.rb +27 -0
- data/lib/asker/lang/lang_factory.rb +7 -1
- data/lib/asker/loader/code_loader.rb +1 -1
- data/lib/asker/loader/content_loader.rb +7 -7
- data/lib/asker/loader/directory_loader.rb +3 -3
- data/lib/asker/loader/embedded_file.rb +42 -0
- data/lib/asker/loader/file_loader.rb +1 -1
- data/lib/asker/loader/image_url_loader.rb +4 -3
- data/lib/asker/loader/input_loader.rb +1 -1
- data/lib/asker/loader/project_loader.rb +14 -5
- data/lib/asker/logger.rb +29 -4
- data/lib/asker/project.rb +14 -79
- data/lib/asker/skeleton.rb +3 -2
- data/lib/asker.rb +37 -9
- metadata +19 -22
data/lib/asker/data/concept.rb
CHANGED
@@ -6,18 +6,25 @@ require 'rexml/document'
|
|
6
6
|
require_relative '../application'
|
7
7
|
require_relative '../logger'
|
8
8
|
require_relative '../lang/lang_factory'
|
9
|
+
require_relative '../loader/embedded_file'
|
9
10
|
require_relative 'table'
|
10
11
|
require_relative 'data_field'
|
11
12
|
|
12
13
|
##
|
13
14
|
# Store Concept information
|
15
|
+
# rubocop:disable Metrics/ClassLength
|
16
|
+
# rubocop:disable Style/ClassVars
|
14
17
|
class Concept
|
15
|
-
attr_reader :id
|
16
|
-
attr_reader :
|
17
|
-
attr_reader :
|
18
|
-
|
18
|
+
attr_reader :id # Unique identifer (Integer)
|
19
|
+
attr_reader :lang # Lang code (By default is the same as map lang)
|
20
|
+
attr_reader :context # Context inherits from map
|
21
|
+
attr_reader :names # Names used to identify or name this concept
|
22
|
+
attr_reader :type # type = text -> Name values are only text
|
23
|
+
attr_reader :filename # Filename where this concept is defined
|
24
|
+
attr_reader :data # Data about this concept
|
25
|
+
attr_accessor :process # (Boolean) if it is necesary generate questions
|
19
26
|
|
20
|
-
@@id = 0
|
27
|
+
@@id = 0 # Global Concept counter
|
21
28
|
|
22
29
|
##
|
23
30
|
# Initilize Concept
|
@@ -25,6 +32,8 @@ class Concept
|
|
25
32
|
# @param filename (String)
|
26
33
|
# @param lang_code (String)
|
27
34
|
# @param context (Array)
|
35
|
+
# rubocop:disable Metrics/MethodLength
|
36
|
+
# rubocop:disable Metrics/AbcSize
|
28
37
|
def initialize(xml_data, filename, lang_code = 'en', context = [])
|
29
38
|
@@id += 1
|
30
39
|
@id = @@id
|
@@ -46,16 +55,17 @@ class Concept
|
|
46
55
|
|
47
56
|
@data = {}
|
48
57
|
@data[:tags] = []
|
49
|
-
@data[:texts] = []
|
50
|
-
@data[:images] = [] #
|
51
|
-
@data[:textfile_paths] = [] # TODO: By now, We'll treat this separated from texts
|
58
|
+
@data[:texts] = [] # Used by standard def inputs
|
59
|
+
@data[:images] = [] # Used by [type => file and type => image_url] def inputs
|
52
60
|
@data[:tables] = []
|
53
61
|
@data[:neighbors] = []
|
54
62
|
@data[:reference_to] = []
|
55
63
|
@data[:referenced_by] = []
|
56
64
|
|
57
|
-
|
65
|
+
read_data_from_xml(xml_data)
|
58
66
|
end
|
67
|
+
# rubocop:enable Metrics/MethodLength
|
68
|
+
# rubocop:enable Metrics/AbcSize
|
59
69
|
|
60
70
|
def name(option = :raw)
|
61
71
|
DataField.new(@names[0], @id, @type).get(option)
|
@@ -79,6 +89,9 @@ class Concept
|
|
79
89
|
@data[:neighbors].reverse!
|
80
90
|
end
|
81
91
|
|
92
|
+
# rubocop:disable Metrics/MethodLength
|
93
|
+
# rubocop:disable Metrics/AbcSize
|
94
|
+
# rubocop:disable Metrics/CyclomaticComplexity
|
82
95
|
def calculate_nearness_to_concept(other)
|
83
96
|
a = Application.instance.config['ai']['formula_weights']
|
84
97
|
weights = a.split(',').map(&:to_f)
|
@@ -98,8 +111,12 @@ class Concept
|
|
98
111
|
max = (max1 * weights[0] + max2 * weights[1] + max3 * weights[2])
|
99
112
|
(alike * 100.0 / max)
|
100
113
|
end
|
114
|
+
# rubocop:enable Metrics/MethodLength
|
115
|
+
# rubocop:enable Metrics/AbcSize
|
116
|
+
# rubocop:enable Metrics/CyclomaticComplexity
|
101
117
|
|
102
118
|
# rubocop:disable Metrics/MethodLength
|
119
|
+
# rubocop:disable Metrics/AbcSize
|
103
120
|
def try_adding_references(other)
|
104
121
|
reference_to = 0
|
105
122
|
@data[:tags].each do |i|
|
@@ -117,9 +134,34 @@ class Concept
|
|
117
134
|
other.data[:referenced_by] << name
|
118
135
|
end
|
119
136
|
# rubocop:enable Metrics/MethodLength
|
137
|
+
# rubocop:enable Metrics/AbcSize
|
138
|
+
|
139
|
+
def tags
|
140
|
+
@data[:tags]
|
141
|
+
end
|
120
142
|
|
121
|
-
def
|
122
|
-
@data[
|
143
|
+
def texts
|
144
|
+
@data[:texts]
|
145
|
+
end
|
146
|
+
|
147
|
+
def images
|
148
|
+
@data[:images]
|
149
|
+
end
|
150
|
+
|
151
|
+
def tables
|
152
|
+
@data[:tables]
|
153
|
+
end
|
154
|
+
|
155
|
+
def neighbors
|
156
|
+
@data[:neighbors]
|
157
|
+
end
|
158
|
+
|
159
|
+
def reference_to
|
160
|
+
@data[:reference_to]
|
161
|
+
end
|
162
|
+
|
163
|
+
def referenced_by
|
164
|
+
@data[:referenced_by]
|
123
165
|
end
|
124
166
|
|
125
167
|
private
|
@@ -137,8 +179,8 @@ class Concept
|
|
137
179
|
when 'table'
|
138
180
|
@data[:tables] << Table.new(self, i)
|
139
181
|
else
|
140
|
-
text = " [ERROR]
|
141
|
-
Logger.
|
182
|
+
text = " [ERROR] Concept #{name} with unkown attribute: #{i.name}"
|
183
|
+
Logger.verboseln Rainbow(text).color(:red)
|
142
184
|
end
|
143
185
|
end
|
144
186
|
end
|
@@ -153,7 +195,8 @@ class Concept
|
|
153
195
|
|
154
196
|
def process_tags(value)
|
155
197
|
if value.text.nil? || value.text.size.zero?
|
156
|
-
|
198
|
+
Logger.verboseln Rainbow("[ERROR] Concept #{name} has tags empty!").red.briht
|
199
|
+
exit 1
|
157
200
|
end
|
158
201
|
|
159
202
|
@data[:tags] = value.text.split(',')
|
@@ -164,17 +207,20 @@ class Concept
|
|
164
207
|
# rubocop:disable Metrics/MethodLength
|
165
208
|
def process_def(value)
|
166
209
|
case value.attributes['type']
|
167
|
-
when 'image'
|
168
|
-
msg = "[DEBUG] Concept#read_xml: image #{Rainbow(value.text).bright}"
|
169
|
-
Project.instance.verbose Rainbow(msg).yellow
|
170
210
|
when 'image_url'
|
171
|
-
@data[:images] << value.text.strip
|
172
|
-
when '
|
173
|
-
@data[:
|
174
|
-
|
211
|
+
@data[:images] << EmbeddedFile.load(value.text.strip, File.dirname(@filename))
|
212
|
+
when 'file'
|
213
|
+
@data[:images] << EmbeddedFile.load(value.text.strip, File.dirname(@filename))
|
214
|
+
when nil
|
175
215
|
@data[:texts] << value.text.strip
|
216
|
+
else
|
217
|
+
msg = "[ERROR] Unknown type: #{value.attributes['type']}"
|
218
|
+
Logger.verboseln Rainbow(msg).red.bright
|
219
|
+
exit 1
|
176
220
|
end
|
177
221
|
end
|
178
222
|
# rubocop:enable Metrics/AbcSize
|
179
223
|
# rubocop:enable Metrics/MethodLength
|
180
224
|
end
|
225
|
+
# rubocop:enable Metrics/ClassLength
|
226
|
+
# rubocop:enable Style/ClassVars
|
data/lib/asker/data/table.rb
CHANGED
@@ -114,6 +114,7 @@ class Table
|
|
114
114
|
|
115
115
|
# rubocop:disable Metrics/MethodLength
|
116
116
|
# rubocop:disable Metrics/AbcSize
|
117
|
+
# rubocop:disable Style/ConditionalAssignment
|
117
118
|
def read_lang_from_xml(xml_data)
|
118
119
|
j = xml_data.text.split(',')
|
119
120
|
codes = @langs.map(&:code)
|
@@ -131,6 +132,7 @@ class Table
|
|
131
132
|
end
|
132
133
|
# rubocop:enable Metrics/MethodLength
|
133
134
|
# rubocop:enable Metrics/AbcSize
|
135
|
+
# rubocop:enable Style/ConditionalAssignment
|
134
136
|
|
135
137
|
def read_type_from_xml(xml_data)
|
136
138
|
j = xml_data.text.split(',')
|
data/lib/asker/data/template.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: false
|
1
2
|
|
2
3
|
require 'rexml/document'
|
3
4
|
require_relative 'row'
|
@@ -40,7 +41,8 @@ class Template
|
|
40
41
|
|
41
42
|
def apply_vars_to_template(vars, template)
|
42
43
|
output = ''
|
43
|
-
return if vars.size.zero?
|
44
|
+
return output if vars.size.zero?
|
45
|
+
|
44
46
|
max = vars.first[1].size
|
45
47
|
(1..max).each do |index|
|
46
48
|
t = template.dup
|
data/lib/asker/data/world.rb
CHANGED
@@ -55,9 +55,10 @@ class World
|
|
55
55
|
|
56
56
|
# rubocop:disable Metrics/MethodLength
|
57
57
|
# rubocop:disable Metrics/AbcSize
|
58
|
+
# rubocop:disable Metrics/CyclomaticComplexity
|
59
|
+
# rubocop:disable Metrics/PerceivedComplexity
|
58
60
|
def find_url_images_from_internet(show_progress)
|
59
|
-
|
60
|
-
return {} unless param == 'yes'
|
61
|
+
return {} unless Application.instance.config['global']['internet'] == 'yes'
|
61
62
|
|
62
63
|
Logger.verbose "\n[INFO] Loading data from Internet" if show_progress
|
63
64
|
threads = []
|
@@ -67,13 +68,15 @@ class World
|
|
67
68
|
@concepts&.each_key { |key| searchs << key }
|
68
69
|
@contexts.each { |filter| searchs << filter.join(' ').to_s }
|
69
70
|
searchs.each do |search|
|
70
|
-
|
71
|
+
Logger.verbose('.') if show_progress
|
71
72
|
threads << Thread.new { urls[search] = ImageUrlLoader.load(search) }
|
72
73
|
end
|
73
74
|
threads.each(&:join) # wait for all threads to finish
|
74
|
-
|
75
|
+
Logger.verbose("\n") if show_progress
|
75
76
|
urls
|
76
77
|
end
|
77
78
|
# rubocop:enable Metrics/MethodLength
|
78
79
|
# rubocop:enable Metrics/AbcSize
|
80
|
+
# rubocop:enable Metrics/CyclomaticComplexity
|
81
|
+
# rubocop:enable Metrics/PerceivedComplexity
|
79
82
|
end
|
@@ -5,6 +5,11 @@ require_relative '../logger'
|
|
5
5
|
|
6
6
|
# Export Code into Screen
|
7
7
|
module CodeDisplayer
|
8
|
+
##
|
9
|
+
# Show all "code" data on screen
|
10
|
+
# @param codes (Array) List of "code" data
|
11
|
+
# rubocop:disable Metrics/AbcSize
|
12
|
+
# rubocop:disable Metrics/MethodLength
|
8
13
|
def self.show(codes)
|
9
14
|
return if codes.nil? || codes.size.zero?
|
10
15
|
|
@@ -42,4 +47,6 @@ module CodeDisplayer
|
|
42
47
|
Logger.verboseln "\n[INFO] Showing CODE statistics"
|
43
48
|
Logger.verboseln my_screen_table.to_s
|
44
49
|
end
|
50
|
+
# rubocop:enable Metrics/AbcSize
|
51
|
+
# rubocop:enable Metrics/MethodLength
|
45
52
|
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
|
2
|
+
[INFO] Showing CONCEPT statistics
|
3
|
+
* Exclude questions: <%= exclude_questions %>
|
4
|
+
* Annotations:
|
5
|
+
├── (d) Definitions <= Concept.def
|
6
|
+
├── (b) Table Matching <= Concept.table.rows.columns
|
7
|
+
├── (f) Tables 1 Field <= Concept.table.fields.size==1
|
8
|
+
├── (i) Images URL <= Concept.def{:type => 'file'}
|
9
|
+
├── (s) Sequences <= Concept.table{:sequence => '...'}
|
10
|
+
└── (t) Table Rows&Cols <= Concept.table.rows.columns
|
@@ -1,5 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'erb'
|
3
4
|
require 'terminal-table'
|
4
5
|
require_relative '../application'
|
5
6
|
require_relative '../logger'
|
@@ -9,11 +10,15 @@ class ConceptAIDisplayer
|
|
9
10
|
##
|
10
11
|
# Display ConceptAI stat on screen
|
11
12
|
# @param concepts_ai (Array)
|
13
|
+
# rubocop:disable Metrics/MethodLength
|
14
|
+
# rubocop:disable Metrics/AbcSize
|
15
|
+
# rubocop:disable Metrics/CyclomaticComplexity
|
16
|
+
# rubocop:disable Metrics/PerceivedComplexity
|
12
17
|
def self.show(concepts_ai)
|
13
18
|
stages = Application.instance.config['questions']['stages']
|
14
19
|
# Create table HEAD
|
15
20
|
screen_table = Terminal::Table.new do |st|
|
16
|
-
title = [
|
21
|
+
title = %w[Concept Questions Entries xFactor]
|
17
22
|
%w[d b f i s t].each do |i|
|
18
23
|
if stages.include? i.to_sym
|
19
24
|
title << i
|
@@ -31,10 +36,10 @@ class ConceptAIDisplayer
|
|
31
36
|
total[:si] = total[:ss] = total[:st] = 0
|
32
37
|
|
33
38
|
concepts_ai.each do |concept_ai|
|
34
|
-
next unless concept_ai.process?
|
39
|
+
next unless concept_ai.concept.process?
|
35
40
|
|
36
|
-
e = concept_ai.texts.size
|
37
|
-
concept_ai.tables.each { |t| e += t.fields.size * t.rows.size }
|
41
|
+
e = concept_ai.concept.texts.size
|
42
|
+
concept_ai.concept.tables.each { |t| e += t.fields.size * t.rows.size }
|
38
43
|
|
39
44
|
sd = sb = sf = 0
|
40
45
|
si = ss = st = 0
|
@@ -48,7 +53,7 @@ class ConceptAIDisplayer
|
|
48
53
|
|
49
54
|
factor = 'Unkown'
|
50
55
|
factor = (t.to_f / e).round(2).to_s unless e.zero?
|
51
|
-
screen_table.add_row [Rainbow(concept_ai.name(:screen)).green.bright,
|
56
|
+
screen_table.add_row [Rainbow(concept_ai.concept.name(:screen)).green.bright,
|
52
57
|
t, e, factor, sd, sb, sf, si, ss, st]
|
53
58
|
|
54
59
|
total[:q] += t
|
@@ -75,9 +80,15 @@ class ConceptAIDisplayer
|
|
75
80
|
total[:sd], total[:sb], total[:sf],
|
76
81
|
total[:si], total[:ss], total[:st]]
|
77
82
|
export_notes
|
78
|
-
Logger.
|
83
|
+
Logger.verboseln "#{screen_table}\n"
|
79
84
|
end
|
85
|
+
# rubocop:enable Metrics/MethodLength
|
86
|
+
# rubocop:enable Metrics/AbcSize
|
87
|
+
# rubocop:enable Metrics/CyclomaticComplexity
|
88
|
+
# rubocop:enable Metrics/PerceivedComplexity
|
80
89
|
|
90
|
+
# rubocop:disable Metrics/MethodLength
|
91
|
+
# rubocop:disable Metrics/AbcSize
|
81
92
|
private_class_method def self.export_excluded_questions(screen_table, concepts_ai)
|
82
93
|
# Create table BODY
|
83
94
|
total = {}
|
@@ -86,7 +97,7 @@ class ConceptAIDisplayer
|
|
86
97
|
total[:si] = total[:ss] = total[:st] = 0
|
87
98
|
|
88
99
|
concepts_ai.each do |concept_ai|
|
89
|
-
next unless concept_ai.process?
|
100
|
+
next unless concept_ai.concept.process?
|
90
101
|
|
91
102
|
sd = concept_ai.excluded_questions[:d].size
|
92
103
|
sb = concept_ai.excluded_questions[:b].size
|
@@ -111,22 +122,12 @@ class ConceptAIDisplayer
|
|
111
122
|
total[:sf], total[:si],
|
112
123
|
total[:ss], total[:st]]
|
113
124
|
end
|
125
|
+
# rubocop:enable Metrics/MethodLength
|
126
|
+
# rubocop:enable Metrics/AbcSize
|
114
127
|
|
115
128
|
private_class_method def self.export_notes
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
Logger.verbose ' * Annotations:'
|
120
|
-
Logger.verbose ' ├── (d) Definitions <= Concept.def'
|
121
|
-
Logger.verbose ' ├── (b) Table Matching <= ' \
|
122
|
-
'Concept.table.rows.columns'
|
123
|
-
Logger.verbose ' ├── (f) Tables 1 Field <= Concept.table.fields.size==1'
|
124
|
-
Logger.verbose ' ├── (i) Images URL <= ' \
|
125
|
-
"Concept.def{:type => 'image_url'}"
|
126
|
-
Logger.verbose ' ├── (s) Sequences <= ' \
|
127
|
-
"Concept.table{:sequence => '...'}"
|
128
|
-
Logger.verbose ' └── (t) Table Rows&Cols <= ' \
|
129
|
-
'Concept.table.rows.columns'
|
130
|
-
Logger.verbose "\n"
|
129
|
+
exclude_questions = Application.instance.config['questions']['exclude'].to_s
|
130
|
+
renderer = ERB.new(File.read(File.join(File.dirname(__FILE__), 'concept_ai_displayer.erb')))
|
131
|
+
Logger.verboseln renderer.result(binding)
|
131
132
|
end
|
132
133
|
end
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
|
2
3
|
require_relative '../application'
|
3
4
|
require_relative '../formatter/concept_string_formatter'
|
@@ -7,23 +8,27 @@ require_relative '../logger'
|
|
7
8
|
module ConceptDisplayer
|
8
9
|
##
|
9
10
|
# Show concepts on screen
|
10
|
-
# @param concepts (Array)
|
11
|
+
# @param concepts (Array) List of concept data
|
12
|
+
# rubocop:disable Metrics/AbcSize
|
13
|
+
# rubocop:disable Metrics/MethodLength
|
11
14
|
def self.show(concepts)
|
12
15
|
show_mode = Application.instance.config['global']['show_mode']
|
13
16
|
return unless show_mode
|
14
17
|
|
15
18
|
msg = "\n[INFO] Showing concept data (#{Rainbow(show_mode).bright})"
|
16
|
-
Logger.
|
19
|
+
Logger.verboseln msg
|
17
20
|
case show_mode
|
18
21
|
when 'resume'
|
19
22
|
s = "* Concepts (#{concepts.count}): "
|
20
23
|
concepts.each { |c| s += c.name + ', ' }
|
21
|
-
Logger.
|
24
|
+
Logger.verboseln s
|
22
25
|
when 'default'
|
23
26
|
# Only show Concepts with process attr true
|
24
27
|
concepts.each do |c|
|
25
|
-
Logger.
|
28
|
+
Logger.verboseln ConceptStringFormatter.to_s(c) if c.process?
|
26
29
|
end
|
27
30
|
end
|
28
31
|
end
|
32
|
+
# rubocop:enable Metrics/AbcSize
|
33
|
+
# rubocop:enable Metrics/MethodLength
|
29
34
|
end
|
@@ -1,9 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require_relative '../application'
|
2
4
|
require_relative 'concept_ai_displayer'
|
3
5
|
require_relative 'code_displayer'
|
4
6
|
|
5
7
|
# Display Stats on screen.
|
8
|
+
# * Display all "Concept AI"
|
9
|
+
# * Display all "Code"
|
6
10
|
module StatsDisplayer
|
11
|
+
# Display Stats on screen.
|
12
|
+
# * Display all "Concept AI"
|
13
|
+
# * Display all "Code"
|
14
|
+
# @param data (Hash) With concept_ai list and code list
|
7
15
|
def self.show(data)
|
8
16
|
return unless Application.instance.config['global']['show_mode']
|
9
17
|
|
@@ -1,6 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative '../project'
|
4
3
|
require_relative '../formatter/question_gift_formatter'
|
5
4
|
|
6
5
|
# Export ConceptIA data to gift to outputfile
|
@@ -8,28 +7,25 @@ module ConceptAIGiftExporter
|
|
8
7
|
##
|
9
8
|
# Export an array of ConceptAI objects from Project into GIFT outpufile
|
10
9
|
# @param concepts_ai (Array)
|
11
|
-
# @param
|
12
|
-
def self.export_all(concepts_ai,
|
13
|
-
concepts_ai.each { |concept_ai| export(concept_ai,
|
10
|
+
# @param file (File)
|
11
|
+
def self.export_all(concepts_ai, file)
|
12
|
+
concepts_ai.each { |concept_ai| export(concept_ai, file) }
|
14
13
|
end
|
15
14
|
|
16
15
|
##
|
17
16
|
# Export 1 concept_ai from project
|
18
17
|
# @param concept_ai (ConceptAI)
|
19
|
-
# @param
|
20
|
-
|
21
|
-
|
22
|
-
return unless concept_ai.process?
|
18
|
+
# @param file (File)
|
19
|
+
private_class_method def self.export(concept_ai, file)
|
20
|
+
return unless concept_ai.concept.process?
|
23
21
|
|
24
|
-
file
|
25
|
-
file.write head(concept_ai.name)
|
22
|
+
file.write head(concept_ai.concept.name)
|
26
23
|
Application.instance.config['questions']['stages'].each do |stage|
|
27
24
|
concept_ai.questions[stage].each do |question|
|
28
25
|
file.write(QuestionGiftFormatter.to_s(question))
|
29
26
|
end
|
30
27
|
end
|
31
28
|
end
|
32
|
-
# rubocop:enable Metrics/AbcSize
|
33
29
|
|
34
30
|
##
|
35
31
|
# Convert Concept name into gift format head
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../formatter/question_moodle_formatter'
|
4
|
+
|
5
|
+
# Export ConceptIA data to gift to moodlefile
|
6
|
+
module ConceptAIMoodleExporter
|
7
|
+
##
|
8
|
+
# Export an array of ConceptAI objects from Project into Moodle format file
|
9
|
+
# @param concepts_ai (Array)
|
10
|
+
# @param project (Project)
|
11
|
+
def self.export_all(concepts_ai, project)
|
12
|
+
file = File.open(project.get(:moodlepath), 'w')
|
13
|
+
file.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
|
14
|
+
file.write("<quiz>\n")
|
15
|
+
file.write("<!--\n#{('=' * 50)}\n")
|
16
|
+
file.write(" Created by : #{Application::NAME}")
|
17
|
+
file.write(" (version #{Application::VERSION})\n")
|
18
|
+
file.write(" File : #{project.get(:moodlename)}\n")
|
19
|
+
file.write(" Time : #{Time.new}\n")
|
20
|
+
file.write(" Author : David Vargas Ruiz\n")
|
21
|
+
file.write("#{('=' * 50)}\n-->\n\n")
|
22
|
+
|
23
|
+
concepts_ai.each { |concept_ai| export(concept_ai, file) }
|
24
|
+
|
25
|
+
file.write("</quiz>\n")
|
26
|
+
file.close
|
27
|
+
end
|
28
|
+
|
29
|
+
##
|
30
|
+
# Export 1 concept_ai from project
|
31
|
+
# @param concept_ai (ConceptAI)
|
32
|
+
# @param file (File)
|
33
|
+
# rubocop:disable Metrics/AbcSize
|
34
|
+
private_class_method def self.export(concept_ai, file)
|
35
|
+
return unless concept_ai.concept.process?
|
36
|
+
|
37
|
+
Application.instance.config['questions']['stages'].each do |stage|
|
38
|
+
concept_ai.questions[stage].each do |question|
|
39
|
+
file.write(QuestionMoodleFormatter.to_s(question))
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
# rubocop:enable Metrics/AbcSize
|
44
|
+
end
|
@@ -17,16 +17,19 @@ module ConceptAIYAMLExporter
|
|
17
17
|
params = { lang: project.get(:lang) ,
|
18
18
|
projectname: project.get(:projectname) }
|
19
19
|
output = { params: params, questions: questions }
|
20
|
-
|
20
|
+
|
21
|
+
yamlfile = File.open(project.get(:yamlpath), 'w')
|
22
|
+
yamlfile.write(output.to_yaml)
|
23
|
+
yamlfile.close
|
21
24
|
end
|
22
25
|
|
23
26
|
private_class_method def self.get_questions_from(concept_ai)
|
24
27
|
data = []
|
25
|
-
return data unless concept_ai.process?
|
28
|
+
return data unless concept_ai.concept.process?
|
26
29
|
|
27
30
|
Application.instance.config['questions']['stages'].each do |stage|
|
28
31
|
concept_ai.questions[stage].each do |question|
|
29
|
-
question.lang = concept_ai.lang
|
32
|
+
question.lang = concept_ai.concept.lang
|
30
33
|
data << QuestionHashFormatter.to_hash(question)
|
31
34
|
end
|
32
35
|
end
|
@@ -7,9 +7,22 @@ require_relative '../formatter/concept_doc_formatter'
|
|
7
7
|
module ConceptDocExporter
|
8
8
|
##
|
9
9
|
# Export arrya of concepts to doc
|
10
|
-
|
10
|
+
# rubocop:disable Metrics/AbcSize
|
11
|
+
# rubocop:disable Metrics/MethodLength
|
12
|
+
def self.export_all(concepts, project)
|
13
|
+
file = File.new(project.get(:lessonpath), 'w')
|
14
|
+
file.write('=' * 50 + "\n")
|
15
|
+
file.write("Created by : #{Application::NAME} (version #{Application::VERSION})\n")
|
16
|
+
file.write("File : #{project.get(:lessonname)}\n")
|
17
|
+
file.write("Time : #{Time.new}\n")
|
18
|
+
file.write("Author : David Vargas Ruiz\n")
|
19
|
+
file.write('=' * 50 + "\n")
|
20
|
+
|
11
21
|
concepts.each do |concept|
|
12
22
|
file.write(ConceptDocFormatter.to_s(concept)) if concept.process
|
13
23
|
end
|
24
|
+
file.close
|
14
25
|
end
|
26
|
+
# rubocop:enable Metrics/AbcSize
|
27
|
+
# rubocop:enable Metrics/MethodLength
|
15
28
|
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'concept_ai_gift_exporter'
|
4
|
+
require_relative 'code_gift_exporter'
|
5
|
+
|
6
|
+
# Export Data (ConceptIA and Code) to gift to outputfile
|
7
|
+
module DataGiftExporter
|
8
|
+
##
|
9
|
+
# Export an array of Data (ConceptAI and Code objects) into GIFT outpufile
|
10
|
+
# @param data (Hash)
|
11
|
+
# @param project (Project)
|
12
|
+
def self.export_all(data, project)
|
13
|
+
file = File.open(project.get(:outputpath), 'w')
|
14
|
+
file.write('// ' + ('=' * 50) + "\n")
|
15
|
+
file.write("// Created by : #{Application::NAME}")
|
16
|
+
file.write(" (version #{Application::VERSION})\n")
|
17
|
+
file.write("// File : #{project.get(:outputname)}\n")
|
18
|
+
file.write("// Time : #{Time.new}\n")
|
19
|
+
file.write("// Author : David Vargas Ruiz\n")
|
20
|
+
file.write('// ' + ('=' * 50) + "\n\n")
|
21
|
+
category = Application.instance.config['questions']['category']
|
22
|
+
file.write("$CATEGORY: $course$/#{category}\n") unless category.nil?
|
23
|
+
|
24
|
+
ConceptAIGiftExporter.export_all(data[:concepts_ai], file)
|
25
|
+
CodeGiftExporter.export_all(data[:codes_ai], file)
|
26
|
+
|
27
|
+
file.close
|
28
|
+
end
|
29
|
+
end
|
@@ -1,7 +1,7 @@
|
|
1
|
-
require_relative '
|
2
|
-
require_relative 'code_gift_exporter'
|
1
|
+
require_relative 'concept_ai_moodle_exporter'
|
3
2
|
require_relative 'concept_ai_yaml_exporter'
|
4
3
|
require_relative 'concept_doc_exporter'
|
4
|
+
require_relative 'data_gift_exporter'
|
5
5
|
|
6
6
|
# Export Output data:
|
7
7
|
# * Gift (ConceptAI, Code)
|
@@ -9,10 +9,13 @@ require_relative 'concept_doc_exporter'
|
|
9
9
|
# * Doc (txt)
|
10
10
|
module OutputFileExporter
|
11
11
|
def self.export(data, project)
|
12
|
-
|
12
|
+
config = Application.instance.config
|
13
|
+
DataGiftExporter.export_all(data, project) if config['output']['gift'] == 'yes'
|
14
|
+
ConceptAIYAMLExporter.export_all(data[:concepts_ai], project) if config['output']['yaml'] == 'yes'
|
15
|
+
ConceptDocExporter.export_all(data[:concepts], project) if config['output']['doc'] == 'yes'
|
16
|
+
# ConceptAIGiftExporter.export_all(data[:concepts_ai], project) if config['output']['gift'] == 'yes'
|
17
|
+
# CodeGiftExporter.export_all(data[:codes_ai], project.get(:outputfile)) if config['output']['gift'] == 'yes'
|
13
18
|
# UNDER DEVELOPMENT
|
14
|
-
|
15
|
-
ConceptAIYAMLExporter.export_all(data[:concepts_ai], project)
|
16
|
-
ConceptDocExporter.export_all(data[:concepts], project.get(:lessonfile))
|
19
|
+
ConceptAIMoodleExporter.export_all(data[:concepts_ai], project) if config['output']['moodle'] == 'yes'
|
17
20
|
end
|
18
21
|
end
|
@@ -1,10 +1,7 @@
|
|
1
1
|
[global]
|
2
2
|
; Connect Google and download find images URLs
|
3
3
|
; Accept yes|no
|
4
|
-
internet =
|
5
|
-
|
6
|
-
; Output files will be save into output folder.
|
7
|
-
outputdir = output
|
4
|
+
internet = yes
|
8
5
|
|
9
6
|
; Display on screen messages about program progress
|
10
7
|
; Accept yes|no
|
@@ -14,6 +11,17 @@ color = yes
|
|
14
11
|
; Accept resume|default
|
15
12
|
show_mode = default
|
16
13
|
|
14
|
+
[output]
|
15
|
+
; Output files will be save into output folder.
|
16
|
+
folder = output
|
17
|
+
|
18
|
+
; List of output files
|
19
|
+
; Accept yes|no
|
20
|
+
gift = yes
|
21
|
+
doc = yes
|
22
|
+
yaml = yes
|
23
|
+
moodle = yes
|
24
|
+
|
17
25
|
[languages]
|
18
26
|
; Default code language
|
19
27
|
default = en
|
@@ -22,6 +30,8 @@ default = en
|
|
22
30
|
; Accept yes|no
|
23
31
|
en = yes
|
24
32
|
es = yes
|
33
|
+
fr = yes
|
34
|
+
du = yes
|
25
35
|
javascript = yes
|
26
36
|
math = no
|
27
37
|
python = yes
|