yml_builder 0.1.3 → 0.1.4

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
  SHA1:
3
- metadata.gz: 6b9e09b15140784ff1d923e16ce05a34917b3474
4
- data.tar.gz: 17ac41c1b712a300704b02a77804e438e9ddf74c
3
+ metadata.gz: c467842b66355a23a26354a37d682f6b51f92978
4
+ data.tar.gz: 985bb3a8e9b5b1506d42f46eacf5dac26198d20c
5
5
  SHA512:
6
- metadata.gz: 6b82a75916cc0eabe77e5963fdbd6f27f71506b8f920fbc731810dbe01c6f4ad899bf261661363a384c64267660c62489e2a47666ac38fe465b86944d1154802
7
- data.tar.gz: c060022856a07301e0dcb91a70d9d30cad0d1386a5babccebe4779ae2924d2b36bffe57a51e157e95f33bcc83f4c279fed14084d56163d78669c19ed3aba90c6
6
+ metadata.gz: cd9d5578dd5ee634250de1dfe75a69aceb910a0698fdf2872f343c291ef9bc6657836ab4cdbccdc9843c4b2d48023ab2f2c26ad212fc1c10c21fe5ac2e7c07cf
7
+ data.tar.gz: bc985ba000bf496bdf2623b6aa307a557b85204adbc3932137069c8225fb786ebd9e2d5cd9eee657860441758f41ea36517a50b13331773d56042fae906441da
data/CHANGELOG.md CHANGED
@@ -1,3 +1,7 @@
1
+ ## 0.1.4 (2019-01-02)
2
+
3
+ * Исправлена проблема зависания вызова `price.to_yaml` при записи большого числа товаров (более 60 тыс.).
4
+
1
5
  ## 0.1.3 (2016-05-27)
2
6
 
3
7
  * Обеспечена совместимость с Rails 5
@@ -9,11 +9,13 @@ module YmlBuilder
9
9
  # price.categories.filter = [1, 3, 4, 5]
10
10
  attr_reader :filter
11
11
 
12
+
12
13
  def initialize(stats)
13
14
  @stats = stats
14
15
  init_class
15
16
  end
16
17
 
18
+
17
19
  # Метод добавляет категорию Интернет-магазина в прайс-лист с учетом выставленных в значении filter настроек.
18
20
  #
19
21
  # @param [Hash] opts параметры категорий Интернет-магазина
@@ -32,11 +34,12 @@ module YmlBuilder
32
34
  raise "Ошибка: не указан 'id' для добавления категории" if opts[:id].nil?
33
35
  raise "Ошибка: не указан 'name' для добавления категории" if opts[:name].nil?
34
36
  @params[opts[:id]] = { parent_id: opts[:parent_id], name: opts[:name] }
35
- @params = Hash[ @params.sort_by { |id, data| id } ]
37
+ @params = Hash[@params.sort_by { |id, data| id }]
36
38
  @stats.add(:categories, 1)
37
39
  true
38
40
  end
39
41
 
42
+
40
43
  # Метод проверяет необходимость добавления категории или товара в прайс-лист
41
44
  # с учетом выставленных в значении filter настроек.
42
45
  #
@@ -46,6 +49,7 @@ module YmlBuilder
46
49
  @filter.count == 0 ? true : @filter.include?(id)
47
50
  end
48
51
 
52
+
49
53
  # Метод позволяет огарничить формирование прайс-листа только категориями, указанными в данном поле
50
54
  # Filter может принимать значения nil или [], тогда считается, что допустимо включение в прайс-лист
51
55
  # всех товаров.
@@ -57,6 +61,7 @@ module YmlBuilder
57
61
  @filter = allow || Array.new
58
62
  end
59
63
 
64
+
60
65
  # Метод формирует фрагмент YML файла каталога Яндекс.Маркет, содержащий список категорий
61
66
  #
62
67
  # @param [Integer] ident отступ от левого края в символах
@@ -80,6 +85,7 @@ module YmlBuilder
80
85
  out.join("\n")
81
86
  end
82
87
 
88
+
83
89
  # Метод возвращает true, если категория, передаваемая в качестве параметра, уже добавлена в прайс-лист
84
90
  #
85
91
  # @param [Object] id идентификатор категории
@@ -88,12 +94,14 @@ module YmlBuilder
88
94
  @params[id].nil? ? false : true
89
95
  end
90
96
 
97
+
91
98
  private
92
99
 
93
- def init_class
94
- @params = Hash.new
95
- self.filter = nil
96
- end
100
+
101
+ def init_class
102
+ @params = Hash.new
103
+ self.filter = nil
104
+ end
97
105
 
