asker-tool 2.1.6 → 2.2.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/{LICENSE.txt → LICENSE} +0 -0
- data/README.md +14 -15
- 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 +12 -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 +90 -49
- data/lib/asker/ai/stages/stage_d.rb +69 -90
- data/lib/asker/ai/stages/stage_f.rb +47 -38
- 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 +7 -15
- data/lib/asker/check_input/input_data.rb +358 -0
- data/lib/asker/check_input.rb +51 -0
- data/lib/asker/cli.rb +28 -28
- data/lib/asker/data/code.rb +5 -16
- data/lib/asker/data/concept.rb +71 -24
- data/lib/asker/data/project_data.rb +63 -0
- data/lib/asker/data/table.rb +2 -0
- data/lib/asker/data/template.rb +3 -1
- data/lib/asker/data/world.rb +8 -16
- 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 +24 -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 +16 -10
- 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_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/lang/lang_factory.rb +7 -1
- data/lib/asker/loader/code_loader.rb +1 -1
- data/lib/asker/loader/content_loader.rb +12 -14
- 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 +1 -3
- data/lib/asker/loader/image_url_loader.rb +8 -9
- data/lib/asker/loader/input_loader.rb +5 -6
- data/lib/asker/loader/project_loader.rb +18 -10
- data/lib/asker/logger.rb +35 -8
- data/lib/asker/skeleton.rb +3 -2
- data/lib/asker.rb +72 -43
- metadata +43 -17
- data/lib/asker/checker.rb +0 -455
- data/lib/asker/project.rb +0 -146
data/lib/asker/data/concept.rb
CHANGED
@@ -3,21 +3,26 @@
|
|
3
3
|
require 'rainbow'
|
4
4
|
require 'rexml/document'
|
5
5
|
|
6
|
-
require_relative '../application'
|
7
|
-
require_relative '../logger'
|
8
6
|
require_relative '../lang/lang_factory'
|
7
|
+
require_relative '../loader/embedded_file'
|
9
8
|
require_relative 'table'
|
10
9
|
require_relative 'data_field'
|
11
10
|
|
12
11
|
##
|
13
12
|
# Store Concept information
|
13
|
+
# rubocop:disable Metrics/ClassLength
|
14
|
+
# rubocop:disable Style/ClassVars
|
14
15
|
class Concept
|
15
|
-
attr_reader :id
|
16
|
-
attr_reader :
|
17
|
-
attr_reader :
|
18
|
-
|
16
|
+
attr_reader :id # Unique identifer (Integer)
|
17
|
+
attr_reader :lang # Lang code (By default is the same as map lang)
|
18
|
+
attr_reader :context # Context inherits from map
|
19
|
+
attr_reader :names # Names used to identify or name this concept
|
20
|
+
attr_reader :type # type = text -> Name values are only text
|
21
|
+
attr_reader :filename # Filename where this concept is defined
|
22
|
+
attr_reader :data # Data about this concept
|
23
|
+
attr_accessor :process # (Boolean) if it is necesary generate questions
|
19
24
|
|
20
|
-
@@id = 0
|
25
|
+
@@id = 0 # Global Concept counter (concept identifier)
|
21
26
|
|
22
27
|
##
|
23
28
|
# Initilize Concept
|
@@ -25,6 +30,8 @@ class Concept
|
|
25
30
|
# @param filename (String)
|
26
31
|
# @param lang_code (String)
|
27
32
|
# @param context (Array)
|
33
|
+
# rubocop:disable Metrics/MethodLength
|
34
|
+
# rubocop:disable Metrics/AbcSize
|
28
35
|
def initialize(xml_data, filename, lang_code = 'en', context = [])
|
29
36
|
@@id += 1
|
30
37
|
@id = @@id
|
@@ -46,16 +53,17 @@ class Concept
|
|
46
53
|
|
47
54
|
@data = {}
|
48
55
|
@data[:tags] = []
|
49
|
-
@data[:texts] = []
|
50
|
-
@data[:images] = [] #
|
51
|
-
@data[:textfile_paths] = [] # TODO: By now, We'll treat this separated from texts
|
56
|
+
@data[:texts] = [] # Used by standard def inputs
|
57
|
+
@data[:images] = [] # Used by [type => file and type => image_url] def inputs
|
52
58
|
@data[:tables] = []
|
53
59
|
@data[:neighbors] = []
|
54
60
|
@data[:reference_to] = []
|
55
61
|
@data[:referenced_by] = []
|
56
62
|
|
57
|
-
|
63
|
+
read_data_from_xml(xml_data)
|
58
64
|
end
|
65
|
+
# rubocop:enable Metrics/MethodLength
|
66
|
+
# rubocop:enable Metrics/AbcSize
|
59
67
|
|
60
68
|
def name(option = :raw)
|
61
69
|
DataField.new(@names[0], @id, @type).get(option)
|
@@ -79,8 +87,12 @@ class Concept
|
|
79
87
|
@data[:neighbors].reverse!
|
80
88
|
end
|
81
89
|
|
90
|
+
# rubocop:disable Metrics/MethodLength
|
91
|
+
# rubocop:disable Metrics/AbcSize
|
92
|
+
# rubocop:disable Metrics/CyclomaticComplexity
|
82
93
|
def calculate_nearness_to_concept(other)
|
83
|
-
a =
|
94
|
+
a = ProjectData.instance.get(:weights)
|
95
|
+
#Application.instance.config['ai']['formula_weights']
|
84
96
|
weights = a.split(',').map(&:to_f)
|
85
97
|
|
86
98
|
max1 = @context.count
|
@@ -98,8 +110,12 @@ class Concept
|
|
98
110
|
max = (max1 * weights[0] + max2 * weights[1] + max3 * weights[2])
|
99
111
|
(alike * 100.0 / max)
|
100
112
|
end
|
113
|
+
# rubocop:enable Metrics/MethodLength
|
114
|
+
# rubocop:enable Metrics/AbcSize
|
115
|
+
# rubocop:enable Metrics/CyclomaticComplexity
|
101
116
|
|
102
117
|
# rubocop:disable Metrics/MethodLength
|
118
|
+
# rubocop:disable Metrics/AbcSize
|
103
119
|
def try_adding_references(other)
|
104
120
|
reference_to = 0
|
105
121
|
@data[:tags].each do |i|
|
@@ -117,9 +133,34 @@ class Concept
|
|
117
133
|
other.data[:referenced_by] << name
|
118
134
|
end
|
119
135
|
# rubocop:enable Metrics/MethodLength
|
136
|
+
# rubocop:enable Metrics/AbcSize
|
137
|
+
|
138
|
+
def tags
|
139
|
+
@data[:tags]
|
140
|
+
end
|
120
141
|
|
121
|
-
def
|
122
|
-
@data[
|
142
|
+
def texts
|
143
|
+
@data[:texts]
|
144
|
+
end
|
145
|
+
|
146
|
+
def images
|
147
|
+
@data[:images]
|
148
|
+
end
|
149
|
+
|
150
|
+
def tables
|
151
|
+
@data[:tables]
|
152
|
+
end
|
153
|
+
|
154
|
+
def neighbors
|
155
|
+
@data[:neighbors]
|
156
|
+
end
|
157
|
+
|
158
|
+
def reference_to
|
159
|
+
@data[:reference_to]
|
160
|
+
end
|
161
|
+
|
162
|
+
def referenced_by
|
163
|
+
@data[:referenced_by]
|
123
164
|
end
|
124
165
|
|
125
166
|
private
|
@@ -137,8 +178,8 @@ class Concept
|
|
137
178
|
when 'table'
|
138
179
|
@data[:tables] << Table.new(self, i)
|
139
180
|
else
|
140
|
-
text = " [ERROR]
|
141
|
-
|
181
|
+
text = " [ERROR] Concept #{name} with unkown attribute: #{i.name}"
|
182
|
+
puts Rainbow(text).color(:red)
|
142
183
|
end
|
143
184
|
end
|
144
185
|
end
|
@@ -153,7 +194,8 @@ class Concept
|
|
153
194
|
|
154
195
|
def process_tags(value)
|
155
196
|
if value.text.nil? || value.text.size.zero?
|
156
|
-
|
197
|
+
puts Rainbow("[ERROR] Concept #{name} has tags empty!").red.briht
|
198
|
+
exit 1
|
157
199
|
end
|
158
200
|
|
159
201
|
@data[:tags] = value.text.split(',')
|
@@ -164,17 +206,22 @@ class Concept
|
|
164
206
|
# rubocop:disable Metrics/MethodLength
|
165
207
|
def process_def(value)
|
166
208
|
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
209
|
when 'image_url'
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
210
|
+
# Link with remote image
|
211
|
+
@data[:images] << EmbeddedFile.load(value.text.strip, File.dirname(@filename))
|
212
|
+
when 'file'
|
213
|
+
# Load local images and text files
|
214
|
+
@data[:images] << EmbeddedFile.load(value.text.strip, File.dirname(@filename))
|
215
|
+
when nil
|
175
216
|
@data[:texts] << value.text.strip
|
217
|
+
else
|
218
|
+
msg = "[ERROR] Unknown type: #{value.attributes['type']}"
|
219
|
+
puts Rainbow(msg).red.bright
|
220
|
+
exit 1
|
176
221
|
end
|
177
222
|
end
|
178
223
|
# rubocop:enable Metrics/AbcSize
|
179
224
|
# rubocop:enable Metrics/MethodLength
|
180
225
|
end
|
226
|
+
# rubocop:enable Metrics/ClassLength
|
227
|
+
# rubocop:enable Style/ClassVars
|
@@ -0,0 +1,63 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'singleton'
|
4
|
+
|
5
|
+
class ProjectData
|
6
|
+
include Singleton
|
7
|
+
attr_reader :default, :param
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
reset
|
11
|
+
end
|
12
|
+
|
13
|
+
def reset
|
14
|
+
@default = { inputbasedir: FileUtils.pwd,
|
15
|
+
stages: { d: true, b: true, f: true, i: true, s: true, t: true },
|
16
|
+
threshold: 0.5,
|
17
|
+
outputdir: 'output',
|
18
|
+
weights: '1, 1, 1' }
|
19
|
+
@param = {}
|
20
|
+
end
|
21
|
+
|
22
|
+
def get(key)
|
23
|
+
return @param[key] unless @param[key].nil?
|
24
|
+
|
25
|
+
@default[key]
|
26
|
+
end
|
27
|
+
|
28
|
+
def set(key, value)
|
29
|
+
@param[key] = value
|
30
|
+
end
|
31
|
+
|
32
|
+
##
|
33
|
+
# Open new project
|
34
|
+
# * setting new params and
|
35
|
+
# * creating output files
|
36
|
+
# IMPORTANT: We need at least these values
|
37
|
+
# * process_file
|
38
|
+
# * inputdirs
|
39
|
+
# rubocop:disable Metrics/MethodLength
|
40
|
+
# rubocop:disable Metrics/AbcSize
|
41
|
+
def open
|
42
|
+
ext = File.extname(@param[:process_file]) || '.haml'
|
43
|
+
@param[:projectname] = @param[:projectname] ||
|
44
|
+
File.basename(@param[:process_file], ext)
|
45
|
+
|
46
|
+
@param[:logname] = "#{@param[:projectname]}-log.txt"
|
47
|
+
@param[:outputname] = "#{@param[:projectname]}-gift.txt"
|
48
|
+
@param[:lessonname] = "#{@param[:projectname]}-doc.txt"
|
49
|
+
@param[:yamlname] = "#{@param[:projectname]}.yaml"
|
50
|
+
@param[:moodlename] = "#{@param[:projectname]}-moodle.xml"
|
51
|
+
|
52
|
+
outputdir = get(:outputdir)
|
53
|
+
@param[:logpath] = File.join(outputdir, get(:logname))
|
54
|
+
@param[:outputpath] = File.join(outputdir, get(:outputname))
|
55
|
+
@param[:lessonpath] = File.join(outputdir, get(:lessonname))
|
56
|
+
@param[:yamlpath] = File.join(outputdir, get(:yamlname))
|
57
|
+
@param[:moodlepath] = File.join(outputdir, get(:moodlename))
|
58
|
+
|
59
|
+
Dir.mkdir(outputdir) unless Dir.exist?(outputdir)
|
60
|
+
end
|
61
|
+
# rubocop:enable Metrics/MethodLength
|
62
|
+
# rubocop:enable Metrics/AbcSize
|
63
|
+
end
|
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
@@ -1,22 +1,14 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require_relative '../loader/image_url_loader'
|
4
|
-
require_relative '../project'
|
5
|
-
require_relative '../logger'
|
6
4
|
|
7
|
-
##
|
8
|
-
# World data
|
9
5
|
class World
|
10
6
|
attr_reader :concepts, :filenames, :contexts, :image_urls
|
11
7
|
|
12
|
-
|
13
|
-
# Initialize World object
|
14
|
-
# @param concepts (Array)
|
15
|
-
# @param show_progress (Boolean)
|
16
|
-
def initialize(concepts, show_progress = true)
|
8
|
+
def initialize(concepts, internet = true)
|
17
9
|
find_neighbors_for_every_concept(concepts)
|
18
10
|
@concepts, @filenames, @contexts = get_lists_from(concepts)
|
19
|
-
@image_urls = find_url_images_from_internet(
|
11
|
+
@image_urls = find_url_images_from_internet(internet)
|
20
12
|
end
|
21
13
|
|
22
14
|
##
|
@@ -55,11 +47,11 @@ class World
|
|
55
47
|
|
56
48
|
# rubocop:disable Metrics/MethodLength
|
57
49
|
# rubocop:disable Metrics/AbcSize
|
58
|
-
|
59
|
-
|
60
|
-
|
50
|
+
# rubocop:disable Metrics/CyclomaticComplexity
|
51
|
+
# rubocop:disable Metrics/PerceivedComplexity
|
52
|
+
def find_url_images_from_internet(internet)
|
53
|
+
return {} unless internet
|
61
54
|
|
62
|
-
Logger.verbose "\n[INFO] Loading data from Internet" if show_progress
|
63
55
|
threads = []
|
64
56
|
searchs = []
|
65
57
|
urls = {}
|
@@ -67,13 +59,13 @@ class World
|
|
67
59
|
@concepts&.each_key { |key| searchs << key }
|
68
60
|
@contexts.each { |filter| searchs << filter.join(' ').to_s }
|
69
61
|
searchs.each do |search|
|
70
|
-
print('.') if show_progress
|
71
62
|
threads << Thread.new { urls[search] = ImageUrlLoader.load(search) }
|
72
63
|
end
|
73
64
|
threads.each(&:join) # wait for all threads to finish
|
74
|
-
print("\n") if show_progress
|
75
65
|
urls
|
76
66
|
end
|
77
67
|
# rubocop:enable Metrics/MethodLength
|
78
68
|
# rubocop:enable Metrics/AbcSize
|
69
|
+
# rubocop:enable Metrics/CyclomaticComplexity
|
70
|
+
# rubocop:enable Metrics/PerceivedComplexity
|
79
71
|
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,11 @@ 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
|
-
|
41
|
+
e = concept_ai.concept.texts.size
|
42
|
+
e += concept_ai.concept.images.size
|
43
|
+
concept_ai.concept.tables.each { |t| e += t.fields.size * t.rows.size }
|
38
44
|
|
39
45
|
sd = sb = sf = 0
|
40
46
|
si = ss = st = 0
|
@@ -48,7 +54,7 @@ class ConceptAIDisplayer
|
|
48
54
|
|
49
55
|
factor = 'Unkown'
|
50
56
|
factor = (t.to_f / e).round(2).to_s unless e.zero?
|
51
|
-
screen_table.add_row [Rainbow(concept_ai.name(:screen)).green.bright,
|
57
|
+
screen_table.add_row [Rainbow(concept_ai.concept.name(:screen)).green.bright,
|
52
58
|
t, e, factor, sd, sb, sf, si, ss, st]
|
53
59
|
|
54
60
|
total[:q] += t
|
@@ -75,9 +81,15 @@ class ConceptAIDisplayer
|
|
75
81
|
total[:sd], total[:sb], total[:sf],
|
76
82
|
total[:si], total[:ss], total[:st]]
|
77
83
|
export_notes
|
78
|
-
Logger.
|
84
|
+
Logger.verboseln "#{screen_table}\n"
|
79
85
|
end
|
86
|
+
# rubocop:enable Metrics/MethodLength
|
87
|
+
# rubocop:enable Metrics/AbcSize
|
88
|
+
# rubocop:enable Metrics/CyclomaticComplexity
|
89
|
+
# rubocop:enable Metrics/PerceivedComplexity
|
80
90
|
|
91
|
+
# rubocop:disable Metrics/MethodLength
|
92
|
+
# rubocop:disable Metrics/AbcSize
|
81
93
|
private_class_method def self.export_excluded_questions(screen_table, concepts_ai)
|
82
94
|
# Create table BODY
|
83
95
|
total = {}
|
@@ -86,7 +98,7 @@ class ConceptAIDisplayer
|
|
86
98
|
total[:si] = total[:ss] = total[:st] = 0
|
87
99
|
|
88
100
|
concepts_ai.each do |concept_ai|
|
89
|
-
next unless concept_ai.process?
|
101
|
+
next unless concept_ai.concept.process?
|
90
102
|
|
91
103
|
sd = concept_ai.excluded_questions[:d].size
|
92
104
|
sb = concept_ai.excluded_questions[:b].size
|
@@ -111,22 +123,12 @@ class ConceptAIDisplayer
|
|
111
123
|
total[:sf], total[:si],
|
112
124
|
total[:ss], total[:st]]
|
113
125
|
end
|
126
|
+
# rubocop:enable Metrics/MethodLength
|
127
|
+
# rubocop:enable Metrics/AbcSize
|
114
128
|
|
115
129
|
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"
|
130
|
+
exclude_questions = Application.instance.config['questions']['exclude'].to_s
|
131
|
+
renderer = ERB.new(File.read(File.join(File.dirname(__FILE__), 'concept_ai_displayer.erb')))
|
132
|
+
Logger.verboseln renderer.result(binding)
|
131
133
|
end
|
132
134
|
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,16 +7,19 @@ 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
|
-
|
17
|
-
|
15
|
+
##
|
16
|
+
# Export 1 concept_ai from project
|
17
|
+
# @param concept_ai (ConceptAI)
|
18
|
+
# @param file (File)
|
19
|
+
private_class_method def self.export(concept_ai, file)
|
20
|
+
return unless concept_ai.concept.process?
|
18
21
|
|
19
|
-
file
|
20
|
-
file.write head(concept_ai.name)
|
22
|
+
file.write head(concept_ai.concept.name)
|
21
23
|
Application.instance.config['questions']['stages'].each do |stage|
|
22
24
|
concept_ai.questions[stage].each do |question|
|
23
25
|
file.write(QuestionGiftFormatter.to_s(question))
|
@@ -25,7 +27,11 @@ module ConceptAIGiftExporter
|
|
25
27
|
end
|
26
28
|
end
|
27
29
|
|
28
|
-
|
30
|
+
##
|
31
|
+
# Convert Concept name into gift format head
|
32
|
+
# @param name (String)
|
33
|
+
# @return String
|
34
|
+
private_class_method def self.head(name)
|
29
35
|
s = "\n"
|
30
36
|
s += '// ' + '=' * 50 + "\n"
|
31
37
|
s += "// Concept name: #{name}\n"
|
@@ -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
|