asker-tool 2.6.0 → 2.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +4 -4
- data/lib/asker/ai/ai.rb +6 -6
- data/lib/asker/ai/ai_calculate.rb +3 -3
- data/lib/asker/ai/code/base_code_ai.rb +5 -30
- data/lib/asker/ai/code/code_ai_factory.rb +6 -12
- data/lib/asker/ai/code/javascript_code_ai.rb +33 -34
- data/lib/asker/ai/code/python_code_ai.rb +35 -36
- data/lib/asker/ai/code/ruby_code_ai.rb +33 -33
- data/lib/asker/ai/code/sql_code_ai.rb +20 -21
- data/lib/asker/ai/concept_ai.rb +12 -22
- data/lib/asker/ai/problem/problem_ai.rb +226 -0
- data/lib/asker/ai/question.rb +34 -45
- data/lib/asker/ai/stages/base_stage.rb +7 -7
- data/lib/asker/ai/stages/stage_b.rb +62 -28
- data/lib/asker/ai/stages/stage_d.rb +10 -10
- data/lib/asker/ai/stages/stage_f.rb +17 -17
- data/lib/asker/ai/stages/stage_i.rb +8 -18
- data/lib/asker/ai/stages/stage_s.rb +28 -26
- data/lib/asker/ai/stages/stage_t.rb +40 -51
- data/lib/asker/application.rb +15 -14
- data/lib/asker/check_input/check_haml_data.rb +52 -51
- data/lib/asker/check_input/check_table.rb +17 -20
- data/lib/asker/check_input.rb +10 -23
- data/lib/asker/cli.rb +43 -24
- data/lib/asker/data/code.rb +10 -9
- data/lib/asker/data/column.rb +21 -17
- data/lib/asker/data/concept.rb +24 -37
- data/lib/asker/data/data_field.rb +2 -2
- data/lib/asker/data/problem.rb +112 -0
- data/lib/asker/data/project_data.rb +11 -15
- data/lib/asker/data/row.rb +25 -23
- data/lib/asker/data/table.rb +25 -46
- data/lib/asker/data/template.rb +7 -7
- data/lib/asker/data/world.rb +3 -3
- data/lib/asker/{formatter → deprecated}/question_moodlexml_formatter.rb +19 -21
- data/lib/asker/displayer/code_displayer.rb +10 -10
- data/lib/asker/displayer/concept_ai_displayer.erb +1 -1
- data/lib/asker/displayer/concept_ai_displayer.rb +16 -16
- data/lib/asker/displayer/concept_displayer.rb +4 -2
- data/lib/asker/displayer/problem_displayer.rb +45 -0
- data/lib/asker/displayer/stats_displayer.rb +7 -12
- data/lib/asker/exporter/code_gift_exporter.rb +2 -2
- data/lib/asker/exporter/concept_ai_gift_exporter.rb +4 -4
- data/lib/asker/exporter/concept_ai_yaml_exporter.rb +7 -7
- data/lib/asker/exporter/concept_doc_exporter.rb +5 -5
- data/lib/asker/exporter/data_gift_exporter.rb +14 -15
- data/lib/asker/exporter/data_moodle_exporter.rb +51 -20
- data/lib/asker/exporter/output_file_exporter.rb +9 -8
- data/lib/asker/exporter/problem_gift_exporter.rb +30 -0
- data/lib/asker/files/language/ca/templates.yaml +6 -0
- data/lib/asker/files/language/du/templates.yaml +6 -0
- data/lib/asker/files/language/en/templates.yaml +7 -1
- data/lib/asker/files/language/es/templates.yaml +6 -0
- data/lib/asker/files/language/fr/templates.yaml +6 -0
- data/lib/asker/formatter/code_string_formatter.rb +5 -5
- data/lib/asker/formatter/concept_doc_formatter.rb +3 -3
- data/lib/asker/formatter/concept_string_formatter.rb +6 -6
- data/lib/asker/formatter/moodle/ddmatch.erb +40 -0
- data/lib/asker/formatter/moodle/gapfill.erb +57 -0
- data/lib/asker/formatter/moodle/ordering.erb +41 -0
- data/lib/asker/formatter/question_gift_formatter.rb +41 -14
- data/lib/asker/formatter/question_hash_formatter.rb +5 -6
- data/lib/asker/formatter/question_moodle_formatter.rb +14 -7
- data/lib/asker/formatter/rb2haml_formatter.rb +8 -7
- data/lib/asker/lang/lang.rb +16 -16
- data/lib/asker/lang/lang_factory.rb +13 -16
- data/lib/asker/lang/text_actions.rb +20 -18
- data/lib/asker/loader/code_loader.rb +10 -22
- data/lib/asker/loader/content_loader.rb +42 -49
- data/lib/asker/loader/directory_loader.rb +13 -16
- data/lib/asker/loader/embedded_file.rb +14 -14
- data/lib/asker/loader/file_loader.rb +5 -4
- data/lib/asker/loader/haml_loader.rb +4 -3
- data/lib/asker/loader/image_url_loader.rb +6 -5
- data/lib/asker/loader/input_loader.rb +24 -10
- data/lib/asker/loader/problem_loader.rb +88 -0
- data/lib/asker/loader/project_loader.rb +5 -12
- data/lib/asker/logger.rb +19 -10
- data/lib/asker/skeleton.rb +19 -35
- data/lib/asker/start.rb +44 -0
- data/lib/asker/version.rb +1 -1
- data/lib/asker.rb +7 -52
- metadata +12 -6
- data/lib/asker/ai/code/problem_code_ai.rb +0 -176
- data/lib/asker/exporter/code_moodle_exporter.rb +0 -15
- data/lib/asker/exporter/concept_ai_moodle_exporter.rb +0 -15
data/lib/asker/lang/lang.rb
CHANGED
@@ -1,15 +1,15 @@
|
|
1
|
-
|
2
|
-
require
|
3
|
-
|
4
|
-
require_relative
|
5
|
-
require_relative '../logger'
|
1
|
+
require "erb"
|
2
|
+
require "yaml"
|
3
|
+
require_relative "text_actions"
|
4
|
+
require_relative "../logger"
|
6
5
|
|
7
6
|
class Lang
|
8
7
|
include TextActions
|
9
8
|
|
10
|
-
attr_reader :code
|
9
|
+
attr_reader :code
|
10
|
+
attr_reader :mistakes
|
11
11
|
|
12
|
-
def initialize(code =
|
12
|
+
def initialize(code = "en")
|
13
13
|
@code = code.to_s
|
14
14
|
load_files
|
15
15
|
end
|
@@ -21,23 +21,23 @@ class Lang
|
|
21
21
|
private
|
22
22
|
|
23
23
|
def load_files
|
24
|
-
dirbase = File.join(File.dirname(__FILE__),
|
25
|
-
filepath = File.join(dirbase, @code,
|
24
|
+
dirbase = File.join(File.dirname(__FILE__), "..", "files", "language")
|
25
|
+
filepath = File.join(dirbase, @code, "templates.yaml")
|
26
26
|
@templates = load_yaml_file(filepath)
|
27
|
-
filepath = File.join(dirbase, @code,
|
27
|
+
filepath = File.join(dirbase, @code, "connectors.yaml")
|
28
28
|
@connectors = load_yaml_file(filepath)
|
29
|
-
filepath = File.join(dirbase, @code,
|
29
|
+
filepath = File.join(dirbase, @code, "mistakes.yaml")
|
30
30
|
@mistakes = load_yaml_file(filepath)
|
31
31
|
end
|
32
32
|
|
33
33
|
def load_yaml_file(filepath)
|
34
34
|
begin
|
35
35
|
content = YAML.load(File.new(filepath))
|
36
|
-
rescue
|
37
|
-
Logger.
|
38
|
-
|
39
|
-
Logger.
|
40
|
-
|
36
|
+
rescue => e
|
37
|
+
Logger.error "Lang: YAML loading error (#{filepath})"
|
38
|
+
Logger.error " : Revise apostrophe into string without \\ symbol"
|
39
|
+
Logger.error " : #{e}"
|
40
|
+
exit 1
|
41
41
|
end
|
42
42
|
content
|
43
43
|
end
|
@@ -1,27 +1,26 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require_relative
|
5
|
-
require_relative
|
3
|
+
require "singleton"
|
4
|
+
require_relative "lang"
|
5
|
+
require_relative "../application"
|
6
|
+
require_relative "../logger"
|
6
7
|
|
7
8
|
##
|
8
|
-
# LangFactory singleton class.
|
9
9
|
# * Read all language codes defined into configuration file
|
10
10
|
# * and load every language
|
11
11
|
# Lang objects are reused
|
12
12
|
class LangFactory
|
13
13
|
include Singleton
|
14
14
|
|
15
|
-
##
|
16
|
-
# Read all language codes from configuration file and load every language
|
17
15
|
def initialize
|
18
|
-
|
16
|
+
# Read all language codes from configuration file and load every language
|
17
|
+
@default = Application.instance.config["languages"]["default"].downcase
|
19
18
|
@langs = {}
|
20
|
-
Application.instance.config[
|
19
|
+
Application.instance.config["languages"].each_pair do |key, value|
|
21
20
|
code = key.downcase
|
22
|
-
next if code ==
|
21
|
+
next if code == "default"
|
23
22
|
|
24
|
-
@langs[code] = Lang.new(code) if value.downcase ==
|
23
|
+
@langs[code] = Lang.new(code) if value.downcase == "yes"
|
25
24
|
end
|
26
25
|
end
|
27
26
|
|
@@ -31,15 +30,13 @@ class LangFactory
|
|
31
30
|
def get(code)
|
32
31
|
return @langs[code] unless @langs[code].nil?
|
33
32
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
33
|
+
Logger.error "LangFactory: Unkown Lang code: #{code}"
|
34
|
+
Logger.error " (a) Change input file code lang"
|
35
|
+
Logger.error " (b) Revise configuration from asker.ini"
|
36
|
+
Logger.error " (c) Revise template files"
|
38
37
|
exit 1
|
39
38
|
end
|
40
39
|
|
41
|
-
##
|
42
|
-
# Return default Lang object
|
43
40
|
def default
|
44
41
|
get(@default)
|
45
42
|
end
|
@@ -1,9 +1,10 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
|
-
|
4
|
-
|
3
|
+
require_relative "../logger"
|
4
|
+
|
5
5
|
module TextActions
|
6
6
|
##
|
7
|
+
# Set of functions used by Lang class
|
7
8
|
# Return text indicated by lang code...
|
8
9
|
def text_for(option, *input)
|
9
10
|
@_text1 = input[0] # FIXME: done to avoid linter complaints.
|
@@ -14,9 +15,10 @@ module TextActions
|
|
14
15
|
@_text6 = input[5]
|
15
16
|
@_text7 = input[6]
|
16
17
|
|
17
|
-
|
18
|
-
|
19
|
-
|
18
|
+
if @templates[option].nil?
|
19
|
+
Logger.error "TextActions: Unkown template (#{option})"
|
20
|
+
exit 1
|
21
|
+
end
|
20
22
|
renderer = ERB.new(@templates[option])
|
21
23
|
renderer.result(binding)
|
22
24
|
end
|
@@ -55,12 +57,12 @@ module TextActions
|
|
55
57
|
# @param filter (Boolean) true => apply filter, false => dont filter
|
56
58
|
# @return Array
|
57
59
|
def text_filter_connectors(input, filter)
|
58
|
-
input_lines = input.split(
|
60
|
+
input_lines = input.split(".")
|
59
61
|
output_lines = []
|
60
62
|
output_words = []
|
61
63
|
input_lines.each_with_index do |line, rowindex|
|
62
64
|
row = []
|
63
|
-
line.split(
|
65
|
+
line.split(" ").each_with_index do |word, colindex|
|
64
66
|
flag = @connectors.include? word.downcase
|
65
67
|
|
66
68
|
# if <word> is a conector and <pFilter>==true Then Choose this <word>
|
@@ -72,7 +74,7 @@ module TextActions
|
|
72
74
|
row << word
|
73
75
|
end
|
74
76
|
end
|
75
|
-
row <<
|
77
|
+
row << "."
|
76
78
|
output_lines << row
|
77
79
|
end
|
78
80
|
|
@@ -103,12 +105,12 @@ module TextActions
|
|
103
105
|
lines = input_struct[:lines]
|
104
106
|
indexes = input_indexes.sort
|
105
107
|
counter = 1
|
106
|
-
text =
|
108
|
+
text = ""
|
107
109
|
|
108
110
|
lines.each do |line|
|
109
111
|
line.each do |value|
|
110
112
|
if value.class == String
|
111
|
-
text += (
|
113
|
+
text += (" " + value)
|
112
114
|
elsif value == value.to_i
|
113
115
|
# INFO: ruby 2.4 unifies Fixnum and Bignum into Integer
|
114
116
|
# Avoid using deprecated classes.
|
@@ -117,14 +119,14 @@ module TextActions
|
|
117
119
|
counter += 1
|
118
120
|
else
|
119
121
|
word = input_struct[:words][value][:word]
|
120
|
-
text += (
|
122
|
+
text += (" " + word)
|
121
123
|
end
|
122
124
|
end
|
123
125
|
end
|
124
126
|
end
|
125
|
-
text.gsub!(
|
126
|
-
text.gsub!(
|
127
|
-
text = text[1, text.size] if text[0] ==
|
127
|
+
text.gsub!(" .", ".")
|
128
|
+
text.gsub!(" ,", ",")
|
129
|
+
text = text[1, text.size] if text[0] == " "
|
128
130
|
text
|
129
131
|
end
|
130
132
|
|
@@ -174,20 +176,20 @@ module TextActions
|
|
174
176
|
end
|
175
177
|
return text if text != input
|
176
178
|
|
177
|
-
text +
|
179
|
+
text + "s"
|
178
180
|
end
|
179
181
|
|
180
182
|
def hide_text(input_text)
|
181
183
|
input = input_text.clone
|
182
184
|
if count_words(input) < 2 && input.size < 10
|
183
|
-
output =
|
185
|
+
output = "[*]"
|
184
186
|
else
|
185
|
-
output =
|
187
|
+
output = ""
|
186
188
|
input.each_char do |char|
|
187
189
|
if ' !|"@#$%&/()=?¿¡+*(){}[],.-_<>'.include? char
|
188
190
|
output += char
|
189
191
|
else
|
190
|
-
output +=
|
192
|
+
output += "?"
|
191
193
|
end
|
192
194
|
end
|
193
195
|
end
|
@@ -1,51 +1,39 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
|
5
|
-
require_relative
|
6
|
-
require_relative '../data/code'
|
3
|
+
require "rexml/document"
|
4
|
+
require_relative "../logger"
|
5
|
+
require_relative "../data/code"
|
7
6
|
|
8
|
-
# Read XML info about Code input data
|
9
7
|
module CodeLoader
|
10
8
|
##
|
11
9
|
# Load XML data about Code object
|
12
10
|
# @param xmldata (XML Object)
|
13
11
|
# @param filepath (String)
|
14
12
|
# @return Code object
|
15
|
-
def self.
|
13
|
+
def self.call(xmldata, filepath)
|
16
14
|
data = read_codedata_from_xml(xmldata, File.basename(filepath))
|
17
15
|
code = Code.new(File.dirname(filepath), data[:path], data[:type])
|
18
16
|
code.features << data[:features]
|
19
17
|
code
|
20
18
|
end
|
21
19
|
|
22
|
-
##
|
23
|
-
# Read Code data from XML content
|
24
|
-
# @param xmldata (XML Object)
|
25
|
-
# @param filename (String) File name that contains data
|
26
|
-
# @return Code object
|
27
20
|
private_class_method def self.read_codedata_from_xml(xmldata, filename)
|
28
|
-
data = {
|
21
|
+
data = {path: "?", type: "?", features: []}
|
29
22
|
xmldata.elements.each do |i|
|
30
|
-
data[:path] = i.text if i.name ==
|
31
|
-
data[:type] = i.text.to_sym if i.name ==
|
32
|
-
data[:features] << read_features(i, filename) if i.name ==
|
23
|
+
data[:path] = i.text if i.name == "path"
|
24
|
+
data[:type] = i.text.to_sym if i.name == "type"
|
25
|
+
data[:features] << read_features(i, filename) if i.name == "features"
|
33
26
|
end
|
34
27
|
data
|
35
28
|
end
|
36
29
|
|
37
|
-
##
|
38
|
-
# Read features data from XML input
|
39
|
-
# @param xmldata (XML object)
|
40
|
-
# @return Array with features (Strings)
|
41
30
|
private_class_method def self.read_features(xmldata, filename)
|
42
31
|
features = []
|
43
32
|
xmldata.elements.each do |i|
|
44
|
-
if i.name ==
|
33
|
+
if i.name == "row"
|
45
34
|
features << i.text
|
46
35
|
else
|
47
|
-
|
48
|
-
Logger.verboseln msg
|
36
|
+
Logger.error "CodeLoader: features/#{i.name} from #{filename}"
|
49
37
|
end
|
50
38
|
end
|
51
39
|
features
|
@@ -1,100 +1,93 @@
|
|
1
|
-
require "rainbow"
|
2
1
|
require "rexml/document"
|
3
2
|
require_relative "code_loader"
|
3
|
+
require_relative "problem_loader"
|
4
4
|
require_relative "../data/concept"
|
5
5
|
require_relative "../data/project_data"
|
6
|
+
require_relative "../lang/lang_factory"
|
7
|
+
require_relative "../logger"
|
6
8
|
|
7
|
-
# Define methods that load data from XML contents
|
8
9
|
module ContentLoader
|
9
10
|
##
|
10
11
|
# Load XML content into Asker data objects
|
11
12
|
# @param filepath (String) File path
|
12
13
|
# @param content (String) XML plane text content
|
13
|
-
def self.
|
14
|
-
concepts = []
|
15
|
-
codes = []
|
14
|
+
def self.call(filepath, content)
|
16
15
|
begin
|
17
16
|
xmlcontent = REXML::Document.new(content)
|
18
17
|
rescue REXML::ParseException
|
19
18
|
raise_error_with(filepath, content)
|
20
19
|
end
|
20
|
+
codes = []
|
21
|
+
concepts = []
|
22
|
+
problems = []
|
21
23
|
lang = read_lang_attribute(xmlcontent)
|
22
24
|
context = read_context_attribute(xmlcontent)
|
23
25
|
|
24
26
|
xmlcontent.root.elements.each do |xmldata|
|
25
27
|
case xmldata.name
|
26
|
-
when "concept"
|
27
|
-
concepts << read_concept(xmldata, filepath, lang, context)
|
28
28
|
when "code"
|
29
29
|
codes << read_code(xmldata, filepath)
|
30
|
+
when "concept"
|
31
|
+
concepts << read_concept(xmldata, filepath, lang, context)
|
32
|
+
when "problem"
|
33
|
+
problems << read_problem(xmldata, filepath, lang, context)
|
30
34
|
else
|
31
|
-
|
32
|
-
puts Rainbow("[INFO ] Only 'concept' and 'code' are available at this level").red
|
35
|
+
Logger.warn "ContentLoader: Unkown tag (#{xmldata.name}) Use concept, code or problem."
|
33
36
|
end
|
34
37
|
end
|
35
38
|
|
36
|
-
{
|
39
|
+
{concepts: concepts, codes: codes, problems: problems}
|
37
40
|
end
|
38
41
|
|
39
|
-
##
|
40
|
-
# Read lang attr from input XML data
|
41
|
-
# @param xmldata (XML Object)
|
42
42
|
private_class_method def self.read_lang_attribute(xmldata)
|
43
43
|
begin
|
44
|
-
|
45
|
-
rescue
|
46
|
-
|
47
|
-
|
44
|
+
lang_code = xmldata.root.attributes["lang"]
|
45
|
+
rescue itself
|
46
|
+
lang_code = ProjectData.instance.lang
|
47
|
+
Logger.warn "ContentLoader: Applying default lang (#{lang_code})"
|
48
48
|
end
|
49
|
-
|
49
|
+
LangFactory.instance.get(lang_code)
|
50
50
|
end
|
51
51
|
|
52
|
-
##
|
53
|
-
# Read context attr from input XML data
|
54
|
-
# @param xmldata (XML Object)
|
55
52
|
private_class_method def self.read_context_attribute(xmldata)
|
56
53
|
begin
|
57
|
-
context = xmldata.root.attributes["context"]
|
58
|
-
|
59
|
-
|
60
|
-
|
54
|
+
context = xmldata.root.attributes["context"].split(",")
|
55
|
+
context.collect!(&:strip)
|
56
|
+
rescue itself
|
57
|
+
context = ["unknown"]
|
58
|
+
Logger.warn "ContentLoader: Context is empty!"
|
61
59
|
end
|
62
60
|
context
|
63
61
|
end
|
64
62
|
|
65
|
-
##
|
66
|
-
# Read concept from input XML data
|
67
|
-
# @param xmldata (XML Object)
|
68
|
-
# @param filepath (String)
|
69
|
-
# @param lang
|
70
|
-
# @param context
|
71
63
|
private_class_method def self.read_concept(xmldata, filepath, lang, context)
|
72
64
|
project = ProjectData.instance
|
73
|
-
|
74
|
-
|
75
|
-
|
65
|
+
concept = Concept.new(xmldata, filepath, lang, context)
|
66
|
+
cond = [File.basename(filepath), :default].include? project.get(:process_file)
|
67
|
+
concept.process = true if cond
|
68
|
+
concept
|
76
69
|
end
|
77
70
|
|
78
|
-
##
|
79
|
-
# Read code from input XML data
|
80
|
-
# @param xmldata (XML Object)
|
81
|
-
# @param filepath (String)
|
82
71
|
private_class_method def self.read_code(xmldata, filepath)
|
83
72
|
project = ProjectData.instance
|
84
|
-
|
85
|
-
|
86
|
-
|
73
|
+
code = CodeLoader.call(xmldata, filepath)
|
74
|
+
cond = [File.basename(filepath), :default].include? project.get(:process_file)
|
75
|
+
code.process = true if cond
|
76
|
+
code
|
77
|
+
end
|
78
|
+
|
79
|
+
private_class_method def self.read_problem(xmldata, filepath, lang, context)
|
80
|
+
project = ProjectData.instance
|
81
|
+
problem = ProblemLoader.new(lang, context).call(xmldata, filepath)
|
82
|
+
cond = [File.basename(filepath), :default].include? project.get(:process_file)
|
83
|
+
problem.process = true if cond
|
84
|
+
problem
|
87
85
|
end
|
88
86
|
|
89
|
-
##
|
90
|
-
# Raise error and save content into error.file
|
91
|
-
# @param filepath (String)
|
92
|
-
# @param content (String)
|
93
87
|
private_class_method def self.raise_error_with(filepath, content)
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
f = File.open('output/error.xml', 'w')
|
88
|
+
Logger.error "ContentLoader: Format error (#{filepath})"
|
89
|
+
Logger.error " : Revise output file (ouput/error.xml)"
|
90
|
+
f = File.open("output/error.xml", "w")
|
98
91
|
f.write(content)
|
99
92
|
f.close
|
100
93
|
raise msg
|
@@ -1,29 +1,25 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative
|
3
|
+
require_relative "file_loader"
|
4
|
+
require_relative "../logger"
|
4
5
|
|
5
|
-
# Load input data from one directory
|
6
6
|
module DirectoryLoader
|
7
7
|
##
|
8
|
-
# Load input data from directory
|
8
|
+
# Load input data from one directory
|
9
9
|
# @param dirname (String) Directory name
|
10
|
-
def self.
|
10
|
+
def self.call(dirname)
|
11
11
|
DirectoryLoader.check_dir(dirname)
|
12
|
-
files = (Dir.new(dirname).entries - [
|
12
|
+
files = (Dir.new(dirname).entries - [".", ".."]).sort
|
13
13
|
# Accept only HAML or XML files
|
14
14
|
accepted = files.select { |f| %w[.xml .haml].include? File.extname(f) }
|
15
15
|
DirectoryLoader.load_files(accepted, dirname)
|
16
16
|
end
|
17
17
|
|
18
|
-
##
|
19
|
-
# Check directory
|
20
|
-
# @param dirname (String) Directory name
|
21
18
|
def self.check_dir(dirname)
|
22
19
|
return if Dir.exist? dirname
|
23
20
|
|
24
|
-
|
25
|
-
|
26
|
-
raise msg
|
21
|
+
Logger.error "DirectoryLoader: #{dirname} directory dosn't exist!"
|
22
|
+
exit 1
|
27
23
|
end
|
28
24
|
|
29
25
|
##
|
@@ -31,13 +27,14 @@ module DirectoryLoader
|
|
31
27
|
# @param filenames (Array) File name list
|
32
28
|
# @param dirname (String) Base directory
|
33
29
|
def self.load_files(filenames, dirname)
|
34
|
-
|
30
|
+
data = {concepts: [], codes: [], problems: []}
|
35
31
|
filenames.each do |filename|
|
36
32
|
filepath = File.join(dirname, filename)
|
37
|
-
|
38
|
-
|
39
|
-
|
33
|
+
loaded = FileLoader.call(filepath)
|
34
|
+
data[:concepts] += loaded[:concepts]
|
35
|
+
data[:codes] += loaded[:codes]
|
36
|
+
data[:problems] += loaded[:problems]
|
40
37
|
end
|
41
|
-
|
38
|
+
data
|
42
39
|
end
|
43
40
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require "base64"
|
2
|
+
require_relative "../logger"
|
2
3
|
|
3
4
|
# Methods to load embedded files defined into asker input data file
|
4
5
|
# Example:
|
@@ -15,35 +16,34 @@ module EmbeddedFile
|
|
15
16
|
return load_video(value, localdir) if is_video? value
|
16
17
|
|
17
18
|
if is_url? value
|
18
|
-
Logger.
|
19
|
+
Logger.error "EmbebbedFile: Unkown URL (#{value})"
|
19
20
|
exit 1
|
20
21
|
end
|
21
22
|
|
22
23
|
filepath = File.join(localdir, value)
|
23
24
|
unless File.exist?(filepath)
|
24
|
-
Logger.
|
25
|
-
# return { text: "URI error", file: :none, type: :unkown }
|
25
|
+
Logger.error "EmbeddedFile: File does not exist (#{filepath})"
|
26
26
|
exit 1
|
27
27
|
end
|
28
28
|
|
29
29
|
# Suposse that filename is TEXT file
|
30
|
-
|
30
|
+
{text: "<pre>#{File.read(filepath)}</pre>", file: :none, type: :text}
|
31
31
|
end
|
32
32
|
|
33
33
|
def self.is_audio?(filename)
|
34
|
-
extens = [
|
35
|
-
extens.each {|ext| return true if filename.downcase.end_with?(ext) }
|
34
|
+
extens = [".mp3", ".ogg", ".wav"]
|
35
|
+
extens.each { |ext| return true if filename.downcase.end_with?(ext) }
|
36
36
|
false
|
37
37
|
end
|
38
38
|
|
39
39
|
def self.is_image?(filename)
|
40
|
-
extens = [
|
40
|
+
extens = [".jpg", ".jpeg", ".png"]
|
41
41
|
extens.each { |ext| return true if filename.downcase.end_with?(ext) }
|
42
42
|
false
|
43
43
|
end
|
44
44
|
|
45
45
|
def self.is_video?(filename)
|
46
|
-
extens = [
|
46
|
+
extens = [".mp4", ".ogv"]
|
47
47
|
extens.each { |ext| return true if filename.downcase.end_with?(ext) }
|
48
48
|
false
|
49
49
|
end
|
@@ -55,7 +55,7 @@ module EmbeddedFile
|
|
55
55
|
end
|
56
56
|
|
57
57
|
def self.load_audio(value, localdir)
|
58
|
-
output = {
|
58
|
+
output = {text: :error, file: :none, type: :audio}
|
59
59
|
|
60
60
|
if is_url? value
|
61
61
|
output[:text] = "<audio src=\"#{value}\" controls></audio>"
|
@@ -66,14 +66,14 @@ module EmbeddedFile
|
|
66
66
|
|
67
67
|
filepath = File.join(localdir, value)
|
68
68
|
unless File.exist?(filepath)
|
69
|
-
Logger.
|
69
|
+
Logger.error "EmbebbedFile: Audio file no exists (#{filepath})"
|
70
70
|
exit 1
|
71
71
|
end
|
72
72
|
output[:text] = '<audio controls><source src="@@PLUGINFILE@@/' + File.basename(filepath) \
|
73
73
|
+ '">Your browser does not support the audio tag.</audio>'
|
74
74
|
output[:file] = '<file name="' + File.basename(filepath) \
|
75
75
|
+ '" path="/" encoding="base64">' \
|
76
|
-
+ Base64.strict_encode64(File.open(filepath,
|
76
|
+
+ Base64.strict_encode64(File.open(filepath, "rb").read) \
|
77
77
|
+ "</file>"
|
78
78
|
output[:type] = :audio
|
79
79
|
output
|
@@ -91,14 +91,14 @@ module EmbeddedFile
|
|
91
91
|
|
92
92
|
filepath = File.join(localdir, value)
|
93
93
|
unless File.exist?(filepath)
|
94
|
-
Logger.
|
94
|
+
Logger.error "EmbeddedFile: Unknown file (#{filepath})"
|
95
95
|
exit 1
|
96
96
|
end
|
97
97
|
output[:text] = '<img src="@@PLUGINFILE@@/' + File.basename(filepath) \
|
98
98
|
+ '" alt="imagen" class="img-responsive atto_image_button_text-bottom">'
|
99
99
|
output[:file] = '<file name="' + File.basename(filepath) \
|
100
100
|
+ '" path="/" encoding="base64">' \
|
101
|
-
+ Base64.strict_encode64(File.open(filepath,
|
101
|
+
+ Base64.strict_encode64(File.open(filepath, "rb").read) \
|
102
102
|
+ "</file>"
|
103
103
|
output[:type] = :image
|
104
104
|
output
|
@@ -116,7 +116,7 @@ module EmbeddedFile
|
|
116
116
|
|
117
117
|
filepath = File.join(localdir, value)
|
118
118
|
unless File.exist?(filepath)
|
119
|
-
Logger.
|
119
|
+
Logger.error "Unknown file (#{filepath})"
|
120
120
|
exit 1
|
121
121
|
end
|
122
122
|
output[:text] = '<video controls><source src="@@PLUGINFILE@@/' \
|
@@ -1,19 +1,20 @@
|
|
1
1
|
require_relative "content_loader"
|
2
2
|
require_relative "haml_loader"
|
3
|
+
require_relative "../logger"
|
3
4
|
|
4
5
|
##
|
5
6
|
# Load a filename and return a Hash with concepts list and code list
|
6
7
|
# return { concepts: [], codes: [] }
|
7
8
|
module FileLoader
|
8
|
-
def self.
|
9
|
+
def self.call(filename)
|
9
10
|
if File.extname(filename).casecmp(".haml").zero?
|
10
11
|
file_content = HamlLoader.load filename
|
11
12
|
elsif File.extname(filename).casecmp(".xml").zero?
|
12
13
|
file_content = File.read(filename)
|
13
14
|
else
|
14
|
-
|
15
|
-
|
15
|
+
Logger.error "FileLoader: HAML or XML required (#{filename})"
|
16
|
+
exit 1
|
16
17
|
end
|
17
|
-
ContentLoader.
|
18
|
+
ContentLoader.call(filename, file_content)
|
18
19
|
end
|
19
20
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require "haml"
|
2
|
+
require_relative "../logger"
|
2
3
|
|
3
4
|
module HamlLoader
|
4
5
|
def self.load(filename)
|
@@ -9,9 +10,9 @@ module HamlLoader
|
|
9
10
|
# INFO <haml 6.1> 20221226
|
10
11
|
# return Haml::Template.new { template }.render
|
11
12
|
rescue => e
|
12
|
-
|
13
|
-
|
14
|
-
exit
|
13
|
+
Logger.error "HamlLoader: Can't load file (#{filename})"
|
14
|
+
Logger.error " : #{e}"
|
15
|
+
exit 1
|
15
16
|
end
|
16
17
|
haml_engine.render
|
17
18
|
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require "net/http"
|
2
2
|
require "uri"
|
3
|
+
require_relative "../logger"
|
3
4
|
|
4
5
|
# Search URL images on Internet
|
5
6
|
# Methods:
|
@@ -15,7 +16,8 @@ module ImageUrlLoader
|
|
15
16
|
elsif input.instance_of? Array
|
16
17
|
filters = sanitize_array(input.clone)
|
17
18
|
else
|
18
|
-
|
19
|
+
Logger.error "ImageUrlLoader: Unkown type (#{input.class})"
|
20
|
+
exit 1
|
19
21
|
end
|
20
22
|
# Search Image URLs from Google site, selected by <filters>
|
21
23
|
search_url = "https://www.google.es/search?q="
|
@@ -33,10 +35,9 @@ module ImageUrlLoader
|
|
33
35
|
end
|
34
36
|
end
|
35
37
|
rescue
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
puts " => Ensure URL is well formed"
|
38
|
+
Logger.warn "ImageUrlLoader: Problems with URL (#{search_url})"
|
39
|
+
Logger.warn " (a) Check Internet connections"
|
40
|
+
Logger.warn " (b) Ensure URL is well formed"
|
40
41
|
end
|
41
42
|
image_urls
|
42
43
|
end
|