Class: Kickscraper::Client

Inherits:
Object
  • Object
show all
Includes:
Connection
Defined in:
lib/kickscraper/client.rb

Constant Summary collapse

CLIENT_ID =
'2II5GGBZLOOZAA5XBU1U0Y44BU57Q58L8KOGM7H0E0YFHP3KTG'

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeClient

Returns a new instance of Client.



11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# File 'lib/kickscraper/client.rb', line 11

def initialize
    @more_projects_available = false

    if Kickscraper.email.nil?
        @user = nil
    else
        if Kickscraper.token.nil?
            token_response = connection.post("xauth/access_token?client_id=#{CLIENT_ID}", {'email' => Kickscraper.email, 'password' => Kickscraper.password }.to_json)
            if token_response.body.error_messages
                raise token_response.body.error_messages.join("\n")
                return
            end
            Kickscraper.token = token_response.body.access_token
            @user = User.coerce(token_response.body.user)
        end
    end
end

Instance Attribute Details

#userObject

Returns the value of attribute user.



7
8
9
# File 'lib/kickscraper/client.rb', line 7

def user
  @user
end

Instance Method Details

#categoriesObject



69
70
71
# File 'lib/kickscraper/client.rb', line 69

def categories
    self::process_api_call "categories", ""
end

#category(id_or_name = nil) ⇒ Object



73
74
75
76
# File 'lib/kickscraper/client.rb', line 73

def category(id_or_name = nil)
    return categories.find{|i| i.name.downcase.start_with? id_or_name.downcase} if id_or_name.is_a? String
        self::process_api_call "category", id_or_name.to_s
end

#coerce_api_response(expected_type, response) ⇒ Object



118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
# File 'lib/kickscraper/client.rb', line 118

def coerce_api_response(expected_type, response)
    
    # define what we should return as an empty response, based on the expected type
    types_that_should_return_an_array = ["projects", "comments", "updates", "categories"]
    empty_response = (types_that_should_return_an_array.include? expected_type) ? [] : nil
    
    
    # get the body from the response
    body = response.body

    
    # if we got an error response back, stop here and return an empty response
    return empty_response if response.headers['status'].to_i >= 400 || !response.headers['content-type'].start_with?('application/json')
    return empty_response if (body.respond_to?("error_messages") && !body.error_messages.empty?) || (body.respond_to?("http_code") && body.http_code == 404)
    
    
    # otherwise, take the response from the api and coerce it to the type we want
    case expected_type.downcase
    when "user"
        
        User.coerce body
        
    when "project"
        
        Project.coerce body
        
    when "projects"
        
        # if the body is just an array of projects, with no root keys, then coerce
        # the array
        if body.is_a?(Array)
            
            @more_projects_available = false
            body.map { |project| Project.coerce project }
            
            
        # else, if the body doesn't have any projects, return an empty array
        elsif body.projects.nil?
            
            @more_projects_available = false
            return empty_response
            
            
        # else, determine if we can load more projects and then return an array of projects
        else
            
            if @last_api_call_params && !body.total_hits.nil?
                @more_projects_available = @last_api_call_params[:page] * 12 < body.total_hits # (there is a huge assumption here that Kickstarter will always return 12 projects per full page!) (in fact, this has changed over the years from 20 to 24 to 12)
            end
            
            return body.projects.map { |project| Project.coerce project }
        end
        
    when "comments"
        
        return empty_response if body.comments.nil?
        body.comments.map { |comment| Comment.coerce comment }
        
    when "updates"
        
        return empty_response if body.updates.nil?
        body.updates.map { |update| Update.coerce update }
        
    when "categories"
        
        return empty_response if body.categories.nil?
        body.categories.map { |category| Category.coerce category }
    
    when "category"
        
        Category.coerce body

    else    
        raise ArgumentError, "invalid api request type"
    end
end

#ending_soon_projects(page = nil) ⇒ Object



41
42
43
# File 'lib/kickscraper/client.rb', line 41

def ending_soon_projects(page = nil)
    self::process_api_call "projects", "ending-soon", "", page
end

#find_project(id_or_slug) ⇒ Object



