muck-raker 0.2.6 → 0.2.7

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.
data/Rakefile CHANGED
@@ -64,6 +64,7 @@ begin
64
64
  gemspec.add_dependency "httparty"
65
65
  gemspec.add_dependency "nokogiri"
66
66
  gemspec.add_dependency "muck-feedbag"
67
+ gemspec.add_dependency "river"
67
68
  gemspec.add_dependency "feedzirra"
68
69
  gemspec.add_dependency "muck-engine"
69
70
  gemspec.add_dependency "muck-users"
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.6
1
+ 0.2.7
@@ -99,6 +99,12 @@ class Service < ActiveRecord::Base
99
99
  end
100
100
  end
101
101
 
102
+ # Requires settings in global_config.yml
103
+ # For example:
104
+ # amazon_access_key_id: 'some key from your account'
105
+ # amazon_secret_access_key: 'the secret from your account'
106
+ # amazon_associate_tag: 'optional'
107
+ # ecs_to_rss_wishlist: "http://www.example.com/ecs_to_rss-wishlist.xslt"
102
108
  def generate_uris(username = '', password = '', uri = '')
103
109
  if self.name == 'Facebook'
104
110
  # Facebook can't just use feeds like everyone else.
@@ -116,7 +122,7 @@ class Service < ActiveRecord::Base
116
122
  elsif self.name == 'Amazon'
117
123
  return [] if username.blank?
118
124
  # Have to build and sign Amazon wishlist rss feeds
119
- am = AmazonRequest.new(GlobalConfig.amazon_access_key_id, GlobalConfig.amazon_secret_access_key, GlobalConfig.amazon_associate_tag)
125
+ am = AmazonRequest.new(GlobalConfig.amazon_access_key_id, GlobalConfig.amazon_secret_access_key, GlobalConfig.ecs_to_rss_wishlist, GlobalConfig.amazon_associate_tag)
120
126
  results = am.get_amazon_feeds(username) # username needs to be the user's Amazon email
121
127
  results.collect { |result| OpenStruct.new(:url => result, :title => 'Amazon Wishlist') }
122
128
  elsif !self.uri_data_template.blank? && !username.blank?
data/muck-raker.gemspec CHANGED
@@ -5,7 +5,7 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{muck-raker}
8
- s.version = "0.2.6"
8
+ s.version = "0.2.7"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Joel Duffin Justin Ball"]
@@ -40,8 +40,6 @@ Gem::Specification.new do |s|
40
40
  "app/helpers/muck_raker_services_helper.rb",
41
41
  "app/models/aggregation.rb",
42
42
  "app/models/aggregation_feed.rb",
43
- "app/models/amazon.rb",
44
- "app/models/amazon_request.rb",
45
43
  "app/models/attention.rb",
46
44
  "app/models/click.rb",
47
45
  "app/models/entry.rb",
@@ -474,7 +472,6 @@ Gem::Specification.new do |s|
474
472
  "locales/zh-TW.yml",
475
473
  "locales/zh.yml",
476
474
  "muck-raker.gemspec",
477
- "public/ecs_to_rss-wishlist.xslt",
478
475
  "public/images/service_icons/16/amazon.png",
479
476
  "public/images/service_icons/16/ask.png",
480
477
  "public/images/service_icons/16/bibsonomy.png",
@@ -887,7 +884,6 @@ Gem::Specification.new do |s|
887
884
  "test/rails_root/test/test_helper.rb",
888
885
  "test/rails_root/test/unit/aggregation_feed_test.rb",
889
886
  "test/rails_root/test/unit/aggregation_test.rb",
890
- "test/rails_root/test/unit/amazon_request_test.rb",
891
887
  "test/rails_root/test/unit/comment_test.rb",
892
888
  "test/rails_root/test/unit/entry_test.rb",
893
889
  "test/rails_root/test/unit/feed_parent_test.rb",
@@ -919,6 +915,7 @@ Gem::Specification.new do |s|
919
915
  s.add_runtime_dependency(%q<httparty>, [">= 0"])
920
916
  s.add_runtime_dependency(%q<nokogiri>, [">= 0"])
921
917
  s.add_runtime_dependency(%q<muck-feedbag>, [">= 0"])
918
+ s.add_runtime_dependency(%q<river>, [">= 0"])
922
919
  s.add_runtime_dependency(%q<feedzirra>, [">= 0"])
923
920
  s.add_runtime_dependency(%q<muck-engine>, [">= 0"])
924
921
  s.add_runtime_dependency(%q<muck-users>, [">= 0"])
@@ -930,6 +927,7 @@ Gem::Specification.new do |s|
930
927
  s.add_dependency(%q<httparty>, [">= 0"])
