asker-tool 2.5.8 → 2.6.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '0359889621d3fa9e0cf0c303e7cd1eed5bd958b6911bd52117947ffded891546'
4
- data.tar.gz: 54bf9b4ee1a12a4317aa65a4645f4b0e6a5d8585b5713b3f3bd428df70a0b317
3
+ metadata.gz: 4e52e2a64c37e3cf1409af05602aa6288819831de131c593bc8720a4d86c38a4
4
+ data.tar.gz: b367db01461c59d95035423634136948a6965724e4dc1e4dd4b8147def181e15
5
5
  SHA512:
6
- metadata.gz: 9e09b85b5a08eba1a49efcb1032a74fa757984528ce793caceea49c9eb653b38cb6bf48f79733858bdf553ec195bbb725d6c39a003648885a2096762b139d0f1
7
- data.tar.gz: f8117340cc933ec01a342b7ddce9cc83135194729613cd29c459466acc00c900bb1a8b1fe55c84272e6e29627ceeb4fc2c29b7924ed5c4d1bcdb48adeb0961f4
6
+ metadata.gz: 01a6a5d7b788295d8fa7b905ce36245f5c0018503bf08ad8cfc0dfd8552ee90566290c50159dcfb0d813e1ee4b65fd82a1d0e4532e4e18d35263c03554da410b
7
+ data.tar.gz: 48ae68fb3f700d91208e013ab2e52fd358b593e76451ff02580b057e01f2f0a6afc6aa83ae82782590b03fff2335d7829e86944dbe9cd042342775f3fe6b1793
data/README.md CHANGED
@@ -21,11 +21,10 @@ gem install asker-tool
21
21
 
22
22
  # Usage
23
23
 