98
106
  end
99
107
  end
@@ -3,12 +3,13 @@ module YmlBuilder # :nodoc:
3
3
 
4
4
  def self.encode_special_chars(out)
5
5
  return out.to_s.gsub(/[\"\&\>\<\']/, '"' => '&quot;',
6
- '&' => '&amp;',
7
- '>' => '&gt;',
8
- '<' => '&lt;',
9
- "'" => '&apos;')
6
+ '&' => '&amp;',
7
+ '>' => '&gt;',
8
+ '<' => '&lt;',
9
+ "'" => '&apos;')
10
10
  end
11
11
 
12
+
12
13
  def self.convert_key(key)
13
14
  return 'currencyId' if key == :currency_id
14
15
  return 'categoryId' if key == :category_id
@@ -20,10 +20,12 @@ module YmlBuilder
20
20
  # Список обязательных полей для данного типа оффера
21
21
  attr_accessor :mandatories
22
22
 
23
+
23
24
  def initialize
24
25
  init_class
25
26
  end
26
27
 
28
+
27
29
  # Метод добавляет ссылку на фотографию товара в конец списка, и ограничивает список 10-ю фотографиями
28
30
  # @param [String] url ссылка на фотографию товара
29
31
  # @example Примеры использования
@@ -33,9 +35,10 @@ module YmlBuilder
33
35
  @picture << url
34
36
  @picture.uniq!
35
37
  warn "Предупреждение: число картинок превышает 10 (offer_id=#{@id}). Сокращаем до 10" if @picture.count > 10
36
- @picture = @picture[0,9]
38
+ @picture = @picture[0, 9]
37
39
  end
38
40
 
41
+
39
42
  # Метод добавляет ссылку на фотографию товара в начало списка, и ограничивает список 10-ю фотографиями
40
43
  # @param [String] url ссылка на фотографию товара (на основную фотографию)
41
44
  # @example Примеры использования
@@ -45,9 +48,10 @@ module YmlBuilder
45
48
  @picture.unshift(url)
46
49
  @picture.uniq!
47
50
  warn "Предупреждение: число картинок превышает 10 (offer_id=#{@id}). Сокращаем до 10" if @picture.count > 10
48
- @picture = @picture[0,9]
51
+ @picture = @picture[0, 9]
49
52
  end
50
53
 
54
+
51
55
  # Метод добавляет характеристики товара (для секции 'param')
52
56
  #
53
57
  # @param [String] name наименование параметра, например "Количество товара"
@@ -58,9 +62,10 @@ module YmlBuilder
58
62
  # offer.add_param(name: "Количество", unit: "шт.", value: 100)
59
63
  # offer.add_param(name: "Обложка", value: "мягкая")
60
64
  def add_param(name:, unit: nil, value:)
61
- @meta[name] = { unit: unit, value: value}
65
+ @meta[name] = { unit: unit, value: value }
62
66
  end
63
67
 
68
+
64
69
  # Метод формирует фрагмент YML файла каталога Яндекс.Маркет для одного товара
65
70
  #
66
71
  # @param [Integer] ident отступ от левого края в символах
@@ -85,89 +90,99 @@ module YmlBuilder
85
90
  out.join("\n")
86
91
  end
87
92
 
93
+
88
94
  private
89
95
 
90
- def method_missing(method_sym, *arguments, &block)
91
- if @params.include?(method_sym.to_s.gsub(/=$/, '').to_sym)
92
- processing_method(method_sym, arguments.first)
93
- else
94
- super
96
+
97
+ def method_missing(method_sym, *arguments, &block)
98
+ if @params.include?(method_sym.to_s.gsub(/=$/, '').to_sym)
99
+ processing_method(method_sym, arguments.first)
100
+ else
101
+ super
102
+ end
95
103
  end
96
- end
97
104
 
98
- def processing_method(method_sym, value)
99
- if method_sym.to_s.match(/=$/)
100
- key = method_sym.to_s.gsub(/=$/, '')
101
- warn "Предупреждение: url не должен превышать 512 символов" if key == 'url' && value.length > 512
102
- warn "Предупреждение: price не может быть равен нулю (offer_id #{@id})" if key == 'price' && value.to_f == 0
103
- warn "Предупреждение: weight не может быть равен нулю (offer_id #{@id})" if key == 'weight' && value.to_f == 0
104
- @params[key.to_sym] = value
105
- else
106
- @params[method_sym.to_s.gsub(/=$/, '').to_sym]
105
+
106
+ def processing_method(method_sym, value)
107
+ if method_sym.to_s.match(/=$/)
108
+ key = method_sym.to_s.gsub(/=$/, '')
109
+ warn "Предупреждение: url не должен превышать 512 символов" if key == 'url' && value.length > 512
110
+ warn "Предупреждение: price не может быть равен нулю (offer_id #{@id})" if key == 'price' && value.to_f == 0
111
+ warn "Предупреждение: weight не может быть равен нулю (offer_id #{@id})" if key == 'weight' && value.to_f == 0
112
+ @params[key.to_sym] = value
113
+ else
114
+ @params[method_sym.to_s.gsub(/=$/, '').to_sym]
115
+ end
107
116
  end