931
928
  s.add_dependency(%q<nokogiri>, [">= 0"])
932
929
  s.add_dependency(%q<muck-feedbag>, [">= 0"])
930
+ s.add_dependency(%q<river>, [">= 0"])
933
931
  s.add_dependency(%q<feedzirra>, [">= 0"])
934
932
  s.add_dependency(%q<muck-engine>, [">= 0"])
935
933
  s.add_dependency(%q<muck-users>, [">= 0"])
@@ -942,6 +940,7 @@ Gem::Specification.new do |s|
942
940
  s.add_dependency(%q<httparty>, [">= 0"])
943
941
  s.add_dependency(%q<nokogiri>, [">= 0"])
944
942
  s.add_dependency(%q<muck-feedbag>, [">= 0"])
943
+ s.add_dependency(%q<river>, [">= 0"])
945
944
  s.add_dependency(%q<feedzirra>, [">= 0"])
946
945
  s.add_dependency(%q<muck-engine>, [">= 0"])
947
946
  s.add_dependency(%q<muck-users>, [">= 0"])
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: muck-raker
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.6
4
+ version: 0.2.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joel Duffin Justin Ball
@@ -62,6 +62,16 @@ dependencies:
62
62
  - !ruby/object:Gem::Version
63
63
  version: "0"
64
64
  version:
65
+ - !ruby/object:Gem::Dependency
66
+ name: river
67
+ type: :runtime
68
+ version_requirement:
69
+ version_requirements: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - ">="
72
+ - !ruby/object:Gem::Version
73
+ version: "0"
74
+ version:
65
75
  - !ruby/object:Gem::Dependency
66
76
  name: feedzirra
67
77
  type: :runtime
@@ -145,8 +155,6 @@ files:
145
155
  - app/helpers/muck_raker_services_helper.rb
146
156
  - app/models/aggregation.rb
147
157
  - app/models/aggregation_feed.rb
148
- - app/models/amazon.rb
149
- - app/models/amazon_request.rb
150
158
  - app/models/attention.rb
151
159
  - app/models/click.rb
152
160
  - app/models/entry.rb
@@ -579,7 +587,6 @@ files:
579
587
  - locales/zh-TW.yml
580
588
  - locales/zh.yml
581
589
  - muck-raker.gemspec
582
- - public/ecs_to_rss-wishlist.xslt
583
590
  - public/images/service_icons/16/amazon.png
584
591
  - public/images/service_icons/16/ask.png
585
592
  - public/images/service_icons/16/bibsonomy.png
@@ -1013,7 +1020,6 @@ test_files:
1013
1020
  - test/rails_root/test/test_helper.rb
1014
1021
  - test/rails_root/test/unit/aggregation_feed_test.rb
1015
1022
  - test/rails_root/test/unit/aggregation_test.rb
1016
- - test/rails_root/test/unit/amazon_request_test.rb
1017
1023
  - test/rails_root/test/unit/comment_test.rb
1018
1024
  - test/rails_root/test/unit/entry_test.rb
1019
1025
  - test/rails_root/test/unit/feed_parent_test.rb
