bol 0.0.1.beta

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. data/.gitignore +4 -0
  2. data/CHANGELOG.md +1 -0
  3. data/Gemfile +2 -0
  4. data/Guardfile +7 -0
  5. data/LICENSE.md +19 -0
  6. data/README.md +170 -0
  7. data/Rakefile +6 -0
  8. data/bol.gemspec +25 -0
  9. data/lib/bol.rb +52 -0
  10. data/lib/bol/category.rb +5 -0
  11. data/lib/bol/configuration.rb +55 -0
  12. data/lib/bol/parser.rb +34 -0
  13. data/lib/bol/parsers.rb +7 -0
  14. data/lib/bol/parsers/categories.rb +17 -0
  15. data/lib/bol/parsers/products.rb +34 -0
  16. data/lib/bol/parsers/refinements.rb +24 -0
  17. data/lib/bol/product.rb +51 -0
  18. data/lib/bol/proxy.rb +37 -0
  19. data/lib/bol/query.rb +79 -0
  20. data/lib/bol/refinement.rb +5 -0
  21. data/lib/bol/refinement_group.rb +5 -0
  22. data/lib/bol/request.rb +90 -0
  23. data/lib/bol/requests.rb +7 -0
  24. data/lib/bol/requests/list.rb +26 -0
  25. data/lib/bol/requests/product.rb +16 -0
  26. data/lib/bol/requests/search.rb +11 -0
  27. data/lib/bol/scope.rb +55 -0
  28. data/lib/bol/signature.rb +44 -0
  29. data/lib/bol/version.rb +3 -0
  30. data/spec/bol/configuration_spec.rb +46 -0
  31. data/spec/bol/parsers/products_spec.rb +77 -0
  32. data/spec/bol/product_spec.rb +71 -0
  33. data/spec/bol/proxy_spec.rb +34 -0
  34. data/spec/bol/query_spec.rb +129 -0
  35. data/spec/bol/request_spec.rb +119 -0
  36. data/spec/bol/scope_spec.rb +84 -0
  37. data/spec/bol/signature_spec.rb +27 -0
  38. data/spec/bol_spec.rb +55 -0
  39. data/spec/fixtures/categorylist.xml +232 -0
  40. data/spec/fixtures/productlists.xml +164 -0
  41. data/spec/fixtures/products.xml +72 -0
  42. data/spec/fixtures/searchproducts-music.xml +108 -0
  43. data/spec/fixtures/searchproducts.xml +322 -0
  44. data/spec/spec_helper.rb +16 -0
  45. data/spec/support.rb +6 -0
  46. metadata +177 -0
