tec_doc 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (65) hide show
  1. data/LICENSE +20 -0
  2. data/README.md +29 -0
  3. data/bin/tec_doc +51 -0
  4. data/lib/tec_doc.rb +28 -0
  5. data/lib/tec_doc/article.rb +317 -0
  6. data/lib/tec_doc/article_attribute.rb +17 -0
  7. data/lib/tec_doc/article_document.rb +49 -0
  8. data/lib/tec_doc/article_oe_number.rb +11 -0
  9. data/lib/tec_doc/article_thumbnail.rb +18 -0
  10. data/lib/tec_doc/assembly_group.rb +77 -0
  11. data/lib/tec_doc/brand.rb +18 -0
  12. data/lib/tec_doc/client.rb +84 -0
  13. data/lib/tec_doc/date_parser.rb +14 -0
  14. data/lib/tec_doc/error.rb +4 -0
  15. data/lib/tec_doc/fuel_type.rb +0 -0
  16. data/lib/tec_doc/generic_article.rb +47 -0
  17. data/lib/tec_doc/language.rb +22 -0
  18. data/lib/tec_doc/vehicle.rb +121 -0
  19. data/lib/tec_doc/vehicle_manufacturer.rb +46 -0
  20. data/lib/tec_doc/vehicle_model.rb +46 -0
  21. data/lib/tec_doc/version.rb +3 -0
  22. data/spec/cassettes/article_all.yml +88 -0
  23. data/spec/cassettes/article_all_with_details.yml +84 -0
  24. data/spec/cassettes/article_details.yml +68 -0
  25. data/spec/cassettes/article_details_for_trade_number.yml +56 -0
  26. data/spec/cassettes/article_document_all.yml +49 -0
  27. data/spec/cassettes/article_document_content.yml +763 -0
  28. data/spec/cassettes/article_information.yml +55 -0
  29. data/spec/cassettes/article_linked_manufacturers.yml +45 -0
  30. data/spec/cassettes/article_linked_vehicle_ids.yml +45 -0
  31. data/spec/cassettes/article_linked_vehicles.yml +372 -0
  32. data/spec/cassettes/article_linked_vehicles_with_details.yml +430 -0
  33. data/spec/cassettes/article_search.yml +62 -0
  34. data/spec/cassettes/article_search_for_linked_manufacturers.yml +47 -0
  35. data/spec/cassettes/article_thumbnail_all.yml +45 -0
  36. data/spec/cassettes/article_thumbnail_content.yml +399 -0
  37. data/spec/cassettes/article_trade_number.yml +46 -0
  38. data/spec/cassettes/article_with_a_lot_linked_vehicles.yml +60 -0
  39. data/spec/cassettes/assembly_group_all.yml +90 -0
  40. data/spec/cassettes/assembly_group_children.yml +55 -0
  41. data/spec/cassettes/brand_all.yml +81 -0
  42. data/spec/cassettes/generic_article_all.yml +46 -0
  43. data/spec/cassettes/language_all.yml +48 -0
  44. data/spec/cassettes/linked_targets_by_manufacturers.yml +2584 -0
  45. data/spec/cassettes/status_401.yml +38 -0
  46. data/spec/cassettes/vehicle_all.yml +79 -0
  47. data/spec/cassettes/vehicle_assembly_groups.yml +83 -0
  48. data/spec/cassettes/vehicle_child_assembly_groups.yml +49 -0
  49. data/spec/cassettes/vehicle_find_by_id.yml +50 -0
  50. data/spec/cassettes/vehicle_manufacturer_all.yml +52 -0
  51. data/spec/cassettes/vehicle_model_all.yml +119 -0
  52. data/spec/spec_helper.rb +28 -0
  53. data/spec/tec_doc/article_document_spec.rb +34 -0
  54. data/spec/tec_doc/article_spec.rb +185 -0
  55. data/spec/tec_doc/article_thumbnail_spec.rb +34 -0
  56. data/spec/tec_doc/assembly_group_spec.rb +48 -0
  57. data/spec/tec_doc/brand_spec.rb +22 -0
  58. data/spec/tec_doc/client_spec.rb +11 -0
  59. data/spec/tec_doc/date_parser_spec.rb +17 -0
  60. data/spec/tec_doc/generic_article_spec.rb +30 -0
  61. data/spec/tec_doc/language_spec.rb +22 -0
  62. data/spec/tec_doc/vehicle_manufacturer_spec.rb +43 -0
  63. data/spec/tec_doc/vehicle_model_spec.rb +35 -0
  64. data/spec/tec_doc/vehicle_spec.rb +80 -0
  65. metadata +426 -0
