auchandirect-scrAPI 0.1.1 → 0.2.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
  SHA1:
3
- metadata.gz: e4f04d459a19fb29b837fc67d14fb9be671b049e
4
- data.tar.gz: 29f59965eb06cf07a737008a099f8cd0743b25ae
3
+ metadata.gz: 9556cd0d6ccba68fa4273213e66b8249400ba175
4
+ data.tar.gz: f4d0ba344bb0318639779c364235f21977b72587
5
5
  SHA512:
6
- metadata.gz: 01bdecbbde94cf407a4bd703134c65dd9200f25138d4662896119e6220491802f7a7bfe114c12571562ba8ce566ac1a1a3468a0de2d39565f301d6fca66d751d
7
- data.tar.gz: eb06be216471dcb79327f3961144669d1ea0d9116f7a0c4db4a8c2ac7de6eea38dd4b1f3dd98a950b94ad1a0b18f119fb342958867e01cf1aeaf957e0e1f5dd5
6
+ metadata.gz: 44991b554adf1f08a87d01851210c2644a84ab9649d5e2260b73d6d618f115ca0ef50b93f508a58d24052dae2bca158bf4cdcf9cb5bfb95a53ac1c3ba1c645c5
7
+ data.tar.gz: 1ddc92e17d7826830a2ac0690381118928a659a49ff31c53f2c30b245cd01142bfdc237bd94cb73f4c78814c10b236c2725a84e2a73c5295a2e2472938b25841
checksums.yaml.gz.sig CHANGED
Binary file
data.tar.gz.sig CHANGED
Binary file
data/README.md CHANGED
@@ -20,7 +20,7 @@ Or install it yourself as:
20
20
 
21
21
  This library should be production ready.