108
- end
109
117
 
110
- def header_line
111
- out = Array.new
112
- out << "id=#{@id.to_s.inspect}"
113
- out << "type=#{@type.to_s.inspect}" if @type != 'simple'
114
- out << "available=\"#{@available.inspect}\""
115
- out << "bid=#{@bid.inspect}" unless @bid.nil?
116
- "<offer #{out.join (' ')}>"
117
- end
118
118
 
119
- def footer_line
120
- '</offer>'
121
- end
119
+ def header_line
120
+ out = Array.new
121
+ out << "id=#{@id.to_s.inspect}"
122
+ out << "type=#{@type.to_s.inspect}" if @type != 'simple'
123
+ out << "available=\"#{@available.inspect}\""
124
+ out << "bid=#{@bid.inspect}" unless @bid.nil?
125
+ "<offer #{out.join (' ')}>"
126
+ end
127
+
122
128
 
123
- def param_line(name, data)
124
- if data[:unit].nil?
125
- "<param name=#{::YmlBuilder::Common.encode_special_chars(name.to_s).inspect}>#{::YmlBuilder::Common.encode_special_chars(data[:value].to_s)}</param>"
126
- else
127
- "<param name=#{::YmlBuilder::Common.encode_special_chars(name.to_s).inspect} unit=#{::YmlBuilder::Common.encode_special_chars(data[:unit]).inspect}>#{::YmlBuilder::Common.encode_special_chars(data[:value].to_s)}</param>"
129
+ def footer_line
130
+ '</offer>'
128
131
  end
129
- end
130
132
 
131
- def to_yml_subsections(key)
132
- out = Array.new
133
133
 
134
- if key == :picture
135
- @picture.each do |url|
136
- out << " <picture>#{url}</picture>"
134
+ def param_line(name, data)
135
+ if data[:unit].nil?
136
+ "<param name=#{::YmlBuilder::Common.encode_special_chars(name.to_s).inspect}>#{::YmlBuilder::Common.encode_special_chars(data[:value].to_s)}</param>"
137
+ else
138
+ "<param name=#{::YmlBuilder::Common.encode_special_chars(name.to_s).inspect} unit=#{::YmlBuilder::Common.encode_special_chars(data[:unit]).inspect}>#{::YmlBuilder::Common.encode_special_chars(data[:value].to_s)}</param>"
137
139
  end
138
- else
139
- @meta.each do |name, data|
140
- out << " #{param_line(name, data)}"
140
+ end
141
+
142
+
143
+ def to_yml_subsections(key)
144
+ out = Array.new
145
+
146
+ if key == :picture
147
+ @picture.each do |url|
148
+ out << " <picture>#{url}</picture>"
149
+ end
150
+ else
151
+ @meta.each do |name, data|
152
+ out << " #{param_line(name, data)}"
153
+ end
141
154
  end
155
+
156
+ out
142
157
  end
143
158
 
144
- out
145
- end
146
159
 
147
- def to_yml_mandatories(key, value)
148
- raise "Ошибка секции 'offer': не заполнено обязательное значение #{key.to_s.inspect}" if (value.nil? || value.to_s == '')
149
- key_xml = ::YmlBuilder::Common.convert_key(key)
150
- " <#{key_xml}>#{::YmlBuilder::Common.encode_special_chars(value)}</#{key_xml}>"
151
- end
160
+ def to_yml_mandatories(key, value)
161
+ raise "Ошибка секции 'offer': не заполнено обязательное значение #{key.to_s.inspect}" if (value.nil? || value.to_s == '')
162
+ key_xml = ::YmlBuilder::Common.convert_key(key)
163
+ " <#{key_xml}>#{::YmlBuilder::Common.encode_special_chars(value)}</#{key_xml}>"
164
+ end
152
165
 
