kickscraper-snow 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,18 @@
1
+ module Kickscraper
2
+ class Category < Api
3
+ attr_accessor :projects
4
+
5
+ def to_s
6
+ name
7
+ end
8
+
9
+ def inspect
10
+ "<Category: '#{to_s}'>"
11
+ end
12
+
13
+ def projects
14
+ return [] unless @projects || self.urls.web.discover
15
+ @projects ||= Kickscraper.client.process_api_url("Projects", self.urls.web.discover)
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,5 @@
1
+ module Kickscraper
2
+ class Comment < Api
3
+
4
+ end
5
+ end
File without changes
File without changes
@@ -0,0 +1,71 @@
1
+ require_relative 'user.rb'
2
+ require_relative 'category.rb'
3
+
4
+ module Kickscraper
5
+ class Project < Api
6
+ coerce_key :creator, Kickscraper::User
7
+ coerce_key :category, Kickscraper::Category
8
+
9
+ attr_accessor :comments, :updates, :rewards
10
+
11
+ def to_s
12
+ name
13
+ end
14
+
15
+ def inspect
16
+ "<Project: '#{to_s}'>"
17
+ end
18
+
19
+ def reload!
20
+ if self.urls.api.nil?
21
+ the_full_project = Kickscraper.client.find_project(self.id)
22
+ project_api_url = the_full_project.nil? ? nil : the_full_project.urls.api.project
23
+ else
24
+ project_api_url = self.urls.api.project
25
+ end
26
+ @raw = Kickscraper.client.process_api_url("Project", project_api_url, false) unless project_api_url.nil?
27
+ Kickscraper::Project::do_coercion(self)
28
+ end
29
+
30
+ def successful?
31
+ pledged >= goal
32
+ end
33
+
34
+ def active?
35
+ state == "live"
36
+ end
37
+
38
+ def comments
39
+ return @comments if @comments
40
+
41
+ # must reload to get urls.api, not returned in public discover search
42
+ reload! unless (self.urls.api && self.urls.api.comments)
43
+
44
+ # if logged in and can use private API, self.urls.api.updates should now be defined
45
+ if (self.urls.api && self.urls.api.updates)
46
+ @comments = Kickscraper.client.process_api_url("Comments", self.urls.api.comments)
47
+ else
48
+ @comments= []
49
+ end
50
+ end
51
+
52
+ def updates
53
+ return @updates if @updates
54
+
55
+ # must reload to get urls.api, not returned in public discover search
56
+ reload! unless (self.urls.api && self.urls.api.updates)
57
+
58
+ # if logged in and can use private API, self.urls.api.updates should now be defined
59
+ if (self.urls.api && self.urls.api.updates)
60
+ @updates = Kickscraper.client.process_api_url("Updates", self.urls.api.updates)
61
+ else
62
+ @updates = []
63
+ end
64
+ end
65
+
66
+ def rewards
67
+ reload! unless @raw['rewards']
68
+ @raw['rewards']
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,5 @@
1
+ module Kickscraper
2
+ class Update < Api
3
+
4
+ end
5
+ end
@@ -0,0 +1,34 @@
1
+ module Kickscraper
2
+ class User < Api
3
+ attr_accessor :backed_projects, :starred_projects
4
+
5
+ def to_s
6
+ name
7
+ end
8
+
9
+ def reload!
10
+ @raw = Kickscraper.client.process_api_url("User", self.urls.api.user, false)
11
+ Kickscraper::User::do_coercion(self)
12
+ end
13
+
14
+ def biography
15
+ reload! unless @raw['biography']
16
+ @raw['biography']
17
+ end
18
+
19
+ def backed_projects
20
+ return [] unless self.urls.api.backed_projects
21
+ @backed_projects ||= Kickscraper.client.process_api_url("Projects", self.urls.api.backed_projects)
22
+ end
23
+
24
+ def starred_projects
25
+ return [] unless self.urls.api.starred_projects
26
+ @starred_projects ||= Kickscraper.client.process_api_url("Projects", self.urls.api.starred_projects)
27
+ end
28
+
29
+ def created_projects
30
+ return [] unless self.urls.api.created_projects
31
+ @created_projects ||= Kickscraper.client.process_api_url("Projects", self.urls.api.created_projects)
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,11 @@
1
+ module Kickscraper
2
+ module Configure
3
+
4
+ attr_accessor :email, :password, :token, :proxy
5
+
6
+ def configure
7
+ yield self
8
+ end
9
+ end
10
+
11
+ end
@@ -0,0 +1,63 @@
1
+ require 'faraday'
2
+ require 'faraday_middleware'
3
+ require 'uri/query_params'
4
+
5
+ class KSToken < Faraday::Middleware
6
+ def initialize(app)
7
+ @app = app
8
+ end
9
+
10
+ def call(env)
11
+ # replace '+' symbols in the query params with their original spaces, because there
12
+ # seems to be a bug in the way some versions of Fararay escape parameters with spaces
13
+ env[:url].query_params.each { |key, value|
14
+ env[:url].query_params[key] = value.tr('+', ' ')
15
+ }
16
+
17
+ # add format=json to all public search requests, or add the oauth_token to all api requests once we have it
18
+ if env[:url].to_s.index('https://api.kickstarter.com').nil?
19
+ env[:url].query_params['format'] = 'json'
20
+ else
21
+ env[:url].query_params['oauth_token'] = Kickscraper.token unless Kickscraper.token.nil?
22
+ end
23
+
24
+ # make the call
25
+ @app.call(env)
26
+ end
27
+ end
28
+
29
+ module Kickscraper
30
+ module Connection
31
+
32
+ private
33
+
34
+ def connection(api_or_search = "api")
35
+ options = {
36
+ :headers => {'Content-Type' => 'application/json', 'Accept' => "application/json; charset=utf-8", 'User-Agent' => "Kickscraper/XXX"},
37
+ :ssl => {:verify => false},
38
+ :url => api_or_search == "api" ? "https://api.kickstarter.com" : "https://www.kickstarter.com",
39
+ :proxy => Kickscraper.proxy.nil? ? "" : Kickscraper.proxy
40
+ }
41
+
42
+ if api_or_search == "api"
43
+ @api_connection ||= Faraday::Connection.new(options) do |connection|
44
+ connection.use Faraday::Request::UrlEncoded
45
+ connection.use FaradayMiddleware::Mashify
46
+ connection.use FaradayMiddleware::FollowRedirects
47
+ connection.use Faraday::Response::ParseJson
48
+ connection.use ::KSToken
49
+ connection.adapter(Faraday.default_adapter)
50
+ end
51
+ else
52
+ @search_connection ||= Faraday::Connection.new(options) do |connection|
53
+ connection.use Faraday::Request::UrlEncoded
54
+ connection.use FaradayMiddleware::Mashify
55
+ connection.use FaradayMiddleware::FollowRedirects
56
+ connection.use Faraday::Response::ParseJson
57
+ connection.use ::KSToken
58
+ connection.adapter(Faraday.default_adapter)
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,15 @@
1
+ module Kickscraper
2
+ class Response
3
+
4
+ attr_accessor :body
5
+
6
+ def initialize(res)
7
+ @body = res.body
8
+ return res.body
9
+ end
10
+
11
+ def error?
12
+ return false
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,3 @@
1
+ module Kickscraper
2
+ VERSION = "0.2.2"
3
+ end
@@ -0,0 +1,26 @@
1
+ describe Kickscraper::Category do
2
+ let(:client) { Kickscraper.client }
3
+ let(:category) { client.categories.first }
4
+
5
+ context "loading category info" do
6
+ subject { category }
7
+
8
+ it { should be_a Kickscraper::Category }
9
+ its(:name) { should_not be_empty }
10
+ its(:projects_count) { should be > 0 }
11
+ end
12
+
13
+ context "urls" do
14
+ subject { category.urls }
15
+
16
+ it { should_not be_empty }
17
+ its(:web) { should_not be_empty }
18
+ end
19
+
20
+
21
+ context "projects" do
22
+ subject { category.projects }
23
+ it_returns "a collection", Kickscraper::Project
24
+ end
25
+ end
26
+
@@ -0,0 +1,84 @@
1
+ describe Kickscraper::Client do
2
+ let(:client) { Kickscraper.client }
3
+
4
+ context "finds a user by id" do
5
+ subject(:user) { client.find_user TEST_USER_ID }
6
+
7
+ its(:id) { should == TEST_USER_ID }
8
+ its(:name) { should == 'Zach Braff' }
9
+ end
10
+
11
+ context "returns nil when finding a non-existent user" do
12
+ subject { client.find_user 9999 }
13
+
14
+ it { should be_nil }
15
+ end
16
+
17
+ context "finds a project by id" do
18
+ subject(:project) { client.find_project TEST_PROJECT_ID }
19
+
20
+ its(:id) { should == TEST_PROJECT_ID }
21
+ its(:slug) { should == TEST_PROJECT_SLUG }
22
+ its(:name) { should == TEST_PROJECT_NAME }
23
+ end
24
+
25
+ context "finds a project by slug" do
26
+ subject(:project) { client.find_project TEST_PROJECT_SLUG }
27
+
28
+ its(:id) { should == TEST_PROJECT_ID }
29
+ its(:slug) { should == TEST_PROJECT_SLUG }
30
+ its(:name) { should == TEST_PROJECT_NAME }
31
+ end
32
+
33
+ context "returns nil when finding a non-existent project" do
34
+ subject { client.find_project 9999 }
35
+ it { should be_nil }
36
+ end
37
+
38
+ describe ".ending_soon_projects" do
39
+ it_behaves_like "ending_soon projects"
40
+ end
41
+
42
+ describe ".recently_launched_project" do
43
+ it_behaves_like "recently_launched projects"
44
+ end
45
+
46
+ # findes recently launched projects with the 'newest_projects' method for backwards compatibility
47
+ describe ".newest_projects" do
48
+ it_behaves_like "newest_projects projects"
49
+ end
50
+
51
+ describe ".popular_projects" do
52
+ it_behaves_like "popular projects"
53
+ end
54
+
55
+ describe ".search_project" do
56
+ it_behaves_like "search projects"
57
+ end
58
+
59
+ # context "loads recently launched projects starting at a specific timestamp" do
60
+ # subject { client.recently_launched_projects((Time.now - (2 * 24 * 60 * 60)).to_i) }
61
+ # it_returns "a collection", Kickscraper::Project
62
+ # end
63
+
64
+ # context "loads projects ending soon starting at a specific deadline" do
65
+ # subject { client.ending_soon_projects((Time.now + (2 * 24 * 60 * 60)).to_i) }
66
+ # it_returns "a collection", Kickscraper::Project
67
+ # end
68
+
69
+ context "lists all categories" do
70
+ subject { client.categories }
71
+ it_returns "a collection", Kickscraper::Category
72
+ end
73
+
74
+ context "loads a category from string" do
75
+ subject { client.category(TEST_CATEGORY_NAME) }
76
+ its(:name) { should eq TEST_CATEGORY_NAME }
77
+ end
78
+
79
+ context "loads a category from an id" do
80
+ subject { client.category(TEST_CATEGORY_ID) }
81
+ its(:name) { should eq TEST_CATEGORY_NAME }
82
+ end
83
+
84
+ end
@@ -0,0 +1,16 @@
1
+ describe Kickscraper do
2
+ subject { Kickscraper.client }
3
+
4
+ it "accepts configuration" do
5
+ Kickscraper.email.should == KICKSCRAPER_TEST_API_EMAIL
6
+ end
7
+
8
+ context "connects to the kickstarter api" do
9
+ it { should_not be_nil }
10
+ it { should be_a Kickscraper::Client }
11
+
12
+ its(:user) { should_not be_nil }
13
+ its(:user) { should be_a Kickscraper::User }
14
+ end
15
+
16
+ end
@@ -0,0 +1,73 @@
1
+ describe Kickscraper::Client do
2
+ context "no email no password client" do
3
+ before(:all) do
4
+ @save_token = Kickscraper.token
5
+ Kickscraper.token=nil
6
+ end
7
+
8
+ after (:all) do
9
+ Kickscraper.token=@save_token
10
+ end
11
+
12
+ let(:client) do
13
+ Kickscraper.configure do |config|
14
+ config.email = nil
15
+ config.password = nil
16
+ end
17
+ Kickscraper::Client.new
18
+ end
19
+
20
+ describe ".find_user" do
21
+ subject(:user) { client.find_user TEST_USER_ID }
22
+
23
+ it { should be_nil } # don't know how to do on purely Public API
24
+ end
25
+
26
+ describe ".find_product" do
27
+ subject(:project) { client.find_project TEST_PROJECT_ID }
28
+
29
+ it { should be_nil } # don't know how to do on purely Public API
30
+ end
31
+
32
+ describe ".categories" do
33
+ subject { client.categories }
34
+
35
+ it { should eq [] } # don't know how to do on purely Public API
36
+ end
37
+
38
+ describe ".category" do
39
+ context "loads a category from string" do
40
+ subject { client.category(TEST_CATEGORY_NAME) }
41
+
42
+ it { should be_nil } # don't know how to do on purely Public API
43
+ end
44
+
45
+ context "loads a category from an id" do
46
+ subject { client.category(TEST_CATEGORY_ID) }
47
+
48
+ it { should be_nil } # don't know how to do on purely Public API
49
+ end
50
+ end
51
+
52
+ describe ".ending_soon_projects" do
53
+ it_behaves_like "ending_soon projects"
54
+ end
55
+
56
+ describe ".recently_launched_project" do
57
+ it_behaves_like "recently_launched projects"
58
+ end
59
+
60
+ # findes recently launched projects with the 'newest_projects' method for backwards compatibility
61
+ describe ".newest_projects" do
62
+ it_behaves_like "newest_projects projects"
63
+ end
64
+
65
+ describe ".popular_projects" do
66
+ it_behaves_like "popular projects"
67
+ end
68
+
69
+ describe ".search_project" do
70
+ it_behaves_like "search projects"
71
+ end
72
+ end
73
+ end