asker-tool 2.1.7 → 2.2.0

Sign up to get free protection for your applications and to get access to all the features.
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