153
- def to_yml_optional(key, value)
154
- return nil if value.nil?
155
- key_xml = ::YmlBuilder::Common.convert_key(key)
156
- " <#{key_xml}>#{::YmlBuilder::Common.encode_special_chars(value)}</#{key_xml}>"
157
- end
158
166
 
159
- def init_class
160
- @params = Hash.new
161
- @meta = Hash.new
162
- @picture = Array.new
167
+ def to_yml_optional(key, value)
168
+ return nil if value.nil?
169
+ key_xml = ::YmlBuilder::Common.convert_key(key)
170
+ " <#{key_xml}>#{::YmlBuilder::Common.encode_special_chars(value)}</#{key_xml}>"
171
+ end
163
172
 
164
- @id = 0
165
- @type = 'unknown'
166
- @available = false
167
- @bid = nil
168
173
 
169
- @mandatories = Array.new
170
- end
174
+ def init_class
175
+ @params = Hash.new
176
+ @meta = Hash.new
177
+ @picture = Array.new
178
+
179
+ @id = 0
180
+ @type = 'unknown'
181
+ @available = false
182
+ @bid = nil
183
+
184
+ @mandatories = Array.new
185
+ end
171
186
 
172
187
  end
173
188
  end
@@ -5,6 +5,7 @@ module YmlBuilder
5
5
  init_class
6
6
  end
7
7
 
8
+
8
9
  # Метод формирует фрагмент YML файла каталога Яндекс.Маркет, содержащий список валют
9
10
  #
10
11
  # @param [Integer] ident отступ от левого края в символах
@@ -25,45 +26,50 @@ module YmlBuilder
25
26
  out.join("\n")
26
27
  end
27
28
 
29
+
28
30
  private
29
31
 
30
- def valid?(method_sym, allow, value)
31
- return true if value.to_s.match(/^\s*[+-]?((\d+_?)*\d+(\.(\d+_?)*\d+)?|\.(\d+_?)*\d+)(\s*|([eE][+-]?(\d+_?)*\d+)\s*)$/)
32
- return true if allow.include?(value)
33
- warn "Предупреждение: значение валюты #{method_sym.to_s.upcase} может быть цифрой или значением из #{allow.inspect}"
34
- false
35
- end
36
32
 
37
- def processing_method(method_sym, value)
38
- if method_sym.to_s.match(/=$/)
39
- key = method_sym.to_s.gsub(/=$/, '')
40
- allow = [:cbrf, :nbu, :nbk, :cb]
41
- valid?(key.to_s, allow, value)
33
+ def valid?(method_sym, allow, value)
34
+ return true if value.to_s.match(/^\s*[+-]?((\d+_?)*\d+(\.(\d+_?)*\d+)?|\.(\d+_?)*\d+)(\s*|([eE][+-]?(\d+_?)*\d+)\s*)$/)
35
+ return true if allow.include?(value)
36
+ warn "Предупреждение: значение валюты #{method_sym.to_s.upcase} может быть цифрой или значением из #{allow.inspect}"
37
+ false
38
+ end
39
+
40
+
41
+ def processing_method(method_sym, value)
42
+ if method_sym.to_s.match(/=$/)
43
+ key = method_sym.to_s.gsub(/=$/, '')
44
+ allow = [:cbrf, :nbu, :nbk, :cb]
45
+ valid?(key.to_s, allow, value)
42
46
 
43
- @params[key.to_sym] = value
44
- else
45
- @params[method_sym.to_s.gsub(/=$/, '').to_sym]
47
+ @params[key.to_sym] = value
48
+ else
49
+ @params[method_sym.to_s.gsub(/=$/, '').to_sym]
50
+ end
46
51
  end
47
- end
48
52
 
49
- def init_class
50
- @params = Hash.new
51
53
 
52
- @params[:rur] = nil
53
- @params[:rub] = nil
54
- @params[:usd] = nil
55
- @params[:eur] = nil
56
- @params[:uah] = nil
57
- @params[:kzt] = nil
58
- end
54
+ def init_class
55
+ @params = Hash.new
59
56
 
60
- def method_missing(method_sym, *arguments, &block)
61
- if @params.include?(method_sym.to_s.gsub(/=$/, '').to_sym)
62
- processing_method(method_sym, arguments.first)
63
- else
64
- super
57
+ @params[:rur] = nil
58
+ @params[:rub] = nil
59
+ @params[:usd] = nil
60
+ @params[:eur] = nil
61
+ @params[:uah] = nil
62
+ @params[:kzt] = nil
63
+ end
64
+
65
+
66
+ def method_missing(method_sym, *arguments, &block)
67
+ if @params.include?(method_sym.to_s.gsub(/=$/, '').to_sym)
68
+ processing_method(method_sym, arguments.first)
69
+ else
70
+ super
71
+ end
65
72
  end
