asker-tool 2.1.3 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +18 -19
- data/bin/asker +2 -1
- data/lib/asker/ai/ai.rb +10 -3
- data/lib/asker/ai/ai_calculate.rb +20 -6
- data/lib/asker/ai/code/base_code_ai.rb +104 -0
- data/lib/asker/{code/ai → ai/code}/code_ai_factory.rb +11 -1
- data/lib/asker/{code/ai → ai/code}/javascript_code_ai.rb +2 -5
- data/lib/asker/ai/code/problem_code_ai.rb +176 -0
- data/lib/asker/{code/ai → ai/code}/python_code_ai.rb +2 -5
- data/lib/asker/{code/ai → ai/code}/ruby_code_ai.rb +14 -7
- data/lib/asker/{code/ai → ai/code}/sql_code_ai.rb +2 -5
- data/lib/asker/ai/concept_ai.rb +12 -2
- data/lib/asker/ai/question.rb +28 -6
- data/lib/asker/ai/stages/base_stage.rb +45 -6
- data/lib/asker/ai/stages/stage_b.rb +100 -50
- data/lib/asker/ai/stages/stage_d.rb +75 -90
- data/lib/asker/ai/stages/stage_f.rb +64 -36
- data/lib/asker/ai/stages/stage_i.rb +79 -92
- data/lib/asker/ai/stages/stage_s.rb +41 -36
- data/lib/asker/ai/stages/stage_t.rb +149 -108
- data/lib/asker/application.rb +24 -7
- data/lib/asker/checker.rb +149 -52
- data/lib/asker/cli.rb +37 -32
- data/lib/asker/data/code.rb +76 -0
- data/lib/asker/data/column.rb +31 -21
- data/lib/asker/data/concept.rb +108 -65
- data/lib/asker/data/data_field.rb +14 -0
- data/lib/asker/data/row.rb +75 -52
- data/lib/asker/data/table.rb +91 -42
- data/lib/asker/data/template.rb +3 -1
- data/lib/asker/data/world.rb +61 -32
- data/lib/asker/{exporter/code_screen_exporter.rb → displayer/code_displayer.rb} +13 -6
- data/lib/asker/displayer/concept_ai_displayer.erb +10 -0
- data/lib/asker/displayer/concept_ai_displayer.rb +133 -0
- data/lib/asker/displayer/concept_displayer.rb +34 -0
- data/lib/asker/displayer/stats_displayer.rb +22 -0
- data/lib/asker/exporter/code_gift_exporter.rb +10 -11
- data/lib/asker/exporter/concept_ai_gift_exporter.rb +21 -13
- data/lib/asker/exporter/concept_ai_moodle_exporter.rb +44 -0
- data/lib/asker/exporter/concept_ai_yaml_exporter.rb +14 -9
- data/lib/asker/exporter/concept_doc_exporter.rb +21 -14
- data/lib/asker/exporter/data_gift_exporter.rb +29 -0
- data/lib/asker/exporter/output_file_exporter.rb +21 -0
- data/lib/asker/files/{config.ini → asker.ini} +48 -1
- data/lib/asker/files/example-concept.haml +24 -8
- 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 +29 -0
- data/lib/asker/files/language/en/connectors.yaml +44 -0
- data/lib/asker/files/language/en/mistakes.yaml +37 -0
- data/lib/asker/files/language/en/templates.yaml +29 -0
- data/lib/asker/files/language/es/connectors.yaml +92 -0
- data/lib/asker/files/language/es/mistakes.yaml +84 -0
- data/lib/asker/files/language/es/templates.yaml +29 -0
- data/lib/asker/files/language/fr/connectors.yaml +76 -0
- data/lib/asker/files/language/fr/mistakes.yaml +82 -0
- data/lib/asker/files/language/fr/templates.yaml +29 -0
- data/lib/asker/files/language/javascript/connectors.yaml +11 -0
- data/lib/asker/files/language/javascript/mistakes.yaml +30 -0
- data/lib/asker/files/language/javascript/templates.yaml +3 -0
- data/lib/asker/files/language/math/connectors.yaml +2 -0
- data/lib/asker/files/language/math/mistakes.yaml +2 -0
- data/lib/asker/files/language/math/templates.yaml +1 -0
- data/lib/asker/files/language/python/connectors.yaml +11 -0
- data/lib/asker/files/language/python/mistakes.yaml +26 -0
- data/lib/asker/files/language/python/templates.yaml +3 -0
- data/lib/asker/files/language/ruby/connectors.yaml +11 -0
- data/lib/asker/files/language/ruby/mistakes.yaml +33 -0
- data/lib/asker/files/language/ruby/templates.yaml +3 -0
- data/lib/asker/files/language/sql/connectors.yaml +6 -0
- data/lib/asker/files/language/sql/mistakes.yaml +11 -0
- data/lib/asker/files/language/sql/templates.yaml +2 -0
- data/lib/asker/formatter/concept_string_formatter.rb +13 -9
- 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.rb +18 -12
- data/lib/asker/lang/lang_factory.rb +32 -5
- data/lib/asker/lang/text_actions.rb +87 -69
- data/lib/asker/loader/code_loader.rb +4 -4
- data/lib/asker/loader/content_loader.rb +16 -12
- data/lib/asker/loader/directory_loader.rb +3 -3
- data/lib/asker/loader/embedded_file.rb +42 -0
- data/lib/asker/loader/file_loader.rb +3 -12
- data/lib/asker/loader/haml_loader.rb +15 -0
- data/lib/asker/loader/image_url_loader.rb +9 -11
- data/lib/asker/loader/input_loader.rb +24 -8
- data/lib/asker/loader/project_loader.rb +42 -30
- data/lib/asker/logger.rb +30 -6
- data/lib/asker/project.rb +28 -117
- data/lib/asker/skeleton.rb +40 -29
- data/lib/asker.rb +68 -79
- metadata +57 -74
- data/docs/changelog/v2.1.md +0 -99
- data/docs/commands.md +0 -12
- data/docs/contributions.md +0 -18
- data/docs/history.md +0 -40
- data/docs/idea.md +0 -44
- data/docs/inputs/README.md +0 -39
- data/docs/inputs/code.md +0 -69
- data/docs/inputs/concepts.md +0 -142
- data/docs/inputs/jedi.md +0 -68
- data/docs/inputs/tables.md +0 -112
- data/docs/inputs/templates.md +0 -87
- data/docs/install/README.md +0 -38
- data/docs/install/manual.md +0 -26
- data/docs/install/scripts.md +0 -38
- data/docs/revise/asker-file.md +0 -41
- data/docs/revise/buenas-practicas/01-convocatoria.md +0 -30
- data/docs/revise/buenas-practicas/02-formulario.md +0 -35
- data/docs/revise/buenas-practicas/03-descripcion.md +0 -63
- data/docs/revise/buenas-practicas/04-resultados.md +0 -17
- data/docs/revise/buenas-practicas/05-reproducir.md +0 -10
- data/docs/revise/ejemplos/01/README.md +0 -27
- data/docs/revise/ejemplos/02/README.md +0 -31
- data/docs/revise/ejemplos/03/README.md +0 -31
- data/docs/revise/ejemplos/04/README.md +0 -37
- data/docs/revise/ejemplos/05/README.md +0 -25
- data/docs/revise/ejemplos/06/README.md +0 -43
- data/docs/revise/ejemplos/README.md +0 -11
- data/docs/revise/projects.md +0 -74
- data/lib/asker/code/ai/base_code_ai.rb +0 -48
- data/lib/asker/code/code.rb +0 -53
- data/lib/asker/exporter/concept_ai_screen_exporter.rb +0 -115
- data/lib/asker/exporter/concept_screen_exporter.rb +0 -25
- data/lib/asker/exporter/main.rb +0 -9
data/lib/asker/lang/lang.rb
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
require 'erb'
|
|
4
4
|
require 'yaml'
|
|
5
5
|
require_relative 'text_actions'
|
|
6
|
+
require_relative '../logger'
|
|
6
7
|
|
|
7
8
|
# Lang#lang
|
|
8
9
|
class Lang
|
|
@@ -22,21 +23,26 @@ class Lang
|
|
|
22
23
|
private
|
|
23
24
|
|
|
24
25
|
def load_files
|
|
25
|
-
dirbase = File.dirname(__FILE__)
|
|
26
|
-
|
|
26
|
+
dirbase = File.join(File.dirname(__FILE__), '..', 'files', 'language')
|
|
27
|
+
filepath = File.join(dirbase, @code, 'templates.yaml')
|
|
28
|
+
@templates = load_yaml_file(filepath)
|
|
29
|
+
filepath = File.join(dirbase, @code, 'connectors.yaml')
|
|
30
|
+
@connectors = load_yaml_file(filepath)
|
|
31
|
+
filepath = File.join(dirbase, @code, 'mistakes.yaml')
|
|
32
|
+
@mistakes = load_yaml_file(filepath)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# rubocop:disable Security/YAMLLoad
|
|
36
|
+
def load_yaml_file(filepath)
|
|
27
37
|
begin
|
|
28
|
-
|
|
38
|
+
content = YAML.load(File.new(filepath))
|
|
29
39
|
rescue StandardError => e
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
40
|
+
Logger.verboseln '[ERROR] Lang.initialize():' \
|
|
41
|
+
" Reading YAML file <#{filepath}>"
|
|
42
|
+
Logger.verboseln '[ADVISE] Revise apostrophe into string without \ symbol'
|
|
33
43
|
raise e
|
|
34
44
|
end
|
|
35
|
-
|
|
36
|
-
@connectors = YAML.load(File.new(filename))
|
|
37
|
-
|
|
38
|
-
filename = File.join(dirbase, 'locales', @code, 'mistakes.yaml')
|
|
39
|
-
@mistakes = YAML.load(File.new(filename))
|
|
45
|
+
content
|
|
40
46
|
end
|
|
41
|
-
|
|
47
|
+
# rubocop:enable Security/YAMLLoad
|
|
42
48
|
end
|
|
@@ -2,18 +2,45 @@
|
|
|
2
2
|
|
|
3
3
|
require 'singleton'
|
|
4
4
|
require_relative 'lang'
|
|
5
|
-
require_relative '../
|
|
5
|
+
require_relative '../application'
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
##
|
|
8
|
+
# LangFactory singleton class.
|
|
9
|
+
# * Read all language codes defined into configuration file
|
|
10
|
+
# * and load every language
|
|
11
|
+
# Lang objects are reused
|
|
8
12
|
class LangFactory
|
|
9
13
|
include Singleton
|
|
10
14
|
|
|
15
|
+
##
|
|
16
|
+
# Read all language codes from configuration file and load every language
|
|
11
17
|
def initialize
|
|
18
|
+
@default = Application.instance.config['languages']['default'].downcase
|
|
12
19
|
@langs = {}
|
|
13
|
-
|
|
20
|
+
Application.instance.config['languages'].each_pair do |key, value|
|
|
21
|
+
code = key.downcase
|
|
22
|
+
next if code == 'default'
|
|
23
|
+
|
|
24
|
+
@langs[code] = Lang.new(code) if value.downcase == 'yes'
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
##
|
|
29
|
+
# Return Lang object associated to code
|
|
30
|
+
# @param code (String)
|
|
31
|
+
def get(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
|
|
14
39
|
end
|
|
15
40
|
|
|
16
|
-
|
|
17
|
-
|
|
41
|
+
##
|
|
42
|
+
# Return default Lang object
|
|
43
|
+
def default
|
|
44
|
+
get(@default)
|
|
18
45
|
end
|
|
19
46
|
end
|
|
@@ -1,134 +1,152 @@
|
|
|
1
1
|
# encoding: utf-8
|
|
2
2
|
|
|
3
|
+
##
|
|
4
|
+
# Set of functions used by Lang class
|
|
3
5
|
module TextActions
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
6
|
+
##
|
|
7
|
+
# Return text indicated by lang code...
|
|
8
|
+
def text_for(option, *input)
|
|
9
|
+
text1 = input[0]
|
|
10
|
+
text2 = input[1]
|
|
11
|
+
text3 = input[2]
|
|
12
|
+
text4 = input[3]
|
|
13
|
+
text5 = input[4]
|
|
14
|
+
text6 = input[5]
|
|
15
|
+
text7 = input[6]
|
|
16
|
+
|
|
17
|
+
# Check if exists option before use it
|
|
18
|
+
raise "[ERROR] Unkown template #{option}" if @templates[option].nil?
|
|
19
|
+
|
|
20
|
+
renderer = ERB.new(@templates[option])
|
|
21
|
+
renderer.result(binding)
|
|
18
22
|
end
|
|
19
23
|
|
|
20
|
-
|
|
21
|
-
|
|
24
|
+
##
|
|
25
|
+
# Convert input text into output text struct
|
|
26
|
+
# @param input (String) Input text
|
|
27
|
+
# @param filter (Boolean) true => apply filter, false => dont filter
|
|
28
|
+
# @return Array
|
|
29
|
+
def text_filter_connectors(input, filter)
|
|
30
|
+
input_lines = input.split('.')
|
|
22
31
|
output_lines = []
|
|
23
32
|
output_words = []
|
|
24
33
|
input_lines.each_with_index do |line, rowindex|
|
|
25
|
-
row=[]
|
|
34
|
+
row = []
|
|
26
35
|
line.split(' ').each_with_index do |word, colindex|
|
|
27
36
|
flag = @connectors.include? word.downcase
|
|
28
37
|
|
|
29
38
|
# if <word> is a conector and <pFilter>==true Then Choose this <word>
|
|
30
39
|
# if <word> isn't a conector and <pFilter>==true and <word>.length>1 Then Choose this <word>
|
|
31
|
-
if (flag and
|
|
32
|
-
output_words << {:word => word,
|
|
33
|
-
:row => rowindex,
|
|
34
|
-
:col => colindex }
|
|
40
|
+
if (flag and filter) || (!flag and !filter and word.length > 1)
|
|
41
|
+
output_words << {:word => word, :row => rowindex, :col => colindex }
|
|
35
42
|
row << (output_words.size-1)
|
|
36
43
|
else
|
|
37
44
|
row << word
|
|
38
|
-
|
|
45
|
+
end
|
|
39
46
|
end
|
|
40
47
|
row << '.'
|
|
41
48
|
output_lines << row
|
|
42
|
-
|
|
49
|
+
end
|
|
43
50
|
|
|
44
51
|
indexes = []
|
|
45
|
-
exclude = ['[', ']', '(', ')', "
|
|
52
|
+
exclude = ['[', ']', '(', ')', '"']
|
|
46
53
|
output_words.each_with_index do |item, index|
|
|
47
54
|
flag = true
|
|
48
|
-
exclude.each { |e| flag = false if
|
|
55
|
+
exclude.each { |e| flag = false if item[:word].include? e }
|
|
49
56
|
indexes << index if flag
|
|
50
57
|
end
|
|
51
58
|
|
|
52
|
-
|
|
53
|
-
return result
|
|
59
|
+
{ lines: output_lines, words: output_words, indexes: indexes }
|
|
54
60
|
end
|
|
55
61
|
|
|
62
|
+
##
|
|
63
|
+
# Return text with connectors
|
|
56
64
|
def text_with_connectors(text)
|
|
57
65
|
text_filter_connectors(text, false)
|
|
58
66
|
end
|
|
59
67
|
|
|
68
|
+
##
|
|
69
|
+
# Return text without connectors
|
|
60
70
|
def text_without_connectors(text)
|
|
61
|
-
|
|
71
|
+
text_filter_connectors(text, true)
|
|
62
72
|
end
|
|
63
73
|
|
|
64
|
-
def build_text_from_filtered(
|
|
65
|
-
lines
|
|
66
|
-
|
|
67
|
-
counter
|
|
68
|
-
|
|
74
|
+
def build_text_from_filtered(input_struct, input_indexes)
|
|
75
|
+
lines = input_struct[:lines]
|
|
76
|
+
indexes = input_indexes.sort
|
|
77
|
+
counter = 1
|
|
78
|
+
text = ''
|
|
69
79
|
|
|
70
80
|
lines.each do |line|
|
|
71
81
|
line.each do |value|
|
|
72
82
|
if value.class == String
|
|
73
|
-
|
|
83
|
+
text += (' ' + value)
|
|
74
84
|
elsif value == value.to_i
|
|
75
85
|
# INFO: ruby 2.4 unifies Fixnum and Bignum into Integer
|
|
76
86
|
# Avoid using deprecated classes.
|
|
77
|
-
if
|
|
78
|
-
|
|
87
|
+
if indexes.include? value
|
|
88
|
+
text += " [#{counter}]"
|
|
79
89
|
counter += 1
|
|
80
90
|
else
|
|
81
|
-
|
|
82
|
-
|
|
91
|
+
word = input_struct[:words][value][:word]
|
|
92
|
+
text += (' ' + word)
|
|
83
93
|
end
|
|
84
94
|
end
|
|
85
95
|
end
|
|
86
96
|
end
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
97
|
+
text.gsub!(' .', '.')
|
|
98
|
+
text.gsub!(' ,', ',')
|
|
99
|
+
text = text[1, text.size] if text[0] == ' '
|
|
100
|
+
text
|
|
91
101
|
end
|
|
92
102
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
t.
|
|
101
|
-
t.gsub!("
|
|
102
|
-
t.gsub!(
|
|
103
|
-
t.gsub!("
|
|
104
|
-
t.
|
|
103
|
+
##
|
|
104
|
+
# Count words
|
|
105
|
+
# @param input (String)
|
|
106
|
+
# @return Integer
|
|
107
|
+
def count_words(input)
|
|
108
|
+
return 0 if input.nil?
|
|
109
|
+
|
|
110
|
+
t = input.clone
|
|
111
|
+
t.gsub!("\n", ' ')
|
|
112
|
+
t.gsub!('/', ' ')
|
|
113
|
+
# t.gsub!("-"," ")
|
|
114
|
+
t.gsub!('.', ' ')
|
|
115
|
+
t.gsub!(',', ' ')
|
|
116
|
+
t.gsub!(' ', ' ')
|
|
117
|
+
t.gsub!(' ', ' ')
|
|
118
|
+
t.split(' ').count
|
|
105
119
|
end
|
|
106
120
|
|
|
107
|
-
|
|
108
|
-
|
|
121
|
+
##
|
|
122
|
+
# Do mistake to input
|
|
123
|
+
# @param input (String)
|
|
124
|
+
# @return String
|
|
125
|
+
def do_mistake_to(input = '')
|
|
126
|
+
text = input.dup
|
|
109
127
|
keys = @mistakes.keys
|
|
110
128
|
|
|
111
129
|
# Try to do mistake with one item from the key list
|
|
112
130
|
keys.shuffle!
|
|
113
131
|
keys.each do |key|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
132
|
+
next unless text.include? key.to_s
|
|
133
|
+
|
|
134
|
+
values = @mistakes[key].split(',')
|
|
135
|
+
values.shuffle!
|
|
136
|
+
text = text.sub(key.to_s, values[0].to_s)
|
|
137
|
+
return text
|
|
120
138
|
end
|
|
121
139
|
|
|
122
140
|
# Force mistake by swapping letters
|
|
123
|
-
if
|
|
124
|
-
i = rand(
|
|
125
|
-
aux =
|
|
126
|
-
|
|
127
|
-
|
|
141
|
+
if text.size > 1
|
|
142
|
+
i = rand(text.size - 2)
|
|
143
|
+
aux = text[i]
|
|
144
|
+
text[i] = text[i + 1]
|
|
145
|
+
text[i + 1] = aux
|
|
128
146
|
end
|
|
129
|
-
return
|
|
147
|
+
return text if text != input
|
|
130
148
|
|
|
131
|
-
|
|
149
|
+
text + 's'
|
|
132
150
|
end
|
|
133
151
|
|
|
134
152
|
def hide_text(input_text)
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
require 'rainbow'
|
|
4
4
|
require 'rexml/document'
|
|
5
5
|
require_relative '../logger'
|
|
6
|
-
require_relative '../
|
|
6
|
+
require_relative '../data/code'
|
|
7
7
|
|
|
8
8
|
# Read XML info about Code input data
|
|
9
9
|
module CodeLoader
|
|
@@ -24,7 +24,7 @@ module CodeLoader
|
|
|
24
24
|
# @param xmldata (XML Object)
|
|
25
25
|
# @param filename (String) File name that contains data
|
|
26
26
|
# @return Code object
|
|
27
|
-
def self.read_codedata_from_xml(xmldata, filename)
|
|
27
|
+
private_class_method def self.read_codedata_from_xml(xmldata, filename)
|
|
28
28
|
data = { path: '?', type: '?', features: [] }
|
|
29
29
|
xmldata.elements.each do |i|
|
|
30
30
|
data[:path] = i.text if i.name == 'path'
|
|
@@ -38,14 +38,14 @@ module CodeLoader
|
|
|
38
38
|
# Read features data from XML input
|
|
39
39
|
# @param xmldata (XML object)
|
|
40
40
|
# @return Array with features (Strings)
|
|
41
|
-
def self.read_features(xmldata, filename)
|
|
41
|
+
private_class_method def self.read_features(xmldata, filename)
|
|
42
42
|
features = []
|
|
43
43
|
xmldata.elements.each do |i|
|
|
44
44
|
if i.name == 'row'
|
|
45
45
|
features << i.text
|
|
46
46
|
else
|
|
47
47
|
msg = Rainbow("[ERROR] features/#{i.name} from #{filename}").color(:red)
|
|
48
|
-
Logger.
|
|
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,11 +39,13 @@ 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
|
|
43
47
|
# @param xmldata (XML Object)
|
|
44
|
-
def self.read_lang_attribute(xmldata)
|
|
48
|
+
private_class_method def self.read_lang_attribute(xmldata)
|
|
45
49
|
begin
|
|
46
50
|
lang = xmldata.root.attributes['lang']
|
|
47
51
|
rescue StandardError
|
|
@@ -53,7 +57,7 @@ module ContentLoader
|
|
|
53
57
|
##
|
|
54
58
|
# Read context attr from input XML data
|
|
55
59
|
# @param xmldata (XML Object)
|
|
56
|
-
def self.read_context_attribute(xmldata)
|
|
60
|
+
private_class_method def self.read_context_attribute(xmldata)
|
|
57
61
|
begin
|
|
58
62
|
context = xmldata.root.attributes['context']
|
|
59
63
|
rescue StandardError
|
|
@@ -68,12 +72,10 @@ module ContentLoader
|
|
|
68
72
|
# @param filepath (String)
|
|
69
73
|
# @param lang
|
|
70
74
|
# @param context
|
|
71
|
-
def self.read_concept(xmldata, filepath, lang, context)
|
|
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 [
|
|
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
|
|
|
@@ -81,18 +83,20 @@ module ContentLoader
|
|
|
81
83
|
# Read code from input XML data
|
|
82
84
|
# @param xmldata (XML Object)
|
|
83
85
|
# @param filepath (String)
|
|
84
|
-
def self.read_code(xmldata, filepath)
|
|
86
|
+
private_class_method def self.read_code(xmldata, filepath)
|
|
85
87
|
project = Project.instance
|
|
86
88
|
c = CodeLoader.load(xmldata, filepath)
|
|
87
|
-
if [
|
|
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
|
|
|
93
|
-
|
|
93
|
+
##
|
|
94
|
+
# Raise error and save content into error.file
|
|
95
|
+
# @param filepath (String)
|
|
96
|
+
# @param content (String)
|
|
97
|
+
private_class_method def self.raise_error_with(filepath, content)
|
|
94
98
|
msg = Rainbow("[ERROR] ContentLoader: Format error in #{filepath}").red.bright
|
|
95
|
-
Logger.
|
|
99
|
+
Logger.verboseln msg
|
|
96
100
|
f = File.open('output/error.xml', 'w')
|
|
97
101
|
f.write(content)
|
|
98
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.
|
|
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.
|
|
52
|
+
Logger.verboseln " └── Input file = #{Rainbow(filepath).bright}"
|
|
53
53
|
else
|
|
54
|
-
Logger.
|
|
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
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require 'haml'
|
|
4
3
|
require_relative 'content_loader'
|
|
4
|
+
require_relative 'haml_loader'
|
|
5
5
|
require_relative '../logger'
|
|
6
6
|
|
|
7
7
|
# Methods that load a filename and return list of concepts
|
|
@@ -11,23 +11,14 @@ module FileLoader
|
|
|
11
11
|
# @param filename (String) File name to be load
|
|
12
12
|
def self.load(filename)
|
|
13
13
|
if File.extname(filename).casecmp('.haml').zero?
|
|
14
|
-
file_content =
|
|
14
|
+
file_content = HamlLoader.load filename
|
|
15
15
|
elsif File.extname(filename).casecmp('.xml').zero?
|
|
16
16
|
file_content = File.read(filename)
|
|
17
17
|
else
|
|
18
18
|
msg = "[ERROR] FileLoader: Format error #{filename}"
|
|
19
|
-
Logger.
|
|
19
|
+
Logger.verboseln msg
|
|
20
20
|
raise msg
|
|
21
21
|
end
|
|
22
22
|
ContentLoader.load(filename, file_content)
|
|
23
23
|
end
|
|
24
|
-
|
|
25
|
-
##
|
|
26
|
-
# Load HAML file name
|
|
27
|
-
# @param filename (String) HAML file name
|
|
28
|
-
def self.load_haml(filename)
|
|
29
|
-
template = File.read(filename)
|
|
30
|
-
haml_engine = Haml::Engine.new(template)
|
|
31
|
-
haml_engine.render
|
|
32
|
-
end
|
|
33
24
|
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'haml'
|
|
4
|
+
|
|
5
|
+
# HAML file loader
|
|
6
|
+
module HamlLoader
|
|
7
|
+
##
|
|
8
|
+
# Load HAML file name
|
|
9
|
+
# @param filename (String) HAML file name
|
|
10
|
+
def self.load(filename)
|
|
11
|
+
template = File.read(filename)
|
|
12
|
+
haml_engine = Haml::Engine.new(template)
|
|
13
|
+
haml_engine.render
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
|
|
2
2
|
require 'net/http'
|
|
3
3
|
require 'uri'
|
|
4
|
-
require_relative '../project'
|
|
5
4
|
require_relative '../application'
|
|
5
|
+
require_relative '../logger'
|
|
6
6
|
|
|
7
7
|
# Search URL images on Internet
|
|
8
8
|
# Methods:
|
|
@@ -12,9 +12,6 @@ require_relative '../application'
|
|
|
12
12
|
module ImageUrlLoader
|
|
13
13
|
# Search "input" images on Google and return URL
|
|
14
14
|
def self.load(input = [])
|
|
15
|
-
param = Application.instance.config['global']['internet'] || 'yes'
|
|
16
|
-
return [] unless param == 'yes'
|
|
17
|
-
|
|
18
15
|
filters = []
|
|
19
16
|
if input.class == String
|
|
20
17
|
filters += sanitize_string(input.clone)
|
|
@@ -39,20 +36,21 @@ module ImageUrlLoader
|
|
|
39
36
|
end
|
|
40
37
|
end
|
|
41
38
|
rescue
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
39
|
+
Logger.verboseln '[ERROR] ImageUrlLoader'
|
|
40
|
+
Logger.verboseln " => #{search_url}"
|
|
41
|
+
Logger.verboseln ' => Check Internet connections'
|
|
42
|
+
Logger.verboseln ' => Ensure URL is well formed'
|
|
46
43
|
end
|
|
47
44
|
image_urls
|
|
48
45
|
end
|
|
49
46
|
|
|
50
47
|
def self.sanitize_string(input)
|
|
48
|
+
text = input.dup
|
|
51
49
|
r = [ ['á', 'a'], ['é', 'e'], ['í', 'i'], ['ó', 'o'], ['ú', 'u'], ['ñ', 'n'], ['Á', 'A'], ['É', 'E'], ['Í', 'I'], ['Ó', 'O'], ['Ú', 'U'], ['Ñ', 'N']]
|
|
52
|
-
r.each { |item|
|
|
50
|
+
r.each { |item| text.gsub!(item[0], item[1]) }
|
|
53
51
|
r = ['-', '_', ',', '"']
|
|
54
|
-
r.each { |item|
|
|
55
|
-
|
|
52
|
+
r.each { |item| text.gsub!(item, ' ') }
|
|
53
|
+
text.split(' ')
|
|
56
54
|
end
|
|
57
55
|
|
|
58
56
|
def self.sanitize_array(input)
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require_relative 'directory_loader'
|
|
4
|
+
require_relative '../ai/concept_ai'
|
|
5
|
+
require_relative '../data/world'
|
|
4
6
|
require_relative '../logger'
|
|
5
7
|
|
|
6
8
|
# Load DATA defined into our Project
|
|
@@ -9,16 +11,30 @@ module InputLoader
|
|
|
9
11
|
# Load input data from every input directory
|
|
10
12
|
# @param inputdirs (Array)
|
|
11
13
|
def self.load(inputdirs)
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
# inputdirs = project.inputdirs.split(',')
|
|
14
|
+
data = { concepts: [], codes: [], world: nil,
|
|
15
|
+
concepts_ai: [], codes_ai: [] }
|
|
16
|
+
Logger.verboseln "\n[INFO] Loading input data"
|
|
16
17
|
inputdirs.each do |dirname|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
temp = DirectoryLoader.load(dirname)
|
|
19
|
+
data[:concepts] += temp[:concepts]
|
|
20
|
+
data[:codes] += temp[:codes]
|
|
20
21
|
end
|
|
22
|
+
create_questions(data)
|
|
23
|
+
end
|
|
21
24
|
|
|
22
|
-
|
|
25
|
+
private_class_method def self.create_questions(data)
|
|
26
|
+
# Create World data
|
|
27
|
+
# * Calculate concept neighbours
|
|
28
|
+
# * TO-DO: Calculate code neighbours
|
|
29
|
+
data[:world] = World.new(data[:concepts])
|
|
30
|
+
# Create ConceptAI data (ConceptAI = concept + questions)
|
|
31
|
+
data[:concepts].each do |concept|
|
|
32
|
+
data[:concepts_ai] << ConceptAI.new(concept, data[:world])
|
|
33
|
+
end
|
|
34
|
+
# Create CodeAI data (CodeAI = code + questions)
|
|
35
|
+
data[:codes].each do |code|
|
|
36
|
+
data[:codes_ai] << CodeAIFactory.get(code)
|
|
37
|
+
end
|
|
38
|
+
data
|
|
23
39
|
end
|
|
24
40
|
end
|