asker-tool 2.6.0 → 2.7.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 +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
|