66
- end
67
73
 
68
74
  end
69
75
  end
@@ -5,27 +5,27 @@ module YmlBuilder # :nodoc:
5
5
  super
6
6
  @type = 'simple'
7
7
 
8
- @params = Hash.new
9
- @params[:url] = nil
10
- @params[:price] = nil
11
- @params[:oldprice] = nil
12
- @params[:currency_id] = nil
13
- @params[:category_id] = nil
14
- @params[:market_category] = nil
15
- @params[:picture] = nil
16
- @params[:store] = nil
17
- @params[:pickup] = nil
18
- @params[:delivery] = nil
8
+ @params = Hash.new
9
+ @params[:url] = nil
10
+ @params[:price] = nil
11
+ @params[:oldprice] = nil
12
+ @params[:currency_id] = nil
13
+ @params[:category_id] = nil
14
+ @params[:market_category] = nil
15
+ @params[:picture] = nil
16
+ @params[:store] = nil
17
+ @params[:pickup] = nil
18
+ @params[:delivery] = nil
19
19
  @params[:local_delivery_cost] = nil
20
- @params[:name] = nil
21
- @params[:vendor] = nil
22
- @params[:vendor_code] = nil
23
- @params[:description] = nil
24
- @params[:country_of_origin] = nil
25
- @params[:adult] = nil
26
- @params[:param] = nil
27
- @params[:weight] = nil
28
- @params[:dimensions] = nil
20
+ @params[:name] = nil
21
+ @params[:vendor] = nil
22
+ @params[:vendor_code] = nil
23
+ @params[:description] = nil
24
+ @params[:country_of_origin] = nil
25
+ @params[:adult] = nil
26
+ @params[:param] = nil
27
+ @params[:weight] = nil
28
+ @params[:dimensions] = nil
29
29
 
30
30
  @mandatories = [:url, :price, :currency_id, :category_id, :delivery, :name]
31
31
  end
@@ -6,26 +6,26 @@ module YmlBuilder # :nodoc:
6
6
 
7
7
  @type = 'vendor.model'
8
8
 
9
- @params[:m] = Hash.new
10
- @params[:m][:url] = nil
11
- @params[:m][:price] = nil
9
+ @params[:m] = Hash.new
10
+ @params[:m][:url] = nil
11
+ @params[:m][:price] = nil
12
12
  @params[:m][:currency_id] = nil
13
13
  @params[:m][:category_id] = nil
14
- @params[:m][:delivery] = nil
15
- @params[:m][:vendor] = nil
16
- @params[:m][:model] = nil
14
+ @params[:m][:delivery] = nil
15
+ @params[:m][:vendor] = nil
16
+ @params[:m][:model] = nil
17
17
 
18
- @params[:o] = Hash.new
19
- @params[:o][:local_delivery_cost] = nil
20
- @params[:o][:type_prefix] = nil
21
- @params[:o][:vendor_code] = nil
22
- @params[:o][:description] = nil
18
+ @params[:o] = Hash.new
19
+ @params[:o][:local_delivery_cost] = nil
20
+ @params[:o][:type_prefix] = nil
21
+ @params[:o][:vendor_code] = nil
22
+ @params[:o][:description] = nil
23
23
  @params[:o][:manufacturer_warranty] = nil
24
- @params[:o][:country_of_origin] = nil
25
- @params[:o][:available] = nil
26
- @params[:o][:sales_notes] = nil
27
- @params[:o][:downloadable] = nil
28
- @params[:o][:adult] = nil
24
+ @params[:o][:country_of_origin] = nil
25
+ @params[:o][:available] = nil
26
+ @params[:o][:sales_notes] = nil
27
+ @params[:o][:downloadable] = nil
28
+ @params[:o][:adult] = nil
29
29
  end
30
30
 
31
31
  end
@@ -5,11 +5,12 @@ module YmlBuilder
5
5
  class Offers
6
6
 
7
7
  def initialize(stats, categories)
8
- @stats = stats
8
+ @stats = stats
9
9
  @categories = categories
10
10
  init_class
11
11
  end
12
12
 
13
+
13
14
  # Метод добавляет товар в прайс-лист с учетом выставленных в значении filter настроек.
14
15
  #
15
16
  # @param [{YmlBuilder::CommonOffer}] offer карточка товара
@@ -29,6 +30,7 @@ module YmlBuilder
29
30
  true
30
31
  end
31
32
 