data/app/models/amazon.rb DELETED
@@ -1,59 +0,0 @@
1
- require 'openssl'
2
-
3
- class Amazon
4
-
5
- # Do we have support for the SHA-256 Secure Hash Algorithm?
6
- # Note that Module#constants returns Strings in Ruby 1.8 and Symbols in 1.9.
7
- DIGEST_SUPPORT = OpenSSL::Digest.constants.include?('SHA256') || OpenSSL::Digest.constants.include?(:SHA256)
8
-
9
- # Requests are authenticated using the SHA-256 Secure Hash Algorithm.
10
- DIGEST = OpenSSL::Digest::Digest.new('sha256') if DIGEST_SUPPORT
11
-
12
- AMAZON_SITES = {
13
- :ca => 'http://ecs.amazonaws.ca/onca/xml',
14
- :de => 'http://ecs.amazonaws.de/onca/xml',
15
- :fr => 'http://ecs.amazonaws.fr/onca/xml',
16
- :jp => 'http://ecs.amazonaws.jp/onca/xml',
17
- :uk => 'http://ecs.amazonaws.co.uk/onca/xml',
18
- :us => 'http://ecs.amazonaws.com/onca/xml'
19
- }
20
-
21
- AMAZON_XSLT_SITES = {
22
- :ca => 'http://xml-ca.amznxslt.com/onca/xml',
23
- :de => 'http://xml-de.amznxslt.com/onca/xml',
24
- :fr => 'http://xml-fr.amznxslt.com/onca/xml',
25
- :jp => 'http://xml-jp.amznxslt.com/onca/xml',
26
- :uk => 'http://xml-uk.amznxslt.com/onca/xml',
27
- :us => 'http://xml-us.amznxslt.com/onca/xml'
28
- }
29
-
30
- class AmazonResultError < StandardError; end
31
-
32
- # Sign an amazon query
33
- # Requires openssl and that GlobalConfig.amazon_secret_access_key be defined.
34
- # Based on ruby-aaws and documentation here
35
- # http://www.caliban.org/ruby/ruby-aws/
36
- # http://docs.amazonwebservices.com/AWSECommerceService/latest/DG/index.html?RequestAuthenticationArticle.html
37
- # Parameters
38
- # query: The query to be signed
39
- def self.sign_query(uri, query, amazon_secret_access_key)
40
- raise 'SHA-256 not available in this version of openssl. Cannot sign Amazon requests.' unless DIGEST_SUPPORT
41
- query << "&Timestamp=#{Time.now.utc.strftime('%Y-%m-%dT%H:%M:%SZ')}"
42
- new_query = query.split('&').collect{|param| "#{param.split('=')[0]}=#{url_encode(param.split('=')[1])}"}.sort.join('&')
43
- to_sign = "GET\n%s\n%s\n%s" % [uri.host, uri.path, new_query]
44
- hmac = OpenSSL::HMAC.digest(DIGEST, amazon_secret_access_key, to_sign)
45
- base64_hmac = [hmac].pack('m').chomp
46
- signature = url_encode(base64_hmac)
47
- new_query << "&Signature=#{signature}"
48
- end
49
-
50
- # Encode a string, such that it is suitable for HTTP transmission.
51
- def self.url_encode(string)
52
- return '' if string.nil?
53
- # Shamelessly plagiarised from Wakou Aoyama's cgi.rb, but then altered slightly to please AWS.
54
- string.gsub( /([^a-zA-Z0-9_.~-]+)/ ) do
55
- '%' + $1.unpack( 'H2' * $1.bytesize ).join( '%' ).upcase
56
- end
57
- end
58
-
59
- end
@@ -1,110 +0,0 @@
1
- class AmazonRequest
2
- include HTTParty
3
- format :xml
4
-
5
- # Initialize Amazon Request. Obtain valid Amazon credentials from your developer account
6
- # Parameters:
7
- # amazon_access_key_id: Valid Amazon access key
8
- # amazon_secret_access_key: Valid Amazon secret access key
9
- # amazon_associate_tag: Valid Amazon associates tag (optional)
10
- # locale: Locale for the specific amazon site to use valid values are :ca, :de, :fr, :jp, :uk, :us (optional, default is us)
11
- def initialize(amazon_access_key_id, amazon_secret_access_key, amazon_associate_tag = nil, locale = :us)
12
- @amazon_access_key_id = amazon_access_key_id
13
- @amazon_secret_access_key = amazon_secret_access_key
14
- @amazon_associate_tag = amazon_associate_tag
15
- @locale = locale
16
- end
17
-
18
- # Generate rss feeds for the give email
19
- # Parameters:
20
- # email: email for which to find feeds.
21
- def get_amazon_feeds(email)
22
- wishlists = get_customer_wishlists(email)
23
- if !wishlists.blank?
24
- wishlists = [wishlists] unless wishlists.is_a?(Array)
25
- wishlist_ids = wishlists.collect{|list| list['ListId']}
26
- generate_wishlist_rss(wishlist_ids)
27
- end
28
- end
29
-
30
- # Get matching id for the given email
31
- # Parameters:
32
- # email: customer's email.
33
- def get_customer_id(email)
34
- query = "Operation=CustomerContentSearch&Email=#{email}"
35
- result = make_request(query)
36
- if result['CustomerContentSearchResponse']['Customers']['TotalResults'].to_i > 0
37
- result['CustomerContentSearchResponse']['Customers']['Customer'][0]
38
- end
39
- end
40
-
41
- # Get information for the given customer id
42
- def get_customer_information(customer_id)
43
- query = "Operation=CustomerContentLookup&ResponseGroup=CustomerLists&CustomerId=#{customer_id}"
44
- make_request(query)
45
- end
46
-
47
- # Get customer's wishlist ids
48
- def get_customer_wishlists(email)
49
- query = "Operation=ListSearch&ListType=WishList&Email=#{email}"
50
- result = make_request(query)
51
- check_errors(result)
52
- result['ListSearchResponse']['Lists']['List']
53
- end
54
-
55
- # For this method to work
56
- # ecs_to_rss_wishlist must be set in global_config.yml
57
- # For example:
58
- # ecs_to_rss_wishlist: "http://www.example.com/ecs_to_rss-wishlist.xslt"
59
- def generate_wishlist_rss(wishlist_ids)
60
- feeds = []
61
- wishlist_ids.each do |wishlist_id|
62
- query = "Operation=ListLookup&ListType=WishList&ListId=#{wishlist_id}&ResponseGroup=ItemAttributes,ListItems,ListInfo,Offers&Sort=DateAdded&Style=#{GlobalConfig.ecs_to_rss_wishlist}"
63
- feeds << make_xslt_request(query)
64
- end
65
- feeds
66
- end
67
-
68
- protected
69
-
70
- def check_errors(result)
71
- result.each_pair do |key, value|
72
- if key == 'Errors'
73
- if value['Error'].is_a?(Array)
74
- raise Amazon::AmazonResultError, value['Error'].collect{|error| error['Message']}.join(' ')
75
- else
76
- raise Amazon::AmazonResultError, value['Error']['Message']
77
- end
78
- elsif value.is_a?(Hash)
79
- check_errors(value)
80
- elsif value.is_a?(Array)
81
- value.each do |item|
82
- if item.is_a?(Hash)
83
- check_errors(item)
84
- end
85
- end
86
- end
87
- end
88
- end
89
-
90
- def make_request(query)
91
- add_required_params(query)
92
- uri = Amazon::AMAZON_SITES[@locale]
93
- signed_query = Amazon.sign_query(URI.parse(uri), query, @amazon_secret_access_key)
94
- AmazonRequest.get(uri, :query => signed_query)
95
- end
96
-
97
- def make_xslt_request(query)
98
- add_required_params(query)
99
- uri = Amazon::AMAZON_XSLT_SITES[@locale]
100
- signed_query = Amazon.sign_query(URI.parse(uri), query, @amazon_secret_access_key)
101
- "#{uri}?#{signed_query}"
102
- end
103
-
104
- def add_required_params(query)
105
- query << "&Service=AWSECommerceService"
106
- query << "&AWSAccessKeyId=#{@amazon_access_key_id}"
107
- query << "&AssociateTag=#{@amazon_associate_tag}" if @amazon_associate_tag
108
- query << "&Version=2009-07-01"
109
- end
110
- end
@@ -1,41 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8" ?>
2
- <xsl:stylesheet version="1.0"
3
- xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
4
- xmlns:aws="http://webservices.amazon.com/AWSECommerceService/2009-07-01">
5
-
6
- <xsl:output method="xml"/>
7
-
8
- <xsl:template match="/">
9
- <rss version="2.0">
10
- <channel>
11
- <xsl:apply-templates select="aws:ListLookupResponse/aws:Lists/aws:List" />
12
- </channel>
13
- </rss>
14
- </xsl:template>
15
-
16
- <xsl:template match="aws:List">
17
- <title>WishList for <xsl:value-of select="aws:CustomerName" /></title>
18
- <link><xsl:value-of select="aws:ListURL"/></link>
19
- <xsl:apply-templates select="aws:ListItem"/>
20
- </xsl:template>
21
-
22
- <xsl:template match="aws:ListItem">
23
- <item>
24
- <title><xsl:value-of select="aws:Item/aws:ItemAttributes/aws:Title" /></title>
25
- <link><xsl:value-of select="aws:Item/aws:DetailPageURL" /></link>
26
- <description>
27
- <p>Author: <xsl:value-of select="aws:Item/aws:ItemAttributes/aws:Author" /></p>
28
- <p>ISBN: <xsl:value-of select="aws:Item/aws:ItemAttributes/aws:ISBN" /></p>
29
- <p>List Price: <xsl:value-of select="aws:Item/aws:ItemAttributes/aws:ListPrice/aws:FormattedPrice" /></p>
30
- <p>Price: <xsl:value-of select="aws:Item/aws:OfferSummary/aws:LowestNewPrice/aws:FormattedPrice"/></p>
31
- <xsl:apply-templates select="aws:Item/aws:ItemLinks/aws:ItemLink"/>
32
- </description>
33
- <guid><xsl:value-of select="aws:Item/aws:DetailPageURL" /></guid>
34
- </item>
35
- </xsl:template>
36
-
37
- <xsl:template match="aws:ItemLink">
38
- <a href="{aws:URL}"><xsl:value-of select="aws:Description" /></a>
39
- </xsl:template>
40
-
41
- </xsl:stylesheet>
@@ -1,15 +0,0 @@
1
- require File.dirname(__FILE__) + '/../test_helper'
2
-
3
- class AmazonRequestTest < ActiveSupport::TestCase
4
-
5
- context "amazon wish list" do
6
- setup do
7
- @email = 'justinball@gmail.com'
8
- end
9
- should "get wishlist" do
10
- # result = AmazonRequest.get_amazon_feeds(@email)
11
- # assert result.length > 0
12
- end
13
- end
14
-
15
- end