22
22
  * It is automaticaly tested through [Travis](https://travis-ci.org/philou/auchandirect-scrAPI)
23
- * It should be daily tested through [TravisCron](http://traviscron.pythonanywhere.com/) to quickly detect modification at www.auchandirect.fr
23
+ * It should be daily tested through [daily-travis](https://github.com/philou/daily-travis) to quickly detect modification at www.auchandirect.fr
24
24
 
25
25
  ## Usage
26
26
 
@@ -42,7 +42,7 @@ cart = Auchandirect::ScrAPI::Cart.login('buyer@mail.org', 'password')
42
42
 
43
43
  begin
44
44
 
45
- Storexplore::Api.browse('http://www.auchandirect.fr').categories.each do |cat|
45
+ Auchandirect::ScrAPI::Items.browse.categories.each do |cat|
46
46
  cat.categories.each do |s_cat|
47
47
  s_cat.categories.each do |ss_cat|
48
48
  ss_cat.items.each do |item|
@@ -21,6 +21,7 @@
21
21
 
22
22
  require 'storexplore'
23
23
  require 'auchandirect/scrAPI/version'
24
+ require 'auchandirect/scrAPI/constants'
24
25
  require 'auchandirect/scrAPI/items'
25
26
  require 'auchandirect/scrAPI/base_cart'
26
27
  require 'auchandirect/scrAPI/dummy_cart'
@@ -29,7 +29,7 @@ module Auchandirect
29
29
 
30
30
  # Main url of the store
31
31
  def self.url
32
- "http://www.auchandirect.fr"
32
+ HOMEPAGE
33
33
  end
34
34
 
35
35
  # Logins to auchan direct store
@@ -41,7 +41,7 @@ module Auchandirect
41
41
 
42
42
  # Url at which a client browser can login
43
43
  def self.login_url
44
- url + login_path
44
+ URL + login_path
45
45
  end
46
46
  # Parameters for a client side login
47
47
  def self.login_parameters(login, password)
@@ -64,7 +64,7 @@ module Auchandirect
64
64
 
65
65
  # Url at which a client browser can logout
66
66
  def self.logout_url
67
- url + logout_path
67
+ URL + logout_path
68
68
  end
69
69
 
70
70
  # Logs out from the store
@@ -122,11 +122,25 @@ module Auchandirect
122
122
  def self.login_form_data(agent)
123
123
  home_page = agent.get(Cart.url)
124
124
 
125
- login_form_json = post(agent, "/boutiques.paniervolant.customerinfos:showsigninpopup", {}, {'Referer' => home_page.uri})
125
+ with_retry(5) do
126
+ login_form_json = post(agent, "/boutiques.paniervolant.customerinfos:showsigninpopup", {}, {'Referer' => home_page.uri})
126
127
 
127
- html_body = JSON.parse(login_form_json.body)["zones"]["secondPopupZone"]
128
- doc = Nokogiri::HTML("<html><body>#{html_body}</body></html>")
129
- doc.xpath("//input[@name='#{FORMDATA_PARAMETER}']/@value").first.content
128
+ html_body = JSON.parse(login_form_json.body)["zones"]["popupZone"]
129
+ doc = Nokogiri::HTML("<html><body>#{html_body}</body></html>")
130
+ doc.xpath("//input[@name='#{FORMDATA_PARAMETER}']/@value").first.content
131
+ end
132
+ end
133
+
134
+ def self.with_retry(attempts)
135
+ begin
136
+ return yield
137
+
138
+ rescue Exception => e
139
+ attempts -= 1
140
+
141
+ retry unless attempts == 0
142
+ raise e
143
+ end
130
144
  end
131
145
 
132
146
  def logged_in?
@@ -135,7 +149,7 @@ module Auchandirect
135
149
  end
136
150
 
137
151
  def get(path)
138
- @agent.get(url + path)
152
+ @agent.get(URL + path)
139
153
  end
140
154
 
141
155
  def post(path, parameters = {}, headers = {})
@@ -143,7 +157,7 @@ module Auchandirect
143
157
  end
144
158
 
145
159
  def self.post(agent, path, parameters = {}, headers = {})
146
- agent.post(url + path, post_parameters.merge(parameters), fast_header.merge(headers))
160
+ agent.post(URL + path, post_parameters.merge(parameters), fast_header.merge(headers))
147
161
  end
148
162
 
149
163
  def self.fast_header
@@ -0,0 +1,31 @@
1
+ # -*- encoding: utf-8 -*-
2
+ #
3
+ # auchandirect/scrAPI/items.rb
4
+ #
5
+ # Copyright (c) 2010-2014 by Philippe Bourgau. All rights reserved.
6
+ #
7
+ # This library is free software; you can redistribute it and/or
8
+ # modify it under the terms of the GNU Lesser General Public
9
+ # License as published by the Free Software Foundation; either
10
+ # version 3.0 of the License, or (at your option) any later version.
11
+ #
12
+ # This library is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
+ # Lesser General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU Lesser General Public
18
+ # License along with this library; if not, write to the Free Software
19
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
20
+ # MA 02110-1301 USA
21
+
22
+ module Auchandirect
23
+ module ScrAPI
24
+
25
+ DOMAIN = 'auchandirect.fr'
26
+ WEBSITE = 'www.auchandirect.fr'
27
+ URL = 'http://www.auchandirect.fr'
28
+ HOMEPAGE = 'http://www.auchandirect.fr/Accueil'
29
+
30
+ end
31
+ end
@@ -35,12 +35,22 @@ module Auchandirect
35
35
  # * price
36
36
  # * image (url of the link to the image)
37
37
  # * remote_id (the id of this item in the auchandirect database)
38
+ class Items
39
+
40
+ # Returns a Storexplore api on whole auchandirect catalog
41
+ def self.browse
42
+ Storexplore::Api.browse(url)
43
+ end
44
+
45
+ # Main url of the store
46
+ def self.url
47
+ HOMEPAGE
48
+ end
38
49
 
39
- module Items
40
50
  NAMES_SEPARATOR = ', '
41
51
  end
42
52
 
43
- Storexplore::Api.define "auchandirect.fr" do
53
+ Storexplore::Api.define DOMAIN do
44
54
 
45
55
  categories '#footer-menu h2 a' do
46
56
  attributes do
@@ -21,7 +21,7 @@
21
21
 
22
22
  module Auchandirect
23
23
  module ScrAPI
24
- VERSION = "0.1.1"
24
+ VERSION = "0.2.0"
25
25
  end
26
26
  end
27
27
 
@@ -49,7 +49,7 @@ when_online("AuchanDirectApi remote spec") do
49
49
  Auchandirect::ScrAPI::Cart.send(:extend, AuchanDirectApiCredentials)
50
50
 
51
51
  describe Auchandirect::ScrAPI::Cart, slow: true, remote: true do
52
- it_should_behave_like "Any Cart", Auchandirect::ScrAPI::Cart, Auchandirect::ScrAPI::Cart.url
52
+ it_should_behave_like "Any Cart", Auchandirect::ScrAPI::Cart, Auchandirect::ScrAPI::Items.url
53
53
  it_should_behave_like "Any Client Cart", Auchandirect::ScrAPI::Cart, "Identifiez-vous"
54
54
  end
55
55
  end
@@ -31,11 +31,11 @@ when_online "AuchanDirectStoreItemsAPI remote spec" do
31
31
  it_should_behave_like "an API"
32
32
 
33
33
  def generate_store
34
- Storexplore::Api.browse("http://www.auchandirect.fr")
34
+ Auchandirect::ScrAPI::Items.browse
35
35
  end
36
36
 
37
37
  it "should have absolute urls for images" do
38
- expect(sample_items_attributes.map {|attr| attr[:image]}).to all_ {include("auchandirect.fr")}
38
+ expect(sample_items_attributes.map {|attr| attr[:image]}).to all_ {include(DOMAIN)}
39
39
  end
40
40
 
41
41
  end
@@ -29,7 +29,7 @@ module Auchandirect
29
29
  it_should_behave_like "an API"
30
30
 
31
31
  def generate_store
32
- @offline_store_dir = File.join(AUCHANDIRECT_SCRAPI_ROOT_DIR,'offline_sites','www.auchandirect.fr')
32
+ @offline_store_dir = File.join(AUCHANDIRECT_SCRAPI_ROOT_DIR,'offline_sites',WEBSITE)
33
33
  auchan_direct_offline = "file://" + File.join(@offline_store_dir, 'index.html')
34
34
  Storexplore::Api.browse(auchan_direct_offline)
35
35
  end
@@ -64,28 +64,35 @@ module Auchandirect
64
64
  def search_through_files_for(grep_hint, selector)
65
65
  `find #{@offline_store_dir} -name *.html -exec grep -l "#{grep_hint}" {} \\;`.split("\n").lazy.
66
66
 
67
- map do |file|
67
+ map do |file|
68
68
  doc = Nokogiri::HTML(open(file))
69
69
  [file, doc.search(selector)]
70
70
  end.
71
71
 
72
- select do |file, elements|
72
+ select do |file, elements|
73
73
  !elements.empty?
74
74
  end.
75
75
 
76
- map do |file, elements|
77
- # example : http://www.auchandirect.fr/petit-dejeuner-epicerie-sucree/chocolats,-confiseries/barres-biscuitees-muesli---cereales/id1/485/53869
76
+ map do |file, elements|
77
+ split_url_to_tokens(file).merge(elements: elements)
78
+ end
79
+ end
78
80
 
79
- file = URI.unescape(file)
80
- file = file.gsub(/^.*\/www\.auchandirect\.fr\//, "")
81
- pieces = file.split("/").take(3)
82
- pieces[2] = pieces[2].split(",")[0]
83
- pieces = pieces.map do |piece|
84
- piece.gsub(/lv_/,'').split(/[\-_, \(\)']+/).select {|p| not (p.size <= 2 or p =~ /^[0-9]/)}
85
- end
81
+ def split_url_to_tokens(file)
82
+ # example : http://www.auchandirect.fr/petit-dejeuner-epicerie-sucree/chocolats,-confiseries/barres-biscuitees-muesli---cereales/id1/485/53869
83
+
84
+ file = URI.unescape(file)
85
+ file = file.gsub(/^.*\/www\.auchandirect\.fr\//, "")
86
86
 
87
- {cat_tokens: pieces[0], sub_cat_tokens: pieces[1], item_tokens: pieces[2], elements: elements}
87
+ pieces = file.split("/").take(3)
88
+
89
+ pieces[2] = pieces[2].split(",")[0]
90
+
91
+ pieces = pieces.map do |piece|
92
+ piece.gsub(/lv_/,'').split(/[\-_, \(\)']+/).select {|p| not (p.size <= 2 or p =~ /^[0-9]/)}
88
93
  end
94
+
95
+ {cat_tokens: pieces[0], sub_cat_tokens: pieces[1], item_tokens: pieces[2]}
89
96
  end
90
97
 
91
98
 
@@ -93,7 +100,7 @@ module Auchandirect
93
100
  filter(store.categories, item_info[:cat_tokens]).each do |cat|
94
101
  filter(cat.categories, item_info[:sub_cat_tokens]).each do |sub_cat|
95
102
  sub_cat.categories.each do |sub_sub_cat|
96
- filter(sub_sub_cat.items, item_info[:item_tokens]).each do |item|
103
+ take_singleton(filter(sub_sub_cat.items, item_info[:item_tokens])).each do |item|
97
104
  return item_info.merge(item: item)
98
105
  end
99
106
  end
@@ -109,6 +116,24 @@ module Auchandirect
109
116
  end
110
117
  end
111
118
  end
119
+
120
+ def take_singleton(items)
121
+ item = nil
122
+
123
+ begin
124
+ item = items.next
125
+ rescue StopIteration
126
+ return []
127
+ end
128
+
129
+ begin
130
+ items.next
131
+ rescue StopIteration
132
+ return [item]
133
+ end
134
+
135
+ return []
136
+ end
112
137
  end
113
138
  end
114
139
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: auchandirect-scrAPI
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Philou
@@ -31,7 +31,7 @@ cert_chain:
31
31
  yLcl1cmm5ALtJ/+Bkkmp0i4amXeTDMvq9r8PBsVsQwxYOYJBP+Umxz3PX6HjFHrQ
32
32
  XdkXx3oZ
33
33
  -----END CERTIFICATE-----
34
- date: 2014-03-31 00:00:00.000000000 Z
34
+ date: 2014-04-26 00:00:00.000000000 Z
35
35
  dependencies:
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: storexplore
@@ -136,6 +136,7 @@ files:
136
136
  - lib/auchandirect/scrAPI.rb
137
137
  - lib/auchandirect/scrAPI/base_cart.rb
138
138
  - lib/auchandirect/scrAPI/cart.rb
139
+ - lib/auchandirect/scrAPI/constants.rb
139
140
  - lib/auchandirect/scrAPI/dummy_cart.rb
140
141
  - lib/auchandirect/scrAPI/invalid_account_error.rb
141
142
  - lib/auchandirect/scrAPI/items.rb
metadata.gz.sig CHANGED
Binary file