33
+
32
34
  # Метод формирует фрагмент YML файла каталога Яндекс.Маркет для всего списка товаров
33
35
  #
34
36
  # @param [Integer] ident отступ от левого края в символах
@@ -37,13 +39,19 @@ module YmlBuilder
37
39
  @offers = @offers.sort_by { |id, offer| id }
38
40
 
39
41
  out = Array.new
40
- out << "<offers>"
41
- @offers.each do |id, offer|
42
- out += offer.to_yml(2).split(/[\n\r]/)
42
+ idx = 1
43
+ out << add_ident("<offers>", ident)
44
+ @offers.each do |_, offer|
45
+ # Формируем один товар в YAML, разбиваем на строки, чтобы к каждой
46
+ # добавить нужное количество пробелов для формирования корректного
47
+ # YAML-файла
48
+ arr = offer.to_yml(2).split(/[\n\r]/)
49
+ arr.map! { |line| add_ident(line, ident) }
50
+ out << arr.join("\n")
51
+ # puts "#{idx}/#{@offers.count}" if idx % 1000 == 0
52
+ idx += 1
43
53
  end
44
- out << "</offers>"
45
-
46
- out.map! { |line| ' '.rjust(ident, ' ') + line }
54
+ out << add_ident("</offers>", ident)
47
55
  out.join("\n")
48
56
  end
49
57
 
@@ -51,9 +59,14 @@ module YmlBuilder
51
59
  private
52
60
 
53
61
 
54
- def init_class
55
- @offers = Hash.new
56
- end
62
+ def add_ident(str, ident)
63
+ ' '.rjust(ident, ' ') + str
64
+ end
65
+
66
+
67
+ def init_class
68
+ @offers = Hash.new
69
+ end
57
70
 
58
71
  end
59
72
  end
@@ -5,6 +5,7 @@ module YmlBuilder
5
5
  init_class
6
6
  end
7
7
 
8
+
8
9
  # Метод формирует фрагмент YML файла каталога Яндекс.Маркет для описания Интернет-магазина
9
10
  #
10
11
  # @return [String] фрагмент YML файла каталога Яндекс.Маркет
@@ -34,43 +35,46 @@ module YmlBuilder
34
35
 
35
36
  private
36
37
 
37
- def init_class
38
- @params = Hash.new
39
-
40
- @params[:m] = Hash.new
41
- @params[:m][:name] = ''
42
- @params[:m][:company] = ''
43
- @params[:m][:url] = ''
44
-
45
- @params[:o] = Hash.new
46
- @params[:o][:phone] = nil
47
- @params[:o][:platform] = nil
48
- @params[:o][:version] = nil
49
- @params[:o][:agency] = nil
50
- @params[:o][:email] = nil
51
- @params[:o][:adult] = nil
52
- @params[:o][:cpa] = nil
53
- end
54
38
 
55
- def method_missing(method_sym, *arguments, &block)
56
- if @params[:m].include?(method_sym.to_s.gsub(/=$/, '').to_sym)
57
- processing_method(:m, method_sym, arguments.first)
58
- elsif @params[:o].include?(method_sym.to_s.gsub(/=$/, '').to_sym)
59
- processing_method(:o, method_sym, arguments.first)
60
- else
61
- super
39
+ def init_class
40
+ @params = Hash.new
41
+
42
+ @params[:m] = Hash.new
43
+ @params[:m][:name] = ''
44
+ @params[:m][:company] = ''
45
+ @params[:m][:url] = ''
46
+
47
+ @params[:o] = Hash.new
48
+ @params[:o][:phone] = nil
49
+ @params[:o][:platform] = nil
50
+ @params[:o][:version] = nil
51
+ @params[:o][:agency] = nil
52
+ @params[:o][:email] = nil
53
+ @params[:o][:adult] = nil
54
+ @params[:o][:cpa] = nil
62
55
  end
63
- end
64
56
 
65
- def processing_method(part, method_sym, value)
66
- if method_sym.to_s.match(/=$/)
67
- key = method_sym.to_s.gsub(/=$/, '')
68
- warn "Предупреждение: название магазина не должно быть больше 20 символов" if key == 'name' && value.length > 20
69
- @params[part][key.to_sym] = value
70
- else
71
- @params[part][method_sym.to_s.gsub(/=$/, '').to_sym]
57
+
58
+ def method_missing(method_sym, *arguments, &block)
59
+ if @params[:m].include?(method_sym.to_s.gsub(/=$/, '').to_sym)
60
+ processing_method(:m, method_sym, arguments.first)
61
+ elsif @params[:o].include?(method_sym.to_s.gsub(/=$/, '').to_sym)
62
+ processing_method(:o, method_sym, arguments.first)
63
+ else
64
+ super
65
+ end
66
+ end
67
+
68
+
69
+ def processing_method(part, method_sym, value)
70
+ if method_sym.to_s.match(/=$/)
71
+ key = method_sym.to_s.gsub(/=$/, '')
72
+ warn "Предупреждение: название магазина не должно быть больше 20 символов" if key == 'name' && value.length > 20
73
+ @params[part][key.to_sym] = value
74
+ else
75
+ @params[part][method_sym.to_s.gsub(/=$/, '').to_sym]
76
+ end
72
77
  end
