CSApi 0.0.4 → 0.0.5
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 +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
|