wtforum 0.3.0 → 0.4.1
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 +7 -0
- data/.ruby-gemset +1 -0
- data/lib/wtforum.rb +125 -20
- data/lib/wtforum/session.rb +8 -18
- data/lib/wtforum/user.rb +16 -137
- data/lib/wtforum/version.rb +3 -4
- data/spec/fixtures/vcr_cassettes/WTForum_Session/when_user_doesn_t_exist/raises_an_exception.yml +67 -0
- data/spec/fixtures/vcr_cassettes/WTForum_Session/when_user_exists/can_log_in_users.yml +814 -0
- data/spec/fixtures/vcr_cassettes/WTForum_User/can_CRUD_users.yml +2965 -0
- data/spec/fixtures/vcr_cassettes/WTForum_User/raises_an_exception_when_a_user_is_not_found.yml +398 -0
- data/spec/integration/wtforum_session_spec.rb +14 -6
- data/spec/integration/wtforum_spec.rb +11 -0
- data/spec/integration/wtforum_user_spec.rb +13 -12
- data/spec/spec_helper.rb +18 -6
- data/wtforum.gemspec +2 -0
- metadata +73 -56
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 00474e1b12114c2ccf88d1ccc553c3f54cdc536d
|
4
|
+
data.tar.gz: f5efb1ed8f8c2213d5496d122970982a219f1bf9
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 0797211a73ee69f5784b3dfd5263f6cf76d76d2243d9ae247b1a0eea6ac1ed94afed767801978912ba5a5856379caab7c742d5e31fdee29991a8bc1345095b91
|
7
|
+
data.tar.gz: f0ecfb63998e32c27d0d5efb8b865926bf0e2a4bbc99feceb9381064e05dbad70a742639b88b57db86a5edda8bab072585e3984419f8c0bfd642f70d7366aa56
|
data/.ruby-gemset
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
wtforum
|
data/lib/wtforum.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
1
|
require "uri"
|
4
2
|
require "active_support/core_ext/object"
|
5
3
|
require "mechanize"
|
@@ -8,31 +6,138 @@ require "nokogiri"
|
|
8
6
|
require "wtforum/user"
|
9
7
|
require "wtforum/session"
|
10
8
|
|
11
|
-
|
9
|
+
class WTForum
|
12
10
|
class WTForumError < StandardError; end
|
13
11
|
|
14
|
-
|
15
|
-
|
12
|
+
def self.extract_value key, options
|
13
|
+
xml = Nokogiri::XML.parse(options[:from])
|
14
|
+
node = xml.css(key.to_s)
|
15
|
+
if node.present?
|
16
|
+
node.text
|
17
|
+
else
|
18
|
+
raise WTForumError, xml.css("errormessage, error, .errorMsg").text
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
attr_accessor :domain, :api_key, :admin_username, :admin_password
|
23
|
+
|
24
|
+
def initialize credentials
|
25
|
+
credentials.each do |key, value|
|
26
|
+
self.send :"#{key}=", value
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def create_session user_id
|
31
|
+
uri = base_api_uri(userid: user_id)
|
32
|
+
uri.path = "/register/setauthtoken"
|
33
|
+
response = agent.get uri
|
34
|
+
Session.create self, response
|
35
|
+
end
|
36
|
+
|
37
|
+
def create_user attributes
|
38
|
+
defaults = { pw: Digest::MD5.hexdigest(attributes.to_s) }
|
39
|
+
attributes[:member] ||= attributes.delete(:username)
|
40
|
+
attributes[:field276177] ||= attributes.delete(:gender)
|
41
|
+
attributes[:field276178] ||= attributes.delete(:location)
|
42
|
+
attributes[:field276179] ||= attributes.delete(:about)
|
43
|
+
attributes.reverse_merge! defaults
|
16
44
|
|
17
|
-
|
18
|
-
|
45
|
+
uri = base_api_uri(attributes)
|
46
|
+
uri.path = "/register/create_account"
|
47
|
+
response = agent.get uri
|
48
|
+
User.create self, response, attributes
|
49
|
+
end
|
50
|
+
|
51
|
+
def find_user user_id
|
52
|
+
response = authorized_agent.get uri(path: "/register/register", query: "edit=1&userid=#{user_id}")
|
53
|
+
raise User::NotFound if response.body.include?("Error: The specified account was not found")
|
54
|
+
|
55
|
+
body = Nokogiri::HTML.parse(response.body)
|
56
|
+
attributes = {
|
57
|
+
id: user_id,
|
58
|
+
member: body.css(".tables td:contains('Username:') + td input").first["value"],
|
59
|
+
email: body.css(".tables td:contains('Email Address:') + td").first.text.split(" - ").first,
|
60
|
+
name: body.css(".tables td:contains('Full Name:') + td input").first["value"],
|
61
|
+
field276177: body.css(".tables select[name='field276177'] option[selected]").first.try(:text).try(:strip),
|
62
|
+
field276178: body.css(".tables input[name='field276178']").first["value"],
|
63
|
+
field276179: body.css(".tables textarea[name='field276179']").first.text
|
64
|
+
}
|
65
|
+
User.new(self, attributes)
|
66
|
+
end
|
67
|
+
|
68
|
+
def find_user_by_username username
|
69
|
+
response = authorized_agent.get uri(path: "/register", query: "action=members&search=true&s_username=#{username}")
|
70
|
+
body = Nokogiri::HTML.parse(response.body)
|
71
|
+
|
72
|
+
# scrape markup: <a href="/profile/1234567" title="View profile">username\t\n</a>
|
73
|
+
# search returns partial matches :( so find the exact match.
|
74
|
+
# hopefully there aren't more than 50 matches!
|
75
|
+
link = body.css("a[title='View profile']:contains('#{username}')").find do |a|
|
76
|
+
a.text.strip == username
|
19
77
|
end
|
20
78
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
79
|
+
link or raise User::NotFound
|
80
|
+
|
81
|
+
id = link["href"].split("/").last
|
82
|
+
find_user(id)
|
83
|
+
end
|
84
|
+
|
85
|
+
def edit_user user_id
|
86
|
+
response = authorized_agent.get uri(path: "/register/register", query: "edit=1&userid=#{user_id}")
|
87
|
+
end
|
88
|
+
|
89
|
+
def edit_user_username user_id
|
90
|
+
authorized_agent.get uri(path: "/register/edit_username", query: "userid=#{user_id}")
|
91
|
+
end
|
92
|
+
|
93
|
+
def edit_user_email user_id
|
94
|
+
authorized_agent.get uri(path: "/register/edit_password", query: "userid=#{user_id}")
|
95
|
+
end
|
96
|
+
|
97
|
+
def count_users
|
98
|
+
response = agent.get uri(path: "/register/members")
|
99
|
+
count = response.body.match(/Members\s+\(([\d,]+)\)/m)[1]
|
100
|
+
count.gsub(",", "").to_i
|
101
|
+
end
|
102
|
+
|
103
|
+
def destroy_user user_id
|
104
|
+
authorized_agent.get uri(path: "/register/delete", query: "mem_userid=#{user_id}")
|
105
|
+
end
|
106
|
+
|
107
|
+
private
|
108
|
+
|
109
|
+
def authorized_agent
|
110
|
+
@authorized_agent ||= begin
|
111
|
+
a = agent
|
112
|
+
a.get(login_uri)
|
113
|
+
a
|
26
114
|
end
|
115
|
+
end
|
116
|
+
|
117
|
+
def agent
|
118
|
+
Mechanize.new
|
119
|
+
end
|
120
|
+
|
121
|
+
def base_uri
|
122
|
+
URI("http://#{domain}")
|
123
|
+
end
|
27
124
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
125
|
+
def base_api_uri attributes={}
|
126
|
+
attributes[:apikey] = api_key
|
127
|
+
uri = base_uri
|
128
|
+
uri.query = attributes.to_param
|
129
|
+
uri
|
130
|
+
end
|
131
|
+
|
132
|
+
def login_uri
|
133
|
+
uri path: "/register/dologin", query: "member=#{admin_username}&pw=#{admin_password}&remember=checked"
|
134
|
+
end
|
135
|
+
|
136
|
+
def uri attributes
|
137
|
+
base_uri.tap do |uri|
|
138
|
+
uri.path = attributes[:path]
|
139
|
+
uri.query = attributes[:query]
|
36
140
|
end
|
37
141
|
end
|
38
142
|
end
|
143
|
+
|
data/lib/wtforum/session.rb
CHANGED
@@ -1,12 +1,8 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
module WTForum
|
1
|
+
class WTForum
|
4
2
|
class Session
|
5
|
-
def self.create
|
6
|
-
|
7
|
-
|
8
|
-
auth_token = WTForum.extract_value(:authtoken, from: page.body)
|
9
|
-
new(auth_token)
|
3
|
+
def self.create wtforum, response
|
4
|
+
auth_token = WTForum.extract_value(:authtoken, from: response.body)
|
5
|
+
new(wtforum, auth_token)
|
10
6
|
rescue WTForumError => e
|
11
7
|
if e.message == "Error: The specified user does not exist."
|
12
8
|
raise WTForum::User::NotFound
|
@@ -15,18 +11,12 @@ module WTForum
|
|
15
11
|
end
|
16
12
|
end
|
17
13
|
|
18
|
-
def initialize token
|
14
|
+
def initialize wtforum, token
|
15
|
+
@wtforum = wtforum
|
19
16
|
@token = token
|
20
17
|
end
|
21
18
|
|
22
|
-
attr_reader :token
|
23
|
-
|
24
|
-
private
|
25
|
-
|
26
|
-
def self.create_uri user_id
|
27
|
-
uri = WTForum.base_api_uri(userid: user_id)
|
28
|
-
uri.path = "/register/setauthtoken"
|
29
|
-
uri
|
30
|
-
end
|
19
|
+
attr_reader :wtforum, :token
|
31
20
|
end
|
32
21
|
end
|
22
|
+
|
data/lib/wtforum/user.rb
CHANGED
@@ -1,76 +1,24 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require "securerandom"
|
4
|
-
|
5
|
-
module WTForum
|
1
|
+
class WTForum
|
6
2
|
class User
|
7
3
|
class NotFound < StandardError; end
|
8
4
|
|
9
|
-
def self.create attributes
|
10
|
-
|
11
|
-
attributes[:member] ||= attributes.delete(:username)
|
12
|
-
attributes[:field276177] ||= attributes.delete(:gender)
|
13
|
-
attributes[:field276178] ||= attributes.delete(:location)
|
14
|
-
attributes[:field276179] ||= attributes.delete(:about)
|
15
|
-
attributes.reverse_merge! defaults
|
16
|
-
uri = create_uri attributes
|
17
|
-
|
18
|
-
page = agent.get(uri)
|
19
|
-
user_id = WTForum.extract_value(:userid, :from => page.body)
|
5
|
+
def self.create wtforum, response, attributes
|
6
|
+
user_id = WTForum.extract_value(:userid, from: response.body)
|
20
7
|
attributes[:id] = user_id.to_i
|
21
|
-
new(attributes)
|
22
|
-
end
|
23
|
-
|
24
|
-
def self.find user_id
|
25
|
-
page = authorized_agent.get(find_uri(user_id))
|
26
|
-
raise NotFound if page.body.include?("Error: The specified account was not found")
|
27
|
-
|
28
|
-
body = Nokogiri::HTML.parse(page.body)
|
29
|
-
attributes = {
|
30
|
-
id: user_id,
|
31
|
-
member: body.css(".tables td:contains('Username:') + td input").first["value"],
|
32
|
-
email: body.css(".tables td:contains('Email Address:') + td").first.text.split(" - ").first,
|
33
|
-
name: body.css(".tables td:contains('Full Name:') + td input").first["value"],
|
34
|
-
field276177: body.css(".tables select[name='field276177'] option[selected]").first.try(:text),
|
35
|
-
field276178: body.css(".tables input[name='field276178']").first["value"],
|
36
|
-
field276179: body.css(".tables textarea[name='field276179']").first.text
|
37
|
-
}
|
38
|
-
new(attributes)
|
39
|
-
end
|
40
|
-
|
41
|
-
def self.find_by_username username
|
42
|
-
page = authorized_agent.get(find_by_username_uri(username))
|
43
|
-
body = Nokogiri::HTML.parse(page.body)
|
44
|
-
|
45
|
-
# scrape markup: <a href="/profile/1234567" title="View profile">username\t\n</a>
|
46
|
-
# search returns partial matches :( so find the exact match.
|
47
|
-
# hopefully there aren't more than 50 matches!
|
48
|
-
link = body.css("a[title='View profile']:contains('#{username}')").find do |a|
|
49
|
-
a.text.strip == username
|
50
|
-
end
|
51
|
-
|
52
|
-
link or raise NotFound
|
53
|
-
|
54
|
-
id = link["href"].split("/").last
|
55
|
-
find id
|
8
|
+
new(wtforum, attributes)
|
56
9
|
end
|
57
10
|
|
58
|
-
def self.update user_id, attributes
|
59
|
-
|
11
|
+
def self.update wtforum, user_id, attributes
|
12
|
+
wtforum.find_user(user_id).update_attributes!(attributes)
|
60
13
|
end
|
61
14
|
|
62
|
-
def self.destroy user_id
|
63
|
-
|
15
|
+
def self.destroy wtforum, user_id
|
16
|
+
wtforum.destroy_user(user_id)
|
64
17
|
true
|
65
18
|
end
|
66
19
|
|
67
|
-
def
|
68
|
-
|
69
|
-
count = page.body.match(/Members \(([\d,]+)\)/)[1]
|
70
|
-
count.gsub(",", "").to_i
|
71
|
-
end
|
72
|
-
|
73
|
-
def initialize attributes
|
20
|
+
def initialize wtforum, attributes
|
21
|
+
self.wtforum = wtforum
|
74
22
|
self.attributes = attributes
|
75
23
|
end
|
76
24
|
|
@@ -80,7 +28,7 @@ module WTForum
|
|
80
28
|
end
|
81
29
|
|
82
30
|
def save!
|
83
|
-
|
31
|
+
wtforum.edit_user(id).tap do |page|
|
84
32
|
form = page.forms.first
|
85
33
|
form["name"] = name
|
86
34
|
form["field276177"] = field276177
|
@@ -88,12 +36,12 @@ module WTForum
|
|
88
36
|
form["field276179"] = field276179
|
89
37
|
form.submit
|
90
38
|
end
|
91
|
-
|
39
|
+
wtforum.edit_user_username(id).tap do |page|
|
92
40
|
form = page.forms.first
|
93
41
|
form["new_username"] = username
|
94
42
|
form.submit
|
95
43
|
end
|
96
|
-
|
44
|
+
wtforum.edit_user_email(id).tap do |page|
|
97
45
|
form = page.forms.first
|
98
46
|
form["email"] = email
|
99
47
|
form.submit
|
@@ -101,10 +49,10 @@ module WTForum
|
|
101
49
|
end
|
102
50
|
|
103
51
|
def destroy
|
104
|
-
self.class.destroy id
|
52
|
+
self.class.destroy self.wtforum, id
|
105
53
|
end
|
106
54
|
|
107
|
-
attr_accessor :id, :member, :email, :name, :field276177, :field276178, :field276179
|
55
|
+
attr_accessor :wtforum, :id, :member, :email, :name, :field276177, :field276178, :field276179
|
108
56
|
attr_writer :pw, :apikey
|
109
57
|
|
110
58
|
def username
|
@@ -146,75 +94,6 @@ module WTForum
|
|
146
94
|
send :"#{key}=", value
|
147
95
|
end
|
148
96
|
end
|
149
|
-
|
150
|
-
def self.agent
|
151
|
-
Mechanize.new
|
152
|
-
end
|
153
|
-
|
154
|
-
def self.authorized_agent
|
155
|
-
@authorized_agent ||= begin
|
156
|
-
a = agent
|
157
|
-
a.get(login_uri)
|
158
|
-
a
|
159
|
-
end
|
160
|
-
end
|
161
|
-
|
162
|
-
def self.login_uri
|
163
|
-
uri = WTForum.base_uri
|
164
|
-
uri.path = "/register/dologin"
|
165
|
-
uri.query = "member=#{WTForum.admin_username}&pw=#{WTForum.admin_password}&remember=checked"
|
166
|
-
uri
|
167
|
-
end
|
168
|
-
|
169
|
-
def self.create_uri attributes
|
170
|
-
uri = WTForum.base_api_uri(attributes)
|
171
|
-
uri.path = "/register/create_account"
|
172
|
-
uri
|
173
|
-
end
|
174
|
-
|
175
|
-
def self.find_uri user_id
|
176
|
-
uri = WTForum.base_uri
|
177
|
-
uri.path = "/register/register"
|
178
|
-
uri.query = "edit=1&userid=#{user_id}"
|
179
|
-
uri
|
180
|
-
end
|
181
|
-
|
182
|
-
def self.find_by_username_uri username
|
183
|
-
uri = WTForum.base_uri
|
184
|
-
uri.path = "/register"
|
185
|
-
uri.query = "action=members&search=true&s_username=#{username}"
|
186
|
-
uri
|
187
|
-
end
|
188
|
-
|
189
|
-
def self.edit_uri user_id
|
190
|
-
find_uri user_id
|
191
|
-
end
|
192
|
-
|
193
|
-
def self.edit_username_uri user_id
|
194
|
-
uri = WTForum.base_uri
|
195
|
-
uri.path = "/register/edit_username"
|
196
|
-
uri.query = "userid=#{user_id}"
|
197
|
-
uri
|
198
|
-
end
|
199
|
-
|
200
|
-
def self.edit_email_uri user_id
|
201
|
-
uri = WTForum.base_uri
|
202
|
-
uri.path = "/register/edit_password"
|
203
|
-
uri.query = "userid=#{user_id}"
|
204
|
-
uri
|
205
|
-
end
|
206
|
-
|
207
|
-
def self.count_uri
|
208
|
-
uri = WTForum.base_uri
|
209
|
-
uri.path = "/register/members"
|
210
|
-
uri
|
211
|
-
end
|
212
|
-
|
213
|
-
def self.destroy_uri user_id
|
214
|
-
uri = WTForum.base_uri
|
215
|
-
uri.path = "/register/delete"
|
216
|
-
uri.query = "mem_userid=#{user_id}"
|
217
|
-
uri
|
218
|
-
end
|
219
97
|
end
|
220
98
|
end
|
99
|
+
|
data/lib/wtforum/version.rb
CHANGED
data/spec/fixtures/vcr_cassettes/WTForum_Session/when_user_doesn_t_exist/raises_an_exception.yml
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
---
|
2
|
+
http_interactions:
|
3
|
+
- request:
|
4
|
+
method: get
|
5
|
+
uri: http://forums.complexityexplorer.org/register/setauthtoken?apikey=pteGzAPZyr4&userid=1
|
6
|
+
body:
|
7
|
+
encoding: US-ASCII
|
8
|
+
string: ''
|
9
|
+
headers:
|
10
|
+
Accept-Encoding:
|
11
|
+
- gzip,deflate,identity
|
12
|
+
Accept:
|
13
|
+
- '*/*'
|
14
|
+
User-Agent:
|
15
|
+
- Mechanize/2.5.1 Ruby/2.0.0p195 (http://github.com/tenderlove/mechanize/)
|
16
|
+
Accept-Charset:
|
17
|
+
- ISO-8859-1,utf-8;q=0.7,*;q=0.7
|
18
|
+
Accept-Language:
|
19
|
+
- en-us,en;q=0.5
|
20
|
+
Host:
|
21
|
+
- forums.complexityexplorer.org
|
22
|
+
Connection:
|
23
|
+
- keep-alive
|
24
|
+
Keep-Alive:
|
25
|
+
- 300
|
26
|
+
response:
|
27
|
+
status:
|
28
|
+
code: 200
|
29
|
+
message: OK
|
30
|
+
headers:
|
31
|
+
Cache-Control:
|
32
|
+
- no-cache, no-store, must-revalidate
|
33
|
+
Content-Encoding:
|
34
|
+
- gzip
|
35
|
+
Content-Type:
|
36
|
+
- text/xml
|
37
|
+
Date:
|
38
|
+
- Wed, 04 Sep 2013 18:33:52 GMT
|
39
|
+
Expires:
|
40
|
+
- Nov, 8 1991 00:00:01 GMT
|
41
|
+
P3p:
|
42
|
+
- CP='NOI DSP COR NID CURa TAIi OUR BUS INT PRE'; policyref='http://forums.complexityexplorer.org/w3c/p3p.xml';
|
43
|
+
Pragma:
|
44
|
+
- no-cache
|
45
|
+
Server:
|
46
|
+
- nginx/1.0.10
|
47
|
+
Set-Cookie:
|
48
|
+
- hascookies=1; path=/; domain=.forums.complexityexplorer.org;
|
49
|
+
- lastvisit=1378319632; path=/; domain=.forums.complexityexplorer.org; expires=Wed,
|
50
|
+
25-Aug-2020 00:00:00 GMT;
|
51
|
+
- newvisit=1378319632; path=/; domain=.forums.complexityexplorer.org; expires=Wed,
|
52
|
+
25-Aug-2020 00:00:00 GMT;
|
53
|
+
Vary:
|
54
|
+
- Accept-Encoding
|
55
|
+
Content-Length:
|
56
|
+
- '123'
|
57
|
+
Connection:
|
58
|
+
- keep-alive
|
59
|
+
body:
|
60
|
+
encoding: ASCII-8BIT
|
61
|
+
string: !binary |-
|
62
|
+
H4sIAAAAAAAAA1XMQQ6CQAxG4as0sxd0Z0gZVnoCPABhfrGJtKRFwvENGxOX
|
63
|
+
b/E97vb5TRs8xLRNl+qcCDpaEZ3a9Ojvp2vqMjtiMQ1khrv5jIhhQr4d0VD/
|
64
|
+
AsWCUZ6CQp+AUzEEqa2EXWKtuP5zXP+GX3LWZ2qBAAAA
|
65
|
+
http_version:
|
66
|
+
recorded_at: Wed, 04 Sep 2013 18:33:52 GMT
|
67
|
+
recorded_with: VCR 2.5.0
|