@@ -0,0 +1,17 @@
1
+ module TecDoc
2
+ class ArticleAttribute
3
+ attr_accessor :block_no, :id, :is_conditional, :is_interval, :name, :short_name, :successor_id, :type, :unit, :value, :value_id
4
+
5
+ def initialize(attributes = {})
6
+ attributes.each do |name, value|
7
+ send("#{name.to_s.gsub(/^attr_/, '')}=", value)
8
+ end
9
+
10
+ @id = @id.to_i if @id
11
+ @value_id = @value_id.to_i if @value_id
12
+ @value = DateParser.new(@value).to_date if @type == "D"
13
+ @is_interval = (@is_interval == "true") if @is_interval.is_a?(String)
14
+ @is_conditional = (@is_conditional == "true") if @is_conditional.is_a?(String)
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,49 @@
1
+ module TecDoc
2
+ class ArticleDocument
3
+ attr_accessor :id, :file_name, :file_type_name, :link_id, :description, :type_id, :type_name
4
+
5
+ # Find document descriptions to an article
6
+ #
7
+ # @option options [Integer] :article_id article ID
8
+ # @option options [Integer] :article_link_id article link ID (optional)
9
+ # @option options [String] :country country code according to ISO 3166
10
+ # @option options [Integer] :doc_type_id document type (KT 141) (optional)
11
+ # @option options [String] :lang language code according to ISO 639
12
+ # @return [Array<TecDoc::ArticleDocument>] list of article documents
13
+ def self.all(options = {})
14
+ options = {
15
+ :country => TecDoc.client.country,
16
+ :lang => I18n.locale.to_s
17
+ }.merge(options)
18
+ response = TecDoc.client.request(:get_article_documents, options)
19
+ response.map do |attributes|
20
+ new attributes
21
+ end
22
+ end
23
+
24
+ def initialize(attributes = {})
25
+ @id = attributes[:doc_id].to_i
26
+ @link_id = attributes[:doc_link_id].to_i
27
+ @file_name = attributes[:doc_file_name].to_s
28
+ @file_type_name = attributes[:doc_file_type_name].to_s
29
+ @type_id = attributes[:doc_type_id].to_i
30
+ @type_name = attributes[:doc_type_name].to_s
31
+ end
32
+
33
+ def url
34
+ base_url = TecDoc.client.connection.wsdl.endpoint.gsub("/services/TecdocToCatWL", "")
35
+ provider = TecDoc.client.provider
36
+ thumbnail_flag = self.is_a?(ArticleThumbnail) ? "1" : "0"
37
+ "#{base_url}/documents/#{provider}/#{id}/#{thumbnail_flag}"
38
+ end
39
+
40
+ def content
41
+ request = TecDoc.client.connection.http
42
+ request.url = url
43
+ request.body = nil
44
+ request.headers = {}
45
+ response = HTTPI.post(request)
46
+ response.raw_body
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,11 @@
1
+ module TecDoc
2
+ class ArticleOENumber
3
+ attr_accessor :block_number, :brand_name, :oe_number, :sort_number
4
+
5
+ def initialize(attributes = {})
6
+ attributes.each do |name, value|
7
+ send("#{name}=", value)
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,18 @@
1
+ module TecDoc
2
+ class ArticleThumbnail < ArticleDocument
3
+ # Find article thumbnail documents
4
+ #
5
+ # @option options [Integer] :article_id Article ID
6
+ # @return [Array<TecDoc::ArticleThumbnail>] list of article thumbnails
7
+ def self.all(options = {})
8
+ response = TecDoc.client.request(:get_thumbnail_by_article_id, options)
9
+ response.map do |attributes|
10
+ thumbnail = new
11
+ thumbnail.id = attributes[:thumb_doc_id].to_i
12
+ thumbnail.file_name = attributes[:thumb_file_name].to_s
13
+ thumbnail.type_id = attributes[:thumb_type_id].to_i
14
+ thumbnail
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,77 @@
1
+ module TecDoc
2
+ class AssemblyGroup
3
+ attr_accessor :id, :parent_id, :name, :has_children, :parent
4
+ attr_writer :children
5
+
6
+ attr_accessor :scope
7
+
8
+ def initialize(attributes={})
9
+ @id = attributes[:assembly_group_node_id].to_i
10
+ @name = attributes[:assembly_group_name].to_s
11
+ @has_children = attributes[:has_childs]
12
+ @scope = attributes[:scope]
13
+ if attributes[:parent_node_id]
14
+ @parent_id = attributes[:parent_node_id].to_i
15
+ end
16
+ end
17
+
18
+ # Find vehicle, axle, motor or universal assembly groups for the search tree
19
+ #
20
+ # @option options [TrueClass, FalseClass] :child_nodes include child nodes
21
+ # @option options [String] :lang language code according to ISO 639
22
+ # @option options [String] :linking_target_type linking target (C: Vehicle type, M: Motor, A: Axle, K: Body Type, U: Universal)
23
+ # @option options [Integer] :parent_node_id parent node id (optional)
24
+ # @return [Array<TecDoc::AssemblyGroup>] list of languages
25
+ def self.all(options = {})
26
+ options = {
27
+ :lang => I18n.locale.to_s
28
+ }.merge(options)
29
+
30
+ if options[:linking_target_id]
31
+ options[:country] ||= TecDoc.client.country
32
+ response = TecDoc.client.request(:get_linked_child_nodes_all_linking_target, options)
33
+ else
34
+ response = TecDoc.client.request(:get_child_nodes_all_linking_target2, options)
35
+ end
36
+
37
+ groups = response.map do |attributes|
38
+ attributes[:scope] = options
39
+ new(attributes)
40
+ end
41
+
42
+ if options[:child_nodes]
43
+ group_ids_map = {}
44
+ groups.each do |group|
45
+ group_ids_map[group.id] = group
46
+ end
47
+ groups.each do |group|
48
+ parent = group_ids_map[group.parent_id]
49
+ if parent
50
+ parent.add_child(group)
51
+ end
52
+ end
53
+ end
54
+
55
+ groups
56
+ end
57
+
58
+ def children
59
+ @children ||= if has_children
60
+ self.class.
61
+ all(scope.merge(:parent_node_id => id)).
62
+ each { |child| child.parent = self }
63
+ else
64
+ []
65
+ end
66
+ end
67
+
68
+ def add_child(child)
69
+ @children ||= []
70
+ @children << child
71
+ end
72
+
73
+ def inspect
74
+ "#<#{self.class} @id=#{id.inspect}, @parent_id=#{parent_id.inspect}, @name=#{name.inspect}, @has_children=#{has_children.inspect}>"
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,18 @@
1
+ module TecDoc
2
+ class Brand
3
+ attr_accessor :number, :name
4
+
5
+ # Get all brands available for provider.
6
+ #
7
+ # @return [Array<TecDoc::Brand>] list of brands
8
+ def self.all
9
+ response = TecDoc.client.request(:get_brands_for_assortment)
10
+ response.map do |attributes|
11
+ manufacturer = new
12
+ manufacturer.number = attributes[:brand_no].to_i
13
+ manufacturer.name = attributes[:brand_name].to_s
14
+ manufacturer
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,84 @@
1
+ module TecDoc
2
+ class Client
3
+ attr_accessor :provider, :country, :connection
4
+
5
+ def initialize(options = {})
6
+ self.provider = options[:provider]
7
+ self.country = options[:country]
8
+ self.connection = Savon::Client.new do |wsdl, http|
9
+ proxy = options[:proxy] || ENV['http_proxy']
10
+ http.proxy = proxy if proxy
11
+ end
12
+ self.mode = options[:mode] || :live
13
+ end
14
+
15
+ def request(operation, options = {})
16
+ log operation, options do
17
+ response = connection.request(operation) do
18
+ soap.body = { :in => { :provider => provider }.merge(options) }
19
+ end
20
+ # Parse errors
21
+ status_node = response.doc.xpath("//status").first
22
+ if status_node.text != "200"
23
+ status_text_node = response.doc.xpath("//statusText").first
24
+ raise Error.new(status_text_node.text)
25
+ end
26
+ # Parse the document
27
+ response.doc.xpath("//data/array/array").map do |node|
28
+ node_to_hash(node)
29
+ end
30
+ # response
31
+ end
32
+ end
33
+
34
+ def mode=(value)
35
+ if value == :test
36
+ connection.wsdl.endpoint = "http://webservicepilot.tecdoc.net/pegasus-2-0/services/TecdocToCatWL"
37
+ connection.wsdl.namespace = connection.wsdl.endpoint
38
+ @mode = :test
39
+ else
40
+ connection.wsdl.endpoint = "http://webservice-cs.tecdoc.net/pegasus-2-0/services/TecdocToCatWL"
41
+ connection.wsdl.namespace = connection.wsdl.endpoint
42
+ @mode = :live
43
+ end
44
+ end
45
+
46
+ attr_reader :mode
47
+
48
+ # Sets the logger to use.
49
+ attr_writer :logger
50
+
51
+ # Returns the logger. Defaults to an instance of +Logger+ writing to STDOUT.
52
+ def logger
53
+ @logger ||= ::Logger.new STDOUT
54
+ end
55
+
56
+ def log(operation, options)
57
+ t = Time.now
58
+ results = yield
59
+ duration = 1000.0 * (Time.now - t)
60
+ logger.info "TecDoc: #{operation.inspect} #{options.inspect} #{'(%.1fms)' % duration}"
61
+ results
62
+ end
63
+
64
+ private
65
+
66
+ def node_to_hash(node)
67
+ attributes = {}
68
+ node.children.each do |n|
69
+ if n.xpath("empty").text == "true"
70
+ attributes[n.name.snakecase.to_sym] = []
71
+ elsif (n_array = n.xpath("array/array")).size > 0
72
+ attributes[n.name.snakecase.to_sym] = n_array.map { |nn| node_to_hash(nn) }
73
+ elsif n.children.reject { |nn| nn.is_a?(Nokogiri::XML::Text) }.size > 0
74
+ attributes[n.name.snakecase.to_sym] = node_to_hash(n)
75
+ elsif n.text == ""
76
+ attributes[n.name.snakecase.to_sym] = nil
77
+ else
78
+ attributes[n.name.snakecase.to_sym] = n.text
79
+ end
80
+ end
81
+ attributes
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,14 @@
1
+ module TecDoc
2
+ class DateParser
3
+ def initialize(value)
4
+ @value = value
5
+ end
6
+
7
+ def to_date
8
+ if @value
9
+ year, month = @value.to_i.divmod(100)
10
+ Date.new(year, month, 1)
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,4 @@
1
+ module TecDoc
2
+ class Error < StandardError
3
+ end
4
+ end
File without changes
@@ -0,0 +1,47 @@
1
+ module TecDoc
2
+ class GenericArticle
3
+ attr_accessor :id, :name
4
+ attr_accessor :scope
5
+
6
+ # getGenericArticlesByManufacturer5()
7
+
8
+ # Get generic articles
9
+ #
10
+ # @option options [Integer] :assembly_group_node_id (optional)
11
+ # @option options [LongList] :generic_article_id (optional)
12
+ # @option options [LongList] :brand_no result of brand selection (optional)
13
+ # @option options [String] :linking_target_type - "C", "M", "A", "K", "U"
14
+ # @option options [Integer] :linking_target_id - null if "U"
15
+ # @option options [Integer] :result_mode - 1: Distinct brand numbers, 2: Distinct generic articles, 3: Both (optional)
16
+ # @option options [Integer] :sort_mode - 1: Brand name, 2: Article norm name (optional)
17
+ # @return [Array<TecDoc::GenericArticle>] list of generic articles
18
+ def self.all(options = {})
19
+ options[:result_mode] = 2
20
+ options[:sort_mode] = 2
21
+ options = {
22
+ :lang => I18n.locale.to_s,
23
+ :country => TecDoc.client.country
24
+ }.merge(options)
25
+ TecDoc.client.request(:get_generic_articles_by_manufacturer6, options).map do |attributes|
26
+ new(attributes, options)
27
+ end
28
+ end
29
+
30
+ def initialize(attributes = {}, scope = {})
31
+ @id = (attributes[:id] || attributes[:generic_article_id]).to_i
32
+ @name = attributes[:article_norm_name]
33
+ @scope = scope
34
+ end
35
+
36
+ # Generic article linked articles
37
+ def articles(options = {})
38
+ options = {
39
+ :linking_target_type => scope[:linking_target_type],
40
+ :linking_target_id => scope[:linking_target_id]
41
+ }.merge(options).merge({
42
+ :generic_article_id => { :array => { :id => [id] } }
43
+ })
44
+ Article.all(options)
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,22 @@
1
+ module TecDoc
2
+ class Language
3
+ attr_accessor :code, :name
4
+
5
+ # Get all languages available for provider.
6
+ #
7
+ # @option options [String] :lang language code according to ISO 639
8
+ # @return [Array<TecDoc::Language>] list of languages
9
+ def self.all(options = {})
10
+ options = {
11
+ :lang => I18n.locale.to_s
12
+ }.merge(options)
13
+ response = TecDoc.client.request(:get_languages, options)
14
+ response.map do |attributes|
15
+ language = new
16
+ language.code = attributes[:language_code].to_s
17
+ language.name = attributes[:language_name].to_s
18
+ language
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,121 @@
1
+ module TecDoc
2
+ class Vehicle
3
+ attr_accessor \
4
+ :id,
5
+ :name,
6
+ :cylinder_capacity,
7
+ :first_country,
8
+ :linked,
9
+ :power_hp_from,
10
+ :power_hp_to,
11
+ :power_kw_from,
12
+ :power_kw_to,
13
+ :date_of_construction_from,
14
+ :date_of_construction_to,
15
+ :motor_codes,
16
+ :manu_id,
17
+ :mod_id,
18
+ :attributes,
19
+ :article_link_id
20
+
21
+ # Find vehicles for simplified selection with motor codes
22
+ #
23
+ # @option options [Integer] :car_type vehicle type (1: Passenger car, 2: Commercial vehicle, 3: Light commercial)
24
+ # @option options [String] :countries_car_selection country code according to ISO 3166
25
+ # @option options [TrueClass, FalseClass] :country_group_flag country group selection
26
+ # @option options [String] :country_user_setting country for article assignments, country code according to assignments ISO 3166 (optional)
27
+ # @option options [Integer, NilClass] :favoured_list simplified vehicle selection (1: first list selection, 0: rest)
28
+ # @option options [String] :lang language code according to ISO 639
29
+ # @option options [TrueClass, FalseClass] :linked selection with/without article assignments (false: all, true: only linked articles)
30
+ # @option options [Integer] :manu_id manufacturer ID
31
+ # @option options [Integer] :mod_id vehicle ID
32
+ # @return [Array<TecDoc::VehicleManufacturer>] list of vehicles with motor codes
33
+ def self.all(options = {})
34
+ options = {
35
+ :car_type => 1,
36
+ :countries_car_selection => TecDoc.client.country,
37
+ :country_group_flag => false,
38
+ :favoured_list => 1,
39
+ :lang => I18n.locale.to_s,
40
+ :linked => false
41
+ }.merge(options)
42
+ response = TecDoc.client.request(:get_vehicle_simplified_selection4, options)
43
+ response.map do |attributes|
44
+ vehicle = new
45
+ car_attributes = attributes[:car_details]
46
+ if car_attributes
47
+ vehicle.manu_id = options[:manu_id].to_i
48
+ vehicle.mod_id = options[:mod_id].to_i
49
+ vehicle.id = car_attributes[:car_id].to_i
50
+ vehicle.name = car_attributes[:car_name].to_s
51
+ vehicle.cylinder_capacity = car_attributes[:cylinder_capacity].to_i
52
+ vehicle.first_country = car_attributes[:first_country].to_s
53
+ vehicle.linked = car_attributes[:linked]
54
+ vehicle.power_hp_from = car_attributes[:power_hp_from].to_i
55
+ vehicle.power_hp_to = car_attributes[:power_hp_to].to_i
56
+ vehicle.power_kw_from = car_attributes[:power_kw_from].to_i
57
+ vehicle.power_kw_to = car_attributes[:power_kw_to].to_i
58
+ vehicle.date_of_construction_from = DateParser.new(car_attributes[:year_of_constr_from]).to_date
59
+ vehicle.date_of_construction_to = DateParser.new(car_attributes[:year_of_constr_to]).to_date
60
+ end
61
+ vehicle.motor_codes = attributes[:motor_codes].map { |mc| mc[:motor_code] }
62
+ vehicle
63
+ end
64
+ end
65
+
66
+ def self.find(options = {})
67
+ id = options.delete(:id)
68
+ options = {
69
+ :car_ids => { :array => { :ids => [id] } },
70
+ :countries_car_selection => TecDoc.client.country,
71
+ :country_user_setting => TecDoc.client.country,
72
+ :country => TecDoc.client.country,
73
+ :lang => TecDoc.client.country,
74
+ :axles => false,
75
+ :cabs => false,
76
+ :country_group_flag => false,
77
+ :motor_codes => true,
78
+ :vehicle_details_2 => false,
79
+ :vehicle_terms => true
80
+ }.merge(options)
81
+ response = TecDoc.client.request(:get_vehicle_by_ids_2, options)
82
+ if attrs = response.first
83
+ details = attrs[:vehicle_details] || {}
84
+ terms = attrs[:vehicle_terms] || {}
85
+ vehicle = new
86
+ vehicle.id = attrs[:car_id].to_i
87
+ vehicle.name = terms[:car_type].to_s
88
+ vehicle.cylinder_capacity = details[:ccm_tech].to_i
89
+ vehicle.power_hp_from = details[:power_hp_from].to_i
90
+ vehicle.power_hp_to = details[:power_hp_to].to_i
91
+ vehicle.power_kw_from = details[:power_kw_from].to_i
92
+ vehicle.power_kw_to = details[:power_kw_to].to_i
93
+ vehicle.date_of_construction_from = DateParser.new(details[:year_of_constr_from]).to_date
94
+ vehicle.date_of_construction_to = DateParser.new(details[:year_of_constr_to]).to_date
95
+ vehicle.manu_id = details[:manu_id].to_i
96
+ vehicle.mod_id = details[:mod_id].to_i
97
+ vehicle.motor_codes = attrs[:motor_codes].map { |mc| mc[:motor_code] }
98
+ vehicle
99
+ else
100
+ nil
101
+ end
102
+ end
103
+
104
+ def attributes
105
+ @attributes || []
106
+ end
107
+
108
+ def attributes=(attrs)
109
+ @attributes = attrs.map{ |attr| ArticleAttribute.new(attr) }
110
+ end
111
+
112
+ # Vehicle linked assembly parent groups
113
+ def assembly_groups(options = {})
114
+ options.merge!({
115
+ :linking_target_type => "C",
116
+ :linking_target_id => id,
117
+ })
118
+ AssemblyGroup.all(options)
119
+ end
120
+ end
121
+ end