asker-tool 2.7.2 → 2.9.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/lib/asker/ai/problem/customizer.rb +36 -0
- data/lib/asker/ai/problem/problem_ai.rb +9 -239
- data/lib/asker/ai/problem/stage_answers.rb +104 -0
- data/lib/asker/ai/problem/stage_base.rb +34 -0
- data/lib/asker/ai/problem/stage_steps.rb +121 -0
- data/lib/asker/application.rb +1 -0
- data/lib/asker/check_input/check_haml_data.rb +2 -2
- data/lib/asker/cli.rb +2 -0
- data/lib/asker/data/concept.rb +5 -5
- data/lib/asker/data/problem.rb +10 -2
- data/lib/asker/data/project_data.rb +3 -2
- data/lib/asker/displayer/code_displayer.rb +2 -2
- data/lib/asker/displayer/concept_ai_displayer.rb +5 -3
- data/lib/asker/displayer/concept_displayer.rb +2 -2
- data/lib/asker/displayer/problem_displayer.rb +14 -7
- data/lib/asker/displayer/stats_displayer.rb +3 -3
- data/lib/asker/exporter/doc/format_code2doc.rb +17 -0
- data/lib/asker/exporter/doc/format_concept2doc.rb +30 -0
- data/lib/asker/exporter/doc/format_problem2doc.rb +41 -0
- data/lib/asker/exporter/export2doc.rb +41 -0
- data/lib/asker/exporter/{data_gift_exporter.rb → export2gift.rb} +8 -8
- data/lib/asker/exporter/{data_moodle_exporter.rb → export2moodle_xml.rb} +13 -11
- data/lib/asker/exporter/export2yaml.rb +70 -0
- data/lib/asker/exporter/export_action.rb +18 -0
- data/lib/asker/exporter/{code_gift_exporter.rb → gift/export_code2gift.rb} +7 -6
- data/lib/asker/exporter/{concept_ai_gift_exporter.rb → gift/export_concept2gift.rb} +7 -8
- data/lib/asker/exporter/{problem_gift_exporter.rb → gift/export_problem2gift.rb} +2 -2
- data/lib/asker/{formatter → exporter/gift}/question_gift_formatter.rb +0 -3
- data/lib/asker/formatter/concept_string_formatter.rb +0 -1
- data/lib/asker/formatter/{question_hash_formatter.rb → question2hash.rb} +15 -7
- data/lib/asker/formatter/{question_moodle_formatter.rb → question2moodle_xml.rb} +3 -5
- data/lib/asker/loader/code_loader.rb +1 -1
- data/lib/asker/loader/content_loader.rb +1 -0
- data/lib/asker/loader/embedded_file/loader.rb +114 -0
- data/lib/asker/loader/embedded_file/type.rb +51 -0
- data/lib/asker/loader/problem_loader.rb +2 -0
- data/lib/asker/logger.rb +1 -1
- data/lib/asker/start.rb +3 -3
- data/lib/asker/version.rb +1 -1
- metadata +22 -16
- data/lib/asker/deprecated/question_moodlexml_formatter.rb +0 -69
- data/lib/asker/exporter/concept_ai_yaml_exporter.rb +0 -36
- data/lib/asker/exporter/concept_doc_exporter.rb +0 -24
- data/lib/asker/exporter/output_file_exporter.rb +0 -18
- data/lib/asker/formatter/concept_doc_formatter.rb +0 -33
- data/lib/asker/loader/embedded_file.rb +0 -133
@@ -0,0 +1,114 @@
|
|
1
|
+
require "base64"
|
2
|
+
require_relative "../../logger"
|
3
|
+
require_relative "type"
|
4
|
+
|
5
|
+
module EmbeddedFile
|
6
|
+
# Methods to load embedded files defined into asker input data file
|
7
|
+
# Examples:
|
8
|
+
# def line with :type = :image_url used to link external file as https://..."
|
9
|
+
# def line with :type = :file used to load local file as image.png or file.txt"
|
10
|
+
class Loader
|
11
|
+
##
|
12
|
+
# @param value (String)
|
13
|
+
# @param localdir (String) Input file base folder
|
14
|
+
# @return Hash
|
15
|
+
def call(value, localdir)
|
16
|
+
filepath = File.join(localdir, value)
|
17
|
+
type = EmbebbedFile::Type.new.for(value, localdir)
|
18
|
+
|
19
|
+
case type
|
20
|
+
when :image
|
21
|
+
return load_image(value, localdir)
|
22
|
+
when :image_url
|
23
|
+
return load_image_url(value, localdir)
|
24
|
+
when :audio
|
25
|
+
return load_audio(value, localdir)
|
26
|
+
when :audio_url
|
27
|
+
return load_audio_url(value, localdir)
|
28
|
+
when :video
|
29
|
+
return load_video(value, localdir)
|
30
|
+
when :video_url
|
31
|
+
return load_video_url(value, localdir)
|
32
|
+
end
|
33
|
+
|
34
|
+
{
|
35
|
+
text: "<pre>#{File.read(filepath)}</pre>",
|
36
|
+
file: :none,
|
37
|
+
type: :text,
|
38
|
+
url: value
|
39
|
+
}
|
40
|
+
end
|
41
|
+
|
42
|
+
def load_audio(value, localdir)
|
43
|
+
filepath = File.join(localdir, value)
|
44
|
+
output = {}
|
45
|
+
output[:text] = '<audio controls><source src="@@PLUGINFILE@@/' + File.basename(filepath) \
|
46
|
+
+ '">Your browser does not support the audio tag.</audio>'
|
47
|
+
output[:file] = '<file name="' + File.basename(filepath) \
|
48
|
+
+ '" path="/" encoding="base64">' \
|
49
|
+
+ Base64.strict_encode64(File.open(filepath, "rb").read) \
|
50
|
+
+ "</file>"
|
51
|
+
output[:type] = :audio
|
52
|
+
output[:url] = value
|
53
|
+
output
|
54
|
+
end
|
55
|
+
|
56
|
+
def load_audio_url(value, localdir)
|
57
|
+
{
|
58
|
+
text: "<audio src=\"#{value}\" controls></audio>",
|
59
|
+
file: :none,
|
60
|
+
type: :url,
|
61
|
+
url: value
|
62
|
+
}
|
63
|
+
end
|
64
|
+
|
65
|
+
def load_image(value, localdir)
|
66
|
+
filepath = File.join(localdir, value)
|
67
|
+
output = {}
|
68
|
+
output[:text] = '<img src="@@PLUGINFILE@@/' + File.basename(filepath) \
|
69
|
+
+ '" alt="imagen" class="img-responsive atto_image_button_text-bottom">'
|
70
|
+
output[:file] = '<file name="' + File.basename(filepath) \
|
71
|
+
+ '" path="/" encoding="base64">' \
|
72
|
+
+ Base64.strict_encode64(File.open(filepath, "rb").read) \
|
73
|
+
+ "</file>"
|
74
|
+
output[:type] = :image
|
75
|
+
output[:url] = value
|
76
|
+
output
|
77
|
+
end
|
78
|
+
|
79
|
+
def load_image_url(value, localdir)
|
80
|
+
{
|
81
|
+
text: "<img src=\"#{value}\" alt=\"image\" width=\"400\" height=\"300\">",
|
82
|
+
file: :none,
|
83
|
+
type: :url,
|
84
|
+
url: value
|
85
|
+
}
|
86
|
+
end
|
87
|
+
|
88
|
+
def load_video(value, localdir)
|
89
|
+
filepath = File.join(localdir, value)
|
90
|
+
output = {}
|
91
|
+
output[:text] = '<video controls><source src="@@PLUGINFILE@@/' \
|
92
|
+
+ File.basename(filepath) \
|
93
|
+
+ '"/>Your browser does not support the video tag.</video>'
|
94
|
+
output[:file] = '<file name="' \
|
95
|
+
+ File.basename(filepath) \
|
96
|
+
+ '" path="/" encoding="base64">' \
|
97
|
+
+ Base64.strict_encode64(File.open(filepath, "rb").read) \
|
98
|
+
+ "</file>"
|
99
|
+
output[:type] = :video
|
100
|
+
output[:url] = value
|
101
|
+
output
|
102
|
+
end
|
103
|
+
|
104
|
+
def load_video_url(value, localdir)
|
105
|
+
{
|
106
|
+
text: "<video controls width=\"400\" height=\"300\">" \
|
107
|
+
+ "<source src=\"#{value}\"/></video>",
|
108
|
+
file: :none,
|
109
|
+
type: :url,
|
110
|
+
url: value
|
111
|
+
}
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
|
2
|
+
module EmbebbedFile
|
3
|
+
class Type
|
4
|
+
def for(value, localdir)
|
5
|
+
if is_url? value
|
6
|
+
return :image_url if is_image? value
|
7
|
+
return :audio_url if is_audio? value
|
8
|
+
return :video_url if is_video? value
|
9
|
+
|
10
|
+
Logger.error "EmbebbedFile::Type.for: Unknown URL type (#{value})"
|
11
|
+
exit 1
|
12
|
+
end
|
13
|
+
|
14
|
+
filepath = File.join(localdir, value)
|
15
|
+
unless File.exist?(filepath)
|
16
|
+
Logger.error "EmbeddedFile::Type.for: File does not exist (#{filepath})"
|
17
|
+
exit 1
|
18
|
+
end
|
19
|
+
|
20
|
+
return :image if is_image? value
|
21
|
+
return :audio if is_audio? value
|
22
|
+
return :video if is_video? value
|
23
|
+
|
24
|
+
:text
|
25
|
+
end
|
26
|
+
|
27
|
+
def is_audio?(filename)
|
28
|
+
extens = [".mp3", ".ogg", ".wav"]
|
29
|
+
extens.each { |ext| return true if filename.downcase.end_with?(ext) }
|
30
|
+
false
|
31
|
+
end
|
32
|
+
|
33
|
+
def is_image?(filename)
|
34
|
+
extens = [".jpg", ".jpeg", ".png"]
|
35
|
+
extens.each { |ext| return true if filename.downcase.end_with?(ext) }
|
36
|
+
false
|
37
|
+
end
|
38
|
+
|
39
|
+
def is_video?(filename)
|
40
|
+
extens = [".mp4", ".ogv"]
|
41
|
+
extens.each { |ext| return true if filename.downcase.end_with?(ext) }
|
42
|
+
false
|
43
|
+
end
|
44
|
+
|
45
|
+
def is_url?(value)
|
46
|
+
return true if value.start_with?("https://", "http://")
|
47
|
+
|
48
|
+
false
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
data/lib/asker/logger.rb
CHANGED
data/lib/asker/start.rb
CHANGED
@@ -2,14 +2,14 @@ require_relative "application"
|
|
2
2
|
require_relative "logger"
|
3
3
|
require_relative "displayer/concept_displayer"
|
4
4
|
require_relative "displayer/stats_displayer"
|
5
|
-
require_relative "exporter/
|
5
|
+
require_relative "exporter/export_action"
|
6
6
|
require_relative "loader/project_loader"
|
7
7
|
require_relative "loader/input_loader"
|
8
8
|
|
9
9
|
class Start
|
10
10
|
def call(filepath)
|
11
11
|
project_data, data = load_input(filepath)
|
12
|
-
ConceptDisplayer.
|
12
|
+
ConceptDisplayer.new.call(data[:concepts])
|
13
13
|
create_output(project_data, data)
|
14
14
|
end
|
15
15
|
|
@@ -37,7 +37,7 @@ class Start
|
|
37
37
|
end
|
38
38
|
|
39
39
|
def create_output(project, data)
|
40
|
-
|
40
|
+
ExportAction.new.call(data, project)
|
41
41
|
StatsDisplayer.show(data)
|
42
42
|
Logger.close
|
43
43
|
end
|
data/lib/asker/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: asker-tool
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.9.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Vargas Ruiz
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-09-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: haml
|
@@ -117,7 +117,11 @@ files:
|
|
117
117
|
- lib/asker/ai/code/ruby_code_ai.rb
|
118
118
|
- lib/asker/ai/code/sql_code_ai.rb
|
119
119
|
- lib/asker/ai/concept_ai.rb
|
120
|
+
- lib/asker/ai/problem/customizer.rb
|
120
121
|
- lib/asker/ai/problem/problem_ai.rb
|
122
|
+
- lib/asker/ai/problem/stage_answers.rb
|
123
|
+
- lib/asker/ai/problem/stage_base.rb
|
124
|
+
- lib/asker/ai/problem/stage_steps.rb
|
121
125
|
- lib/asker/ai/question.rb
|
122
126
|
- lib/asker/ai/stages/base_stage.rb
|
123
127
|
- lib/asker/ai/stages/main.rb
|
@@ -142,21 +146,24 @@ files:
|
|
142
146
|
- lib/asker/data/table.rb
|
143
147
|
- lib/asker/data/template.rb
|
144
148
|
- lib/asker/data/world.rb
|
145
|
-
- lib/asker/deprecated/question_moodlexml_formatter.rb
|
146
149
|
- lib/asker/displayer/code_displayer.rb
|
147
150
|
- lib/asker/displayer/concept_ai_displayer.erb
|
148
151
|
- lib/asker/displayer/concept_ai_displayer.rb
|
149
152
|
- lib/asker/displayer/concept_displayer.rb
|
150
153
|
- lib/asker/displayer/problem_displayer.rb
|
151
154
|
- lib/asker/displayer/stats_displayer.rb
|
152
|
-
- lib/asker/exporter/
|
153
|
-
- lib/asker/exporter/
|
154
|
-
- lib/asker/exporter/
|
155
|
-
- lib/asker/exporter/
|
156
|
-
- lib/asker/exporter/
|
157
|
-
- lib/asker/exporter/
|
158
|
-
- lib/asker/exporter/
|
159
|
-
- lib/asker/exporter/
|
155
|
+
- lib/asker/exporter/doc/format_code2doc.rb
|
156
|
+
- lib/asker/exporter/doc/format_concept2doc.rb
|
157
|
+
- lib/asker/exporter/doc/format_problem2doc.rb
|
158
|
+
- lib/asker/exporter/export2doc.rb
|
159
|
+
- lib/asker/exporter/export2gift.rb
|
160
|
+
- lib/asker/exporter/export2moodle_xml.rb
|
161
|
+
- lib/asker/exporter/export2yaml.rb
|
162
|
+
- lib/asker/exporter/export_action.rb
|
163
|
+
- lib/asker/exporter/gift/export_code2gift.rb
|
164
|
+
- lib/asker/exporter/gift/export_concept2gift.rb
|
165
|
+
- lib/asker/exporter/gift/export_problem2gift.rb
|
166
|
+
- lib/asker/exporter/gift/question_gift_formatter.rb
|
160
167
|
- lib/asker/files/asker.ini
|
161
168
|
- lib/asker/files/example-code.haml
|
162
169
|
- lib/asker/files/example-concept.haml
|
@@ -191,7 +198,6 @@ files:
|
|
191
198
|
- lib/asker/files/language/sql/mistakes.yaml
|
192
199
|
- lib/asker/files/language/sql/templates.yaml
|
193
200
|
- lib/asker/formatter/code_string_formatter.rb
|
194
|
-
- lib/asker/formatter/concept_doc_formatter.rb
|
195
201
|
- lib/asker/formatter/concept_string_formatter.rb
|
196
202
|
- lib/asker/formatter/moodle/ddmatch.erb
|
197
203
|
- lib/asker/formatter/moodle/gapfill.erb
|
@@ -200,9 +206,8 @@ files:
|
|
200
206
|
- lib/asker/formatter/moodle/ordering.erb
|
201
207
|
- lib/asker/formatter/moodle/shortanswer.erb
|
202
208
|
- lib/asker/formatter/moodle/truefalse.erb
|
203
|
-
- lib/asker/formatter/
|
204
|
-
- lib/asker/formatter/
|
205
|
-
- lib/asker/formatter/question_moodle_formatter.rb
|
209
|
+
- lib/asker/formatter/question2hash.rb
|
210
|
+
- lib/asker/formatter/question2moodle_xml.rb
|
206
211
|
- lib/asker/formatter/rb2haml_formatter.rb
|
207
212
|
- lib/asker/lang/lang.rb
|
208
213
|
- lib/asker/lang/lang_factory.rb
|
@@ -210,7 +215,8 @@ files:
|
|
210
215
|
- lib/asker/loader/code_loader.rb
|
211
216
|
- lib/asker/loader/content_loader.rb
|
212
217
|
- lib/asker/loader/directory_loader.rb
|
213
|
-
- lib/asker/loader/embedded_file.rb
|
218
|
+
- lib/asker/loader/embedded_file/loader.rb
|
219
|
+
- lib/asker/loader/embedded_file/type.rb
|
214
220
|
- lib/asker/loader/file_loader.rb
|
215
221
|
- lib/asker/loader/haml_loader.rb
|
216
222
|
- lib/asker/loader/image_url_loader.rb
|
@@ -1,69 +0,0 @@
|
|
1
|
-
# Transform Questions into Gift format
|
2
|
-
module QuestionMoodleXMLFormatter
|
3
|
-
def self.to_s(question)
|
4
|
-
@question = question
|
5
|
-
|
6
|
-
case @question.type
|
7
|
-
when :choice
|
8
|
-
s += choice_to_s(question)
|
9
|
-
when :boolean
|
10
|
-
when :match
|
11
|
-
when :short
|
12
|
-
end
|
13
|
-
s.flaten!
|
14
|
-
end
|
15
|
-
|
16
|
-
def self.choice_to_s(question)
|
17
|
-
s = []
|
18
|
-
|
19
|
-
penalties = ["", "%-50%", "%-33.33333%", "%-25%", "%-20%"]
|
20
|
-
penalty = penalties[question.bads.size]
|
21
|
-
|
22
|
-
s << "<!-- question: #{question.name} -->"
|
23
|
-
s << '<question type="multichoice">'
|
24
|
-
s << " <name>"
|
25
|
-
s << " <text>#{question.name}</text>"
|
26
|
-
s << " </name>"
|
27
|
-
s << ' <questiontext format="html">'
|
28
|
-
s << " <text><![CDATA[#{question.text}]]></text>"
|
29
|
-
s << " </questiontext>"
|
30
|
-
s << ' <generalfeedback format="html">'
|
31
|
-
s << " <text>#{question.feedback}</text>"
|
32
|
-
s << " </generalfeedback>"
|
33
|
-
s << " <defaultgrade>1.0000000</defaultgrade>"
|
34
|
-
s << " <penalty>#{penalty}</penalty>"
|
35
|
-
s << " <hidden>0</hidden>"
|
36
|
-
s << " <single>true</single>"
|
37
|
-
s << " <shuffleanswers>#{question.shuffle?}</shuffleanswers>"
|
38
|
-
s << " <answernumbering>abc</answernumbering>"
|
39
|
-
s << ' <incorrectfeedback format="html">'
|
40
|
-
s << " <text>#{question.feedback}</text>"
|
41
|
-
s << " </incorrectfeedback>"
|
42
|
-
s << ' <answer fraction="100" format="html">'
|
43
|
-
s << " <text>#{question.good}</text>"
|
44
|
-
s << " </answer>"
|
45
|
-
s << ' <answer fraction="-25" format="html">'
|
46
|
-
s << " <text>#{question.bad[0]}</text>"
|
47
|
-
s << " </answer>"
|
48
|
-
s << " </question>"
|
49
|
-
s << ' <answer fraction="-25" format="html">'
|
50
|
-
s << " <text>#{question.bad[1]}</text>"
|
51
|
-
s << " </answer>"
|
52
|
-
s << " </question>"
|
53
|
-
s << ' <answer fraction="-25" format="html">'
|
54
|
-
s << " <text>#{question.bad[2]}</text>"
|
55
|
-
s << " </answer>"
|
56
|
-
s << " </question>"
|
57
|
-
s
|
58
|
-
end
|
59
|
-
|
60
|
-
def self.sanitize(input = "")
|
61
|
-
output = input.dup
|
62
|
-
output.tr!("\n", " ")
|
63
|
-
output.tr!(":", ":")
|
64
|
-
output.tr!("=", "\\=")
|
65
|
-
# output.gsub!('{', "\\{")
|
66
|
-
# output.gsub!('}', "\\}")
|
67
|
-
output
|
68
|
-
end
|
69
|
-
end
|
@@ -1,36 +0,0 @@
|
|
1
|
-
require "yaml"
|
2
|
-
require_relative "../formatter/question_hash_formatter"
|
3
|
-
|
4
|
-
# Use to export data from ConceptIA to YAML format
|
5
|
-
module ConceptAIYAMLExporter
|
6
|
-
##
|
7
|
-
# Export array of ConceptAI objects from Project to YAML output file
|
8
|
-
# @param concepts_ai (Array)
|
9
|
-
# @param project (Project)
|
10
|
-
def self.export_all(concepts_ai, project)
|
11
|
-
questions = []
|
12
|
-
concepts_ai.each do |concept_ai|
|
13
|
-
questions += get_questions_from concept_ai
|
14
|
-
end
|
15
|
-
params = {lang: project.get(:lang),
|
16
|
-
projectname: project.get(:projectname)}
|
17
|
-
output = {params: params, questions: questions}
|
18
|
-
|
19
|
-
yamlfile = File.open(project.get(:yamlpath), "w")
|
20
|
-
yamlfile.write(output.to_yaml)
|
21
|
-
yamlfile.close
|
22
|
-
end
|
23
|
-
|
24
|
-
private_class_method def self.get_questions_from(concept_ai)
|
25
|
-
data = []
|
26
|
-
return data unless concept_ai.concept.process?
|
27
|
-
|
28
|
-
Application.instance.config["questions"]["stages"].each do |stage|
|
29
|
-
concept_ai.questions[stage].each do |question|
|
30
|
-
question.lang = concept_ai.concept.lang
|
31
|
-
data << QuestionHashFormatter.to_hash(question)
|
32
|
-
end
|
33
|
-
end
|
34
|
-
data
|
35
|
-
end
|
36
|
-
end
|
@@ -1,24 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative "../formatter/concept_doc_formatter"
|
4
|
-
require_relative "../version"
|
5
|
-
|
6
|
-
##
|
7
|
-
# Export Concept to Doc file
|
8
|
-
module ConceptDocExporter
|
9
|
-
##
|
10
|
-
# Export array of concepts to doc
|
11
|
-
def self.export_all(concepts, project)
|
12
|
-
file = File.new(project.get(:lessonpath), "w")
|
13
|
-
file.write("=" * 50 + "\n")
|
14
|
-
file.write("Created by : #{Asker::NAME} (version #{Asker::VERSION})\n")
|
15
|
-
file.write("File : #{project.get(:lessonname)}\n")
|
16
|
-
file.write("Time : #{Time.new}\n")
|
17
|
-
file.write("=" * 50 + "\n")
|
18
|
-
|
19
|
-
concepts.each do |concept|
|
20
|
-
file.write(ConceptDocFormatter.to_s(concept)) if concept.process
|
21
|
-
end
|
22
|
-
file.close
|
23
|
-
end
|
24
|
-
end
|
@@ -1,18 +0,0 @@
|
|
1
|
-
require_relative "concept_ai_yaml_exporter"
|
2
|
-
require_relative "concept_doc_exporter"
|
3
|
-
require_relative "data_gift_exporter"
|
4
|
-
require_relative "data_moodle_exporter"
|
5
|
-
|
6
|
-
##
|
7
|
-
# Export Output data files
|
8
|
-
# * YAML, Doc (txt), Gift (ConceptAI, Code) and Moodle XML (ConceptAI, Code)
|
9
|
-
module OutputFileExporter
|
10
|
-
def self.export(data, project)
|
11
|
-
config = Application.instance.config
|
12
|
-
|
13
|
-
ConceptAIYAMLExporter.export_all(data[:concepts_ai], project) if config["output"]["yaml"] == "yes"
|
14
|
-
ConceptDocExporter.export_all(data[:concepts], project) if config["output"]["doc"] == "yes"
|
15
|
-
DataGiftExporter.export_all(data, project) if config["output"]["gift"] == "yes"
|
16
|
-
DataMoodleExporter.call(data, project) if config["output"]["moodle"] == "yes"
|
17
|
-
end
|
18
|
-
end
|
@@ -1,33 +0,0 @@
|
|
1
|
-
# frozen_string_literal: false
|
2
|
-
|
3
|
-
require "rainbow"
|
4
|
-
require "terminal-table"
|
5
|
-
|
6
|
-
module ConceptDocFormatter
|
7
|
-
##
|
8
|
-
# Formatter Concept into Doc
|
9
|
-
# @param concept (Concept)
|
10
|
-
def self.to_s(concept)
|
11
|
-
out = ""
|
12
|
-
out << "\n#{Rainbow(concept.name).bg(:blue).bright}\n\n"
|
13
|
-
concept.texts.each { |i| out << "* #{i}\n" }
|
14
|
-
out << "\n"
|
15
|
-
concept.tables.each do |table|
|
16
|
-
out << table_to_s(table)
|
17
|
-
end
|
18
|
-
out
|
19
|
-
end
|
20
|
-
|
21
|
-
##
|
22
|
-
# Formatter Table to Doc
|
23
|
-
# @param table (Table)
|
24
|
-
# @return String
|
25
|
-
def self.table_to_s(table)
|
26
|
-
my_screen_table = Terminal::Table.new do |st|
|
27
|
-
st << table.fields
|
28
|
-
st << :separator
|
29
|
-
table.rows.each { |r| st.add_row r }
|
30
|
-
end
|
31
|
-
"#{my_screen_table}\n"
|
32
|
-
end
|
33
|
-
end
|
@@ -1,133 +0,0 @@
|
|
1
|
-
require "base64"
|
2
|
-
require_relative "../logger"
|
3
|
-
|
4
|
-
# Methods to load embedded files defined into asker input data file
|
5
|
-
# Example:
|
6
|
-
# * def line with :type = :image_url used to link external file as https://..."
|
7
|
-
# * def line with :type = :file used to load local file as image.png or file.txt"
|
8
|
-
module EmbeddedFile
|
9
|
-
##
|
10
|
-
# @param value (String)
|
11
|
-
# @param localdir (String) Input file base folder
|
12
|
-
# @return Hash
|
13
|
-
def self.load(value, localdir)
|
14
|
-
return load_image(value, localdir) if is_image? value
|
15
|
-
return load_audio(value, localdir) if is_audio? value
|
16
|
-
return load_video(value, localdir) if is_video? value
|
17
|
-
|
18
|
-
if is_url? value
|
19
|
-
Logger.error "EmbebbedFile: Unknown URL type (#{value})"
|
20
|
-
exit 1
|
21
|
-
end
|
22
|
-
|
23
|
-
filepath = File.join(localdir, value)
|
24
|
-
unless File.exist?(filepath)
|
25
|
-
Logger.error "EmbeddedFile: File does not exist (#{filepath})"
|
26
|
-
exit 1
|
27
|
-
end
|
28
|
-
|
29
|
-
# Suposse that filename is TEXT file
|
30
|
-
{text: "<pre>#{File.read(filepath)}</pre>", file: :none, type: :text}
|
31
|
-
end
|
32
|
-
|
33
|
-
def self.is_audio?(filename)
|
34
|
-
extens = [".mp3", ".ogg", ".wav"]
|
35
|
-
extens.each { |ext| return true if filename.downcase.end_with?(ext) }
|
36
|
-
false
|
37
|
-
end
|
38
|
-
|
39
|
-
def self.is_image?(filename)
|
40
|
-
extens = [".jpg", ".jpeg", ".png"]
|
41
|
-
extens.each { |ext| return true if filename.downcase.end_with?(ext) }
|
42
|
-
false
|
43
|
-
end
|
44
|
-
|
45
|
-
def self.is_video?(filename)
|
46
|
-
extens = [".mp4", ".ogv"]
|
47
|
-
extens.each { |ext| return true if filename.downcase.end_with?(ext) }
|
48
|
-
false
|
49
|
-
end
|
50
|
-
|
51
|
-
def self.is_url?(value)
|
52
|
-
return true if value.start_with?("https://", "http://")
|
53
|
-
|
54
|
-
false
|
55
|
-
end
|
56
|
-
|
57
|
-
def self.load_audio(value, localdir)
|
58
|
-
output = {text: :error, file: :none, type: :audio}
|
59
|
-
|
60
|
-
if is_url? value
|
61
|
-
output[:text] = "<audio src=\"#{value}\" controls></audio>"
|
62
|
-
output[:file] = :none
|
63
|
-
output[:type] = :url
|
64
|
-
return output
|
65
|
-
end
|
66
|
-
|
67
|
-
filepath = File.join(localdir, value)
|
68
|
-
unless File.exist?(filepath)
|
69
|
-
Logger.error "EmbebbedFile: Audio file no exists (#{filepath})"
|
70
|
-
exit 1
|
71
|
-
end
|
72
|
-
output[:text] = '<audio controls><source src="@@PLUGINFILE@@/' + File.basename(filepath) \
|
73
|
-
+ '">Your browser does not support the audio tag.</audio>'
|
74
|
-
output[:file] = '<file name="' + File.basename(filepath) \
|
75
|
-
+ '" path="/" encoding="base64">' \
|
76
|
-
+ Base64.strict_encode64(File.open(filepath, "rb").read) \
|
77
|
-
+ "</file>"
|
78
|
-
output[:type] = :audio
|
79
|
-
output
|
80
|
-
end
|
81
|
-
|
82
|
-
def self.load_image(value, localdir)
|
83
|
-
output = {text: :error, file: :none, type: :image}
|
84
|
-
|
85
|
-
if is_url? value
|
86
|
-
output[:text] = "<img src=\"#{value}\" alt=\"image\" width=\"400\" height=\"300\">"
|
87
|
-
output[:file] = :none
|
88
|
-
output[:type] = :url
|
89
|
-
return output
|
90
|
-
end
|
91
|
-
|
92
|
-
filepath = File.join(localdir, value)
|
93
|
-
unless File.exist?(filepath)
|
94
|
-
Logger.error "EmbeddedFile: Unknown file (#{filepath})"
|
95
|
-
exit 1
|
96
|
-
end
|
97
|
-
output[:text] = '<img src="@@PLUGINFILE@@/' + File.basename(filepath) \
|
98
|
-
+ '" alt="imagen" class="img-responsive atto_image_button_text-bottom">'
|
99
|
-
output[:file] = '<file name="' + File.basename(filepath) \
|
100
|
-
+ '" path="/" encoding="base64">' \
|
101
|
-
+ Base64.strict_encode64(File.open(filepath, "rb").read) \
|
102
|
-
+ "</file>"
|
103
|
-
output[:type] = :image
|
104
|
-
output
|
105
|
-
end
|
106
|
-
|
107
|
-
def self.load_video(value, localdir)
|
108
|
-
output = {text: :error, file: :none, type: :video}
|
109
|
-
if is_url? value
|
110
|
-
output[:text] = "<video controls width=\"400\" height=\"300\">" \
|
111
|
-
+ "<source src=\"#{value}\"/></video>"
|
112
|
-
output[:file] = :none
|
113
|
-
output[:type] = :url
|
114
|
-
return output
|
115
|
-
end
|
116
|
-
|
117
|
-
filepath = File.join(localdir, value)
|
118
|
-
unless File.exist?(filepath)
|
119
|
-
Logger.error "Unknown file (#{filepath})"
|
120
|
-
exit 1
|
121
|
-
end
|
122
|
-
output[:text] = '<video controls><source src="@@PLUGINFILE@@/' \
|
123
|
-
+ File.basename(filepath) \
|
124
|
-
+ '"/>Your browser does not support the video tag.</video>'
|
125
|
-
output[:file] = '<file name="' \
|
126
|
-
+ File.basename(filepath) \
|
127
|
-
+ '" path="/" encoding="base64">' \
|
128
|
-
+ Base64.strict_encode64(File.open(filepath, "rb").read) \
|
129
|
-
+ "</file>"
|
130
|
-
output[:type] = :video
|
131
|
-
output
|
132
|
-
end
|
133
|
-
end
|