73
- end
74
78
 
75
79
 
76
80
  end
@@ -2,18 +2,21 @@ module YmlBuilder # :nodoc:
2
2
  class Stats
3
3
  attr_reader :stats
4
4
 
5
+
5
6
  def initialize
6
7
  init_class
7
8
  end
8
9
 
10
+
9
11
  def init_class
10
- @stats = Hash.new
12
+ @stats = Hash.new
11
13
  @stats[:categories] = 0
12
- @stats[:total] = 0
13
- @stats[:available] = 0
14
- @stats[:price] = 0
14
+ @stats[:total] = 0
15
+ @stats[:available] = 0
16
+ @stats[:price] = 0
15
17
  end
16
18
 
19
+
17
20
  def add(key, value)
18
21
  @stats[key] += value
19
22
  end
@@ -1,3 +1,4 @@
1
1
  module YmlBuilder # :nodoc:
2
- VERSION = "0.1.3"
2
+ VERSION = "0.1.4"
3
3
  end
4
+
@@ -31,14 +31,15 @@ module YmlBuilder
31
31
 
32
32
 
33
33
  def initialize
34
- @stats = ::YmlBuilder::Stats.new
35
- @shop = ::YmlBuilder::Shop.new
36
- @currencies = ::YmlBuilder::Currencies.new
37
- @categories = ::YmlBuilder::Categories.new(@stats)
38
- @offers = ::YmlBuilder::Offers.new(@stats, @categories)
34
+ @stats = ::YmlBuilder::Stats.new
35
+ @shop = ::YmlBuilder::Shop.new
36
+ @currencies = ::YmlBuilder::Currencies.new
37
+ @categories = ::YmlBuilder::Categories.new(@stats)
38
+ @offers = ::YmlBuilder::Offers.new(@stats, @categories)
39
39
  @local_delivery_cost = nil
40
40
  end
41
41
 
42
+
42
43
  # Метод устанавливает стоимость доставки в месте локации магазина. Например, если магазин находится в Москве,
43
44
  # то при указанни данной стоимости, она будет показана покупателям в этом же районе.
44
45
  #
@@ -48,6 +49,7 @@ module YmlBuilder
48
49
  @local_delivery_cost = value
49
50
  end
50
51
 
52
+
51
53
  # Метод возвращает статистику по результатам генерации прайс-листа: всего товаров, товаров в наличии, стоимость
52
54
  # товаров в наличии (без учета количества)
53
55
  #
@@ -59,6 +61,7 @@ module YmlBuilder
59
61
  @stats.stats
60
62
  end
61
63
 
64
+
62
65
  # Метод возвращает текстовую строку с прайс-листом в формате Яндекс.Маркет
63
66
  #
64
67
  # @return [String] строка с прайс-листом в формате utf-8
@@ -75,6 +78,7 @@ module YmlBuilder
75
78
  add_header_footer(out)
76
79
  end
77
80
 
81
+
78
82
  # Метод для записи прайслиста в файл. Запись осущесствится в кодировке windows-1251
79
83
  #
80
84
  # @param [String] filename название файла для записи прайс-листа
@@ -83,25 +87,28 @@ module YmlBuilder
83
87
  # price = YmlBuilder::Yml.new
84
88
  # price.save('price.yml')
85
89
  def save(filename)
86
- File.open(filename, 'w:windows-1251') {|f| f.write(to_yml) }
90
+ File.open(filename, 'w:windows-1251') { |f| f.write(to_yml) }
87
91
  end
88
92
 
93
+
89
94
  private
90
95
 
91
- def add_header_footer(text)
92
- out = Array.new
93
- out << "<?xml version=\"1.0\" encoding=\"windows-1251\"?>"
94
- out << "<!DOCTYPE yml_catalog SYSTEM \"shops.dtd\">"
95
- out << "<yml_catalog date=#{::Time.now.strftime("%Y-%m-%d %H:%M").inspect}>"
96
- out << text
97
- out << "</yml_catalog>"
98
- out.join("\n")
99
- end
100
96
 
