ls_linkdirect_api 0.0.2

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 5321f05c60a0c21073823cbb981ed34ce7492439
4
+ data.tar.gz: b118e82ea754f7e80d43dca2beca6757fcaec427
5
+ SHA512:
6
+ metadata.gz: ff02cf9f6d5833634f9f2fcce3a4f831703cb017922a8101e37757349bafd0fad1f696e0e747c839fb093357003028879db73b98bb0183b0b204d58a7a0a3958
7
+ data.tar.gz: a5839df1bdebcb6b2100281d4e7e6affd660458b92452778eda35882c142258337c26a645e5e871c306eba8afe4da8283727d9a19f3231123c91f1d05fa441f8
data/.gitignore ADDED
@@ -0,0 +1,22 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ *.bundle
19
+ *.so
20
+ *.o
21
+ *.a
22
+ mkmf.log
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format documentation
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in ls_linkdirect_api.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Kirk Jarvis
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,89 @@
1
+ # LsLinkdirectAPI
2
+
3
+ Ruby wrapper for [LinkShare LinkLocator Direct](http://helpcenter.linkshare.com/publisher/questions.php?questionid=50).
4
+ Supported web services:
5
+ * [TextLinks]
6
+ * [BannerLinks]
7
+ * [DRMLinks]
8
+
9
+ ## Installation
10
+
11
+ Add this line to your application's Gemfile:
12
+
13
+ gem 'ls_linkdirect_api'
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install ls_linkdirect_api
22
+
23
+ ## Usage
24
+
25
+ Before using **LsLinkdirectAPI** you need to set up your publisher token first. If you use Ruby on Rails, the token can be set in a configuration file (i.e. `app/config/initializers/linkshare_api.rb`), otherwise just set it in your script. The token can be found on LinkShare's Web Services page under the Links tab.
26
+
27
+ Currently there are three services that can be used with this gem. To use those services, you name the service as the class when you declare a new instance of the class (i.e. `LsLinkdirectAPI::TextLinks.new`) see examples below.
28
+
29
+ ```ruby
30
+ require "ls_linkdirect_api" # no need for RoR
31
+ LsLinkdirectAPI.token = ENV["LINKSHARE_TOKEN"]
32
+ ```
33
+ ### Text Link Request
34
+
35
+ This request gives you the available text links. To specify the links your request returns, you can filter it using these parameters: MID, Category, Start Date, and End Date.
36
+
37
+ ```ruby
38
+ textlinks = LsLinkdirectAPI::TextLinks.new
39
+ params = { mid: -1, cat: -1, startDate: 01012014, endDate: 05012014 }
40
+ # all params are optional gem will add defaults where required
41
+ response = textlinks.get(params)
42
+ response.data.each do |item|
43
+ puts "Name: #{item.linkName}"
44
+ puts "Click URL: #{item.clickURL}"
45
+ puts "Tracking Pixil : #{item.showURL}"
46
+ puts "Text Display: #{item.textDisplay}"
47
+ end
48
+ ```
49
+ ### Banner Link Request
50
+
51
+ This feed gives you the available banner links. To obtain specific banner links, you can filter this request using these parameters: MID, Category, Size, Start Date, and End Date.
52
+
53
+ [LinkLocator Direct: Banner Size Codes](http://helpcenter.linkshare.com/publisher/questions.php?questionid=907)
54
+
55
+ ```ruby
56
+ bannerlinks = LsLinkdirectAPI:: BannerLinks.new
57
+ params = { mid: -1, cat: -1, startDate: 01012014, endDate: 05012014, size: 1 }
58
+ # all params are optional gem will add defaults where required
59
+ response = bannerlinks.get(params)
60
+ response.data.each do |item|
61
+ puts "Name: #{item.linkName}"
62
+ puts "Click URL: #{item.clickURL}"
63
+ puts "Tracking Pixil : #{item.showURL}"
64
+ puts "Text Display: #{item.textDisplay}"
65
+ puts "Image URL: #{item.imgURL}"
66
+ end
67
+ ```
68
+
69
+ ### DRM Link Request
70
+ This feed gives you the available DRM links. To obtain specific DRM links, you can filter it using these parameters: MID, Category, Start Date, and End Date.
71
+
72
+ ```ruby
73
+ drmlinks = LsLinkdirectAPI:: DRMLinks.new
74
+ params = { mid: -1, cat: -1, startDate: 01012014, endDate: 05012014 }
75
+ # all params are optional gem will add defaults where required
76
+ response = drmlinks.get(params)
77
+ response.data.each do |item|
78
+ puts "Name: #{item.linkName}"
79
+ puts "Code: #{item.code}"
80
+ end
81
+ ```
82
+
83
+ ## Contributing
84
+
85
+ 1. Fork it ( https://github.com/[my-github-username]/ls_linkdirect_api/fork )
86
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
87
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
88
+ 4. Push to the branch (`git push origin my-new-feature`)
89
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
@@ -0,0 +1,38 @@
1
+ require "addressable/uri"
2
+ require "cgi"
3
+ require "htmlentities"
4
+ require "httparty"
5
+ #require "net/http"
6
+ require "recursive_open_struct"
7
+ require "uri"
8
+
9
+ require "ls_linkdirect_api/api_resource"
10
+ require "ls_linkdirect_api/api_response"
11
+ require "ls_linkdirect_api/version"
12
+ require "ls_linkdirect_api/text_links"
13
+ require "ls_linkdirect_api/banner_links"
14
+ require "ls_linkdirect_api/drm_links"
15
+
16
+ require "ls_linkdirect_api/errors/error"
17
+ require "ls_linkdirect_api/errors/authentication_error"
18
+ require "ls_linkdirect_api/errors/argument_error"
19
+ require "ls_linkdirect_api/errors/not_implemented_error"
20
+ require "ls_linkdirect_api/errors/invalid_request_error"
21
+
22
+
23
+
24
+ module LsLinkdirectAPI
25
+ @api_base_url = "http://lld2.linksynergy.com/services/restLinks"
26
+ @api_timeout = 30
27
+
28
+ class << self
29
+ attr_accessor :token, :api_base_url
30
+ attr_reader :api_timeout
31
+ end
32
+
33
+ def self.api_timeout=(timeout)
34
+ raise ArgumentError, "Timeout must be a Fixnum; got #{timeout.class} instead" unless timeout.is_a? Fixnum
35
+ raise ArgumentError, "Timeout must be > 0; got #{timeout} instead" unless timeout > 0
36
+ @api_timeout = timeout
37
+ end
38
+ end
@@ -0,0 +1,104 @@
1
+ module LsLinkdirectAPI
2
+ class APIResource
3
+ include HTTParty
4
+
5
+ def class_name
6
+ self.class.name.split('::')[-1]
7
+ end
8
+
9
+ def base_path
10
+ if self.class == LsLinkdirectAPI::APIResource
11
+ raise NotImplementedError.new(
12
+ "APIResource is an abstract class. You should perform actions on its subclasses (i.e. TextLinks)"
13
+ )
14
+ end
15
+ "/get#{CGI.escape(class_name)}/"
16
+ end
17
+
18
+ def get(params = {})
19
+
20
+ unless token ||= LsLinkdirectAPI.token
21
+ raise AuthenticationError.new(
22
+ "No token provided. Set your token key using: LsLinkdirectAPI.token = 'TOKEN' " +
23
+ "You can retrieve your Your Web Services Token from the Linkshare web interface. " +
24
+ "http://helpcenter.linkshare.com/publisher/questions.php?questionid=58 for details."
25
+ )
26
+ end
27
+
28
+ if token =~ /\s/
29
+ raise AuthenticationError.new(
30
+ "Your token looks invalid. " +
31
+ "Double-check your token at http://linkshare.com"
32
+ )
33
+ end
34
+
35
+ raise ArgumentError, "Params must be a Hash; got #{params.class} instead" unless params.is_a? Hash
36
+
37
+ params.merge!({
38
+ token: token,
39
+ })
40
+ make_params_valid(params)
41
+ resource_url = LsLinkdirectAPI.api_base_url + base_path + self.params_path(params)
42
+ request(resource_url, params)
43
+ end
44
+
45
+ def request(resource_url, params)
46
+ timeout = LsLinkdirectAPI.api_timeout
47
+ begin
48
+ response = self.class.get(resource_url, query: nil, timeout: timeout)
49
+ rescue Timeout::Error
50
+ raise ConnectionError.new("Timeout error (#{timeout}s)")
51
+ end
52
+ process(response, "#{class_name}", params)
53
+ end
54
+
55
+ private
56
+
57
+ def process(response, response_name, params)
58
+ case response.code
59
+ when 200, 201, 204
60
+ APIResponse.new(response, response_name, params)
61
+ when 400, 404
62
+ raise InvalidRequestError.new(response.message, response.code)
63
+ when 401
64
+ raise AuthenticationError.new(response.message, response.code)
65
+ else
66
+ raise Error.new(response.message, response.code)
67
+ end
68
+ end
69
+
70
+ def check_date_format(date)
71
+ if date
72
+ if date =~ /(0[1-9]|1[012])(0[1-9]|[12][0-9]|3[01])(19|20)\d\d/
73
+ date
74
+ else
75
+ raise ArgumentError, "Data format needs to be MMDDYYYY."
76
+ end
77
+ else
78
+ ''
79
+ end
80
+ end
81
+
82
+ def make_params_valid(params)
83
+ unless params[:mid]
84
+ params[:mid] = -1
85
+ end
86
+
87
+ unless params[:cat]
88
+ params[:cat] = -1
89
+ end
90
+
91
+ unless params[:page]
92
+ params[:page] = 1
93
+ end
94
+
95
+ unless params[:campaignID]
96
+ params[:campaignID] = -1
97
+ end
98
+
99
+ unless params[:size]
100
+ params[:size] = -1
101
+ end
102
+ end
103
+ end
104
+ end
@@ -0,0 +1,36 @@
1
+ require "recursive_open_struct"
2
+
3
+ module LsLinkdirectAPI
4
+ class APIResponse
5
+ attr_reader :data, :request
6
+
7
+ def initialize(response, response_name, params)
8
+ @request = response.request
9
+ @response_name = response_name
10
+ @params = params
11
+ result = response[ "get#{response_name}Response" ]
12
+ @data = parse(result["return"])
13
+ end
14
+
15
+ def all
16
+ get_next_page = true
17
+ while get_next_page
18
+ cls = Object.const_get('LsLinkdirectAPI').const_get(@response_name)
19
+ @params[:page] += 1
20
+ next_page_response = cls.new.get(@params)
21
+ @data += next_page_response.data
22
+ get_next_page = false if next_page_response.data == []
23
+ end
24
+ @data
25
+ end
26
+
27
+ private
28
+
29
+ def parse(raw_data)
30
+ data = []
31
+ data = [RecursiveOpenStruct.new(raw_data)] if raw_data.is_a?(Hash) # If we got exactly one result, put it in an array.
32
+ raw_data.each { |i| data << RecursiveOpenStruct.new(i) } if raw_data.is_a?(Array)
33
+ data
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,7 @@
1
+ module LsLinkdirectAPI
2
+ class BannerLinks < APIResource
3
+ def params_path(params)
4
+ "#{params[:token]}/#{params[:mid]}/#{params[:cat]}/#{check_date_format(params[:startDate])}/#{check_date_format(params[:endDate])}/#{params[:size]}/#{params[:campaignID]}/#{params[:page]}"
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ module LsLinkdirectAPI
2
+ class DRMLinks < APIResource
3
+ def params_path(params)
4
+ "#{params[:token]}/#{params[:mid]}/#{params[:cat]}/#{check_date_format(params[:startDate])}/#{check_date_format(params[:endDate])}/#{params[:campaignID]}/#{params[:page]}"
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,4 @@
1
+ module LsLinkdirectAPI
2
+ class ArgumentError < Error
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module LsLinkdirectAPI
2
+ class AuthenticationError < Error
3
+ end
4
+ end
@@ -0,0 +1,15 @@
1
+ module LsLinkdirectAPI
2
+ class Error < StandardError
3
+ attr_reader :message, :code
4
+
5
+ def initialize(message = nil, code = nil)
6
+ @message = message
7
+ @code = code
8
+ end
9
+
10
+ def to_s
11
+ code_string = code.nil? ? "" : " (Code #{code})"
12
+ "#{message}#{code_string}"
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,4 @@
1
+ module LsLinkdirectAPI
2
+ class InvalidRequestError < Error
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module LsLinkdirectAPI
2
+ class NotImplementedError < Error
3
+ end
4
+ end
@@ -0,0 +1,7 @@
1
+ module LsLinkdirectAPI
2
+ class TextLinks < APIResource
3
+ def params_path(params)
4
+ "#{params[:token]}/#{params[:mid]}/#{params[:cat]}/#{check_date_format(params[:startDate])}/#{check_date_format(params[:endDate])}/#{params[:campaignID]}/#{params[:page]}"
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,3 @@
1
+ module LsLinkdirectAPI
2
+ VERSION = "0.0.2"
3
+ end
@@ -0,0 +1,31 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'ls_linkdirect_api/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "ls_linkdirect_api"
8
+ spec.version = LsLinkdirectAPI::VERSION
9
+ spec.authors = ["Kirk Jarvis"]
10
+ spec.email = ["zuuzlo@yahoo.com"]
11
+ spec.summary = %q{Ruby wrapper for accessing Linkshare LinkLocator Direct API using REST. }
12
+ spec.description = %q{This wrapper will access the Linkshare LinkLocator Direct Web Service, which is available to all publishers. The authentication of a publisher is done using the publisher’s Web services token. Publishers that do not have a Web services token, can go to Web Services under the Links tab on the Publisher Dashboard and click the button to generate a token. Since the token is used for authentication, it is a required parameter for all requests.}
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_dependency "addressable", "~> 2.3.5"
22
+ spec.add_dependency "htmlentities", "~> 4.3.1"
23
+ spec.add_dependency "httparty", "~> 0.11.0"
24
+ spec.add_dependency "recursive-open-struct", "~> 0.4.3"
25
+
26
+ spec.add_development_dependency "bundler", "~> 1.6"
27
+ spec.add_development_dependency "rake"
28
+ spec.add_development_dependency "rspec"
29
+ spec.add_development_dependency "webmock"
30
+ spec.add_development_dependency "pry"
31
+ end
@@ -0,0 +1,239 @@
1
+ require 'spec_helper'
2
+
3
+ describe LsLinkdirectAPI do
4
+ context "errors" do
5
+
6
+ it "raise connection error if times out" do
7
+ expect{ LsLinkdirectAPI.api_timeout = "" }.to raise_error(LsLinkdirectAPI::ArgumentError,"Timeout must be a Fixnum; got String instead")
8
+ end
9
+
10
+ it "raise connection error if times out" do
11
+ expect{ LsLinkdirectAPI.api_timeout = 0 }.to raise_error(LsLinkdirectAPI::ArgumentError,"Timeout must be > 0; got 0 instead")
12
+ end
13
+
14
+
15
+ it "raises authenication if token not present" do
16
+ textlinks = LsLinkdirectAPI::TextLinks.new
17
+ expect{ textlinks.get({})}.to raise_error(LsLinkdirectAPI::AuthenticationError)
18
+ end
19
+
20
+ it "raises authenication if token has spaces" do
21
+ LsLinkdirectAPI.token = 'afajfdafd dfjaskdfk'
22
+ textlinks = LsLinkdirectAPI::TextLinks.new
23
+ expect{ textlinks.get({})}.to raise_error(LsLinkdirectAPI::AuthenticationError)
24
+ end
25
+
26
+ it "raises ArgumentError if params is not a hash" do
27
+ LsLinkdirectAPI.token = 'afajfdafddfjaskdfk'
28
+ textlinks = LsLinkdirectAPI::TextLinks.new
29
+ expect{ textlinks.get('text')}.to raise_error(LsLinkdirectAPI::ArgumentError)
30
+ end
31
+
32
+ it "base_path for TextLinks is getTextLinks" do
33
+ textlinks = LsLinkdirectAPI::TextLinks.new
34
+ expect(textlinks.base_path).to eq("/getTextLinks/")
35
+ end
36
+
37
+ it "raises Not Implemented Error if APIResource is accessed" do
38
+ textlinks = LsLinkdirectAPI::APIResource.new
39
+ expect{ textlinks.base_path }.to raise_error(LsLinkdirectAPI::NotImplementedError)
40
+ end
41
+
42
+ it "raises ArgumentError on wrong date format" do
43
+ LsLinkdirectAPI.token = 'afajfdafddfjaskdfk'
44
+ textlinks = LsLinkdirectAPI::TextLinks.new
45
+ params = { endDate: 'dec 10'}
46
+ expect{ textlinks.get(params)}.to raise_error(LsLinkdirectAPI::ArgumentError)
47
+ end
48
+ end
49
+
50
+ context "response code is not 200, 201, 204" do
51
+ it "raise Invalid Request Error if response is 400" do
52
+ LsLinkdirectAPI.token = '400'
53
+ xml_response = <<-XML
54
+ <?xml version="1.0" encoding="UTF-8"?>
55
+ <ns1:XMLFault xmlns:ns1="http://cxf.apache.org/bindings/xformat"><ns1:faultstring xmlns:ns1="http://cxf.apache.org/bindings/xformat">Invalid URL/Verb combination. Verb: GET Path: /etTextLinks/06a400a42d5ee2822cc4342b7cedf714bffa542768b1c06d571c0ebe8aa85203/38605/-1//05162014/-1/1</ns1:faultstring></ns1:XMLFault>
56
+ XML
57
+ stub_request(
58
+ :get,
59
+ "http://lld2.linksynergy.com/services/restLinks/getTextLinks/400/-1/-1//05162014/-1/1"
60
+ ).
61
+ to_return(
62
+ status: 400,
63
+ body: xml_response,
64
+ headers: { "Content-type" => "text/xml; charset=UTF-8" }
65
+ )
66
+ textlinks = LsLinkdirectAPI::TextLinks.new
67
+ params = { endDate: '05162014'}
68
+ expect { textlinks.get(params) }.to raise_error(LsLinkdirectAPI::InvalidRequestError)
69
+ end
70
+ end
71
+ context "response code is 200 TextLinks" do
72
+ before do
73
+ LsLinkdirectAPI.token = '200'
74
+ xml_response = <<-XML
75
+ <?xml version="1.0" encoding="UTF-8"?>
76
+ <ns1:getTextLinksResponse xmlns:ns1="http://endpoint.linkservice.linkshare.com/"><ns1:return><ns1:campaignID>0</ns1:campaignID><ns1:categoryID>200321300</ns1:categoryID><ns1:categoryName>Toys</ns1:categoryName><ns1:linkID>3997</ns1:linkID><ns1:linkName>5/15-5/18 10% off Outdoor Toys. Promo Code OUTDOOR10</ns1:linkName><ns1:mid>38605</ns1:mid><ns1:nid>1</ns1:nid><ns1:clickURL>http://click.linksynergy.com/fs-bin/click?id=V8uMkWlCTes&amp;offerid=328293.3997&amp;type=3</ns1:clickURL><ns1:endDate>May 19, 2014</ns1:endDate><ns1:landURL>www.kohls.com/catalog.jsp?N=3000060558</ns1:landURL><ns1:showURL>http://ad.linksynergy.com/fs-bin/show?id=V8uMkWlCTes&amp;bids=328293.3997&amp;type=3</ns1:showURL><ns1:startDate>May 15, 2014</ns1:startDate><ns1:textDisplay>Extra 10% off Outdoor Toys. Promo Code OUTDOOR10</ns1:textDisplay></ns1:return><ns1:return><ns1:campaignID>0</ns1:campaignID><ns1:categoryID>0</ns1:categoryID><ns1:categoryName>Default</ns1:categoryName><ns1:linkID>3986</ns1:linkID><ns1:linkName>Free Shipping $50+ with Code FREE50MAY</ns1:linkName><ns1:mid>38605</ns1:mid><ns1:nid>1</ns1:nid><ns1:clickURL>http://click.linksynergy.com/fs-bin/click?id=V8uMkWlCTes&amp;offerid=328293.3986&amp;type=3</ns1:clickURL><ns1:endDate>May 19, 2014</ns1:endDate><ns1:landURL>http://www.kohls.com</ns1:landURL><ns1:showURL>http://ad.linksynergy.com/fs-bin/show?id=V8uMkWlCTes&amp;bids=328293.3986&amp;type=3</ns1:showURL><ns1:startDate>May 16, 2014</ns1:startDate><ns1:textDisplay>Free Shipping $50+ with Code FREE50MAY. Valid 5/16-5/18.</ns1:textDisplay></ns1:return></ns1:getTextLinksResponse>
77
+ XML
78
+ stub_request(
79
+ :get,
80
+ "http://lld2.linksynergy.com/services/restLinks/getTextLinks/200/-1/-1//05162014/-1/1"
81
+ ).
82
+ to_return(
83
+ status: 200,
84
+ body: xml_response,
85
+ headers: { "Content-type" => "text/xml; charset=UTF-8" }
86
+ )
87
+ end
88
+
89
+ let(:textlinks) { LsLinkdirectAPI::TextLinks.new }
90
+ let(:params) { { endDate: '05162014'} }
91
+ let(:response) { textlinks.get(params) }
92
+
93
+ it "first record linkid is 3997" do
94
+ expect(response.data.first.linkID).to eq("3997")
95
+ end
96
+
97
+ it "last record linkid is 3986" do
98
+ expect(response.data.last.linkID).to eq("3986")
99
+ end
100
+ end
101
+
102
+ context "response code is 200 BannerLinks" do
103
+ before do
104
+ LsLinkdirectAPI.token = '200'
105
+ xml_response = <<-XML
106
+ <?xml version="1.0" encoding="UTF-8"?>
107
+ <ns1:getBannerLinksResponse xmlns:ns1="http://endpoint.linkservice.linkshare.com/"><ns1:return><ns1:campaignID>0</ns1:campaignID><ns1:categoryID>0</ns1:categoryID><ns1:categoryName>Default</ns1:categoryName><ns1:linkID>3</ns1:linkID><ns1:linkName>Candie's</ns1:linkName><ns1:mid>38605</ns1:mid><ns1:nid>1</ns1:nid><ns1:clickURL>http://click.linksynergy.com/fs-bin/click?id=V8uMkWlCTes&amp;offerid=328293.3&amp;type=4</ns1:clickURL><ns1:endDate>Dec 31, 2019</ns1:endDate><ns1:height>31</ns1:height><ns1:iconURL>http://merchant.linksynergy.com/fs/banners/38605/38605_3.jpg</ns1:iconURL><ns1:imgURL>http://ad.linksynergy.com/fs-bin/show?id=V8uMkWlCTes&amp;bids=328293.3&amp;type=4</ns1:imgURL><ns1:landURL>http://www.kohls.com/catalog/juniors-candie-s-clothing.jsp?CN=4294719935+4294875004+4294719810</ns1:landURL><ns1:serverType>4</ns1:serverType><ns1:size>7</ns1:size><ns1:startDate>Jul 18, 2013</ns1:startDate><ns1:width>88</ns1:width></ns1:return><ns1:return><ns1:campaignID>0</ns1:campaignID><ns1:categoryID>0</ns1:categoryID><ns1:categoryName>Default</ns1:categoryName><ns1:linkID>4</ns1:linkID><ns1:linkName>Candie's</ns1:linkName><ns1:mid>38605</ns1:mid><ns1:nid>1</ns1:nid><ns1:clickURL>http://click.linksynergy.com/fs-bin/click?id=V8uMkWlCTes&amp;offerid=328293.4&amp;type=4</ns1:clickURL><ns1:endDate>Dec 31, 2019</ns1:endDate><ns1:height>90</ns1:height><ns1:iconURL>http://merchant.linksynergy.com/fs/banners/38605/38605_4.jpg</ns1:iconURL><ns1:imgURL>http://ad.linksynergy.com/fs-bin/show?id=V8uMkWlCTes&amp;bids=328293.4&amp;type=4</ns1:imgURL><ns1:landURL>http://www.kohls.com/catalog/juniors-candie-s-clothing.jsp?CN=4294719935+4294875004+4294719810</ns1:landURL><ns1:serverType>4</ns1:serverType><ns1:size>5</ns1:size><ns1:startDate>Jul 18, 2013</ns1:startDate><ns1:width>120</ns1:width></ns1:return></ns1:getBannerLinksResponse>
108
+ XML
109
+ stub_request(
110
+ :get,
111
+ "http://lld2.linksynergy.com/services/restLinks/getBannerLinks/200/-1/-1//05162014/-1/-1/1"
112
+ ).
113
+ to_return(
114
+ status: 200,
115
+ body: xml_response,
116
+ headers: { "Content-type" => "text/xml; charset=UTF-8" }
117
+ )
118
+ end
119
+
120
+ let(:bannerlinks) { LsLinkdirectAPI::BannerLinks.new }
121
+ let(:params) { { endDate: '05162014'} }
122
+ let(:response) { bannerlinks.get(params) }
123
+
124
+ it "first record linkid is 3" do
125
+ expect(response.data.first.linkID).to eq("3")
126
+ end
127
+
128
+ it "last record linkid is 4" do
129
+ expect(response.data.last.linkID).to eq("4")
130
+ end
131
+ end
132
+
133
+ context "response code is 200 DRMLinks" do
134
+ before do
135
+ LsLinkdirectAPI.token = '200'
136
+ xml_response = <<-XML
137
+ <?xml version="1.0" encoding="UTF-8"?>
138
+ <ns1:getDRMLinksResponse xmlns:ns1="http://endpoint.linkservice.linkshare.com/"><ns1:return><ns1:campaignID>0</ns1:campaignID><ns1:categoryID>78</ns1:categoryID><ns1:categoryName>Dynamic Media - Banners</ns1:categoryName><ns1:linkID>6885</ns1:linkID><ns1:linkName>Banner 300x250</ns1:linkName><ns1:mid>14028</ns1:mid><ns1:nid>1</ns1:nid><ns1:code>&lt;script src='http://ad.linksynergy.com/fs-bin/show?id=V8uMkWlCTes&amp;bids=299527.6885&amp;catid=78&amp;gridnum=13&amp;type=14'>&lt;/script>&lt;noscript>&lt;a href='http://click.linksynergy.com/fs-bin/click?id=V8uMkWlCTes&amp;offerid=299527&amp;type=4&amp;subid='>&lt;img src='http://ad.linksynergy.com/fs-bin/show?id=V8uMkWlCTes&amp;bids=299527&amp;subid=&amp;type=4&amp;gridnum=13'>&lt;/a>&lt;/noscript></ns1:code><ns1:endDate>Oct 13, 2017</ns1:endDate><ns1:height>250</ns1:height><ns1:serverType>4</ns1:serverType><ns1:showURL>http://ad.linksynergy.com/fs-bin/show?id=V8uMkWlCTes&amp;bids=299527.6885&amp;catid=78&amp;gridnum=13&amp;type=14</ns1:showURL><ns1:size>13</ns1:size><ns1:startDate>Oct 13, 2011</ns1:startDate><ns1:width>300</ns1:width></ns1:return><ns1:return><ns1:campaignID>0</ns1:campaignID><ns1:categoryID>78</ns1:categoryID><ns1:categoryName>Dynamic Media - Banners</ns1:categoryName><ns1:linkID>4027</ns1:linkID><ns1:linkName>Banner 120x240</ns1:linkName><ns1:mid>14028</ns1:mid><ns1:nid>1</ns1:nid><ns1:code>&lt;script src='http://ad.linksynergy.com/fs-bin/show?id=V8uMkWlCTes&amp;bids=299527.4027&amp;catid=78&amp;gridnum=8&amp;type=14'>&lt;/script>&lt;noscript>&lt;a href='http://click.linksynergy.com/fs-bin/click?id=V8uMkWlCTes&amp;offerid=299527&amp;type=4&amp;subid='>&lt;img src='http://ad.linksynergy.com/fs-bin/show?id=V8uMkWlCTes&amp;bids=299527&amp;subid=&amp;type=4&amp;gridnum=8'>&lt;/a>&lt;/noscript></ns1:code><ns1:endDate>Feb 28, 2017</ns1:endDate><ns1:height>240</ns1:height><ns1:serverType>4</ns1:serverType><ns1:showURL>http://ad.linksynergy.com/fs-bin/show?id=V8uMkWlCTes&amp;bids=299527.4027&amp;catid=78&amp;gridnum=8&amp;type=14</ns1:showURL><ns1:size>8</ns1:size><ns1:startDate>Feb 27, 2007</ns1:startDate><ns1:width>120</ns1:width></ns1:return></ns1:getDRMLinksResponse>
139
+ XML
140
+ stub_request(
141
+ :get,
142
+ "http://lld2.linksynergy.com/services/restLinks/getDRMLinks/200/-1/-1//05162014/-1/1"
143
+ ).
144
+ to_return(
145
+ status: 200,
146
+ body: xml_response,
147
+ headers: { "Content-type" => "text/xml; charset=UTF-8" }
148
+ )
149
+ end
150
+
151
+ let(:drmlinks) { LsLinkdirectAPI::DRMLinks.new }
152
+ let(:params) { { endDate: '05162014'} }
153
+ let(:response) { drmlinks.get(params) }
154
+
155
+ it "first record linkid is 6885" do
156
+ expect(response.data.first.linkID).to eq("6885")
157
+ end
158
+
159
+ it "last record linkid is 4027" do
160
+ expect(response.data.last.linkID).to eq("4027")
161
+ end
162
+ end
163
+ context "multi page using all" do
164
+ before do
165
+ LsLinkdirectAPI.token = '200'
166
+ xml_response0 = <<-XML
167
+ <?xml version="1.0" encoding="UTF-8"?>
168
+ <ns1:getTextLinksResponse xmlns:ns1="http://endpoint.linkservice.linkshare.com/"><ns1:return><ns1:campaignID>0</ns1:campaignID><ns1:categoryID>200321300</ns1:categoryID><ns1:categoryName>Toys</ns1:categoryName><ns1:linkID>3997</ns1:linkID><ns1:linkName>5/15-5/18 10% off Outdoor Toys. Promo Code OUTDOOR10</ns1:linkName><ns1:mid>38605</ns1:mid><ns1:nid>1</ns1:nid><ns1:clickURL>http://click.linksynergy.com/fs-bin/click?id=V8uMkWlCTes&amp;offerid=328293.3997&amp;type=3</ns1:clickURL><ns1:endDate>May 19, 2014</ns1:endDate><ns1:landURL>www.kohls.com/catalog.jsp?N=3000060558</ns1:landURL><ns1:showURL>http://ad.linksynergy.com/fs-bin/show?id=V8uMkWlCTes&amp;bids=328293.3997&amp;type=3</ns1:showURL><ns1:startDate>May 15, 2014</ns1:startDate><ns1:textDisplay>Extra 10% off Outdoor Toys. Promo Code OUTDOOR10</ns1:textDisplay></ns1:return></ns1:getTextLinksResponse>
169
+ XML
170
+ stub_request(
171
+ :get,
172
+ "http://lld2.linksynergy.com/services/restLinks/getTextLinks/200/-1/-1//05162014/-1/1"
173
+ ).
174
+ to_return(
175
+ status: 200,
176
+ body: xml_response0,
177
+ headers: { "Content-type" => "text/xml; charset=UTF-8" }
178
+ )
179
+
180
+ xml_response1 = <<-XML
181
+ <?xml version="1.0" encoding="UTF-8"?>
182
+ <ns1:getTextLinksResponse xmlns:ns1="http://endpoint.linkservice.linkshare.com/"><ns1:return><ns1:campaignID>0</ns1:campaignID><ns1:categoryID>0</ns1:categoryID><ns1:categoryName>Default</ns1:categoryName><ns1:linkID>3986</ns1:linkID><ns1:linkName>Free Shipping $50+ with Code FREE50MAY</ns1:linkName><ns1:mid>38605</ns1:mid><ns1:nid>1</ns1:nid><ns1:clickURL>http://click.linksynergy.com/fs-bin/click?id=V8uMkWlCTes&amp;offerid=328293.3986&amp;type=3</ns1:clickURL><ns1:endDate>May 19, 2014</ns1:endDate><ns1:landURL>http://www.kohls.com</ns1:landURL><ns1:showURL>http://ad.linksynergy.com/fs-bin/show?id=V8uMkWlCTes&amp;bids=328293.3986&amp;type=3</ns1:showURL><ns1:startDate>May 16, 2014</ns1:startDate><ns1:textDisplay>Free Shipping $50+ with Code FREE50MAY. Valid 5/16-5/18.</ns1:textDisplay></ns1:return></ns1:getTextLinksResponse>
183
+ XML
184
+ stub_request(
185
+ :get,
186
+ "http://lld2.linksynergy.com/services/restLinks/getTextLinks/200/-1/-1//05162014/-1/2"
187
+ ).
188
+ to_return(
189
+ status: 200,
190
+ body: xml_response1,
191
+ headers: { "Content-type" => "text/xml; charset=UTF-8" }
192
+ )
193
+
194
+ xml_response2 = <<-XML
195
+ <?xml version="1.0" encoding="UTF-8"?>
196
+ <ns1:getTextLinksResponse xmlns:ns1="http://endpoint.linkservice.linkshare.com/"><ns1:return><ns1:campaignID>0</ns1:campaignID><ns1:categoryID>200334761</ns1:categoryID><ns1:categoryName>Jewelry</ns1:categoryName><ns1:linkID>3961</ns1:linkID><ns1:linkName>Get Set for Summer Sale</ns1:linkName><ns1:mid>38605</ns1:mid><ns1:nid>1</ns1:nid><ns1:clickURL>http://click.linksynergy.com/fs-bin/click?id=V8uMkWlCTes&amp;offerid=328293.3961&amp;type=3</ns1:clickURL><ns1:endDate>May 21, 2014</ns1:endDate><ns1:landURL>http://www.kohls.com/catalog/jewelry.jsp?CN=4294719765&amp;N=4294719765+3000060490</ns1:landURL><ns1:showURL>http://ad.linksynergy.com/fs-bin/show?id=V8uMkWlCTes&amp;bids=328293.3961&amp;type=3</ns1:showURL><ns1:startDate>May 14, 2014</ns1:startDate><ns1:textDisplay>$1599.99 14k gold certified 1-ct. T.W. diamond solitaire rings. Select styles. reg. $4250. Valid 5/14-5/20.</ns1:textDisplay></ns1:return></ns1:getTextLinksResponse>
197
+ XML
198
+ stub_request(
199
+ :get,
200
+ "http://lld2.linksynergy.com/services/restLinks/getTextLinks/200/-1/-1//05162014/-1/3"
201
+ ).
202
+ to_return(
203
+ status: 200,
204
+ body: xml_response2,
205
+ headers: { "Content-type" => "text/xml; charset=UTF-8" }
206
+ )
207
+
208
+ xml_response3 = <<-XML
209
+ <?xml version="1.0" encoding="UTF-8"?>
210
+ <ns1:getTextLinksResponse xmlns:ns1="http://endpoint.linkservice.linkshare.com/"></ns1:getTextLinksResponse>
211
+ XML
212
+ stub_request(
213
+ :get,
214
+ "http://lld2.linksynergy.com/services/restLinks/getTextLinks/200/-1/-1//05162014/-1/4"
215
+ ).
216
+ to_return(
217
+ status: 200,
218
+ body: xml_response3,
219
+ headers: { "Content-type" => "text/xml; charset=UTF-8" }
220
+ )
221
+ end
222
+
223
+ let(:textlinks) { LsLinkdirectAPI::TextLinks.new }
224
+ let(:params) { { endDate: '05162014'} }
225
+ let(:response) { textlinks.get(params) }
226
+
227
+ it "first record linkid is 3997" do
228
+ expect(response.all.first.linkID).to eq("3997")
229
+ end
230
+
231
+ it "last record linkid is 3961" do
232
+ expect(response.all.last.linkID).to eq("3961")
233
+ end
234
+
235
+ it "has 3 text links" do
236
+ expect(response.all.size).to eq(3)
237
+ end
238
+ end
239
+ end
@@ -0,0 +1,13 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+ require 'webmock/rspec'
4
+ require 'ls_linkdirect_api'
5
+ #require_relative './support/fake_pepperjam_api'
6
+
7
+ RSpec.configure do |config|
8
+ =begin
9
+ config.before(:each) do
10
+ stub_request(:any, /api.pepperjamnetwork.com/ ).to_rack( FakePepperjamApi )
11
+ end
12
+ =end
13
+ end
metadata ADDED
@@ -0,0 +1,198 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ls_linkdirect_api
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - Kirk Jarvis
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-05-19 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: addressable
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: 2.3.5
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: 2.3.5
27
+ - !ruby/object:Gem::Dependency
28
+ name: htmlentities
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: 4.3.1
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: 4.3.1
41
+ - !ruby/object:Gem::Dependency
42
+ name: httparty
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: 0.11.0
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: 0.11.0
55
+ - !ruby/object:Gem::Dependency
56
+ name: recursive-open-struct
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: 0.4.3
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ~>
67
+ - !ruby/object:Gem::Version
68
+ version: 0.4.3
69
+ - !ruby/object:Gem::Dependency
70
+ name: bundler
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ~>
74
+ - !ruby/object:Gem::Version
75
+ version: '1.6'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ~>
81
+ - !ruby/object:Gem::Version
82
+ version: '1.6'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rake
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - '>='
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - '>='
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rspec
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - '>='
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - '>='
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: webmock
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - '>='
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - '>='
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: pry
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - '>='
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - '>='
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ description: This wrapper will access the Linkshare LinkLocator Direct Web Service,
140
+ which is available to all publishers. The authentication of a publisher is done
141
+ using the publisher’s Web services token. Publishers that do not have a Web services
142
+ token, can go to Web Services under the Links tab on the Publisher Dashboard and
143
+ click the button to generate a token. Since the token is used for authentication,
144
+ it is a required parameter for all requests.
145
+ email:
146
+ - zuuzlo@yahoo.com
147
+ executables: []
148
+ extensions: []
149
+ extra_rdoc_files: []
150
+ files:
151
+ - .gitignore
152
+ - .rspec
153
+ - Gemfile
154
+ - LICENSE.txt
155
+ - README.md
156
+ - Rakefile
157
+ - lib/ls_linkdirect_api.rb
158
+ - lib/ls_linkdirect_api/api_resource.rb
159
+ - lib/ls_linkdirect_api/api_response.rb
160
+ - lib/ls_linkdirect_api/banner_links.rb
161
+ - lib/ls_linkdirect_api/drm_links.rb
162
+ - lib/ls_linkdirect_api/errors/argument_error.rb
163
+ - lib/ls_linkdirect_api/errors/authentication_error.rb
164
+ - lib/ls_linkdirect_api/errors/error.rb
165
+ - lib/ls_linkdirect_api/errors/invalid_request_error.rb
166
+ - lib/ls_linkdirect_api/errors/not_implemented_error.rb
167
+ - lib/ls_linkdirect_api/text_links.rb
168
+ - lib/ls_linkdirect_api/version.rb
169
+ - ls_linkdirect_api.gemspec
170
+ - spec/ls_linkdirect_api_spec.rb
171
+ - spec/spec_helper.rb
172
+ homepage: ''
173
+ licenses:
174
+ - MIT
175
+ metadata: {}
176
+ post_install_message:
177
+ rdoc_options: []
178
+ require_paths:
179
+ - lib
180
+ required_ruby_version: !ruby/object:Gem::Requirement
181
+ requirements:
182
+ - - '>='
183
+ - !ruby/object:Gem::Version
184
+ version: '0'
185
+ required_rubygems_version: !ruby/object:Gem::Requirement
186
+ requirements:
187
+ - - '>='
188
+ - !ruby/object:Gem::Version
189
+ version: '0'
190
+ requirements: []
191
+ rubyforge_project:
192
+ rubygems_version: 2.0.3
193
+ signing_key:
194
+ specification_version: 4
195
+ summary: Ruby wrapper for accessing Linkshare LinkLocator Direct API using REST.
196
+ test_files:
197
+ - spec/ls_linkdirect_api_spec.rb
198
+ - spec/spec_helper.rb