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.
Files changed (64) hide show
  1. checksums.yaml +4 -4
  2. data/{LICENSE.txt → LICENSE} +0 -0
  3. data/README.md +1 -1
  4. data/bin/asker +1 -1
  5. data/lib/asker/ai/ai.rb +6 -3
  6. data/lib/asker/ai/ai_calculate.rb +20 -6
  7. data/lib/asker/ai/concept_ai.rb +11 -2
  8. data/lib/asker/ai/question.rb +28 -6
  9. data/lib/asker/ai/stages/base_stage.rb +45 -6
  10. data/lib/asker/ai/stages/stage_b.rb +100 -50
  11. data/lib/asker/ai/stages/stage_d.rb +75 -90
  12. data/lib/asker/ai/stages/stage_f.rb +64 -36
  13. data/lib/asker/ai/stages/stage_i.rb +79 -92
  14. data/lib/asker/ai/stages/stage_s.rb +41 -36
  15. data/lib/asker/ai/stages/stage_t.rb +114 -73
  16. data/lib/asker/application.rb +8 -7
  17. data/lib/asker/checker.rb +6 -8
  18. data/lib/asker/cli.rb +27 -9
  19. data/lib/asker/data/code.rb +4 -1
  20. data/lib/asker/data/concept.rb +67 -21
  21. data/lib/asker/data/table.rb +2 -0
  22. data/lib/asker/data/template.rb +3 -1
  23. data/lib/asker/data/world.rb +7 -4
  24. data/lib/asker/displayer/code_displayer.rb +7 -0
  25. data/lib/asker/displayer/concept_ai_displayer.erb +10 -0
  26. data/lib/asker/displayer/concept_ai_displayer.rb +23 -22
  27. data/lib/asker/displayer/concept_displayer.rb +9 -4
  28. data/lib/asker/displayer/stats_displayer.rb +8 -0
  29. data/lib/asker/exporter/concept_ai_gift_exporter.rb +7 -11
  30. data/lib/asker/exporter/concept_ai_moodle_exporter.rb +44 -0
  31. data/lib/asker/exporter/concept_ai_yaml_exporter.rb +6 -3
  32. data/lib/asker/exporter/concept_doc_exporter.rb +14 -1
  33. data/lib/asker/exporter/data_gift_exporter.rb +29 -0
  34. data/lib/asker/exporter/output_file_exporter.rb +9 -6
  35. data/lib/asker/files/{config.ini → asker.ini} +14 -4
  36. data/lib/asker/files/language/du/connectors.yaml +81 -0
  37. data/lib/asker/files/language/du/mistakes.yaml +82 -0
  38. data/lib/asker/files/language/du/templates.yaml +28 -49
  39. data/lib/asker/files/language/en/templates.yaml +19 -19
  40. data/lib/asker/files/language/es/mistakes.yaml +9 -7
  41. data/lib/asker/files/language/es/templates.yaml +19 -19
  42. data/lib/asker/files/language/fr/connectors.yaml +68 -84
  43. data/lib/asker/files/language/fr/templates.yaml +22 -22
  44. data/lib/asker/formatter/concept_string_formatter.rb +7 -4
  45. data/lib/asker/formatter/moodle/matching.erb +38 -0
  46. data/lib/asker/formatter/moodle/multichoice.erb +49 -0
  47. data/lib/asker/formatter/moodle/shortanswer.erb +30 -0
  48. data/lib/asker/formatter/moodle/truefalse.erb +47 -0
  49. data/lib/asker/formatter/question_gift_formatter.rb +21 -19
  50. data/lib/asker/formatter/question_moodle_formatter.rb +27 -0
  51. data/lib/asker/lang/lang_factory.rb +7 -1
  52. data/lib/asker/loader/code_loader.rb +1 -1
  53. data/lib/asker/loader/content_loader.rb +7 -7
  54. data/lib/asker/loader/directory_loader.rb +3 -3
  55. data/lib/asker/loader/embedded_file.rb +42 -0
  56. data/lib/asker/loader/file_loader.rb +1 -1
  57. data/lib/asker/loader/image_url_loader.rb +4 -3
  58. data/lib/asker/loader/input_loader.rb +1 -1
  59. data/lib/asker/loader/project_loader.rb +14 -5
  60. data/lib/asker/logger.rb +29 -4
  61. data/lib/asker/project.rb +14 -79
  62. data/lib/asker/skeleton.rb +3 -2
  63. data/lib/asker.rb +37 -9
  64. metadata +19 -22
@@ -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, :lang, :context
16
- attr_reader :names, :type, :filename
17
- attr_reader :data
18
- attr_accessor :process
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 # Concept counter
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] = [] # TODO: By now, We'll treat images separated from texts
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
- read_data_from_xml(xml_data)
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 method_missing(method)
122
- @data[method]
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] <#{i.name}> unkown XML attribute for concept #{name}"
141
- Logger.verbose Rainbow(text).color(:red)
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
- raise '[Error] tags label empty!'
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 'textfile_path'
173
- @data[:textfile_paths] << value.text.strip
174
- else
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
@@ -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(',')
@@ -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
@@ -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
- param = Application.instance.config['global']['internet'] || 'yes'
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
- print('.') if show_progress
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
- print("\n") if show_progress
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 = ['Concept', 'Questions', 'Entries', 'xFactor']
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.verbose "#{screen_table}\n"
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
- Logger.verbose "\n[INFO] Showing CONCEPT statistics\n"
117
- Logger.verbose ' * Exclude questions: ' +
118
- Application.instance.config['questions']['exclude'].to_s
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.verbose msg
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.verbose s
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.verbose ConceptStringFormatter.to_s(c) if c.process?
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 project (Project)
12
- def self.export_all(concepts_ai, project)
13
- concepts_ai.each { |concept_ai| export(concept_ai, project) }
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 project (Project)
20
- # rubocop:disable Metrics/AbcSize
21
- private_class_method def self.export(concept_ai, project)
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 = project.get(:outputfile)
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
- project.get(:yamlfile).write(output.to_yaml)
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
- def self.export_all(concepts, file)
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 'concept_ai_gift_exporter'
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
- ConceptAIGiftExporter.export_all(data[:concepts_ai], project)
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
- CodeGiftExporter.export_all(data[:codes_ai], project.get(:outputfile))
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 = no
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