101
- def lds_to_yml(ident = 4)
102
- return "" if @local_delivery_cost.nil?
103
- ' '.rjust(ident, ' ') + "<local_delivery_cost>#{@local_delivery_cost}</local_delivery_cost>\n"
104
- end
97
+ def add_header_footer(text)
98
+ out = Array.new
99
+ out << "<?xml version=\"1.0\" encoding=\"windows-1251\"?>"
100
+ out << "<!DOCTYPE yml_catalog SYSTEM \"shops.dtd\">"
101
+ out << "<yml_catalog date=#{::Time.now.strftime("%Y-%m-%d %H:%M").inspect}>"
102
+ out << text
103
+ out << "</yml_catalog>"
104
+ out.join("\n")
105
+ end
106
+
107
+
108
+ def lds_to_yml(ident = 4)
109
+ return "" if @local_delivery_cost.nil?
110
+ ' '.rjust(ident, ' ') + "<local_delivery_cost>#{@local_delivery_cost}</local_delivery_cost>\n"
111
+ end
105
112
 
106
113
  end
107
114
  end
@@ -0,0 +1,53 @@
1
+ require 'rspec'
2
+ require 'yml_builder'
3
+
4
+ # Запрос URL
5
+ # У пользователя не отрабатывает генерация 60 тыс. товаров
6
+ # В ходе тестирования стало понятно, что огромная задержка происходит
7
+ # в функции to_yaml. Функция переписана вручную.
8
+
9
+ describe 'Пример 4 - Формирование выгрузки на 100 тыс. товаров' do
10
+
11
+ it 'Test' do
12
+ price = YmlBuilder::Yml.new
13
+ price.shop.name = 'Магазин ТЕСТ'
14
+ price.shop.company = "ООО 'Рога & Копыта'"
15
+ price.shop.url = 'http://example-site.ru'
16
+ price.shop.phone = '+7 (123) 456-7890'
17
+ price.shop.platform = 'OpenCart'
18
+ price.shop.version = '2.0'
19
+ price.currencies.rub = 1
20
+ price.currencies.usd = 55.04
21
+ price.currencies.eur = :cbrf
22
+ price.categories.add(id: 1, name: "Тестовая категория")
23
+
24
+ 0.upto(100_000) do |tovar_id|
25
+ if tovar_id % 1000 == 0
26
+ puts "#{tovar_id}/100000"
27
+ end
28
+
29
+ item = YmlBuilder::Offer.new('simple')
30
+ item.id = tovar_id
31
+ item.available = [true, false].sample
32
+ item.currency_id = ['RUR', 'EUR'].sample
33
+ item.delivery =[true, false].sample
34
+ item.category_id = 1
35
+ item.name = "Товар #{tovar_id}"
36
+ item.url = "http://example-site.ru/items/#{tovar_id}"
37
+ item.price = Random.rand(300) + 100
38
+ item.add_picture("http://example-site.ru/#{tovar_id}/image1")
39
+ item.add_param(name: 'Обложка', value: 'Мягкая')
40
+ item.add_param(name: 'Страниц', value: 10, unit: 'шт.')
41
+
42
+ price.offers.add(item)
43
+ end
44
+
45
+ puts
46
+ puts "Добавление товаров завершено"
47
+ print "Фрагмент итоговой выгрузки... "
48
+ puts price.to_yml[1..1024]
49
+ puts price.stats.inspect
50
+ end
51
+
52
+ end
53
+
data/test/test_yml.yml CHANGED
@@ -1,6 +1,6 @@
1
1
  <?xml version="1.0" encoding="windows-1251"?>
2
2
  <!DOCTYPE yml_catalog SYSTEM "shops.dtd">
3
- <yml_catalog date="2015-05-11 17:24">
3
+ <yml_catalog date="2019-01-02 23:01">
4
4
  <shop>
5
5
  <name>������� ����</name>
6
6
  <company>��� &apos;���� &amp; ������&apos;</company>
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: yml_builder
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.1.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stan Zhuravlev
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-05-27 00:00:00.000000000 Z
11
+ date: 2019-01-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -69,6 +69,7 @@ files:
69
69
  - test/example_1_spec.rb
70
70
  - test/example_2_spec.rb
71
71
  - test/example_3_spec.rb
72
+ - test/example_4_huge_items_spec.rb
72
73
  - test/example_full_spec.rb
73
74
  - test/test_yml.yml
74
75
  homepage: https://github.com/StanZhuravlev/yml_builder