24
- | Step | Action | Description |
25
- | ---: | --------------------- | ----------- |
26
- | 1 | Create your **input file** | Create input file with your contents (_conceptual map_). Here are some [examples](./docs/examples). And more examples at this [repository](https://github.com/dvarrui/asker-inputs).
27
- | 2 | **Run `asker`** | `asker PATH/TO/INPUT` |
28
- | 3 | Choose your **output files** | Output files saved into the `output` folder |
24
+ | Step | Action | Tool | Description |
25
+ | ---: | --------------------- | ---- | ----------- |
26
+ | 1 | Define your concepts | Text plain editor | Create input file with your contents (_conceptual map_). Here are some [examples](./docs/examples). And more examples at this [repository](https://github.com/dvarrui/asker-inputs).
27
+ | 2 | Generate questions | `asker PATH/TO/INPUT` | **Run `asker`** to process input file. Output files are saved into the `output` folder |
29
28
 
30
29
  Let's see an example creating questions from ACDC input example file:
31
30
 
@@ -46,6 +45,10 @@ Let's see an example creating questions from ACDC input example file:
46
45
 
47
46
  * [Free Software License](LICENSE).
48
47
  * Multiplatform.
48
+ * Input files formats: XML, HAML.
49
+ * Output formats: GIFT, Moodle XML.
50
+ * Question types: true/false, multiple choice, short answer, matching.
51
+ * Embeded files: mp3, ogg, wav, jpg, jpeg, png, mp4, ogv and plain text files.
49
52
 
50
53
  # Documentation
51
54
 
data/lib/asker/ai/ai.rb CHANGED
@@ -13,13 +13,13 @@ module AI
13
13
 
14
14
  make_questions_stages_di
15
15
  # Process every table of this concept
16
- concept.tables.each do |tab|
17
- list1, list2 = get_list1_and_list2_from(tab)
18
- make_questions_stages_bsf(tab, list1, list2)
19
- make_questions_stages_t(tab, list1, list2)
16
+ concept.tables.each do |table|
17
+ list1, list2 = get_list1_and_list2_from(table)
18
+ make_questions_stages_bsf(table, list1, list2)
19
+ make_questions_stages_t(table, list1, list2)
20
20
  end
21
21
  # -------------------------------------------------------
22
- # Exclude questions as is defined into config.ini params
22
+ # Exclude questions as is defined into asker.ini params
23
23
  exclude_questions
24
24
  end
25
25
 
@@ -30,27 +30,24 @@ module AI
30
30
  end
31
31
 
32
32
  # Make questions for stages B, S and F
33
- def make_questions_stages_bsf(tab, list1, list2)
33
+ def make_questions_stages_bsf(table, list1, list2)
34
34
  # Stage B: process table to make match questions
35
- @questions[:b] += StageB.new(self).run(tab, list1, list2)
35
+ @questions[:b] += StageB.new(self).run(table, list1, list2)
36
36
  # Stage S: process tables with sequences
37
- @questions[:s] += StageS.new(self).run(tab, list1, list2)
37
+ @questions[:s] += StageS.new(self).run(table, list1, list2)
38
38
  # Stage F: process tables with only 1 field
39
- @questions[:f] += StageF.new(self).run(tab, list1, list2)
39
+ @questions[:f] += StageF.new(self).run(table, list1, list2)
40
40
  end
41
41
 
42
- # Make questions for stage T
43
- def make_questions_stages_t(tab, list1, list2)
42
+ def make_questions_stages_t(table, list1, list2)
44
43
  # Stage T: process_tableXfields
45
44
  list3 = list1 + list2
46
45
  list1.each do |row|
47
46
  reorder_list_with_row(list3, row)
48
- @questions[:t] += StageT.new(self).run(tab, row, list3)
47
+ @questions[:t] += StageT.new(self).run(table, row, list3)
49
48
  end
50
49
  end
51
50
 
52
- # rubocop:disable Metrics/AbcSize
53
- # rubocop:disable Metrics/MethodLength
54
51
  def exclude_questions
55
52
  param = Application.instance.config['questions']['exclude']
56
53
  return if param.nil?
@@ -66,8 +63,6 @@ module AI
66
63
  @questions = input
67
64
  @excluded_questions = output
68
65
  end
69
- # rubocop:enable Metrics/AbcSize
70
- # rubocop:enable Metrics/MethodLength
71
66
 
72
67
  def string_has_this_tags?(input, tags)
73
68
  flag = false
@@ -7,8 +7,6 @@ module AICalculate
7
7
  # * return list1 (Array) List with all the rows from the table
8
8
  # * return list2 (Array) List with similar rows (same table name) from the neighbours tables
9
9
  # @param p_table (Table)
10
- # rubocop:disable Metrics/MethodLength
11
- # rubocop:disable Metrics/AbcSize
12
10
  def get_list1_and_list2_from(p_table)
13
11
  # create <list1> with all the rows from the table
14
12
  list1 = []
@@ -32,8 +30,6 @@ module AICalculate
32
30
  end
33
31
  [list1, list2]
34
32
  end
35
- # rubocop:enable Metrics/MethodLength
36
- # rubocop:enable Metrics/AbcSize
37
33
 
38
34
  def calculate_nearness_between_texts(text1, text2)
39
35
  return 0.0 if text2.nil? || text2.empty?
@@ -44,26 +40,23 @@ module AICalculate
44
40
  (count * 100 / words.count)
45
41
  end
46
42
 
47
- # rubocop:disable Metrics/MethodLength
48
- # rubocop:disable Metrics/AbcSize
49
43
  def reorder_list_with_row(list, row)
50
- # evaluate every row of the list2
44
+ # evaluate every row of the list, and calculate weight
45
+ magic_number = -300
51
46
  list.each do |r|
52
47
  if r[:id] == row[:id]
53
- r[:weight] = -300
48
+ r[:weight] = magic_number
54
49
  else
55
- val = 0
50
+ value = 0
56
51
  s = row[:data].count
57
52
  s.times do |i|
58
- val += calculate_nearness_between_texts(row[:data][i], r[:data][i])
53
+ value += calculate_nearness_between_texts(row[:data][i], r[:data][i])
59
54
  end
60
- val /= s
61
- r[:weight] = val
55
+ value /= s
56
+ r[:weight] = value
62
57
  end
63
58
  end
64
59
  list.sort! { |a, b| a[:weight] <=> b[:weight] }
65
60
  list.reverse!
66
61
  end
67
- # rubocop:enable Metrics/MethodLength
68
- # rubocop:enable Metrics/AbcSize
69
62
  end
@@ -1,7 +1,6 @@
1
-
2
- require_relative 'stage_d'
3
- require_relative 'stage_b'
4
- require_relative 'stage_f'
5
- require_relative 'stage_i'
6
- require_relative 'stage_s'
7
- require_relative 'stage_t'
1
+ require_relative "stage_d"
2
+ require_relative "stage_b"
3
+ require_relative "stage_f"
4
+ require_relative "stage_i"
5
+ require_relative "stage_s"
6
+ require_relative "stage_t"
@@ -1,20 +1,15 @@
1
- # frozen_string_literal: true
2
-
3
- require 'set'
4
- require_relative 'base_stage'
5
- require_relative '../question'
1
+ require "set"
2
+ require_relative "base_stage"
3
+ require_relative "../question"
6
4
 
7
5
  ##
8
6
  # StageT create questions based con Table data
9
7
  # range t1-t9
10
- # rubocop:disable Metrics/ClassLength
11
8
  class StageT < BaseStage
12
9
  # process_tableXfields
13
- # rubocop:disable Metrics/MethodLength
14
- # rubocop:disable Metrics/AbcSize
15
10
  def run(table, row, list)
16
11
  questions = []
17
- return questions unless concept.type == 'text'
12
+ return questions unless concept.type == "text"
18
13
 
19
14
  if table.fields.count == 2
20
15
  questions += process_table2fields(table, row, list, 0, 1)
@@ -29,19 +24,12 @@ class StageT < BaseStage
29
24
 
30
25
  questions
31
26
  end
32
- # rubocop:enable Metrics/MethodLength
33
- # rubocop:enable Metrics/AbcSize
34
27
 
35
28
  private
36
29
 
37
- # rubocop:disable Metrics/MethodLength
38
- # rubocop:disable Metrics/AbcSize
39
- # rubocop:disable Metrics/CyclomaticComplexity
40
- # rubocop:disable Metrics/PerceivedComplexity
41
30
  def process_table2fields(table, row, list, col1, col2)
42
31
  questions = []
43
32
  lang = concept.lang
44
- # create questions
45
33
 
46
34
  # Question choice: Using the column #0
47
35
  s = Set.new [row[:data][col1], lang.text_for(:none)]
@@ -50,6 +38,7 @@ class StageT < BaseStage
50
38
 
51
39
  if s.count > 3
52
40
  q = Question.new
41
+ q.set_choice
53
42
  q.name = "#{name}-#{num}-t1table-#{table.name}"
54
43
  q.text = random_image_for(name) \
55
44
  + lang.text_for(:t1table, name, table.fields[col1].capitalize, \
@@ -61,12 +50,14 @@ class StageT < BaseStage
61
50
  questions << q
62
51
  end
63
52
 
64
- s = Set.new [row[:data][col1], lang.text_for(:none)]
65
- list.each { |i| s.add(i[:data][col1]) }
66
- a = s.to_a
53
+ # REPETIDO???
54
+ # s = Set.new [row[:data][col1], lang.text_for(:none)]
55
+ # list.each { |i| s.add(i[:data][col1]) }
56
+ # a = s.to_a
67
57
 
68
58
  if s.count > 4
69
59
  q = Question.new
60
+ q.set_choice
70
61
  q.name = "#{name}-#{num}-t2table-#{table.name}"
71
62
  q.text = random_image_for(name) \
72
63
  + lang.text_for(:t2table, name, table.fields[col1].capitalize, \
@@ -85,6 +76,7 @@ class StageT < BaseStage
85
76
 
86
77
  if s.count > 3
87
78
  q = Question.new
79
+ q.set_choice
88
80
  q.name = "#{name}-#{num}-t3table-#{table.name}"
89
81
  q.text = random_image_for(name) \
90
82
  + lang.text_for(:t3table, name, table.fields[col1].capitalize, \
@@ -96,12 +88,14 @@ class StageT < BaseStage
96
88
  questions << q
97
89
  end
98
90
 
99
- s = Set.new [row[:data][col2], lang.text_for(:none)]
100
- list.each { |i| s.add(i[:data][col2]) }
101
- a = s.to_a
91
+ # REPTIDO???
92
+ # s = Set.new [row[:data][col2], lang.text_for(:none)]
93
+ # list.each { |i| s.add(i[:data][col2]) }
94
+ # a = s.to_a
102
95
 
103
96
  if s.count > 4
104
97
  q = Question.new
98
+ q.set_choice
105
99
  q.name = "#{name}-#{num}-t4table-#{table.name}"
106
100
  q.text = random_image_for(name) \
107
101
  + lang.text_for(:t4table, name, table.fields[col1].capitalize, \
@@ -120,7 +114,7 @@ class StageT < BaseStage
120
114
  q.text = random_image_for(name) \
121
115
  + lang.text_for(:t5table, name, table.fields[col1].capitalize, \
122
116
  row[:data][col1], table.fields[col2].capitalize, row[:data][col2])
123
- q.good = 'TRUE'
117
+ q.good = "TRUE"
124
118
  questions << q
125
119
 
126
120
  # Question Boolean: FALSE
@@ -135,7 +129,7 @@ class StageT < BaseStage
135
129
  q.text = random_image_for(name) \
136
130
  + lang.text_for(:t6table, name, table.fields[col1].capitalize, \
137
131
  row[:data][col1], table.fields[col2].capitalize, a[1])
138
- q.good = 'FALSE'
132
+ q.good = "FALSE"
139
133
  questions << q
140
134
  end
141
135
 
@@ -203,9 +197,4 @@ class StageT < BaseStage
203
197
  end
204
198
  questions
205
199
  end
206
- # rubocop:enable Metrics/MethodLength
207
- # rubocop:enable Metrics/AbcSize
208
- # rubocop:enable Metrics/CyclomaticComplexity
209
- # rubocop:enable Metrics/PerceivedComplexity
210
200
  end
211
- # rubocop:enable Metrics/ClassLength
@@ -1,4 +1,3 @@
1
- require "colorize"
2
1
  require_relative "check_table"
3
2
 
4
3
  class CheckHamlData
@@ -32,7 +31,6 @@ class CheckHamlData
32
31
 
33
32
  def show_errors
34
33
  errors = 0
35
- puts "\n"
36
34
  @outputs.each do |i|
37
35
  next if i[:state] == :ok
38
36
 
@@ -41,16 +39,20 @@ class CheckHamlData
41
39
  data = { id: i[:id], msg: i[:msg], source: i[:source][0, 40] }
42
40
  order = i[:id] + 1
43
41
  data = { order: order, msg: i[:msg], source: i[:source][0, 40] }
44
- print format(' %<order>03d : %<msg>32s. => '.white, data)
45
- puts format('%<source>s'.light_yellow, data)
42
+ message = Rainbow(" %<order>03d : %<msg>32s. => ").white
43
+ print format(message, data)
44
+ message = Rainbow("%<source>s").yellow.bright
45
+ puts format(message, data)
46
46
  end
47
- puts '...' if errors == 11
47
+ puts "..." if errors == 11
48
48
  end
49
49
 
50
- if errors.positive?
51
- puts "\n[ ASKER ] Please! Revise #{errors.to_s.light_red} error/s\n"
50
+ if errors.zero?
51
+ puts Rainbow("Syntax OK!").green.bright
52
+ else
53
+ message = "\nRevise #{errors.to_s} syntax error/s\n"
54
+ puts Rainbow(message).yellow.bright
52
55
  end
53
- puts 'Syntax OK!'.green if errors.zero?
54
56
  end
55
57
 
56
58
  def check
@@ -144,7 +146,10 @@ class CheckHamlData
144
146
  @outputs[index][:type] = :tags
145
147
  @outputs[index][:level] = 2
146
148
  @outputs[index][:state] = :ok
147
- if find_parent(index) != :concept
149
+ if line.strip == '%tags'
150
+ @outputs[index][:state] = :err
151
+ @outputs[index][:msg] = 'Please, fill with concept tags!'
152
+ elsif find_parent(index) != :concept
148
153
  @outputs[index][:state] = :err
149
154
  @outputs[index][:msg] = 'Parent(concept) not found!'
150
155
  elsif !line.match(/^\s\s\s\s%tags\s/)
@@ -166,6 +171,12 @@ class CheckHamlData
166
171
  elsif !line.match(/^\s\s\s\s%def[\s{]/)
167
172
  @outputs[index][:state] = :err
168
173
  @outputs[index][:msg] = 'Write 4 spaces before %def'
174
+ else
175
+ items = line.strip.split
176
+ if items.size < 2
177
+ @outputs[index][:state] = :err
178
+ @outputs[index][:msg] = '%def has no definition'
179
+ end
169
180
  end
170
181
  end
171
182
 
@@ -38,9 +38,9 @@ module CheckTable
38
38
  when 6
39
39
  @outputs[index][:level] = 3
40
40
  parent = find_parent(index)
41
- unless %i[table features].include? parent
41
+ unless %i[table template features].include? parent
42
42
  @outputs[index][:state] = :err
43
- @outputs[index][:msg] = 'Parent(table/features) not found!'
43
+ @outputs[index][:msg] = 'Parent(table/template/features) not found!'
44
44
  end
45
45
  when 8
46
46
  @outputs[index][:level] = 4
@@ -60,6 +60,16 @@ module CheckTable
60
60
 
61
61
  @outputs[index][:type] = :col
62
62
  @outputs[index][:state] = :ok
63
+
64
+ # row parent requires empty msg
65
+ if @outputs[index - 1][:type] == :row
66
+ if @outputs[index - 1][:source].strip != "%row"
67
+ require "debug"; binding.break
68
+ @outputs[index - 1][:state] = :err
69
+ @outputs[index - 1 ][:msg] = 'Row with cols requires empty text!'
70
+ end
71
+ end
72
+
63
73
  case count_spaces(line)
64
74
  when 8
65
75
  @outputs[index][:level] = 4
@@ -27,14 +27,15 @@ class CheckInput
27
27
 
28
28
  def check_file_exist
29
29
  if @filepath.nil?
30
- raise Rainbow("Can't check nil filename")
30
+ puts Rainbow("[ERROR] Can't check nil filename").red.bright
31
+ return false
31
32
  end
32
33
  unless File.exist? @filepath
33
- puts Rainbow('File not found!').red.bright if @verbose
34
+ puts Rainbow("[ERROR] File not found!: #{@filepath}").red.bright if @verbose
34
35
  return false
35
36
  end
36
37
  unless File.extname(@filepath) == '.haml'
37
- puts Rainbow('Only check HAML files!').yellow.bright if @verbose
38
+ puts Rainbow("[ERROR] Check require's HAML file!").red.bright if @verbose
38
39
  return false
39
40
  end
40
41
  true
@@ -172,7 +172,7 @@ class Concept
172
172
 
173
173
  def process_tags(value)
174
174
  if value.text.nil? || value.text.size.zero?
175
- puts Rainbow("[ERROR] Concept without tags: #{name} ").red.briht
175
+ puts Rainbow("[ERROR] Concept without tags: #{name} ").red.bright
176
176
  exit 1
177
177
  end
178
178
 
@@ -189,7 +189,11 @@ class Concept
189
189
  # Load local images and text files
190
190
  @data[:images] << EmbeddedFile.load(value.text.strip, File.dirname(@filename))
191
191
  when nil
192
- @data[:texts] << value.text.strip
192
+ if value.text.nil?
193
+ warn Rainbow("[WARN] def: without text!").yellow.bright
194
+ else
195
+ @data[:texts] << value.text.strip
196
+ end
193
197
  else
194
198
  msg = "[ERROR] Unknown type: #{value.attributes['type']}"
195
199
  puts Rainbow(msg).red.bright
@@ -1,21 +1,17 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'erb'
4
- require 'terminal-table'
5
- require_relative '../application'
6
- require_relative '../logger'
3
+ require "erb"
4
+ require "terminal-table"
5
+ require_relative "../application"
6
+ require_relative "../logger"
7
7
 
8
8
  # Display ConceptAI stat on screen
9
9
  class ConceptAIDisplayer
10
10
  ##
11
11
  # Display ConceptAI stat on screen
12
12
  # @param concepts_ai (Array)
13
- # rubocop:disable Metrics/MethodLength
14
- # rubocop:disable Metrics/AbcSize
15
- # rubocop:disable Metrics/CyclomaticComplexity
16
- # rubocop:disable Metrics/PerceivedComplexity
17
13
  def self.show(concepts_ai)
18
- stages = Application.instance.config['questions']['stages']
14
+ stages = Application.instance.config["questions"]["stages"]
19
15
  # Create table HEAD
20
16
  screen_table = Terminal::Table.new do |st|
21
17
  title = %w[Concept Questions Entries xFactor]
@@ -52,7 +48,7 @@ class ConceptAIDisplayer
52
48
  st = concept_ai.questions[:t].size if stages.include? :t
53
49
  t = sd + sb + sf + si + ss + st
54
50
 
55
- factor = 'Unkown'
51
+ factor = "Unkown"
56
52
  factor = (t.to_f / e).round(2).to_s unless e.zero?
57
53
  screen_table.add_row [Rainbow(concept_ai.concept.name(:screen)).green.bright,
58
54
  t, e, factor, sd, sb, sf, si, ss, st]
@@ -83,13 +79,7 @@ class ConceptAIDisplayer
83
79
  export_notes
84
80
  Logger.verboseln "#{screen_table}\n"
85
81
  end
86
- # rubocop:enable Metrics/MethodLength
87
- # rubocop:enable Metrics/AbcSize
88
- # rubocop:enable Metrics/CyclomaticComplexity
89
- # rubocop:enable Metrics/PerceivedComplexity
90
82
 
91
- # rubocop:disable Metrics/MethodLength
92
- # rubocop:disable Metrics/AbcSize
93
83
  private_class_method def self.export_excluded_questions(screen_table, concepts_ai)
94
84
  # Create table BODY
95
85
  total = {}
@@ -123,8 +113,6 @@ class ConceptAIDisplayer
123
113
  total[:sf], total[:si],
124
114
  total[:ss], total[:st]]
125
115
  end
126
- # rubocop:enable Metrics/MethodLength
127
- # rubocop:enable Metrics/AbcSize
128
116
 
129
117
  private_class_method def self.export_notes
130
118
  exclude_questions = Application.instance.config['questions']['exclude'].to_s
@@ -1,31 +1,27 @@
1
- require_relative '../application'
2
- require_relative '../formatter/concept_string_formatter'
1
+ require_relative "../application"
2
+ require_relative "../formatter/concept_string_formatter"
3
3
  require_relative "../logger"
4
4
 
5
5
  module ConceptDisplayer
6
6
  ##
7
7
  # Show concepts on screen
8
8
  # @param concepts (Array) List of concept data
9
- # rubocop:disable Metrics/AbcSize
10
- # rubocop:disable Metrics/MethodLength
11
9
  def self.show(concepts)
12
- show_mode = Application.instance.config['global']['show_mode']
10
+ show_mode = Application.instance.config["global"]["show_mode"]
13
11
  return unless show_mode
14
12
 
15
13
  msg = "\n[INFO] Showing concept data (#{Rainbow(show_mode).bright})"
16
14
  Logger.verboseln msg
17
15
  case show_mode
18
- when 'resume'
16
+ when "resume"
19
17
  s = "* Concepts (#{concepts.count}): "
20
- concepts.each { |c| s += c.name + ', ' }
18
+ concepts.each { |c| s += c.name + ", " }
21
19
  Logger.verboseln s
22
- when 'default'
20
+ when "default"
23
21
  # Only show Concepts with process attr true
24
22
  concepts.each do |c|
25
23
  Logger.verboseln ConceptStringFormatter.to_s(c) if c.process?
26
24
  end
27
25
  end
28
26
  end
29
- # rubocop:enable Metrics/AbcSize
30
- # rubocop:enable Metrics/MethodLength
31
27
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'rainbow'
4
- require 'terminal-table'
3
+ require "rainbow"
4
+ require "terminal-table"
5
5
 
6
6
  # Define methods to transform Concept into String
7
7
  module ConceptStringFormatter
@@ -15,32 +15,33 @@ module ConceptStringFormatter
15
15
  tt.to_s
16
16
  end
17
17
 
18
- # rubocop:disable Metrics/AbcSize
19
- # rubocop:disable Metrics/MethodLength
20
18
  private_class_method def self.get_tt_rows(concept)
21
19
  rows = []
22
20
  rows << [Rainbow(concept.id.to_s).bright,
23
- Rainbow(concept.name(:screen)).white.bg(:blue).bright +
24
- " (lang=#{concept.lang.lang}) "]
25
- rows << [Rainbow('Filename').blue, concept.filename]
26
- rows << [Rainbow('Context').blue, concept.context.join(', ').to_s]
27
- rows << [Rainbow('Tags').blue, concept.tags.join(', ').to_s]
28
- rows << [Rainbow('Reference to').blue,
21
+ Rainbow(concept.name(:screen)).green.bright]
22
+ # + " (lang=#{concept.lang.lang}) "]
23
+ # rows << [Rainbow("Filename").white, concept.filename]
24
+ # rows << [Rainbow("Context").white, concept.context.join(', ').to_s]
25
+ rows << [Rainbow("Tags").white, concept.tags.join(', ').to_s]
26
+ unless concept.reference_to.size.zero?
27
+ rows << [Rainbow("Reference to").white,
29
28
  concept.reference_to.join(', ')[0...70].to_s]
30
- rows << [Rainbow('Referenced by').blue,
29
+ end
30
+ unless concept.referenced_by.size.zero?
31
+ rows << [Rainbow("Referenced by").white,
31
32
  concept.referenced_by.join(', ')[0...70].to_s]
33
+ end
32
34
  rows << format_texts(concept)
33
35
  unless concept.images.size.zero?
34
- counter1 = 0
35
- concept.images.each { |image| counter1 += 1 if image[:file] == :none }
36
- counter2 = concept.images.size - counter1
37
- rows << [Rainbow('.def(images)').blue, "#{counter1} text / #{counter2} file"]
36
+ counter = concept.images.size
37
+ # counter1 = 0
38
+ # concept.images.each { |image| counter1 += 1 if image[:file] == :none }
39
+ # counter2 = concept.images.size - counter1
40
+ rows << [Rainbow("def(file)").white, "#{counter} file/s"]
38
41
  end
39
42
  rows << format_tables(concept) unless concept.tables.count.zero?
40
43
  rows << format_neighbors(concept)
41
44
  end
42
- # rubocop:enable Metrics/AbcSize
43
- # rubocop:enable Metrics/MethodLength
44
45
 
45
46
  private_class_method def self.format_texts(concept)
46
47
  list = []
@@ -51,20 +52,22 @@ module ConceptStringFormatter
51
52
  end
52
53
  list << i[0...70].to_s + '...'
53
54
  end
54
- [Rainbow('.def(text)').blue, list.join("\n")]
55
+ # [Rainbow("def").white, list.join("\n")]
56
+ [Rainbow("def").white, list.size.to_s]
55
57
  end
56
58
 
57
59
  private_class_method def self.format_tables(concept)
58
60
  return [] if concept.tables.count.zero?
59
61
 
60
62
  list = concept.tables.map(&:to_s)
61
- [Rainbow('.tables').color(:blue), list.join("\n")]
63
+ [Rainbow("tables").white, list.join("\n")]
62
64
  end
63
65
 
64
66
  private_class_method def self.format_neighbors(concept)
65
67
  list = concept.neighbors[0..4].map do |i|
66
- i[:concept].name(:screen) + '(' + i[:value].to_s[0..4] + ')'
68
+ value = Rainbow(i[:value].to_s[0..4]).white
69
+ "#{value} #{i[:concept].name(:screen)}"
67
70
  end
68
- [Rainbow('.neighbors').blue, list.join("\n")]
71
+ [Rainbow("neighbors").white, list.join("\n")]
69
72
  end
70
73
  end
@@ -27,25 +27,17 @@ module DirectoryLoader
27
27
  end
28
28
 
29
29
  ##
30
- # Load accepted files from dirname directory
30
+ # Load files from dirname directory
31
31
  # @param filenames (Array) File name list
32
32
  # @param dirname (String) Base directory
33
33
  def self.load_files(filenames, dirname)
34
34
  output = { concepts: [], codes: [] }
35
35
  filenames.each do |filename|
36
36
  filepath = File.join(dirname, filename)
37
- data = DirectoryLoader.load_file(filepath, filename == filenames.last)
37
+ data = FileLoader.load(filepath)
38
38
  output[:concepts] += data[:concepts]
39
39
  output[:codes] += data[:codes]
40
40
  end
41
41
  output
42
42
  end
43
-
44
- ##
45
- # Load one input file
46
- # @param filepath (String) Path to input file
47
- # @param last (Boolean) True if it is the last filename
48
- def self.load_file(filepath, last = false)
49
- FileLoader.load(filepath)
50
- end
51
43
  end
@@ -1,4 +1,4 @@
1
- require 'base64'
1
+ require "base64"
2
2
 
3
3
  # Methods to load embedded files defined into asker input data file
4
4
  # Example:
@@ -27,29 +27,30 @@ module EmbeddedFile
27
27
  end
28
28
 
29
29
  # Suposse that filename is TEXT file
30
- return { text: "<pre>#{File.read(filepath)}</pre>", file: :none, type: :text }
30
+ return {text: "<pre>#{File.read(filepath)}</pre>", file: :none, type: :text}
31
31
  end
32
32
 
33
33
  def self.is_audio?(filename)
34
- extens = ['.mp3', '.ogg', '.wav']
34
+ extens = [ ".mp3", ".ogg", ".wav"]
35
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 = ['.jpg', '.jpeg', '.png']
41
- extens.each {|ext| return true if filename.downcase.end_with?(ext) }
40
+ extens = [ ".jpg", ".jpeg", ".png" ]
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 = ['.mp4', '.ogv']
47
- extens.each {|ext| return true if filename.downcase.end_with?(ext) }
46
+ extens = [ ".mp4", ".ogv" ]
47
+ extens.each { |ext| return true if filename.downcase.end_with?(ext) }
48
48
  false
49
49
  end
50
50
 
51
51
  def self.is_url?(value)
52
- return true if value.start_with?('https://') || value.start_with?('http://')
52
+ return true if value.start_with?("https://", "http://")
53
+
53
54
  false
54
55
  end
55
56
 
@@ -72,13 +73,14 @@ module EmbeddedFile
72
73
  + '">Your browser does not support the audio tag.</audio>'
73
74
  output[:file] = '<file name="' + File.basename(filepath) \
74
75
  + '" path="/" encoding="base64">' \
75
- + Base64.strict_encode64(File.open(filepath, 'rb').read) + '</file>'
76
+ + Base64.strict_encode64(File.open(filepath, 'rb').read) \
77
+ + "</file>"
76
78
  output[:type] = :audio
77
79
  output
78
80
  end
79
81
 
80
82
  def self.load_image(value, localdir)
81
- output = { text: :error, file: :none, type: :image}
83
+ output = {text: :error, file: :none, type: :image}
82
84
 
83
85
  if is_url? value
84
86
  output[:text] = "<img src=\"#{value}\" alt=\"image\" width=\"400\" height=\"300\">"
@@ -96,14 +98,14 @@ module EmbeddedFile
96
98
  + '" alt="imagen" class="img-responsive atto_image_button_text-bottom">'
97
99
  output[:file] = '<file name="' + File.basename(filepath) \
98
100
  + '" path="/" encoding="base64">' \
99
- + Base64.strict_encode64(File.open(filepath, 'rb').read) + '</file>'
101
+ + Base64.strict_encode64(File.open(filepath, 'rb').read) \
102
+ + "</file>"
100
103
  output[:type] = :image
101
104
  output
102
105
  end
103
106
 
104
107
  def self.load_video(value, localdir)
105
- output = { text: :error, file: :none, type: :video}
106
-
108
+ output = {text: :error, file: :none, type: :video}
107
109
  if is_url? value
108
110
  output[:text] = "<video controls width=\"400\" height=\"300\">" \
109
111
  + "<source src=\"#{value}\"/></video>"
@@ -117,11 +119,14 @@ module EmbeddedFile
117
119
  Logger.verbose Rainbow("[ERROR] Unknown file! #{filepath}").red.bright
118
120
  exit 1
119
121
  end
120
- output[:text] = '<video controls><source src="@@PLUGINFILE@@/' + File.basename(filepath) \
122
+ output[:text] = '<video controls><source src="@@PLUGINFILE@@/' \
123
+ + File.basename(filepath) \
121
124
  + '"/>Your browser does not support the video tag.</video>'
122
- output[:file] = '<file name="' + File.basename(filepath) \
125
+ output[:file] = '<file name="' \
126
+ + File.basename(filepath) \
123
127
  + '" path="/" encoding="base64">' \
124
- + Base64.strict_encode64(File.open(filepath, 'rb').read) + '</file>'
128
+ + Base64.strict_encode64(File.open(filepath, "rb").read) \
129
+ + "</file>"
125
130
  output[:type] = :video
126
131
  output
127
132
  end
@@ -1,12 +1,14 @@
1
1
  require_relative "content_loader"
2
2
  require_relative "haml_loader"
3
3
 
4
- # Load a filename and return list of concepts
4
+ ##
5
+ # Load a filename and return a Hash with concepts list and code list
6
+ # return { concepts: [], codes: [] }
5
7
  module FileLoader
6
8
  def self.load(filename)
7
- if File.extname(filename).casecmp('.haml').zero?
9
+ if File.extname(filename).casecmp(".haml").zero?
8
10
  file_content = HamlLoader.load filename
9
- elsif File.extname(filename).casecmp('.xml').zero?
11
+ elsif File.extname(filename).casecmp(".xml").zero?
10
12
  file_content = File.read(filename)
11
13
  else
12
14
  puts "[ERROR] FileLoader: Format error #{filename}"
@@ -6,13 +6,13 @@ module HamlLoader
6
6
  begin
7
7
  # INFO <haml 5.1> 20221223
8
8
  haml_engine = Haml::Engine.new(template)
9
- return haml_engine.render
10
9
  # INFO <haml 6.1> 20221226
11
10
  # return Haml::Template.new { template }.render
12
- rescue StandardError => e
11
+ rescue => e
13
12
  puts "[ERROR] HamlLoader: Can't load <#{filename}> file!"
14
13
  puts " => #{e}"
15
14
  exit 0
16
15
  end
16
+ haml_engine.render
17
17
  end
18
18
  end
@@ -1,6 +1,5 @@
1
-
2
- require 'net/http'
3
- require 'uri'
1
+ require "net/http"
2
+ require "uri"
4
3
 
5
4
  # Search URL images on Internet
6
5
  # Methods:
@@ -11,44 +10,47 @@ module ImageUrlLoader
11
10
  # Search "input" images on Google and return URL
12
11
  def self.load(input = [])
13
12
  filters = []
14
- if input.class == String
13
+ if input.instance_of? String
15
14
  filters += sanitize_string(input.clone)
16
- elsif input.class == Array
15
+ elsif input.instance_of? Array
17
16
  filters = sanitize_array(input.clone)
18
17
  else
19
18
  raise "[ERROR] ImageUrlLoader: Unkown type #{input.class}"
20
19
  end
21
20
  # Search Image URLs from Google site, selected by <filters>
22
- search_url = 'https://www.google.es/search?q='
23
- search_url << filters.flatten.join('+').to_s
24
- search_url << '&source=lnms&tbm=isch&sa=X&ved=2ahUKEwj_g8Wfst7nAhWpzoUKHf_wDbsQ_AUoAnoECBMQBA&biw=1280&bih=591'
21
+ search_url = "https://www.google.es/search?q="
22
+ search_url << filters.flatten.join("+").to_s
23
+ search_url << "&source=lnms&tbm=isch&sa=X&ved=2ahUKEwj_g8Wfst7nAhWpzoUKHf_wDbsQ_AUoAnoECBMQBA&biw=1280&bih=591"
25
24
  image_urls = []
26
25
  begin
27
26
  uri = URI.parse(search_url)
28
27
  response = Net::HTTP.get_response(uri)
29
28
 
30
- r = response.body.split(' ')
29
+ r = response.body.split(" ")
31
30
  r.each do |line|
32
31
  if line.include? 'src="https'
33
32
  image_urls << line.delete('"')[4, line.size]
34
33
  end
35
34
  end
36
35
  rescue
37
- puts '[ERROR] ImageUrlLoader'
36
+ puts "[ERROR] ImageUrlLoader"
38
37
  puts " => #{search_url}"
39
- puts ' => Check Internet connections'
40
- puts ' => Ensure URL is well formed'
38
+ puts " => Check Internet connections"
39
+ puts " => Ensure URL is well formed"
41
40
  end
42
41
  image_urls
43
42
  end
44
43
 
45
44
  def self.sanitize_string(input)
46
45
  text = input.dup
47
- r = [ ['á', 'a'], ['é', 'e'], ['í', 'i'], ['ó', 'o'], ['ú', 'u'], ['ñ', 'n'], ['Á', 'A'], ['É', 'E'], ['Í', 'I'], ['Ó', 'O'], ['Ú', 'U'], ['Ñ', 'N']]
46
+ r = [
47
+ %w[á a], %w[é e], %w[í i], %w[ó o], %w[ú u], %w[ñ n],
48
+ %w[Á A], %w[É E], %w[Í I], %w[Ó O], %w[Ú U], %w[Ñ N]
49
+ ]
48
50
  r.each { |item| text.gsub!(item[0], item[1]) }
49
- r = ['-', '_', ',', '"']
50
- r.each { |item| text.gsub!(item, ' ') }
51
- text.split(' ')
51
+ r = %w[- _ , "]
52
+ r.each { |item| text.gsub!(item, " ") }
53
+ text.split(" ")
52
54
  end
53
55
 
54
56
  def self.sanitize_array(input)
@@ -1,14 +1,13 @@
1
- require_relative 'directory_loader'
2
- require_relative '../ai/concept_ai'
3
- require_relative '../data/world'
1
+ require_relative "directory_loader"
2
+ require_relative "../ai/concept_ai"
3
+ require_relative "../data/world"
4
4
 
5
5
  module InputLoader
6
6
  ##
7
7
  # Load input data from every input directory
8
8
  # @param inputdirs (Array)
9
9
  def self.load(inputdirs, internet = true)
10
- data = { concepts: [], codes: [], world: nil,
11
- concepts_ai: [], codes_ai: [] }
10
+ data = {concepts: [], codes: [], world: nil, concepts_ai: [], codes_ai: []}
12
11
  inputdirs.each do |dirname|
13
12
  temp = DirectoryLoader.load(dirname)
14
13
  data[:concepts] += temp[:concepts]
@@ -1,14 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'yaml'
4
- require_relative '../data/project_data'
3
+ require "yaml"
4
+ require_relative "../data/project_data"
5
5
 
6
6
  # Load params into Project class using arg input
7
- # * load
8
- # * load_from_string
9
- # * load_from_yaml
10
- # * load_from_directory
11
- # * load_error
12
7
  module ProjectLoader
13
8
  ##
14
9
  # Load project from args
@@ -17,22 +12,21 @@ module ProjectLoader
17
12
  def self.load(args)
18
13
  project = ProjectData.instance
19
14
 
20
- if args.class == Hash
15
+ if args.instance_of? Hash
21
16
  project.param.merge!(args)
22
17
  project.open
23
18
  return project
24
- elsif args.class == String
19
+ elsif args.instance_of? String
25
20
  ProjectLoader.load_from_string(args)
26
21
  project.open
27
22
  return project
28
23
  end
29
24
 
30
- msg = '[ERROR] ProjectLoader:'
25
+ msg = "[ERROR] ProjectLoader:"
31
26
  msg += "Configuration params format is <#{pArgs.class}>!"
32
27
  puts Rainbow(msg).red
33
28
  raise msg
34
29
  end
35
- # rubocop:enable Metrics/MethodLength
36
30
 
37
31
  ##
38
32
  # Load project from filepath. Options:
@@ -50,19 +44,16 @@ module ProjectLoader
50
44
  exit 1
51
45
  end
52
46
 
53
- if File.extname(filepath) == '.haml' || File.extname(filepath) == '.xml'
47
+ if File.extname(filepath) == ".haml" || File.extname(filepath) == ".xml"
54
48
  project.set(:inputdirs, File.dirname(filepath))
55
49
  project.set(:process_file, File.basename(filepath))
56
50
  return project
57
- elsif File.extname(filepath) == '.yaml'
51
+ elsif File.extname(filepath) == ".yaml"
58
52
  return load_from_yaml(filepath)
59
53
  end
60
54
  error_loading(filepath)
61
55
  end
62
- # rubocop:enable Metrics/MethodLength
63
- # rubocop:enable Metrics/AbcSize
64
56
 
65
- # rubocop:disable Security/YAMLLoad
66
57
  def self.load_from_yaml(arg)
67
58
  project = ProjectData.instance
68
59
  project.param.merge!(YAML.load(File.open(arg)))
@@ -70,7 +61,6 @@ module ProjectLoader
70
61
  project.set(:projectdir, File.dirname(arg))
71
62
  project
72
63
  end
73
- # rubocop:enable Security/YAMLLoad
74
64
 
75
65
  ##
76
66
  # Error found and exit application.
data/lib/asker/logger.rb CHANGED
@@ -27,13 +27,13 @@ class Logger
27
27
  end
28
28
 
29
29
  def self.create(logpath)
30
- @logfile = File.open(logpath, 'w')
31
- @logfile.write('=' * 50 + "\n")
30
+ @logfile = File.open(logpath, "w")
31
+ @logfile.write("=" * 50 + "\n")
32
32
  @logfile.write("Created by : #{Asker::NAME}")
33
33
  @logfile.write(" (version #{Asker::VERSION})\n")
34
34
  @logfile.write("File : #{File.basename(logpath)}\n")
35
35
  @logfile.write("Time : #{Time.new}\n")
36
- @logfile.write('=' * 50 + "\n\n")
36
+ @logfile.write("=" * 50 + "\n\n")
37
37
  end
38
38
 
39
39
  def self.close
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'fileutils'
4
- require 'rainbow'
5
- require_relative 'version'
3
+ require "fileutils"
4
+ require "rainbow"
5
+ require_relative "version"
6
6
 
7
7
  # Skeleton: create skeleton for asker input files
8
8
  # * create
@@ -17,15 +17,15 @@ module Skeleton
17
17
  # rubocop:disable Metrics/MethodLength
18
18
  def self.create_input(inputpath)
19
19
  puts "\n[INFO] Creating example input #{Rainbow(inputpath).bright}"
20
- if File.extname(inputpath) == '.haml'
20
+ if File.extname(inputpath) == ".haml"
21
21
  dirpath = File.dirname(inputpath)
22
22
  filename = File.basename(inputpath)
23
23
  else
24
24
  dirpath = inputpath
25
- filename = 'example-concept.haml'
25
+ filename = "example-concept.haml"
26
26
  end
27
27
  create_dir dirpath
28
- source = File.join(File.dirname(__FILE__), 'files/example-concept.haml')
28
+ source = File.join(File.dirname(__FILE__), "files", "example-concept.haml")
29
29
  copyfile(source, File.join(dirpath, filename))
30
30
  end
31
31
  # rubocop:enable Metrics/MethodLength
@@ -34,7 +34,7 @@ module Skeleton
34
34
  # Create default configuration files
35
35
  def self.create_configuration
36
36
  puts "\n[INFO] Creating configuration files"
37
- src = File.join(File.dirname(__FILE__), 'files', Asker::CONFIGFILE)
37
+ src = File.join(File.dirname(__FILE__), "files", Asker::CONFIGFILE)
38
38
  dst = File.join(Asker::CONFIGFILE)
39
39
  copyfile(src, dst)
40
40
  end
@@ -49,7 +49,7 @@ module Skeleton
49
49
  begin
50
50
  FileUtils.mkdir_p(dirpath)
51
51
  puts "* Create dir => #{Rainbow(dirpath).green}"
52
- rescue StandardError
52
+ rescue
53
53
  puts "* Create dir ERROR => #{Rainbow(dirpath).red}"
54
54
  end
55
55
  end
@@ -67,7 +67,7 @@ module Skeleton
67
67
  begin
68
68
  FileUtils.cp(target, dest)
69
69
  puts "* Create file => #{Rainbow(dest).green}"
70
- rescue StandardError
70
+ rescue
71
71
  puts "* Create file ERROR => #{Rainbow(dest).red}"
72
72
  end
73
73
  end
data/lib/asker/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  class Asker
2
- VERSION = "2.5.8"
2
+ VERSION = "2.6.0"
3
3
  NAME = "asker"
4
4
  GEM = "asker-tool"
5
5
  CONFIGFILE = "asker.ini"
data/lib/asker.rb CHANGED
@@ -1,5 +1,4 @@
1
1
  require 'rainbow'
2
- require 'colorize'
3
2
 
4
3
  require_relative 'asker/skeleton'
5
4
  require_relative 'asker/check_input'
@@ -51,12 +50,12 @@ class Asker
51
50
  project_data.set(:weights, formula_weights)
52
51
  end
53
52
 
54
- private_class_method def self.init_logger(project_data)
55
- Logger.create(project_data.get(:logpath))
53
+ private_class_method def self.init_logger(project)
54
+ Logger.create(project.get(:logpath))
56
55
  Logger.instance.set_verbose(Application.instance.config['verbose'])
57
56
  Logger.verboseln '[INFO] Project open'
58
- Logger.verboseln ' ├── inputdirs = ' + Rainbow(project_data.get(:inputdirs)).bright
59
- Logger.verboseln ' └── process_file = ' + Rainbow(project_data.get(:process_file)).bright
57
+ Logger.verboseln ' ├── inputdirs = ' + Rainbow(project.get(:inputdirs)).bright
58
+ Logger.verboseln ' └── process_file = ' + Rainbow(project.get(:process_file)).bright
60
59
  end
61
60
 
62
61
  private_class_method def self.create_output(project, data)
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.5.8
4
+ version: 2.6.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: 2022-12-29 00:00:00.000000000 Z
11
+ date: 2023-05-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: haml
@@ -52,20 +52,6 @@ dependencies:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: '3.0'
55
- - !ruby/object:Gem::Dependency
56
- name: colorize
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - "~>"
60
- - !ruby/object:Gem::Version
61
- version: '0.8'
62
- type: :runtime
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - "~>"
67
- - !ruby/object:Gem::Version
68
- version: '0.8'
69
55
  - !ruby/object:Gem::Dependency
70
56
  name: rexml
71
57
  requirement: !ruby/object:Gem::Requirement