@@ -0,0 +1,84 @@
1
+ require 'spec_helper'
2
+
3
+ describe Bol::Scope do
4
+ describe 'combining categories' do
5
+ it 'should add two categories for a combined scope' do
6
+ cat = Bol::Scope.new(1) + Bol::Scope.new(2)
7
+ cat.ids.should == [1, 2]
8
+ end
9
+
10
+ it 'should not duplicate IDs when adding' do
11
+ cat = Bol::Scope.new(1) + Bol::Scope.new(2) + Bol::Scope.new(2)
12
+ cat.ids.should == [1,2]
13
+ end
14
+
15
+ it 'should subtract two categories to reduce scope' do
16
+ a = Bol::Scope.new(1) + Bol::Scope.new(2)
17
+ b = Bol::Scope.new(2)
18
+ (a - b).ids.should == [1]
19
+ end
20
+
21
+ it 'should join ids in a string' do
22
+ Bol::Scope.new([1,2,3]).to_s.should == '1+2+3'
23
+ end
24
+ end
25
+
26
+ describe '#search' do
27
+ it 'should default to root category from the class' do
28
+ query = Bol::Scope.new.search 'foo'
29
+ query.should be_instance_of Bol::Proxy
30
+ query.category_id.should == '0'
31
+ end
32
+
33
+ it 'should set query term' do
34
+ Bol::Requests::Search.should_receive(:new).with(instance_of(Bol::Query)).and_return(stub(proxy: nil, query: nil))
35
+ Bol::Scope.new.search 'foo'
36
+ end
37
+ end
38
+
39
+ describe 'default category' do
40
+ it 'should set request category scope to 0' do
41
+ Bol::Scope.new.ids.should == [0]
42
+ end
43
+ end
44
+
45
+ describe 'lists' do
46
+ let(:cat) { Bol::Scope.new.top_products }
47
+
48
+ it 'should create a list request' do
49
+ cat.should be_instance_of Bol::Proxy
50
+ end
51
+
52
+ it 'should be scoped to the category' do
53
+ cat.category_id.should == '0'
54
+ end
55
+ end
56
+
57
+ describe 'categories' do
58
+ let(:cat) { Bol::Scope.new.categories }
59
+
60
+ it 'should create category list request' do
61
+ cat.request.should be_instance_of Bol::Requests::List
62
+ end
63
+
64
+ it 'should use a query with a param to limit to categories' do
65
+ cat.query.params[:includeCategories].should == true
66
+ cat.query.params[:includeProducts].should == false
67
+ cat.query.params[:includeRefinements].should == false
68
+ end
69
+ end
70
+
71
+ describe 'refinements' do
72
+ let(:cat) { Bol::Scope.new.refinements }
73
+
74
+ it 'should create refinement list request' do
75
+ cat.request.should be_instance_of Bol::Requests::List
76
+ end
77
+
78
+ it 'should use a query with a param to limit to refinements' do
79
+ cat.query.params[:includeCategories].should == false
80
+ cat.query.params[:includeProducts].should == false
81
+ cat.query.params[:includeRefinements].should == true
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,27 @@
1
+ require 'spec_helper'
2
+
3
+ describe Bol::Signature do
4
+ let(:subject) { described_class.new('date', 'path', {}) }
5
+
6
+ def configure
7
+ Bol.configuration.access_key = 'foo'
8
+ Bol.configuration.secret = 'bar'
9
+ end
10
+
11
+ before { configure }
12
+
13
+ it 'should return a string' do
14
+ subject.generate.should be_instance_of(String)
15
+ end
16
+
17
+ it 'should validate configuration' do
18
+ Bol.reset_configuration
19
+ expect {
20
+ described_class.new(1, 2, {})
21
+ }.to raise_error(Bol::ConfigurationError)
22
+ configure
23
+ expect {
24
+ described_class.new(1, 2, {})
25
+ }.not_to raise_error
26
+ end
27
+ end
@@ -0,0 +1,55 @@
1
+ require 'spec_helper'
2
+
3
+ describe Bol do
4
+ describe '#configure' do
5
+ it 'should create configuration object' do
6
+ Bol.configure access_key: 'foo'
7
+ Bol.configuration.access_key.should == 'foo'
8
+ end
9
+
10
+ it 'should reset configuration' do
11
+ Bol.configure access_key: 'foo'
12
+ expect {
13
+ Bol.reset_configuration
14
+ }.to change {
15
+ Bol.configuration.access_key
16
+ }.to nil
17
+ end
18
+
19
+ it 'should yield config object without argument' do
20
+ Bol.configure do |c|
21
+ c.should == Bol.configuration
22
+ end
23
+ end
24
+
25
+ it 'should raise with non-hash argument' do
26
+ expect { Bol.configure 'foo' }.to raise_error ArgumentError
27
+ end
28
+
29
+ it 'should not yield with argument' do
30
+ Bol.configure(access_key: 'foo') { |c| flunk }
31
+ end
32
+ end
33
+
34
+ describe 'shortcut methods' do
35
+ it 'should delegate search to a new scope object' do
36
+ Bol::Scope.any_instance.should_receive(:search).with('foo')
37
+ Bol.search('foo')
38
+ end
39
+
40
+ it 'should delegate categories to a new scope object' do
41
+ Bol::Scope.any_instance.should_receive(:categories)
42
+ Bol.categories
43
+ end
44
+
45
+ it 'should delegate find to a new scope object' do
46
+ Bol::Scope.any_instance.should_receive(:search).with(1)
47
+ Bol.search(1)
48
+ end
49
+
50
+ it 'should delegate refinements to a new scope object' do
51
+ Bol::Scope.any_instance.should_receive(:refinements)
52
+ Bol.refinements
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,232 @@
1
+ <?xml version="1.0" encoding="utf-8" standalone="yes"?>
2
+ <CategoryListResponse xmlns="http://openapi.bol.com/openapi-3.0.0">
3
+ <SessionId>2957E300-B2AC-4749-99C5-12831D6286A2</SessionId>
4
+ <Category>
5
+ <Id>1</Id>
6
+ <Name>categorieen</Name>
7
+ <CategoryRefinement>
8
+ <Id>1430</Id>
9
+ <Name>Nederlandse boeken</Name>
10
+ </CategoryRefinement>
11
+ <CategoryRefinement>
12
+ <Id>3131</Id>
13
+ <Name>Buitenlandse boeken</Name>
14
+ </CategoryRefinement>
15
+ </Category>
16
+ <Category>
17
+ <Id>1312</Id>
18
+ <Name>taal</Name>
19
+ <CategoryRefinement>
20
+ <Id>8293</Id>
21
+ <Name>Nederlandse boeken</Name>
22
+ </CategoryRefinement>
23
+ <CategoryRefinement>
24
+ <Id>8292</Id>
25
+ <Name>Engelse boeken</Name>
26
+ </CategoryRefinement>
27
+ <CategoryRefinement>
28
+ <Id>8296</Id>
29
+ <Name>Duitse boeken</Name>
30
+ </CategoryRefinement>
31
+ <CategoryRefinement>
32
+ <Id>8294</Id>
33
+ <Name>Franse boeken</Name>
34
+ </CategoryRefinement>
35
+ <CategoryRefinement>
36
+ <Id>8298</Id>
37
+ <Name>Spaanse boeken</Name>
38
+ </CategoryRefinement>
39
+ <CategoryRefinement>
40
+ <Id>8297</Id>
41
+ <Name>Turkse boeken</Name>
42
+ </CategoryRefinement>
43
+ </Category>
44
+ <Category>
45
+ <Id>4852</Id>
46
+ <Name>prijs</Name>
47
+ <CategoryRefinement>
48
+ <Id>7143</Id>
49
+ <Name>Tot € 10</Name>
50
+ </CategoryRefinement>
51
+ <CategoryRefinement>
52
+ <Id>4854</Id>
53
+ <Name>Tot € 20</Name>
54
+ </CategoryRefinement>
55
+ <CategoryRefinement>
56
+ <Id>4855</Id>
57
+ <Name>Tot € 30</Name>
58
+ </CategoryRefinement>
59
+ <CategoryRefinement>
60
+ <Id>4856</Id>
61
+ <Name>Tot € 40</Name>
62
+ </CategoryRefinement>
63
+ <CategoryRefinement>
64
+ <Id>4857</Id>
65
+ <Name>Tot € 50</Name>
66
+ </CategoryRefinement>
67
+ <CategoryRefinement>
68
+ <Id>4858</Id>
69
+ <Name>Tot € 100</Name>
70
+ </CategoryRefinement>
71
+ <CategoryRefinement>
72
+ <Id>5014</Id>
73
+ <Name>Tot € 200</Name>
74
+ </CategoryRefinement>
75
+ <CategoryRefinement>
76
+ <Id>4860</Id>
77
+ <Name>Tot € 300</Name>
78
+ </CategoryRefinement>
79
+ <CategoryRefinement>
80
+ <Id>4861</Id>
81
+ <Name>Tot € 400</Name>
82
+ </CategoryRefinement>
83
+ <CategoryRefinement>
84
+ <Id>4862</Id>
85
+ <Name>Tot € 500</Name>
86
+ </CategoryRefinement>
87
+ <CategoryRefinement>
88
+ <Id>4863</Id>
89
+ <Name>Tot € 750</Name>
90
+ </CategoryRefinement>
91
+ <CategoryRefinement>
92
+ <Id>4864</Id>
93
+ <Name>Tot € 1000</Name>
94
+ </CategoryRefinement>
95
+ <CategoryRefinement>
96
+ <Id>4865</Id>
97
+ <Name>Tot € 1500</Name>
98
+ </CategoryRefinement>
99
+ <CategoryRefinement>
100
+ <Id>4866</Id>
101
+ <Name>Tot € 2000</Name>
102
+ </CategoryRefinement>
103
+ <CategoryRefinement>
104
+ <Id>7346</Id>
105
+ <Name>Tot € 2500</Name>
106
+ </CategoryRefinement>
107
+ <CategoryRefinement>
108
+ <Id>4867</Id>
109
+ <Name>€ 2500 en meer</Name>
110
+ </CategoryRefinement>
111
+ </Category>
112
+ <Category>
113
+ <Id>1317</Id>
114
+ <Name>onderwerp</Name>
115
+ <CategoryRefinement>
116
+ <Id>4294965600</Id>
117
+ <Name>2012</Name>
118
+ </CategoryRefinement>
119
+ <CategoryRefinement>
120
+ <Id>4294965780</Id>
121
+ <Name>De beste luisterboeken voor in de file</Name>
122
+ </CategoryRefinement>
123
+ <CategoryRefinement>
124
+ <Id>4294966229</Id>
125
+ <Name>De leukste luisterboeken voor op vakantie</Name>
126
+ </CategoryRefinement>
127
+ <CategoryRefinement>
128
+ <Id>4294966964</Id>
129
+ <Name>Economie &amp; Management</Name>
130
+ </CategoryRefinement>
131
+ <CategoryRefinement>
132
+ <Id>4294966963</Id>
133
+ <Name>Gedrag &amp; Maatschappij</Name>
134
+ </CategoryRefinement>
135
+ <CategoryRefinement>
136
+ <Id>4294966967</Id>
137
+ <Name>Gezondheidszorg</Name>
138
+ </CategoryRefinement>
139
+ <CategoryRefinement>
140
+ <Id>4294965025</Id>
141
+ <Name>Girl's only</Name>
142
+ </CategoryRefinement>
143
+ <CategoryRefinement>
144
+ <Id>4294965588</Id>
145
+ <Name>Happinez</Name>
146
+ </CategoryRefinement>
147
+ <CategoryRefinement>
148
+ <Id>4294964522</Id>
149
+ <Name>Jaarkalenders</Name>
150
+ </CategoryRefinement>
151
+ <CategoryRefinement>
152
+ <Id>4294964509</Id>
153
+ <Name>Je eigen lichaam</Name>
154
+ </CategoryRefinement>
155
+ <CategoryRefinement>
156
+ <Id>4294965319</Id>
157
+ <Name>Kalenders</Name>
158
+ </CategoryRefinement>
159
+ <CategoryRefinement>
160
+ <Id>4294966309</Id>
161
+ <Name>Koopjeskelder uitverkoop</Name>
162
+ </CategoryRefinement>
163
+ <CategoryRefinement>
164
+ <Id>4294965337</Id>
165
+ <Name>Luchtfotoboeken</Name>
166
+ </CategoryRefinement>
167
+ <CategoryRefinement>
168
+ <Id>4294965561</Id>
169
+ <Name>Luisterboekenvoordeel!</Name>
170
+ </CategoryRefinement>
171
+ <CategoryRefinement>
172
+ <Id>4294966965</Id>
173
+ <Name>Overige uittreksels</Name>
174
+ </CategoryRefinement>
175
+ <CategoryRefinement>
176
+ <Id>4294966948</Id>
177
+ <Name>Rechten</Name>
178
+ </CategoryRefinement>
179
+ <CategoryRefinement>
180
+ <Id>4294965978</Id>
181
+ <Name>Roman</Name>
182
+ </CategoryRefinement>
183
+ <CategoryRefinement>
184
+ <Id>4294966940</Id>
185
+ <Name>Scandinavische thrillers</Name>
186
+ </CategoryRefinement>
187
+ <CategoryRefinement>
188
+ <Id>4294966380</Id>
189
+ <Name>Scheurkalenders</Name>
190
+ </CategoryRefinement>
191
+ <CategoryRefinement>
192
+ <Id>4294964608</Id>
193
+ <Name>Seizoenen</Name>
194
+ </CategoryRefinement>
195
+ <CategoryRefinement>
196
+ <Id>4294965664</Id>
197
+ <Name>Spanning</Name>
198
+ </CategoryRefinement>
199
+ <CategoryRefinement>
200
+ <Id>4294965612</Id>
201
+ <Name>Techniek &amp; Informatica</Name>
202
+ </CategoryRefinement>
203
+ <CategoryRefinement>
204
+ <Id>4294964491</Id>
205
+ <Name>Vanaf 24 maanden</Name>
206
+ </CategoryRefinement>
207
+ <CategoryRefinement>
208
+ <Id>4294965320</Id>
209
+ <Name>Verjaardagskalenders</Name>
210
+ </CategoryRefinement>
211
+ <CategoryRefinement>
212
+ <Id>4294966079</Id>
213
+ <Name>Voordelige bestsellers</Name>
214
+ </CategoryRefinement>
215
+ </Category>
216
+ <Category>
217
+ <Id>7287</Id>
218
+ <Name>aanraders</Name>
219
+ <CategoryRefinement>
220
+ <Id>7288</Id>
221
+ <Name>Te reserveren</Name>
222
+ </CategoryRefinement>
223
+ <CategoryRefinement>
224
+ <Id>7290</Id>
225
+ <Name>Bestbeoordeeld</Name>
226
+ </CategoryRefinement>
227
+ <CategoryRefinement>
228
+ <Id>7289</Id>
229
+ <Name>Nieuw verschenen</Name>
230
+ </CategoryRefinement>
231
+ </Category>
232
+ </CategoryListResponse>
@@ -0,0 +1,164 @@
1
+ <?xml version="1.0" encoding="utf-8" standalone="yes"?>
2
+ <ProductListResponse xmlns="http://openapi.bol.com/openapi-3.0.0">
3
+ <SessionId>BEFA78E4-FA97-46E6-8C82-1792F485B16C</SessionId>
4
+ <TotalResultSize>12128</TotalResultSize>
5
+ <Product>
6
+ <Id>1001004011242363</Id>
7
+ <Title>In mijn dromen</Title>
8
+ <Type>book</Type>
9
+ <Publisher>Anthos</Publisher>
10
+ <ShortDescription>Rosalie heeft een kapperszaak in de Pijp in
11
+ Amsterdam en is getrouwd met de zakelijke en ordelijke Jeroen.
12
+ Een vakantie naar Marrakech zou hun relatie weer passie moeten
13
+ geven maar de reis eindigt in een nachtmerrie. Jeroen wil geen
14
+ gehoor geven aan Rosalies slechte voorgevoel en het vliegtuig
15
+ waarin Jeroen alleen terugkeert stort neer. Terug in
16
+ Amsterdam beseft Rosalie dat ze haar voorspellende dromen niet
17
+ langer kan negeren. Haar besluit om de politie in te lichten
18
+ over haar vermoeden dat het v...</ShortDescription>
19
+ <LongDescription>Rosalie heeft een kapperszaak in de Pijp in
20
+ Amsterdam en is getrouwd met de zakelijke en ordelijke Jeroen.
21
+ Een vakantie naar Marrakech zou hun relatie weer passie moeten
22
+ geven maar de reis eindigt in een nachtmerrie. Jeroen wil geen
23
+ gehoor geven aan Rosalies slechte voorgevoel en het vliegtuig
24
+ waarin Jeroen alleen terugkeert stort neer.&lt;br/ &gt;Terug in
25
+ Amsterdam beseft Rosalie dat ze haar voorspellende dromen niet
26
+ langer kan negeren. Haar besluit om de politie in te lichten
27
+ over haar vermoeden dat het vliegtuigongeluk geen ongeluk was,
28
+ maakt haar echter alleen maar wanhopiger, want men neemt haar
29
+ niet serieus. Intussen probeert ze met behulp van haar vrienden
30
+ en collega"s de draad van het leven weer op te pakken, maar
31
+ haar voorspellende dromen vergemakkelijken haar situatie
32
+ niet</LongDescription>
33
+ <ReleaseDate>2011-06-23+02:00</ReleaseDate>
34
+ <Ean>9789041416841</Ean>
35
+ <BindingCode>ING</BindingCode>
36
+ <BindingDescription>Paperback</BindingDescription>
37
+ <LanguageCode>nl</LanguageCode>
38
+ <LanguageDescription>Nederlands</LanguageDescription>
39
+ <Offers>
40
+ <Offer>
41
+ <State>new</State>
42
+ <Price>19.95</Price>
43
+ <AvailabilityCode>170</AvailabilityCode>
44
+ <AvailabilityDescription>Op werkdagen voor 22.30 uur
45
+ besteld, morgen in huis</AvailabilityDescription>
46
+ <Supplier>
47
+ <Id>-1</Id>
48
+ <Name>bol.com</Name>
49
+ </Supplier>
50
+ </Offer>
51
+ </Offers>
52
+ <Urls>
53
+ <Main>
54
+ http://www.bol.com/nl/p/nederlandse-boeken/in-mijn-dromen/1001004011242363/index.html</Main>
55
+ </Urls>
56
+ <Authors>
57
+ <Author>
58
+ <Id>55945</Id>
59
+ <Name>Simone van der Vlugt</Name>
60
+ </Author>
61
+ </Authors>
62
+ <Images>
63
+ <ExtraSmall>
64
+ http://s-bol.com/imgbase0/imagebase/mini/FC/3/6/3/2/1001004011242363.jpg</ExtraSmall>
65
+ <Small>
66
+ http://s-bol.com/imgbase0/imagebase/tout/FC/3/6/3/2/1001004011242363.jpg</Small>
67
+ <Medium>
68
+ http://s-bol.com/imgbase0/imagebase/thumb/FC/3/6/3/2/1001004011242363.jpg</Medium>
69
+ <Large>
70
+ http://s-bol.com/imgbase0/imagebase/regular/FC/3/6/3/2/1001004011242363.jpg</Large>
71
+ <ExtraLarge>
72
+ http://s-bol.com/imgbase0/imagebase/large/FC/3/6/3/2/1001004011242363.jpg</ExtraLarge>
73
+ </Images>
74
+ </Product>
75
+ <Product>
76
+ <Id>1001004011459347</Id>
77
+ <Title>Kort</Title>
78
+ <Type>book</Type>
79
+ <Publisher>Bezige Bij B.V., Uitgeverij De</Publisher>
80
+ <ShortDescription>Tomas Ross is al meer dan dertig jaar een van
81
+ de meest toonaangevende thrillerauteurs in ons land. Hij is de
82
+ Godfather van de Nederlandse faction; in zijn spannende en
83
+ gedurfde thrillers balanceert hij op de scheidslijn tussen feit
84
+ en fictie. Vele politieke kwesties nam hij al onder
85
+ vuur en ook het koningshuis ontkomt niet aan zijn kritische oog
86
+ en scherpe pen. In Kort zijn twintig van Ross beste
87
+ verhalen voor het eerst gebundeld in een
88
+ uitgave. Twintig verhalen over kleine criminaliteit en
89
+ georganiseerde misdaad, de bvd en het koningshuis, stom toeval
90
+ en het werk van een meesterbrein. Twintig verhalen die waar
91
+ gebeurd (hadden kunnen) zijn. Een meesterproef van een
92
+ schrijver op de toppen van zijn talent.</ShortDescription>
93
+ <LongDescription>Tomas Ross is al meer dan dertig jaar een van
94
+ de meest toonaangevende thrillerauteurs in ons land. Hij is de
95
+ Godfather van de Nederlandse faction; in zijn spannende en
96
+ gedurfde thrillers balanceert hij op de scheidslijn tussen feit
97
+ en fictie. Vele politieke kwesties nam hij al onder
98
+ vuur en ook het koningshuis ontkomt niet aan zijn kritische oog
99
+ en scherpe pen. In Kort zijn twintig van Ross beste
100
+ verhalen voor het eerst gebundeld in een
101
+ uitgave. Twintig verhalen over kleine criminaliteit en
102
+ georganiseerde misdaad, de bvd en het koningshuis, stom toeval
103
+ en het werk van een meesterbrein. Twintig verhalen die waar
104
+ gebeurd (hadden kunnen) zijn. Een meesterproef van een
105
+ schrijver op de toppen van zijn talent.</LongDescription>
106
+ <ReleaseDate>2011-06-02+02:00</ReleaseDate>
107
+ <Ean>9789023472315</Ean>
108
+ <BindingCode>EBOOK</BindingCode>
109
+ <BindingDescription>Digitaal boek</BindingDescription>
110
+ <LanguageCode>nl</LanguageCode>
111
+ <LanguageDescription>Nederlands</LanguageDescription>
112
+ <FormatCode>Adobe ePub</FormatCode>
113
+ <Offers>
114
+ <Offer>
115
+ <State>new</State>
116
+ <Price>4.95</Price>
117
+ <ListPrice>7.95</ListPrice>
118
+ <AvailabilityCode>140</AvailabilityCode>
119
+ <AvailabilityDescription>Direct te
120
+ downloaden.</AvailabilityDescription>
121
+ <Supplier>
122
+ <Id>-1</Id>
123
+ <Name>bol.com</Name>
124
+ </Supplier>
125
+ </Offer>
126
+ </Offers>
127
+ <Urls>
128
+ <Main>
129
+ http://www.bol.com/nl/p/nederlandse-boeken/kort/1001004011459347/index.html</Main>
130
+ </Urls>
131
+ <Authors>
132
+ <Author>
133
+ <Id>30715</Id>
134
+ <Name>Tomas Ross</Name>
135
+ </Author>
136
+ </Authors>
137
+ <Images>
138
+ <ExtraSmall>
139
+ http://s-bol.com/imgbase0/imagebase/mini/FC/7/4/3/9/1001004011459347.jpg</ExtraSmall>
140
+ <Small>
141
+ http://s-bol.com/imgbase0/imagebase/tout/FC/7/4/3/9/1001004011459347.jpg</Small>
142
+ <Medium>
143
+ http://s-bol.com/imgbase0/imagebase/thumb/FC/7/4/3/9/1001004011459347.jpg</Medium>
144
+ <Large>
145
+ http://s-bol.com/imgbase0/imagebase/regular/FC/7/4/3/9/1001004011459347.jpg</Large>
146
+ <ExtraLarge>
147
+ http://s-bol.com/imgbase0/imagebase/large/FC/7/4/3/9/1001004011459347.jpg</ExtraLarge>
148
+ </Images>
149
+ <Promotions>
150
+ <Promotion>
151
+ <Title>Het is Zomerzotheid bij bol.com!</Title>
152
+ <Description>Ik ga met vakantie en neem
153
+ mee. Bol.com heeft de artikelen die in
154
+ elke koffer thuishoren nu extra scherp geprijsd. Bekijk
155
+ daarom nu onze vakantie-aanbiedingen en profiteer van
156
+ kortingen tot 50%.</Description>
157
+ <Url>
158
+ http://www.bol.com/nl/m/service/zomerzotheid/index.html</Url>
159
+ <UrlText>Bekijk alle actie-artikelen tijdens de
160
+ Zomerzotheid</UrlText>
161
+ </Promotion>
162
+ </Promotions>
163
+ </Product>
164
+ </ProductListResponse>