CSApi 0.0.4 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CONTRIBUTORS +2 -0
- data/Gemfile +4 -0
- data/{LICENSE.txt → LICENSE} +0 -0
- data/examples/example.rb +22 -16
- data/lib/csapi.rb +47 -143
- data/lib/csapi/errors.rb +9 -0
- data/lib/csapi/messages.rb +101 -0
- data/lib/csapi/request.rb +68 -0
- data/lib/csapi/search.rb +85 -0
- data/lib/csapi/version.rb +1 -1
- data/readme.md +6 -2
- metadata +10 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 155eb0a39f7dbf9a5c75756e9f50ee73b0d1b42c
|
4
|
+
data.tar.gz: a3c35ded375372df4e48d1852dafbfca56b6e0e0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 83a322ecb1cc8cca2d497a530ceb95e2f1c6048eb22d2a278b9cce089c711562890da1953f19eef3874c26083c1eb8dceae4d9e675bfd33c09806276c4b7cfe2
|
7
|
+
data.tar.gz: 5ab3947319ac8b2ac0b5adc4568a4101bcf905a82a43e845685d1c65714406b87491ab36e9349555da8d0f96e2e3378cc77abd162dd272a2e9e434a270b036be
|
data/CONTRIBUTORS
ADDED
data/Gemfile
CHANGED
data/{LICENSE.txt → LICENSE}
RENAMED
File without changes
|
data/examples/example.rb
CHANGED
@@ -1,11 +1,14 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
#encoding: utf-8
|
3
3
|
|
4
|
-
|
4
|
+
require_relative '../lib/CSApi.rb'
|
5
5
|
require 'pp'
|
6
6
|
|
7
|
+
user = ENV['USER'] || 'user'
|
8
|
+
password = ENV['PASSWORD'] || 'password'
|
9
|
+
|
7
10
|
begin
|
8
|
-
api = CS::Api.new(
|
11
|
+
api = CS::Api.new(user,password)
|
9
12
|
rescue CS::AuthError
|
10
13
|
puts "Incorrect username or password"
|
11
14
|
exit
|
@@ -16,7 +19,6 @@ end
|
|
16
19
|
# ===
|
17
20
|
profile = api.profile('205974')
|
18
21
|
|
19
|
-
|
20
22
|
## ===
|
21
23
|
## Get a user's photos, by default ours
|
22
24
|
## ===
|
@@ -41,17 +43,17 @@ requests = api.requests(limit)
|
|
41
43
|
# ===
|
42
44
|
# Get the current user's inbox messages
|
43
45
|
# ===
|
44
|
-
|
45
|
-
pp m.count
|
46
|
+
messages = api.messages('inbox', 1)
|
46
47
|
|
47
|
-
|
48
|
-
|
48
|
+
messages.each do |m|
|
49
|
+
puts m.to_h
|
49
50
|
end
|
50
51
|
|
51
|
-
|
52
|
-
|
52
|
+
|
53
|
+
if messages.has_more?
|
54
|
+
p messages.more.count
|
53
55
|
else
|
54
|
-
|
56
|
+
p "end of messages"
|
55
57
|
end
|
56
58
|
|
57
59
|
|
@@ -61,25 +63,25 @@ end
|
|
61
63
|
details = {
|
62
64
|
subject: 'This is my request subject',
|
63
65
|
number: 1, #How many people travel with you
|
64
|
-
arrival: 1339543920, #a
|
65
|
-
departure: 1339643920, #a
|
66
|
+
arrival: Time.at(1339543920), #a Time instance
|
67
|
+
departure: Time.at(1339643920), #a Time instance
|
66
68
|
arrival_flexible: true,
|
67
69
|
departure_flexible: false,
|
68
70
|
is_open_couchrequest: false,
|
69
71
|
to: 12345, #a numeric user id, I guess, have yet to figure this out ,
|
70
72
|
message: 'This is my request message' #I've yet to figure out how to do the multi-part requests
|
71
73
|
}
|
72
|
-
couch_request = CS::Request.new(details)
|
74
|
+
#couch_request = CS::Request.new(details)
|
73
75
|
|
74
76
|
api.requests(1).each do |key, value|
|
75
77
|
pp value
|
76
78
|
end
|
77
|
-
|
79
|
+
|
78
80
|
## ===
|
79
81
|
## Search for people in a city with various search constraints
|
80
82
|
## ===
|
81
83
|
options = {
|
82
|
-
location: '
|
84
|
+
location: 'mexico city',
|
83
85
|
gender: 'female',
|
84
86
|
:'has-photo' => false,
|
85
87
|
:'member-type' => 'host' ,
|
@@ -89,7 +91,11 @@ options = {
|
|
89
91
|
:'min-age' => nil,
|
90
92
|
:'max-age' => nil,
|
91
93
|
}
|
92
|
-
|
94
|
+
search = CS::CouchSearch.new(options)
|
95
|
+
results = search.execute
|
96
|
+
|
93
97
|
results.each do |id, user|
|
94
98
|
puts "Found (UID:#{id}) #{user[:name]} in #{user[:location]} with a couch status of #{user[:status]} and a photo #{user[:pic]}\n\n"
|
95
99
|
end
|
100
|
+
|
101
|
+
puts results.more.count
|
data/lib/csapi.rb
CHANGED
@@ -10,18 +10,41 @@ Copyright (c) 2012 Partido Surrealista Mexicano
|
|
10
10
|
require 'httparty'
|
11
11
|
require 'json'
|
12
12
|
require 'nokogiri'
|
13
|
+
|
14
|
+
require_relative 'csapi/version.rb'
|
15
|
+
require_relative 'csapi/errors.rb'
|
16
|
+
require_relative 'csapi/messages.rb'
|
17
|
+
require_relative 'csapi/request.rb'
|
18
|
+
require_relative 'csapi/search.rb'
|
19
|
+
|
13
20
|
module CS
|
14
|
-
|
15
|
-
|
21
|
+
|
22
|
+
@@instance = nil
|
23
|
+
|
24
|
+
def self.instance
|
25
|
+
@@instance
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.instance= instance
|
29
|
+
@@instance = instance
|
30
|
+
end
|
31
|
+
|
32
|
+
class HTTP
|
16
33
|
include HTTParty
|
17
34
|
base_uri 'https://api.couchsurfing.org'
|
18
35
|
headers "Content-Type" => 'application/json'
|
19
36
|
follow_redirects false
|
20
|
-
|
37
|
+
#debug_output $stderr
|
38
|
+
end
|
21
39
|
|
40
|
+
class Api
|
41
|
+
|
42
|
+
attr_accessor :uid;
|
43
|
+
@uid = '0'
|
44
|
+
|
22
45
|
def initialize(username, password)
|
23
46
|
@username = username
|
24
|
-
r =
|
47
|
+
r = HTTP.post('/sessions', body:{username: username, password: password}.to_json)
|
25
48
|
|
26
49
|
raise CS::AuthError.new("Could not login") if r.code != 200
|
27
50
|
|
@@ -33,20 +56,17 @@ module CS
|
|
33
56
|
@uid = data['url'].gsub(/[^\d]/, '')
|
34
57
|
@profile = data.keep_if {|k,v| ['realname', 'username', 'profile_image', 'gender', 'address'].include?(k)}
|
35
58
|
@profile['uid'] = @uid
|
36
|
-
|
37
|
-
|
59
|
+
HTTP.headers 'Cookie' => @cookies
|
60
|
+
CS.instance = self
|
38
61
|
end
|
39
62
|
|
40
|
-
def CS::instance
|
41
|
-
@@instance
|
42
|
-
end
|
43
63
|
|
44
64
|
def requests(limit=10)
|
45
65
|
url = "/users/#{@uid}/couchrequests"
|
46
66
|
q = {
|
47
67
|
limit: limit
|
48
68
|
}
|
49
|
-
r =
|
69
|
+
r = HTTP.get(url, query:q)
|
50
70
|
requests = {}
|
51
71
|
response = JSON.parse r.body
|
52
72
|
response['object'].each do |req|
|
@@ -59,67 +79,57 @@ module CS
|
|
59
79
|
|
60
80
|
def request(id)
|
61
81
|
url = "/couchrequests/#{id}"
|
62
|
-
r =
|
82
|
+
r = HTTP.get(url)
|
63
83
|
JSON.parse r.body
|
64
84
|
end
|
65
85
|
|
66
86
|
|
67
|
-
def messages(
|
68
|
-
|
69
|
-
types = ['inbox', 'sent'];
|
70
|
-
throw ArgumentError.new("Can't fetch messages of kind #{type}") if !types.include? type;
|
71
|
-
|
72
|
-
url = "/users/#{@uid}/messages"
|
73
|
-
q = {
|
74
|
-
type: type,
|
75
|
-
limit: limit
|
76
|
-
}
|
77
|
-
|
78
|
-
if (start)
|
79
|
-
q[:start] = start
|
80
|
-
end
|
81
|
-
|
82
|
-
r = self.class.get(url, query:q);
|
83
|
-
object = JSON.parse r.body
|
84
|
-
|
85
|
-
return CS::Messages.new(object, q, self);
|
87
|
+
def messages(*args)
|
88
|
+
CS::Messages.getMessages(*args)
|
86
89
|
end
|
87
|
-
|
90
|
+
|
91
|
+
|
88
92
|
def message(url)
|
89
|
-
r =
|
93
|
+
r = HTTP.get(url)
|
90
94
|
JSON.parse r.body
|
91
95
|
end
|
92
96
|
|
97
|
+
|
93
98
|
def userdata
|
94
99
|
@profile
|
95
100
|
end
|
96
101
|
|
102
|
+
|
97
103
|
def profile(user=@uid)
|
98
104
|
url = "/users/#{user}/profile"
|
99
|
-
r =
|
105
|
+
r = HTTP.get(url)
|
100
106
|
JSON.parse r.body
|
101
107
|
end
|
102
108
|
|
109
|
+
|
103
110
|
def photos(user=@uid)
|
104
111
|
url = "/users/#{user}/photos"
|
105
|
-
r =
|
112
|
+
r = HTTP.get(url)
|
106
113
|
JSON.parse r.body
|
107
114
|
end
|
108
115
|
|
116
|
+
|
109
117
|
def friends(user=@uid)
|
110
118
|
url = "/users/#{user}/friends"
|
111
|
-
r =
|
119
|
+
r = HTTP.get(url)
|
112
120
|
JSON.parse r.body
|
113
121
|
end
|
114
122
|
|
123
|
+
|
115
124
|
def references(user=@uid)
|
116
125
|
url = "/users/#{user}/references"
|
117
|
-
r =
|
126
|
+
r = HTTP.get(url)
|
118
127
|
JSON.parse r.body
|
119
128
|
end
|
120
129
|
|
130
|
+
|
121
131
|
def search(options)
|
122
|
-
|
132
|
+
|
123
133
|
defaults = {
|
124
134
|
location: nil,
|
125
135
|
gender: nil,
|
@@ -133,113 +143,7 @@ module CS
|
|
133
143
|
:platform => 'android'
|
134
144
|
}
|
135
145
|
|
136
|
-
options = defaults.merge(options)
|
137
|
-
html = self.class.get('/msearch', :query => options)
|
138
|
-
doc = Nokogiri::HTML(html);
|
139
|
-
users = {}
|
140
|
-
statuses = {
|
141
|
-
'M' => 'maybe',
|
142
|
-
'T' => 'travelling',
|
143
|
-
'Y' => 'available',
|
144
|
-
'N' => 'unavailable'
|
145
|
-
}
|
146
|
-
doc.xpath('//article').each do |article|
|
147
|
-
id = article.at_css('a').attr('href').split('/').last
|
148
|
-
user = {
|
149
|
-
name: article.children.at_css("h2").content,
|
150
|
-
location: article.children.at_css("div.location").content,
|
151
|
-
status: statuses[article['class'].match(/couch-([A-Z])/)[1]],
|
152
|
-
pic: article.at_css('img').attr('src')
|
153
|
-
}
|
154
|
-
users[id] = user
|
155
|
-
end
|
156
|
-
|
157
|
-
users;
|
158
|
-
end
|
159
|
-
end
|
160
|
-
|
161
|
-
|
162
|
-
class AuthError < StandardError
|
163
|
-
end
|
164
|
-
|
165
|
-
class APIError < StandardError
|
166
|
-
end
|
167
|
-
|
168
|
-
class Messages
|
169
|
-
|
170
|
-
@after = nil
|
171
|
-
@q = {}
|
172
|
-
@data = []
|
173
|
-
|
174
|
-
def initialize(object, q, ref)
|
175
146
|
|
176
|
-
@after = object['after'] if object.include? 'after';
|
177
|
-
@q = q;
|
178
|
-
@ref = ref
|
179
|
-
@data = object['object']
|
180
|
-
end
|
181
|
-
|
182
|
-
def count
|
183
|
-
return @data.count
|
184
|
-
end
|
185
|
-
|
186
|
-
def has_more?
|
187
|
-
return @after != nil
|
188
|
-
end
|
189
|
-
|
190
|
-
def each
|
191
|
-
@data.each do |url|
|
192
|
-
yield @ref.message(url)
|
193
|
-
end
|
194
|
-
end
|
195
|
-
|
196
|
-
def more
|
197
|
-
more = @ref.messages(@q[:type], @q[:limit], @after)
|
198
|
-
@data = more['object']
|
199
|
-
@after = more.include?('after') ? more['after'] : nil;
|
200
|
-
return self
|
201
|
-
end
|
202
|
-
|
203
|
-
private
|
204
|
-
@ref = nil
|
205
|
-
|
206
|
-
end
|
207
|
-
|
208
|
-
|
209
|
-
class Request
|
210
|
-
@api = nil
|
211
|
-
|
212
|
-
def initialize(options={})
|
213
|
-
if options[:username] && options[:password]
|
214
|
-
api = CS.new(options[:username], options[:password])
|
215
|
-
options.del(:username)
|
216
|
-
options.del(:password)
|
217
|
-
else
|
218
|
-
api = CS::instance
|
219
|
-
if api==nil
|
220
|
-
raise CS::APIError('You have not authenticated with the service or did not provide a :username and :password')
|
221
|
-
end
|
222
|
-
end
|
223
|
-
|
224
|
-
#pp api.userdata
|
225
|
-
options[:subject] = options[:subject] || "#{api.userdata['realname']} from #{api.userdata['address']['country']} sent you a new CouchRequest!"
|
226
|
-
options[:number] = options[:number] || 1
|
227
|
-
options[:arrival_flexible] = options[:arrival_flexible] || false
|
228
|
-
options[:departure_flexible] = options[:departure_flexible] || false
|
229
|
-
options[:is_open_couchrequest] = options[:is_open_couchrequest] || false
|
230
|
-
options[:from] = api.userdata['uid']
|
231
|
-
options[:to] = options[:to] || api.userdata['uid']
|
232
|
-
options[:arrival] = Time.at(options[:arrival]).strftime("%FT%TZ") || (Time.now()+86400).strftime("%FT%TZ")
|
233
|
-
options[:departure] = Time.at(options[:departure]).strftime("%FT%TZ") || (Time.now()+86400*3).strftime("%FT%TZ")
|
234
|
-
options[:message] = options[:message] || "I'm to lazy to write a proper couch request. HOST ME PLZ?"
|
235
|
-
#puts options.to_json
|
236
|
-
|
237
|
-
url = "/couchrequests"
|
238
|
-
api.post(url, body:options.to_json)
|
239
|
-
|
240
|
-
#pp response.code
|
241
|
-
#pp response.body
|
242
|
-
|
243
147
|
end
|
244
148
|
end
|
245
149
|
|
data/lib/csapi/errors.rb
ADDED
@@ -0,0 +1,101 @@
|
|
1
|
+
module CS
|
2
|
+
|
3
|
+
class Messages
|
4
|
+
include Enumerable
|
5
|
+
|
6
|
+
attr_accessor :data, :after, :q
|
7
|
+
|
8
|
+
def self.getMessages(type='inbox', limit=5, start=nil)
|
9
|
+
types = ['inbox', 'sent'];
|
10
|
+
throw ArgumentError.new("Can't fetch messages of kind #{type}") unless types.include? type;
|
11
|
+
|
12
|
+
url = "/users/#{CS::instance.uid}/messages"
|
13
|
+
q = {
|
14
|
+
type: type,
|
15
|
+
limit: limit
|
16
|
+
}
|
17
|
+
|
18
|
+
if (start)
|
19
|
+
q[:start] = start
|
20
|
+
end
|
21
|
+
|
22
|
+
r = HTTP.get(url, query:q);
|
23
|
+
object = JSON.parse r.body
|
24
|
+
|
25
|
+
CS::Messages.new(object, q);
|
26
|
+
end
|
27
|
+
|
28
|
+
|
29
|
+
def initialize(object, q)
|
30
|
+
@after = object['after'] if object.include? 'after';
|
31
|
+
@q = q;
|
32
|
+
@data = object['object'].map {|u| Message.new(u) }
|
33
|
+
end
|
34
|
+
|
35
|
+
|
36
|
+
def method_missing meth, *args, &block
|
37
|
+
@data.send(meth.to_sym, *args, &block)
|
38
|
+
end
|
39
|
+
|
40
|
+
|
41
|
+
def has_more?
|
42
|
+
return @after != nil
|
43
|
+
end
|
44
|
+
|
45
|
+
|
46
|
+
def more limit=nil
|
47
|
+
Messages.getMessages(@q[:type], (limit || @q[:limit]), @after)
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
|
52
|
+
class Message
|
53
|
+
|
54
|
+
@url = nil
|
55
|
+
@fetched = false
|
56
|
+
@data = nil
|
57
|
+
@vars = [:title, :message, :date, :user_is_sender, :is_unread, :user, :url, :couch_request]
|
58
|
+
#attr_accessor *@vars
|
59
|
+
|
60
|
+
def initialize(url)
|
61
|
+
@url = url
|
62
|
+
@fetched = false
|
63
|
+
end
|
64
|
+
|
65
|
+
def fetch
|
66
|
+
req = HTTP.get(@url)
|
67
|
+
@data = JSON.parse req.body
|
68
|
+
end
|
69
|
+
|
70
|
+
def to_h
|
71
|
+
fetch unless @fetched
|
72
|
+
@data
|
73
|
+
end
|
74
|
+
|
75
|
+
def date
|
76
|
+
fetch unless @fetched
|
77
|
+
Date.parse(@date)
|
78
|
+
end
|
79
|
+
|
80
|
+
def unread?
|
81
|
+
fetch unless @fetched
|
82
|
+
@is_unread
|
83
|
+
end
|
84
|
+
|
85
|
+
def is_sender?
|
86
|
+
fetch unless @fetched
|
87
|
+
@user_is_sender
|
88
|
+
end
|
89
|
+
|
90
|
+
def method_missing meth
|
91
|
+
if vars.include? meth
|
92
|
+
fetch unless @fetched
|
93
|
+
@data[meth.to_s]
|
94
|
+
else
|
95
|
+
raise ArgumentError.new
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
end
|
100
|
+
|
101
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
module CS
|
2
|
+
|
3
|
+
class Request
|
4
|
+
@api = nil
|
5
|
+
|
6
|
+
attr_accessor :subject, :number, :arrival_flexible, :departure_flexible, :is_open_couchrequest, :from, :to, :arrival, :departure, :message
|
7
|
+
|
8
|
+
@options = [:subject, :number, :arrival_flexible, :departure_flexible, :is_open_couchrequest, :from, :to, :arrival, :departure, :message]
|
9
|
+
|
10
|
+
@defaults = {
|
11
|
+
subject: "A ruby programmer wants to surf your couch!",
|
12
|
+
number: 1,
|
13
|
+
arrival_flexible: false,
|
14
|
+
departure_flexible: false,
|
15
|
+
is_open_couchrequest: false,
|
16
|
+
from: nil,
|
17
|
+
to: nil,
|
18
|
+
arrival: Time.now,
|
19
|
+
departure: (Time.now+3600),
|
20
|
+
message: "I'm to lazy to write a proper couch request. HOST ME PLZ?"
|
21
|
+
}
|
22
|
+
|
23
|
+
|
24
|
+
def initialize options={}
|
25
|
+
options = @defaults.merge(options)
|
26
|
+
options.each do |k,v|
|
27
|
+
self.send "@#{k}=", val
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
def arrival= date
|
33
|
+
raise ArgumentError.new("This does not seem like a Time instance") unless date.is_a? Time
|
34
|
+
@arrival = date
|
35
|
+
end
|
36
|
+
|
37
|
+
|
38
|
+
def departure= date
|
39
|
+
raise ArgumentError.new("This does not seem like a Time instance") unless date.is_a? Time
|
40
|
+
@departure = date
|
41
|
+
end
|
42
|
+
|
43
|
+
|
44
|
+
def to_h
|
45
|
+
params = {}
|
46
|
+
@options.each {|key| params[key.to_sym] = instance_variable_get("@#{key}") }
|
47
|
+
params
|
48
|
+
end
|
49
|
+
|
50
|
+
|
51
|
+
def send!
|
52
|
+
raise CS::APIError('You have not authenticated with the service or did not provide a :username and :password') unless CS.instance
|
53
|
+
|
54
|
+
data = self.to_h
|
55
|
+
data[:arrival] = data[:arrival].strftime("%FT%TZ")
|
56
|
+
data[:departure] = data[:departure].strftime("%FT%TZ")
|
57
|
+
|
58
|
+
me = CS.instance.userdata['uid']
|
59
|
+
data[:from] ||= me
|
60
|
+
data[:to] ||= me
|
61
|
+
|
62
|
+
CS::HTTP.post('/couchrequests', body: data)
|
63
|
+
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
data/lib/csapi/search.rb
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
module CS
|
2
|
+
|
3
|
+
class CouchSearch
|
4
|
+
attr_accessor :results, :options
|
5
|
+
|
6
|
+
@results = nil
|
7
|
+
@@instance = nil
|
8
|
+
|
9
|
+
def self.instance
|
10
|
+
@@instance
|
11
|
+
end
|
12
|
+
|
13
|
+
def initialize options={}
|
14
|
+
defaults = {
|
15
|
+
location: nil,
|
16
|
+
gender: nil,
|
17
|
+
:'has-photo' => nil,
|
18
|
+
:'member-type' => 'host' ,
|
19
|
+
vouched: nil,
|
20
|
+
verified: nil,
|
21
|
+
network: nil,
|
22
|
+
:'min-age' => nil,
|
23
|
+
:'max-age' => nil,
|
24
|
+
:platform => 'android'
|
25
|
+
}
|
26
|
+
|
27
|
+
@options = options.merge(defaults)
|
28
|
+
@@instance = self
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
|
33
|
+
def execute
|
34
|
+
html = HTTP.get('/msearch', :query => @options)
|
35
|
+
doc = Nokogiri::HTML(html);
|
36
|
+
users = {}
|
37
|
+
statuses = {
|
38
|
+
'M' => 'maybe',
|
39
|
+
'T' => 'travelling',
|
40
|
+
'Y' => 'available',
|
41
|
+
'N' => 'unavailable'
|
42
|
+
}
|
43
|
+
doc.xpath('//article').each do |article|
|
44
|
+
id = article.at_css('a').attr('href').split('/').last
|
45
|
+
user = {
|
46
|
+
string_id: article.attr('rel'),
|
47
|
+
name: article.children.at_css("h2").content,
|
48
|
+
location: article.children.at_css("div.location").content,
|
49
|
+
status: statuses[article['class'].match(/couch-([A-Z])/)[1]],
|
50
|
+
pic: article.at_css('img').attr('src')
|
51
|
+
}
|
52
|
+
users[id] = user
|
53
|
+
end
|
54
|
+
|
55
|
+
@results = CS::SearchResults.new(users)
|
56
|
+
@results
|
57
|
+
end
|
58
|
+
|
59
|
+
|
60
|
+
def more
|
61
|
+
@options[:page] = (@options[:page]||0)+1
|
62
|
+
@options[:exclude_ids] = results.collect {|k, u| u[:string_id]}
|
63
|
+
results
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
|
68
|
+
class SearchResults
|
69
|
+
include Enumerable
|
70
|
+
attr_accessor :data
|
71
|
+
|
72
|
+
def initialize(data)
|
73
|
+
@data = data
|
74
|
+
end
|
75
|
+
|
76
|
+
def method_missing meth, *args, &block
|
77
|
+
@data.send(meth.to_sym, *args, &block)
|
78
|
+
end
|
79
|
+
|
80
|
+
def more
|
81
|
+
CS::CouchSearch.instance.more
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
85
|
+
end
|
data/lib/csapi/version.rb
CHANGED
data/readme.md
CHANGED
@@ -1,7 +1,11 @@
|
|
1
1
|
This is a simple CouchSurfing API
|
2
2
|
=================================
|
3
3
|
|
4
|
-
This
|
4
|
+
This a unofficial CS API client written in Ruby.
|
5
|
+
|
6
|
+
Using this client will likely result in a **violation of [Couchsurfing's TOS](https://www.couchsurfing.org/n/terms)**. I have contacted the [tech team](https://support.couchsurfing.org/hc/en-us/requests/new?category=support) as well as the [twitter](https://twitter.com/couchsurfing) folks to ask for permission of any sort to use the API, but I've yet to hear back from them.
|
7
|
+
|
8
|
+
The API was reverse-engineered, and if you'd like some pointers on that, please read [unRob/CouchSurfing-API#2](https://github.com/unRob/CouchSurfing-API/pull/2#issuecomment-16404056).
|
5
9
|
|
6
10
|
##Example
|
7
11
|
See [example.rb](https://github.com/unRob/CouchSurfing-API/blob/master/examples/example.rb)
|
@@ -53,4 +57,4 @@ as the name is changed.
|
|
53
57
|
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
54
58
|
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
55
59
|
|
56
|
-
0. You just DO WHAT THE FUCK YOU WANT TO.
|
60
|
+
0. You just DO WHAT THE FUCK YOU WANT TO.
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: CSApi
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Roberto Hidalgo
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2014-05-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: httparty
|
@@ -61,12 +61,17 @@ extensions: []
|
|
61
61
|
extra_rdoc_files: []
|
62
62
|
files:
|
63
63
|
- .gitignore
|
64
|
+
- CONTRIBUTORS
|
64
65
|
- Gemfile
|
65
|
-
- LICENSE
|
66
|
+
- LICENSE
|
66
67
|
- Rakefile
|
67
68
|
- csapi.gemspec
|
68
69
|
- examples/example.rb
|
69
70
|
- lib/csapi.rb
|
71
|
+
- lib/csapi/errors.rb
|
72
|
+
- lib/csapi/messages.rb
|
73
|
+
- lib/csapi/request.rb
|
74
|
+
- lib/csapi/search.rb
|
70
75
|
- lib/csapi/version.rb
|
71
76
|
- readme.md
|
72
77
|
homepage: https://github.com/unRob/CouchSurfing-API
|
@@ -90,8 +95,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
90
95
|
version: '0'
|
91
96
|
requirements: []
|
92
97
|
rubyforge_project:
|
93
|
-
rubygems_version: 2.
|
98
|
+
rubygems_version: 2.2.2
|
94
99
|
signing_key:
|
95
100
|
specification_version: 4
|
96
101
|
summary: I have no idea what is this
|
97
102
|
test_files: []
|
103
|
+
has_rdoc: false
|