33
34
35
# File 'lib/kickscraper/client.rb', line 33

def find_project(id_or_slug)
    self::process_api_call "project", id_or_slug.to_s
end

#find_user(id) ⇒ Object



29
30
31
# File 'lib/kickscraper/client.rb', line 29

def find_user(id)
    self::process_api_call "user", id.to_s
end

#load_more_projectsObject



61
62
63
64
65
66
67
# File 'lib/kickscraper/client.rb', line 61

def load_more_projects
    if self::more_projects_available?
        self::process_api_call @last_api_call_params[:request_for], @last_api_call_params[:additional_path], @last_api_call_params[:search_terms], (@last_api_call_params[:page] + 1),  @last_api_call_params[:category_id],  @last_api_call_params[:state] 
    else
        []
    end
end

#make_api_call(request_for, additional_path = "", search_terms = "", page = nil, category_id = nil, state = nil) ⇒ Object



196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
# File 'lib/kickscraper/client.rb', line 196

def make_api_call(request_for, additional_path = "", search_terms = "", page = nil, category_id = nil, state = nil)
    
    # set the url/path differently for each type of request
    case request_for.downcase
    when "user"
        api_or_search = "api"
        path = "/v1/users"
    when "project"
        api_or_search = "api"
        path = "/v1/projects"
    when "projects"
        api_or_search = "search"
        path = "/discover"
    when "category", "categories"
        api_or_search = "api"
        path = "/v1/categories"
    end
    
    
    # add the additional path if we have it
    path += "/" + CGI.escape(additional_path) unless additional_path.empty?
    
    
    # create the params hash and add the params we want
    params = {}
    params[:term] = search_terms unless search_terms.empty?
    params[:page] = page unless page.nil?
    params[:category_id] = category_id unless category_id.nil? 
    params[:state] = state unless state.nil?
    params[:client_id] = CLIENT_ID if api_or_search == "api"

    # make the connection and return the response
    connection(api_or_search).get(path, params)
end

#more_projects_available?Boolean Also known as: can_load_more_projects

Returns:

  • (Boolean)


55
56
57
# File 'lib/kickscraper/client.rb', line 55

def more_projects_available?
    @more_projects_available
end


45
46
47
# File 'lib/kickscraper/client.rb', line 45

def popular_projects(page = nil)
    self::process_api_call "projects", "popular", "", page
end

#process_api_call(request_for, additional_path, search_terms = "", page = nil, category_id = nil, state = nil) ⇒ Object



79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/kickscraper/client.rb', line 79

def process_api_call(request_for, additional_path, search_terms = "", page = nil, category_id = nil, state = nil)
    
    # save the parameters for this call, so we can repeat it to get the next page of results
    @last_api_call_params = {
        request_for: request_for, 
        additional_path: additional_path, 
        search_terms: search_terms,
        page: page.nil? ? 1 : page,
        category_id: category_id,
        state: state
    }
    
    # make the api call (to the API resource we want)
    response = self::make_api_call(request_for, additional_path, search_terms, page, category_id,state)
    
    # handle the response, returning an object with the results
    self::coerce_api_response(request_for, response)
end

#process_api_url(request_for, api_url, coerce_response = true) ⇒ Object



99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/kickscraper/client.rb', line 99

def process_api_url(request_for, api_url, coerce_response = true)
    
    # make the api call to whatever url we specified
    response = connection.get(api_url)
    
    
    # if we want to coerce the response, do it now
    if coerce_response
        
        self::coerce_api_response(request_for, response)
        
    # else, just return the raw body
    else
        
        response.body
    end
end

#recently_launched_projects(page = nil) ⇒ Object Also known as: newest_projects



49
50
51
# File 'lib/kickscraper/client.rb', line 49

def recently_launched_projects(page = nil)
    self::process_api_call "projects", "recently-launched", "", page
end

#search_projects(search_terms, page = nil, category_id = nil, state = nil) ⇒ Object



37
38
39
# File 'lib/kickscraper/client.rb', line 37

def search_projects(search_terms, page = nil, category_id = nil, state = nil)
    self::process_api_call "projects", "advanced", search_terms, page, category_id, state
end