asker-tool 2.5.8 → 2.6.0

Sign up to get free protection for your applications and to get access to all the features.
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