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
@@ -12,12 +12,11 @@ module ConceptStringFormatter
12
12
  def self.to_s(concept)
13
13
  tt = Terminal::Table.new
14
14
  get_tt_rows(concept).each { |row| tt.add_row row }
15
- "#{tt}\n"
15
+ tt.to_s
16
16
  end
17
17
 
18
18
  # rubocop:disable Metrics/AbcSize
19
19
  # rubocop:disable Metrics/MethodLength
20
- # rubocop:disable Layout/LineLength
21
20
  private_class_method def self.get_tt_rows(concept)
22
21
  rows = []
23
22
  rows << [Rainbow(concept.id.to_s).bright,
@@ -31,13 +30,17 @@ module ConceptStringFormatter
31
30
  rows << [Rainbow('Referenced by').blue,
32
31
  concept.referenced_by.join(', ')[0...70].to_s]
33
32
  rows << format_texts(concept)
34
- rows << [Rainbow('.def(images)').blue, concept.images.size.to_s] unless concept.images.size.zero?
33
+ unless concept.images.size.zero?
34
+ counter1 = 0
35
+ concept.images.each { |image| counter1 += 1 if image[:file] == :none }
36
+ counter2 = concept.images.size - counter1
37
+ rows << [Rainbow('.def(images)').blue, "#{counter1} text / #{counter2} file"]
38
+ end
35
39
  rows << format_tables(concept) unless concept.tables.count.zero?
36
40
  rows << format_neighbors(concept)
37
41
  end
38
42
  # rubocop:enable Metrics/AbcSize
39
43
  # rubocop:enable Metrics/MethodLength
40
- # rubocop:enable Layout/LineLength
41
44
 
42
45
  private_class_method def self.format_texts(concept)
43
46
  list = []
@@ -0,0 +1,38 @@
1
+ <% unless question.comment.nil? || question.comment.empty? %>
2
+ <!-- question: <%= question.comment %> -->
3
+ <% end %>
4
+ <question type="matching">
5
+ <name>
6
+ <text><%= question.name %></text>
7
+ </name>
8
+ <questiontext format="html">
9
+ <text><![CDATA[<%= question.text %>]]></text>
10
+ <% unless question.encode == :none %>
11
+ <%= question.encode %>
12
+ <% end %>
13
+ </questiontext>
14
+ <generalfeedback format="html">
15
+ <text><![CDATA[<%= question.feedback.to_s %>]]></text>
16
+ </generalfeedback>
17
+ <defaultgrade>1.0000000</defaultgrade>
18
+ <penalty>0.3333333</penalty>
19
+ <hidden>0</hidden>
20
+ <shuffleanswers>true</shuffleanswers>
21
+ <correctfeedback format="html">
22
+ <text></text>
23
+ </correctfeedback>
24
+ <partiallycorrectfeedback format="html">
25
+ <text></text>
26
+ </partiallycorrectfeedback>
27
+ <incorrectfeedback format="html">
28
+ <text></text>
29
+ </incorrectfeedback>
30
+ <% question.matching.each do |i, j| %>
31
+ <subquestion format="html">
32
+ <text><![CDATA[<%= i %>]]></text>
33
+ <answer>
34
+ <text><![CDATA[<%= j %>]]></text>
35
+ </answer>
36
+ </subquestion>
37
+ <% end %>
38
+ </question>
@@ -0,0 +1,49 @@
1
+ <% unless question.comment.nil? || question.comment.empty? %>
2
+ <!-- question: <%= question.comment %> -->
3
+ <% end %>
4
+ <question type="multichoice">
5
+ <name>
6
+ <text><%= question.name %></text>
7
+ </name>
8
+ <questiontext format="html">
9
+ <text><![CDATA[<%= question.text %>]]></text>
10
+ <% unless question.encode == :none %>
11
+ <%= question.encode %>
12
+ <% end %>
13
+ </questiontext>
14
+ <generalfeedback format="html">
15
+ <text><![CDATA[<%= question.feedback.to_s %>]]></text>
16
+ </generalfeedback>
17
+ <defaultgrade>1.0000000</defaultgrade>
18
+ <penalty>0.3333333</penalty>
19
+ <hidden>0</hidden>
20
+ <single>true</single>
21
+ <shuffleanswers>true</shuffleanswers>
22
+ <answernumbering>abc</answernumbering>
23
+ <correctfeedback format="html">
24
+ <text></text>
25
+ </correctfeedback>
26
+ <partiallycorrectfeedback format="html">
27
+ <text></text>
28
+ </partiallycorrectfeedback>
29
+ <incorrectfeedback format="html">
30
+ <text></text>
31
+ </incorrectfeedback>
32
+ <answer fraction="100" format="html">
33
+ <text><%= question.good %></text>
34
+ <feedback format="html">
35
+ <text></text>
36
+ </feedback>
37
+ </answer>
38
+ <%
39
+ question.bads.shuffle! if question.shuffle?
40
+ question.bads.each do |i|
41
+ %>
42
+ <answer fraction="<%= penalty %>" format="html">
43
+ <text><![CDATA[<%= i %>]]></text>
44
+ <feedback format="html">
45
+ <text></text>
46
+ </feedback>
47
+ </answer>
48
+ <% end %>
49
+ </question>
@@ -0,0 +1,30 @@
1
+ <% unless question.comment.nil? || question.comment.empty? %>
2
+ <!-- question: <%= question.comment %> -->
3
+ <% end %>
4
+ <question type="shortanswer">
5
+ <name>
6
+ <text><%= question.name %></text>
7
+ </name>
8
+ <questiontext format="html">
9
+ <text><![CDATA[<%= question.text %>]]></text>
10
+ <% unless question.encode == :none %>
11
+ <%= question.encode %>
12
+ <% end %>
13
+ </questiontext>
14
+ <generalfeedback format="html">
15
+ <text><![CDATA[<%= question.feedback.to_s %>]]></text>
16
+ </generalfeedback>
17
+ <defaultgrade>1.0000000</defaultgrade>
18
+ <penalty>0.3333333</penalty>
19
+ <hidden>0</hidden>
20
+ <usecase>0</usecase>
21
+ <% question.shorts.uniq! %>
22
+ <% question.shorts.each do |i| %>
23
+ <answer fraction="100" format="moodle_auto_format">
24
+ <text><![CDATA[<%= i %>]]></text>
25
+ <feedback format="html">
26
+ <text></text>
27
+ </feedback>
28
+ </answer>
29
+ <% end %>
30
+ </question>
@@ -0,0 +1,47 @@
1
+ <% unless question.comment.nil? || question.comment.empty? %>
2
+ <!-- question: <%= question.comment %> -->
3
+ <% end %>
4
+ <question type="truefalse">
5
+ <name>
6
+ <text><%= question.name %></text>
7
+ </name>
8
+ <questiontext format="html">
9
+ <text><![CDATA[<%= question.text %>]]></text>
10
+ <% unless question.encode == :none %>
11
+ <%= question.encode %>
12
+ <% end %>
13
+ </questiontext>
14
+ <generalfeedback format="html">
15
+ <text><![CDATA[<%= question.feedback.to_s %>]]></text>
16
+ </generalfeedback>
17
+ <defaultgrade>1.0000000</defaultgrade>
18
+ <penalty>1.0000000</penalty>
19
+ <hidden>0</hidden>
20
+ <% if question.good == 'TRUE' %>
21
+ <answer fraction="100" format="moodle_auto_format">
22
+ <text>true</text>
23
+ <feedback format="html">
24
+ <text></text>
25
+ </feedback>
26
+ </answer>
27
+ <answer fraction="0" format="moodle_auto_format">
28
+ <text>false</text>
29
+ <feedback format="html">
30
+ <text></text>
31
+ </feedback>
32
+ </answer>
33
+ <% else %>
34
+ <answer fraction="0" format="moodle_auto_format">
35
+ <text>true</text>
36
+ <feedback format="html">
37
+ <text></text>
38
+ </feedback>
39
+ </answer>
40
+ <answer fraction="100" format="moodle_auto_format">
41
+ <text>false</text>
42
+ <feedback format="html">
43
+ <text></text>
44
+ </feedback>
45
+ </answer>
46
+ <% end %>
47
+ </question>
@@ -7,50 +7,52 @@ module QuestionGiftFormatter
7
7
  # @param question (Question)
8
8
  # @return String
9
9
  def self.to_s(question)
10
- @question = question
10
+ s = ''
11
+ return s unless question.encode == :none
12
+
11
13
  # Return question using gift format
12
- cond = @question.comment.nil? && @question.comment.empty?
13
- s = "// #{@question.comment}\n" unless cond
14
- s << "::#{@question.name}::[html]#{sanitize(@question.text)}\n"
14
+ cond = question.comment.nil? || question.comment.empty?
15
+ s = "// #{question.comment}\n" unless cond
16
+ s << "::#{question.name}::[html]#{sanitize(question.text)}\n"
15
17
 
16
- case @question.type
18
+ case question.type
17
19
  when :choice
18
20
  s += "{\n"
19
- a = [" =#{sanitize(@question.good)}\n"]
21
+ a = [" =#{sanitize(question.good)}\n"]
20
22
  penalties = ['', '%-50%', '%-33.33333%', '%-25%', '%-20%']
21
- penalty = penalties[@question.bads.size]
23
+ penalty = penalties[question.bads.size]
22
24
 
23
- @question.bads.each { |i| a << (" ~#{penalty}" + sanitize(i) + "\n") }
24
- a.shuffle! if @question.shuffle?
25
+ question.bads.each { |i| a << (" ~#{penalty}" + sanitize(i) + "\n") }
26
+ a.shuffle! if question.shuffle?
25
27
  a.each do |i|
26
28
  text = i
27
29
  text = i[0, 220] + '...(ERROR: text too long)' if text.size > 255
28
30
  s << text
29
31
  end
30
- s += " #####{sanitize(@question.feedback.to_s)}\n" if @question.feedback
32
+ s += " #####{sanitize(question.feedback.to_s)}\n" if question.feedback
31
33
  s += "}\n\n"
32
34
  when :boolean
33
- s << "{#{@question.good}#####{sanitize(@question.feedback.to_s)}}\n\n"
35
+ s << "{#{question.good}#####{sanitize(question.feedback.to_s)}}\n\n"
34
36
  when :match
35
37
  s << "{\n"
36
38
  a = []
37
- @question.matching.each do |i, j|
39
+ question.matching.each do |i, j|
38
40
  i = i[0, 220] + '...(ERROR: text too long)' if i.size > 255
39
41
  j = j[0, 220] + '...(ERROR: text too long)' if j.size > 255
40
42
  a << " =#{sanitize(i)} -> #{sanitize(j)}\n"
41
43
  end
42
- a.shuffle! if @question.shuffle?
44
+ a.shuffle! if question.shuffle?
43
45
  a.each { |i| s << i }
44
46
  s << "}\n\n"
45
47
  when :short
46
48
  s << "{\n"
47
- @question.shorts.uniq!
48
- @question.shorts.each do |i|
49
+ question.shorts.uniq!
50
+ question.shorts.each do |i|
49
51
  text = i
50
52
  text = i[0, 220] + '...(ERROR: too long)' if text.size > 255
51
53
  s << " =%100%#{text}#\n"
52
54
  end
53
- s << " #####{sanitize(@question.feedback.to_s)}\n" if @question.feedback
55
+ s << " #####{sanitize(question.feedback.to_s)}\n" if question.feedback
54
56
  s << "}\n\n"
55
57
  end
56
58
  s
@@ -62,10 +64,10 @@ module QuestionGiftFormatter
62
64
  # @return String
63
65
  def self.sanitize(input = '')
64
66
  output = input.dup
65
- output.gsub!("#", "\\#")
67
+ output.gsub!('#', '\#')
66
68
  output.gsub!("\n", " ")
67
- #output.gsub!(":", "\\:")
68
- output.gsub!("=", "\\=")
69
+ output.gsub!(':', '\:')
70
+ output.gsub!('=', '\=')
69
71
  output.gsub!("\{", "\\{")
70
72
  output.gsub!("\}", "\\}")
71
73
  output
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: false
2
+
3
+ require 'erb'
4
+
5
+ # Transform Questions into Gift format
6
+ module QuestionMoodleFormatter
7
+ ##
8
+ # Convert question object into gift formatted string
9
+ # @param question (Question)
10
+ # @return String
11
+ def self.to_s(question)
12
+ case question.type
13
+ when :choice
14
+ penalties = ['', '-50', '-33.33333', '-25', '-20']
15
+ penalty = penalties[question.bads.size]
16
+ template = File.read(File.join(File.dirname(__FILE__), 'moodle', 'multichoice.erb'))
17
+ when :boolean
18
+ template = File.read(File.join(File.dirname(__FILE__), 'moodle', 'truefalse.erb'))
19
+ when :match
20
+ template = File.read(File.join(File.dirname(__FILE__), 'moodle', 'matching.erb'))
21
+ when :short
22
+ template = File.read(File.join(File.dirname(__FILE__), 'moodle', 'shortanswer.erb'))
23
+ end
24
+ renderer = ERB.new(template)
25
+ renderer.result(binding)
26
+ end
27
+ end
@@ -29,7 +29,13 @@ class LangFactory
29
29
  # Return Lang object associated to code
30
30
  # @param code (String)
31
31
  def get(code)
32
- @langs[code]
32
+ return @langs[code] unless @langs[code].nil?
33
+
34
+ puts Rainbow("[ERROR] Unkown Lang code: #{code}").bright
35
+ puts Rainbow(' => Change input file code lang').bright
36
+ puts Rainbow(' => Revise configuration from config.ini').bright
37
+ puts Rainbow(' => Revise template files').bright
38
+ exit 1
33
39
  end
34
40
 
35
41
  ##
@@ -45,7 +45,7 @@ module CodeLoader
45
45
  features << i.text
46
46
  else
47
47
  msg = Rainbow("[ERROR] features/#{i.name} from #{filename}").color(:red)
48
- Logger.verbose msg
48
+ Logger.verboseln msg
49
49
  end
50
50
  end
51
51
  features
@@ -13,6 +13,8 @@ module ContentLoader
13
13
  # Load XML content into Asker data objects
14
14
  # @param filepath (String) File path
15
15
  # @param content (String) XML plane text content
16
+ # rubocop:disable Metrics/MethodLength
17
+ # rubocop:disable Metrics/AbcSize
16
18
  def self.load(filepath, content)
17
19
  concepts = []
18
20
  codes = []
@@ -37,6 +39,8 @@ module ContentLoader
37
39
 
38
40
  { concepts: concepts, codes: codes }
39
41
  end
42
+ # rubocop:enable Metrics/MethodLength
43
+ # rubocop:enable Metrics/AbcSize
40
44
 
41
45
  ##
42
46
  # Read lang attr from input XML data
@@ -71,9 +75,7 @@ module ContentLoader
71
75
  private_class_method def self.read_concept(xmldata, filepath, lang, context)
72
76
  project = Project.instance
73
77
  c = Concept.new(xmldata, filepath, lang, context)
74
- if [ File.basename(filepath), :default ].include? project.process_file
75
- c.process = true
76
- end
78
+ c.process = true if [File.basename(filepath), :default].include? project.get(:process_file)
77
79
  c
78
80
  end
79
81
 
@@ -84,9 +86,7 @@ module ContentLoader
84
86
  private_class_method def self.read_code(xmldata, filepath)
85
87
  project = Project.instance
86
88
  c = CodeLoader.load(xmldata, filepath)
87
- if [ File.basename(filepath), :default ].include? project.process_file
88
- c.process = true
89
- end
89
+ c.process = true if [File.basename(filepath), :default].include? project.get(:process_file)
90
90
  c
91
91
  end
92
92
 
@@ -96,7 +96,7 @@ module ContentLoader
96
96
  # @param content (String)
97
97
  private_class_method def self.raise_error_with(filepath, content)
98
98
  msg = Rainbow("[ERROR] ContentLoader: Format error in #{filepath}").red.bright
99
- Logger.verbose msg
99
+ Logger.verboseln msg
100
100
  f = File.open('output/error.xml', 'w')
101
101
  f.write(content)
102
102
  f.close
@@ -13,7 +13,7 @@ module DirectoryLoader
13
13
  files = (Dir.new(dirname).entries - ['.', '..']).sort
14
14
  # Accept only HAML or XML files
15
15
  accepted = files.select { |f| %w[.xml .haml].include? File.extname(f) }
16
- Logger.verbose " * Input directory = #{Rainbow(dirname).bright}"
16
+ Logger.verboseln " * Input directory = #{Rainbow(dirname).bright}"
17
17
  DirectoryLoader.load_files(accepted, dirname)
18
18
  end
19
19
 
@@ -49,9 +49,9 @@ module DirectoryLoader
49
49
  # @param last (Boolean) True if it is the last filename
50
50
  def self.load_file(filepath, last = false)
51
51
  if last
52
- Logger.verbose " └── Input file = #{Rainbow(filepath).bright}"
52
+ Logger.verboseln " └── Input file = #{Rainbow(filepath).bright}"
53
53
  else
54
- Logger.verbose " ├── Input file = #{Rainbow(filepath).bright}"
54
+ Logger.verboseln " ├── Input file = #{Rainbow(filepath).bright}"
55
55
  end
56
56
  FileLoader.load(filepath)
57
57
  end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'base64'
4
+
5
+ # Methods to load embedded files defined into asker input data file
6
+ # Example:
7
+ # * def line with :type = :image_url used to link external file as https://..."
8
+ # * def line with :type = :file used to load local file as image.png or file.txt"
9
+ module EmbeddedFile
10
+ ##
11
+ # @param value (String)
12
+ # @param localdir (String) Input file base folder
13
+ # @return Hash
14
+ # rubocop:disable Metrics/MethodLength
15
+ # rubocop:disable Metrics/AbcSize
16
+ def self.load(value, localdir)
17
+ # When filename is an URL
18
+ if value.start_with?('https://') || value.start_with?('http://')
19
+ return { text: "<img src=\"#{value}\" alt=\"image\" width=\"400\" height=\"300\">", file: :none }
20
+ end
21
+
22
+ filepath = File.join(localdir, value)
23
+ unless File.exist?(filepath)
24
+ # When filename is unkown!
25
+ Logger.verbose Rainbow("[ERROR] Unknown file! #{filepath}").red.bright
26
+ exit 1
27
+ end
28
+ # When filename is PNG, JPG o JPEG
29
+ if ['.png', '.jpg', '.jpeg'].include? File.extname(filepath)
30
+ # converts image into base64 strings
31
+ text = '<img src="@@PLUGINFILE@@/' + File.basename(filepath) \
32
+ + '" alt="imagen" class="img-responsive atto_image_button_text-bottom">'
33
+ data = '<file name="' + File.basename(filepath) + '" path="/" encoding="base64">' \
34
+ + Base64.strict_encode64(File.open(filepath, 'rb').read) + '</file>'
35
+ return { text: text, file: data }
36
+ end
37
+ # Suposse that filename is TXT file
38
+ return { text: "<pre>#{File.read(filepath)}</pre>", file: :none } if File.exist?(filepath)
39
+ end
40
+ # rubocop:enable Metrics/MethodLength
41
+ # rubocop:enable Metrics/AbcSize
42
+ end
@@ -16,7 +16,7 @@ module FileLoader
16
16
  file_content = File.read(filename)
17
17
  else
18
18
  msg = "[ERROR] FileLoader: Format error #{filename}"
19
- Logger.verbose msg
19
+ Logger.verboseln msg
20
20
  raise msg
21
21
  end
22
22
  ContentLoader.load(filename, file_content)
@@ -45,11 +45,12 @@ module ImageUrlLoader
45
45
  end
46
46
 
47
47
  def self.sanitize_string(input)
48
+ text = input.dup
48
49
  r = [ ['á', 'a'], ['é', 'e'], ['í', 'i'], ['ó', 'o'], ['ú', 'u'], ['ñ', 'n'], ['Á', 'A'], ['É', 'E'], ['Í', 'I'], ['Ó', 'O'], ['Ú', 'U'], ['Ñ', 'N']]
49
- r.each { |item| input.gsub!(item[0], item[1]) }
50
+ r.each { |item| text.gsub!(item[0], item[1]) }
50
51
  r = ['-', '_', ',', '"']
51
- r.each { |item| input.gsub!(item, ' ') }
52
- input.split(' ')
52
+ r.each { |item| text.gsub!(item, ' ') }
53
+ text.split(' ')
53
54
  end
54
55
 
55
56
  def self.sanitize_array(input)
@@ -13,7 +13,7 @@ module InputLoader
13
13
  def self.load(inputdirs)
14
14
  data = { concepts: [], codes: [], world: nil,
15
15
  concepts_ai: [], codes_ai: [] }
16
- Logger.verbose "\n[INFO] Loading input data"
16
+ Logger.verboseln "\n[INFO] Loading input data"
17
17
  inputdirs.each do |dirname|
18
18
  temp = DirectoryLoader.load(dirname)
19
19
  data[:concepts] += temp[:concepts]
@@ -14,22 +14,26 @@ module ProjectLoader
14
14
  ##
15
15
  # Load project from args
16
16
  # @param args (String or Hash)
17
+ # rubocop:disable Metrics/MethodLength
17
18
  def self.load(args)
18
19
  project = Project.instance
19
20
 
20
21
  if args.class == Hash
21
22
  project.param.merge!(args)
23
+ project.open
22
24
  return project
23
25
  elsif args.class == String
24
26
  ProjectLoader.load_from_string(args)
27
+ project.open
25
28
  return project
26
29
  end
27
30
 
28
31
  msg = '[ERROR] ProjectLoader:'
29
32
  msg += "Configuration params format is <#{pArgs.class}>!"
30
- Logger.verbose Rainbow(msg).red
33
+ Logger.verboseln Rainbow(msg).red
31
34
  raise msg
32
35
  end
36
+ # rubocop:enable Metrics/MethodLength
33
37
 
34
38
  ##
35
39
  # Load project from filepath. Options:
@@ -37,11 +41,13 @@ module ProjectLoader
37
41
  # * XML filepath
38
42
  # * YAML filepath
39
43
  # @param filepath (String)
44
+ # rubocop:disable Metrics/MethodLength
45
+ # rubocop:disable Metrics/AbcSize
40
46
  def self.load_from_string(filepath)
41
47
  project = Project.instance
42
48
  unless File.exist?(filepath)
43
49
  msg = Rainbow("[ERROR] #{filepath} not found!").red.bright
44
- Logger.verbose msg
50
+ Logger.verboseln msg
45
51
  exit 1
46
52
  end
47
53
 
@@ -51,11 +57,13 @@ module ProjectLoader
51
57
  return project
52
58
  elsif File.extname(filepath) == '.yaml'
53
59
  return load_from_yaml(filepath)
54
- else
55
- error_loading(filepath)
56
60
  end
61
+ error_loading(filepath)
57
62
  end
63
+ # rubocop:enable Metrics/MethodLength
64
+ # rubocop:enable Metrics/AbcSize
58
65
 
66
+ # rubocop:disable Security/YAMLLoad
59
67
  def self.load_from_yaml(arg)
60
68
  project = Project.instance
61
69
  project.param.merge!(YAML.load(File.open(arg)))
@@ -63,12 +71,13 @@ module ProjectLoader
63
71
  project.set(:projectdir, File.dirname(arg))
64
72
  project
65
73
  end
74
+ # rubocop:enable Security/YAMLLoad
66
75
 
67
76
  ##
68
77
  # Error found and exit application.
69
78
  def self.error_loading(arg)
70
79
  msg = Rainbow("[ERROR] Loading... #{arg}").red.bright
71
- Logger.verbose msg
80
+ Logger.verboseln msg
72
81
  exit 1
73
82
  end
74
83
  end
data/lib/asker/logger.rb CHANGED
@@ -1,15 +1,21 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'singleton'
3
4
  require_relative 'application'
4
- require_relative 'project'
5
5
 
6
6
  # Display and log project messages
7
- module Logger
7
+ class Logger
8
+ include Singleton
9
+
10
+ def initialize
11
+ @logfile = null
12
+ end
13
+
8
14
  ##
9
15
  # Display and log text
10
16
  def self.verbose(msg)
11
- puts msg if Application.instance.config['global']['verbose'] == 'yes'
12
- Project.instance.get(:logfile)&.write("#{msg}\n")
17
+ print msg if Application.instance.config['global']['verbose'] == 'yes'
18
+ @logfile&.write(msg)
13
19
  end
14
20
 
15
21
  ##
@@ -17,4 +23,23 @@ module Logger
17
23
  def self.verboseln(msg)
18
24
  verbose(msg + "\n")
19
25
  end
26
+
27
+ ##
28
+ # Create or reset logfile
29
+ def self.create(project)
30
+ @logfile = File.open(project.get(:logpath), 'w')
31
+ @logfile.write('=' * 50 + "\n")
32
+ @logfile.write("Created by : #{Application::NAME}")
33
+ @logfile.write(" (version #{Application::VERSION})\n")
34
+ @logfile.write("File : #{project.get(:logname)}\n")
35
+ @logfile.write("Time : #{Time.new}\n")
36
+ @logfile.write("Author : David Vargas Ruiz\n")
37
+ @logfile.write('=' * 50 + "\n\n")
38
+ end
39
+
40
+ ##
41
+ # Close Log file
42
+ def self.close
43
+ @logfile.close
44
+ end
20
45
  end