etherpad-lite 0.0.4 → 0.1.0.rc2
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +8 -0
- data/README.rdoc +54 -28
- data/lib/etherpad-lite/client.rb +152 -51
- data/lib/etherpad-lite/models/author.rb +52 -5
- data/lib/etherpad-lite/models/group.rb +56 -7
- data/lib/etherpad-lite/models/instance.rb +24 -31
- data/lib/etherpad-lite/models/pad.rb +39 -7
- data/lib/etherpad-lite/models/padded.rb +7 -2
- data/lib/etherpad-lite/models/session.rb +12 -2
- data/spec/author_spec.rb +1 -1
- data/spec/config.yml +4 -9
- data/spec/config.yml.example +4 -9
- data/spec/group_spec.rb +30 -4
- data/spec/instance_spec.rb +12 -2
- data/spec/pad_spec.rb +12 -1
- data/spec/session_spec.rb +1 -1
- data/spec/spec_helper.rb +4 -8
- metadata +28 -46
data/CHANGELOG
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
** RELEASE 0.1.0 (Pending) **
|
2
|
+
|
3
|
+
* Requires Etherpad Lite 1.1+
|
4
|
+
* Added support for get/setHTML
|
5
|
+
* Uses POST for API calls which alter data - this allows much larger pad content to be written
|
6
|
+
* Various minor improvements and bugfixes
|
7
|
+
* More complete documentation and examples
|
8
|
+
|
1
9
|
** RELEASE 0.0.4 (09/12/2011) **
|
2
10
|
|
3
11
|
* Bugfix to Pads. A Pad initialied with a specific revision was not returning that revision's text.
|
data/README.rdoc
CHANGED
@@ -1,13 +1,15 @@
|
|
1
1
|
= Etherpad Lite Ruby Client
|
2
2
|
|
3
|
-
etherpad-lite is a Ruby client for Etherpad Lite's HTTP JSON API. Etherpad Lite is a collaborative editor provided by the Etherpad Foundation
|
3
|
+
The etherpad-lite Ruby Gem is a Ruby client for Etherpad Lite's HTTP JSON API. Etherpad Lite is a collaborative editor provided by the {Etherpad Foundation}[http://etherpad.org].
|
4
4
|
|
5
|
-
See https://github.com/Pita/etherpad-lite for information on how to install and configure your own Etherpad Lite instance, and read https://github.com/Pita/etherpad-lite/wiki/HTTP-API for an in-depth description of Etherpad Lite's HTTP API.
|
5
|
+
See {github.com/Pita/etherpad-lite}[https://github.com/Pita/etherpad-lite] for information on how to install and configure your own Etherpad Lite instance, and read {github.com/Pita/etherpad-lite/wiki/HTTP-API}[https://github.com/Pita/etherpad-lite/wiki/HTTP-API] for an in-depth description of Etherpad Lite's HTTP API.
|
6
6
|
|
7
|
-
==
|
7
|
+
== Installation
|
8
8
|
gem install etherpad-lite
|
9
9
|
|
10
|
-
|
10
|
+
*NOTE* Support for Ruby 1.8.x is deprecated and will be removed in future versions. Upgrade to Ruby 1.9.x and stop being an old fuddie-duddie. It's the IE6 of Ruby.
|
11
|
+
|
12
|
+
== Basic usage
|
11
13
|
require 'etherpad-lite'
|
12
14
|
|
13
15
|
# Connect to your Etherpad Lite instance
|
@@ -23,19 +25,24 @@ See https://github.com/Pita/etherpad-lite for information on how to install and
|
|
23
25
|
pad.text = "What hath God wrought?"
|
24
26
|
|
25
27
|
# There are now 2 revisions!
|
26
|
-
puts pad.
|
27
|
-
=>
|
28
|
+
puts pad.revision_numbers
|
29
|
+
=> [0, 1]
|
28
30
|
|
29
31
|
# Iterate through each revision
|
30
32
|
pad.revisions.each do |pad_rev|
|
31
|
-
puts pad_rev.rev
|
33
|
+
puts "Revision #{pad_rev.rev}:"
|
32
34
|
puts pad_rev.text
|
33
35
|
end
|
34
36
|
|
35
|
-
|
37
|
+
Full docs are at {jordanhollinger.com/docs/ruby-etherpad-lite/}[http://jordanhollinger.com/docs/ruby-etherpad-lite/]
|
38
|
+
|
39
|
+
== Advanced usage
|
40
|
+
The above example deals with public pads, accessible to anyone through the Web UI. There is another class of pads - group pads - which deal with groups, authors and sessions.
|
41
|
+
Examples are documented in EtherpadLite::Group, EtherpadLite::Author, and EtherpadLite::Session.
|
36
42
|
|
37
|
-
==
|
38
|
-
For your view, I recommend the jQuery plugin at https://github.com/johnyma22/etherpad-lite-jquery-plugin.
|
43
|
+
== Example use in Rails
|
44
|
+
For your view, I recommend the jQuery plugin at {github.com/johnyma22/etherpad-lite-jquery-plugin}[https://github.com/johnyma22/etherpad-lite-jquery-plugin].
|
45
|
+
Also, I recommend reading the docs for EtherpadLite::Group first.
|
39
46
|
|
40
47
|
Add the following to your Gemfile
|
41
48
|
gem 'etherpad-lite'
|
@@ -46,27 +53,28 @@ On login, create a Hash in your session to store EtherpadLite API sessions:
|
|
46
53
|
Some example controller actions:
|
47
54
|
|
48
55
|
class EtherpadController < ApplicationController
|
56
|
+
# /etherpad
|
49
57
|
def index
|
50
58
|
# The idea is that your users are probably members of some kind of groups.
|
51
59
|
# These groups can be mapped to EtherpadLite Groups. List all the user's groups.
|
52
60
|
@app_groups = current_user.groups
|
53
61
|
end
|
54
62
|
|
63
|
+
# /etherpad/groups/:id
|
55
64
|
def group
|
56
|
-
ether = EtherpadLite.connect(:local, '
|
65
|
+
ether = EtherpadLite.connect(:local, File.new('/var/www/etherpad-lite/APIKEY.txt'))
|
57
66
|
@app_group = YourAppGroup.find(params[:id])
|
58
|
-
# Map your app's group to an EtherpadLite Group
|
67
|
+
# Map your app's group to an EtherpadLite Group, and list all its pads
|
59
68
|
group = ether.group("my_app_group_#{@app_group.id}")
|
60
|
-
# List all the pads in group
|
61
69
|
@pads = group.pads
|
62
70
|
end
|
63
71
|
|
72
|
+
# /etherpad/pads/:ep_group_id/:ep_pad_name
|
64
73
|
def pad
|
65
|
-
ether = EtherpadLite.connect(:local, '
|
66
|
-
# Get the EtherpadLite Group by id
|
67
|
-
@group = ether.get_group(params[:
|
68
|
-
|
69
|
-
@pad = @group.pad(params[:pad_name])
|
74
|
+
ether = EtherpadLite.connect(:local, File.new('/var/www/etherpad-lite/APIKEY.txt'))
|
75
|
+
# Get the EtherpadLite Group and Pad by id
|
76
|
+
@group = ether.get_group(params[:ep_group_id])
|
77
|
+
@pad = @group.pad(params[:ep_pad_name])
|
70
78
|
# Map the user to an EtherpadLite Author
|
71
79
|
author = ether.author("my_app_user_#{current_user.id}", :name => current_user.name)
|
72
80
|
# Get or create an hour-long session for this Author in this Group
|
@@ -81,24 +89,42 @@ Some example controller actions:
|
|
81
89
|
end
|
82
90
|
end
|
83
91
|
|
84
|
-
==
|
85
|
-
|
86
|
-
with the goal of making
|
87
|
-
|
92
|
+
== Why is the Ruby client so different from the others? What gives you the right?!?
|
93
|
+
Most of the EPL clients are extremely thin wrappers around the HTTP API. The Ruby client offers a slightly higher level of abstraction,
|
94
|
+
with the goal of making it as simple, powerful, and dare I say fun, as possible. That said, there are times when a bare-bones client may be
|
95
|
+
preferable. In a hopefully not misguided attempt to please everyone, the Ruby client is written in two layers:
|
96
|
+
- A high-level "models" interface starting with EtherpadLite::Instance (above)
|
97
|
+
- A low-level client matching the HTTP API (EtherpadLite::Client, below)
|
88
98
|
|
89
|
-
In the examples above, the
|
99
|
+
In the examples above, the low-level client is accessible from the high-level interface:
|
90
100
|
client = ether.client
|
91
101
|
client.getText('my first etherpad lite pad')
|
92
102
|
=> {:text => "What hath God wrought?"}
|
93
103
|
|
94
|
-
|
104
|
+
or you can explicitly load just the low-level client:
|
95
105
|
require 'etherpad-lite/client'
|
96
|
-
client = EtherpadLite::Client.new('
|
106
|
+
client = EtherpadLite::Client.new('http://beta.etherpad.org/api', 'api key')
|
107
|
+
|
108
|
+
The methods available to the low-level client should precisely match the HTTP API. In general, it behaves identically to the other
|
109
|
+
clients, particularly PHP's and Python's.
|
110
|
+
|
111
|
+
== Testing
|
112
|
+
Testing this library is fairly simple. It requires:
|
113
|
+
- A recent version of Rspec
|
114
|
+
- A running copy of Etherpad Lite with a fresh db for each run of the tests (configure connection in spec/config.yml)
|
115
|
+
|
116
|
+
Bring up Etherpad Lite with:
|
117
|
+
|
118
|
+
rm var/dirty.db && bin/run.sh
|
119
|
+
|
120
|
+
Run the tests with
|
121
|
+
|
122
|
+
rspec spec
|
97
123
|
|
98
|
-
==
|
124
|
+
== License
|
99
125
|
Copyright 2011 Jordan Hollinger
|
100
126
|
|
101
127
|
Licensed under the Apache License
|
102
128
|
|
103
|
-
==
|
104
|
-
This Ruby client was inspired by TomNomNom's
|
129
|
+
== Credit
|
130
|
+
This Ruby client was inspired by {TomNomNom's PHP client}[https://github.com/TomNomNom/etherpad-lite-client] and {devjones's Python client}[https://github.com/devjones/PyEtherpadLite].
|
data/lib/etherpad-lite/client.rb
CHANGED
@@ -3,46 +3,94 @@ require 'net/http'
|
|
3
3
|
require 'net/https'
|
4
4
|
require 'json'
|
5
5
|
|
6
|
+
# Ruby 1.8.x may not work, and I don't care
|
7
|
+
BAD_RUBY = RUBY_VERSION < '1.9.0' # :nodoc:
|
8
|
+
|
6
9
|
module EtherpadLite
|
10
|
+
MAJOR_VERSION, MINOR_VERSION, TINY_VERSION, PRE_VERSION = 0, 1, 0, 'rc2' # :nodoc:
|
11
|
+
# The client version
|
12
|
+
VERSION = [MAJOR_VERSION, MINOR_VERSION, TINY_VERSION, PRE_VERSION].compact.join '.'
|
13
|
+
|
14
|
+
# An error returned by the server
|
15
|
+
class APIError < StandardError
|
16
|
+
MESSAGE = "Error while talking to the API (%s). Make sure you are running the latest version of the Etherpad Lite server. If that is not possible, try rolling this client back to an earlier version."
|
17
|
+
end
|
18
|
+
|
7
19
|
# A thin wrapper around Etherpad Lite's HTTP JSON API
|
20
|
+
#
|
21
|
+
# client1 = EtherpadLite::Client.new('https://etherpad.yoursite.com[https://etherpad.yoursite.com]', 'your api key')
|
22
|
+
#
|
23
|
+
# # An alias for http://localhost:9001
|
24
|
+
# client2 = EtherpadLite::Client.new(:local, File.new('/path/to/APIKEY.txt'))
|
25
|
+
#
|
26
|
+
# # An alias for http://localhost:9001
|
27
|
+
# ether = EtherpadLite::Client.new(9001, File.new('/path/to/APIKEY.txt'))
|
8
28
|
class Client
|
29
|
+
# Aliases to common Etherpad Lite hosts
|
30
|
+
HOST_ALIASES = {:local => 'http://localhost:9001',
|
31
|
+
:localhost => 'http://localhost:9001'}
|
32
|
+
|
33
|
+
# The Etherpad Lite HTTP API version this library version targets
|
9
34
|
API_VERSION = 1
|
10
35
|
|
36
|
+
# HTTP API response code for okay
|
11
37
|
CODE_OK = 0
|
38
|
+
# HTTP API response code for invalid method parameters
|
12
39
|
CODE_INVALID_PARAMETERS = 1
|
40
|
+
# HTTP API response code for Etherpad Lite error
|
13
41
|
CODE_INTERNAL_ERROR = 2
|
42
|
+
# HTTP API response code for invalid api method
|
14
43
|
CODE_INVALID_METHOD = 3
|
44
|
+
# HTTP API response code for invalid api key
|
15
45
|
CODE_INVALID_API_KEY = 4
|
16
46
|
|
17
|
-
|
47
|
+
# A URI object containing the URL of the Etherpad Lite instance
|
48
|
+
attr_reader :uri
|
49
|
+
# The API key
|
50
|
+
attr_reader :api_key
|
18
51
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
def self.ca_path; @@ca_path; end
|
24
|
-
|
25
|
-
# Manually set path to the system's CA certs. Use this if the location couldn't be determined automatically.
|
26
|
-
def self.ca_path=(path); @@ca_path = path; end
|
52
|
+
class << self
|
53
|
+
# Path to the system's CA certs (for connecting over SSL)
|
54
|
+
attr_accessor :ca_path
|
55
|
+
end
|
27
56
|
|
28
|
-
# Instantiate a new Etherpad Lite Client.
|
29
|
-
|
57
|
+
# Instantiate a new Etherpad Lite Client.
|
58
|
+
#
|
59
|
+
# client1 = EtherpadLite::Client.new('https://etherpad.yoursite.com[https://etherpad.yoursite.com]', 'your api key')
|
60
|
+
#
|
61
|
+
# # An alias for http://localhost:9001
|
62
|
+
# client2 = EtherpadLite::Client.new(:local, File.new('/path/to/APIKEY.txt'))
|
63
|
+
#
|
64
|
+
# # An alias for http://localhost:9001
|
65
|
+
# client3 = EtherpadLite::Client.new(9001, File.new('/path/to/APIKEY.txt'))
|
66
|
+
def initialize(host_or_alias, api_key_or_file)
|
67
|
+
# Parse the host
|
68
|
+
url = if host_or_alias.is_a? Symbol
|
69
|
+
raise ArgumentError, %Q|Unknown host alias "#{host_or_alias}"| unless HOST_ALIASES.has_key? host_or_alias
|
70
|
+
HOST_ALIASES[host_or_alias]
|
71
|
+
elsif host_or_alias.is_a? Fixnum
|
72
|
+
"http://localhost:#{host_or_alias}"
|
73
|
+
else
|
74
|
+
host_or_alias.clone
|
75
|
+
end
|
76
|
+
url << '/api' unless url =~ /\/api$/i
|
30
77
|
@uri = URI.parse(url)
|
31
|
-
raise ArgumentError, "#{url}
|
32
|
-
|
33
|
-
|
34
|
-
|
78
|
+
raise ArgumentError, "#{url} does not contain a valid host and port" unless @uri.host and @uri.port
|
79
|
+
|
80
|
+
# Parse the api key
|
81
|
+
if api_key_or_file.is_a? File
|
82
|
+
@api_key = begin
|
83
|
+
api_key_or_file.read
|
84
|
+
rescue IOError
|
85
|
+
api_key_or_file.reopen(api_key_or_file.path, mode='r')
|
86
|
+
api_key_or_file.read
|
87
|
+
end
|
88
|
+
api_key_or_file.close
|
89
|
+
else
|
90
|
+
@api_key = api_key_or_file
|
91
|
+
end
|
35
92
|
|
36
|
-
|
37
|
-
def call(method, params={})
|
38
|
-
# Build path
|
39
|
-
params[:apikey] = @api_key
|
40
|
-
params = params.map { |p| p.join('=') }.join('&').gsub(/\s/, '%20')
|
41
|
-
path = [@uri.path, API_VERSION, method].compact.join('/') << '?' << params
|
42
|
-
# Send request
|
43
|
-
get = Net::HTTP::Get.new(path)
|
44
|
-
response = @http.request(get)
|
45
|
-
handleResult response.body
|
93
|
+
connect!
|
46
94
|
end
|
47
95
|
|
48
96
|
# Groups
|
@@ -50,29 +98,29 @@ module EtherpadLite
|
|
50
98
|
|
51
99
|
# Creates a new Group
|
52
100
|
def createGroup
|
53
|
-
|
101
|
+
post :createGroup
|
54
102
|
end
|
55
103
|
|
56
104
|
# Creates a new Group for groupMapper if one doesn't already exist. Helps you map your application's groups to Etherpad Lite's groups.
|
57
105
|
def createGroupIfNotExistsFor(groupMapper)
|
58
|
-
|
106
|
+
post :createGroupIfNotExistsFor, :groupMapper => groupMapper
|
59
107
|
end
|
60
108
|
|
61
109
|
# Deletes a group
|
62
110
|
def deleteGroup(groupID)
|
63
|
-
|
111
|
+
post :deleteGroup, :groupID => groupID
|
64
112
|
end
|
65
113
|
|
66
114
|
# Returns all the Pads in the given Group
|
67
115
|
def listPads(groupID)
|
68
|
-
|
116
|
+
get :listPads, :groupID => groupID
|
69
117
|
end
|
70
118
|
|
71
119
|
# Creates a new Pad in the given Group
|
72
120
|
def createGroupPad(groupID, padName, text=nil)
|
73
121
|
params = {:groupID => groupID, :padName => padName}
|
74
122
|
params[:text] = text unless text.nil?
|
75
|
-
|
123
|
+
post :createGroupPad, params
|
76
124
|
end
|
77
125
|
|
78
126
|
# Authors
|
@@ -82,14 +130,14 @@ module EtherpadLite
|
|
82
130
|
def createAuthor(name=nil)
|
83
131
|
params = {}
|
84
132
|
params[:name] = name unless name.nil?
|
85
|
-
|
133
|
+
post :createAuthor, params
|
86
134
|
end
|
87
135
|
|
88
136
|
# Creates a new Author for authorMapper if one doesn't already exist. Helps you map your application's authors to Etherpad Lite's authors.
|
89
137
|
def createAuthorIfNotExistsFor(authorMapper, name=nil)
|
90
138
|
params = {:authorMapper => authorMapper}
|
91
139
|
params[:name] = name unless name.nil?
|
92
|
-
|
140
|
+
post :createAuthorIfNotExistsFor, params
|
93
141
|
end
|
94
142
|
|
95
143
|
# Sessions
|
@@ -99,27 +147,27 @@ module EtherpadLite
|
|
99
147
|
|
100
148
|
# Creates a new Session for the given Author in the given Group
|
101
149
|
def createSession(groupID, authorID, validUntil)
|
102
|
-
|
150
|
+
post :createSession, :groupID => groupID, :authorID => authorID, :validUntil => validUntil
|
103
151
|
end
|
104
152
|
|
105
153
|
# Deletes the given Session
|
106
154
|
def deleteSession(sessionID)
|
107
|
-
|
155
|
+
post :deleteSession, :sessionID => sessionID
|
108
156
|
end
|
109
157
|
|
110
158
|
# Returns information about the Session
|
111
159
|
def getSessionInfo(sessionID)
|
112
|
-
|
160
|
+
get :getSessionInfo, :sessionID => sessionID
|
113
161
|
end
|
114
162
|
|
115
163
|
# Returns all Sessions in the given Group
|
116
164
|
def listSessionsOfGroup(groupID)
|
117
|
-
|
165
|
+
get :listSessionsOfGroup, :groupID => groupID
|
118
166
|
end
|
119
167
|
|
120
168
|
# Returns all Sessions belonging to the given Author
|
121
169
|
def listSessionsOfAuthor(authorID)
|
122
|
-
|
170
|
+
get :listSessionsOfAuthor, :authorID => authorID
|
123
171
|
end
|
124
172
|
|
125
173
|
# Pad content
|
@@ -129,12 +177,24 @@ module EtherpadLite
|
|
129
177
|
def getText(padID, rev=nil)
|
130
178
|
params = {:padID => padID}
|
131
179
|
params[:rev] = rev unless rev.nil?
|
132
|
-
|
180
|
+
get :getText, params
|
133
181
|
end
|
134
182
|
|
135
183
|
# Sets the text of the given Pad
|
136
184
|
def setText(padID, text)
|
137
|
-
|
185
|
+
post :setText, :padID => padID, :text => text
|
186
|
+
end
|
187
|
+
|
188
|
+
# Returns the text of the given Pad as HTML. Optionally pass a revision number to get the HTML for that revision.
|
189
|
+
def getHTML(padID, rev=nil)
|
190
|
+
params = {:padID => padID}
|
191
|
+
params[:rev] = rev unless rev.nil?
|
192
|
+
get :getHTML, params
|
193
|
+
end
|
194
|
+
|
195
|
+
# Sets the HTML text of the given Pad
|
196
|
+
def setHTML(padID, html)
|
197
|
+
post :setHTML, :padID => padID, :html => html
|
138
198
|
end
|
139
199
|
|
140
200
|
# Pad
|
@@ -146,42 +206,42 @@ module EtherpadLite
|
|
146
206
|
def createPad(padID, text=nil)
|
147
207
|
params = {:padID => padID}
|
148
208
|
params[:text] = text unless text.nil?
|
149
|
-
|
209
|
+
post :createPad, params
|
150
210
|
end
|
151
211
|
|
152
212
|
# Returns the number of revisions the given Pad contains
|
153
213
|
def getRevisionsCount(padID)
|
154
|
-
|
214
|
+
get :getRevisionsCount, :padID => padID
|
155
215
|
end
|
156
216
|
|
157
217
|
# Delete the given Pad
|
158
218
|
def deletePad(padID)
|
159
|
-
|
219
|
+
post :deletePad, :padID => padID
|
160
220
|
end
|
161
221
|
|
162
222
|
# Returns the Pad's read-only id
|
163
223
|
def getReadOnlyID(padID)
|
164
|
-
|
224
|
+
get :getReadOnlyID, :padID => padID
|
165
225
|
end
|
166
226
|
|
167
227
|
# Sets a boolean for the public status of a Pad
|
168
228
|
def setPublicStatus(padID, publicStatus)
|
169
|
-
|
229
|
+
post :setPublicStatus, :padID => padID, :publicStatus => publicStatus
|
170
230
|
end
|
171
231
|
|
172
232
|
# Gets a boolean for the public status of a Pad
|
173
233
|
def getPublicStatus(padID)
|
174
|
-
|
234
|
+
get :getPublicStatus, :padID => padID
|
175
235
|
end
|
176
236
|
|
177
237
|
# Sets the password on a pad
|
178
238
|
def setPassword(padID, password)
|
179
|
-
|
239
|
+
post :setPassword, :padID => padID, :password => password
|
180
240
|
end
|
181
241
|
|
182
242
|
# Returns true if the Pad has a password, false if not
|
183
243
|
def isPasswordProtected(padID)
|
184
|
-
|
244
|
+
get :isPasswordProtected, :padID => padID
|
185
245
|
end
|
186
246
|
|
187
247
|
# Returns true if the connection to the Etherpad Lite instance is using SSL/HTTPS.
|
@@ -191,16 +251,54 @@ module EtherpadLite
|
|
191
251
|
|
192
252
|
protected
|
193
253
|
|
254
|
+
# Alias to "call" using the GET HTTP method
|
255
|
+
def get(method, params={})
|
256
|
+
call method, params, :get
|
257
|
+
end
|
258
|
+
|
259
|
+
# Alias to "call" using the POST HTTP method
|
260
|
+
def post(method, params={})
|
261
|
+
call method, params, :post
|
262
|
+
end
|
263
|
+
|
264
|
+
# Calls the EtherpadLite API and returns the :data portion of the response Hash.
|
265
|
+
#
|
266
|
+
# "method" should be a valid API method name, as a String or Symbol.
|
267
|
+
#
|
268
|
+
# "params" should be any URL or form parameters as a Hash.
|
269
|
+
#
|
270
|
+
# "http_method" should be :get or :post, defaults to :get.
|
271
|
+
#
|
272
|
+
def call(method, params={}, http_method=:get)
|
273
|
+
params[:apikey] = @api_key
|
274
|
+
uri = [@uri.path, API_VERSION, method].compact.join('/')
|
275
|
+
http_method = :post if BAD_RUBY # XXX A horrible, horrible hack for Ruby 1.8
|
276
|
+
req = case http_method
|
277
|
+
when :get then Net::HTTP::Get.new(uri << '?' << URI.encode_www_form(params))
|
278
|
+
when :post
|
279
|
+
post = Net::HTTP::Post.new(uri)
|
280
|
+
post.set_form_data(params)
|
281
|
+
post
|
282
|
+
else raise ArgumentError, "#{http_method} is not a valid HTTP method"
|
283
|
+
end
|
284
|
+
response = @http.request(req)
|
285
|
+
handleResult response.body
|
286
|
+
end
|
287
|
+
|
194
288
|
# Parses the JSON response from the server, returning the data object as a Hash with symbolized keys.
|
195
289
|
# If the API response contains an error code, an exception is raised.
|
196
290
|
def handleResult(response)
|
197
|
-
|
291
|
+
begin
|
292
|
+
response = JSON.parse(response, :symbolize_names => true)
|
293
|
+
rescue JSON::ParserError
|
294
|
+
raise APIError, APIError::MESSAGE % response
|
295
|
+
end
|
198
296
|
case response[:code]
|
199
297
|
when CODE_OK then response[:data]
|
200
298
|
when CODE_INVALID_PARAMETERS, CODE_INVALID_API_KEY, CODE_INVALID_METHOD
|
201
299
|
raise ArgumentError, response[:message]
|
202
300
|
else
|
203
|
-
raise
|
301
|
+
raise APIError, "An unknown error ocurrced while handling the response: #{response.to_s}"
|
204
302
|
end
|
205
303
|
end
|
206
304
|
|
@@ -211,9 +309,9 @@ module EtherpadLite
|
|
211
309
|
@http = Net::HTTP.new(@uri.host, @uri.port)
|
212
310
|
if secure?
|
213
311
|
@http.use_ssl = true
|
214
|
-
if
|
312
|
+
if self.class.ca_path
|
215
313
|
@http.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
216
|
-
@http.ca_path =
|
314
|
+
@http.ca_path = self.class.ca_path
|
217
315
|
else
|
218
316
|
@http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
219
317
|
end
|
@@ -227,3 +325,6 @@ end
|
|
227
325
|
EtherpadLite::Client.ca_path = path and break if File.exists? path
|
228
326
|
end
|
229
327
|
$stderr.puts %q|WARNING Ruby etherpad-lite client was unable to find your CA Certificates; HTTPS connections will *not* be verified! You may remedy this with "EtherpadLite::Client.ca_path = '/path/to/certs'"| unless EtherpadLite::Client.ca_path
|
328
|
+
|
329
|
+
# Warn about old Ruby versions
|
330
|
+
$stderr.puts "WARNING You are using an ancient version of Ruby which may not be supported. Upgrade Ruby!" if BAD_RUBY
|
@@ -1,7 +1,54 @@
|
|
1
1
|
module EtherpadLite
|
2
2
|
# An Author of Pad content
|
3
|
+
#
|
4
|
+
# Authors are used to create a Session in a Group. Authors may be created with
|
5
|
+
# a name and a mapper. A mapper is usually an identifier stored in your third-party system,
|
6
|
+
# like a foreign key or username.
|
7
|
+
#
|
8
|
+
# Author Examples:
|
9
|
+
#
|
10
|
+
# @ether = EtherpadLite.connect(:local, 'api key')
|
11
|
+
#
|
12
|
+
# # Create a new author with both a name and a mapper
|
13
|
+
# author1 = @ether.create_author(:name => 'Theodor Seuss Geisel', :mapper => 'author_1')
|
14
|
+
#
|
15
|
+
# # Load (and create, if necessary) a mapped author with a name
|
16
|
+
# author2 = @ether.author('author_2', :name => 'Richard Bachman')
|
17
|
+
#
|
18
|
+
# # Load (and create, if necessary) a author by mapper
|
19
|
+
# author3 = @ether.author('author_3')
|
20
|
+
#
|
21
|
+
# # Load author1 by id
|
22
|
+
# author4 = @ether.get_author(author1.id)
|
23
|
+
#
|
24
|
+
# Session examples:
|
25
|
+
#
|
26
|
+
# # Create two hour-long session for author 1 in two different groups
|
27
|
+
# group1 = @ether.group('my awesome group')
|
28
|
+
# group2 = @ether.group('my other awesome group')
|
29
|
+
#
|
30
|
+
# session1 = author1.create_session(group1, 60)
|
31
|
+
# session2 = author1.create_session(group2, 60)
|
32
|
+
#
|
33
|
+
# Attribute examples:
|
34
|
+
#
|
35
|
+
# author1.name #> "Theodor Seuss Geisel"
|
36
|
+
#
|
37
|
+
# author1.mapper #> "author_1"
|
38
|
+
#
|
39
|
+
# author2.sessions #> [#<EtherpadLite::Session>, #<EtherpadLite::Session>]
|
40
|
+
#
|
41
|
+
# author2.session_ids.include? session1.id #> true
|
42
|
+
#
|
3
43
|
class Author
|
4
|
-
|
44
|
+
# The EtherpadLite::Instance object
|
45
|
+
attr_reader :instance
|
46
|
+
# The author's id
|
47
|
+
attr_reader :id
|
48
|
+
# The author's name (if any)
|
49
|
+
attr_reader :name
|
50
|
+
# The author's foreign mapper (if any)
|
51
|
+
attr_reader :mapper
|
5
52
|
|
6
53
|
# Creates a new Author. Optionally, you may pass the :mapper option your third party system's author id.
|
7
54
|
# This will allow you to find the Author again later using the same identifier as your foreign system.
|
@@ -9,9 +56,9 @@ module EtherpadLite
|
|
9
56
|
#
|
10
57
|
# Options:
|
11
58
|
#
|
12
|
-
#
|
59
|
+
# mapper => uid of Author from another system
|
13
60
|
#
|
14
|
-
#
|
61
|
+
# name => Author's name
|
15
62
|
def self.create(instance, options={})
|
16
63
|
result = options[:mapper] \
|
17
64
|
? instance.client.createAuthorIfNotExistsFor(options[:mapper], options[:name]) \
|
@@ -23,9 +70,9 @@ module EtherpadLite
|
|
23
70
|
#
|
24
71
|
# Options:
|
25
72
|
#
|
26
|
-
#
|
73
|
+
# mapper => the foreign author id it's mapped to
|
27
74
|
#
|
28
|
-
#
|
75
|
+
# name => the Author's name
|
29
76
|
def initialize(instance, id, options={})
|
30
77
|
@instance = instance
|
31
78
|
@id = id
|
@@ -1,10 +1,59 @@
|
|
1
1
|
module EtherpadLite
|
2
|
-
# A Group
|
2
|
+
# A Group serves as a container for related pads. Only an Author with a Session can access a group Pad.
|
3
|
+
#
|
4
|
+
# Group examples:
|
5
|
+
#
|
6
|
+
# # Create a new group
|
7
|
+
# group1 = @ether.create_group
|
8
|
+
# # Etherpad Lite will assign it an internal id
|
9
|
+
# group.id #> 'g.asdflsadf7w9823kjlasdf'
|
10
|
+
#
|
11
|
+
# # Create a new group with a mapper, so it can be easily found again
|
12
|
+
# group2 = @ether.create_group :mapper => 'Blurg'
|
13
|
+
#
|
14
|
+
# # Load (or create, if it doesn't exist) a group mapped to "Flarb"
|
15
|
+
# group3 = @ether.group('Flarb')
|
16
|
+
#
|
17
|
+
# # Load an existing group based on its internal id
|
18
|
+
# group4 = @ether.get_group('g.823lasdlfj98asdfj')
|
19
|
+
#
|
20
|
+
# Group pad examples:
|
21
|
+
#
|
22
|
+
# # Create a new pad in this group, optionally specifying its initial text
|
23
|
+
# pad1 = group1.create_pad('group 1 pad', :text => 'Words!')
|
24
|
+
#
|
25
|
+
# # Load (or create, if it doesn't exist) a pad in this group
|
26
|
+
# pad2 = group2.pad('group 2 pad')
|
27
|
+
#
|
28
|
+
# # Load an existing pad from group 2
|
29
|
+
# pad3 = group2.get_pad('important pad')
|
30
|
+
#
|
31
|
+
# Session examples:
|
32
|
+
#
|
33
|
+
# # Create two hour-long session for an author in group 1
|
34
|
+
# author = @ether.author('author_1')
|
35
|
+
# session = group1.create_session(author, 60)
|
36
|
+
#
|
37
|
+
# Understand how ids work. A group pad's id is the group_id + '$' + pad_name:
|
38
|
+
#
|
39
|
+
# pad2.group_id == group2.id #> true
|
40
|
+
#
|
41
|
+
# pad2.id == group2.id + '$' + pad2.name #> true
|
42
|
+
#
|
43
|
+
# pad2 == group2.pad('group 2 pad') == @ether.get_pad("#{group2.id}$group 2 pad") == @ether.get_pad('group 2 pad', :groupID => group2.id) #> true
|
44
|
+
#
|
45
|
+
# group2.mapper #> "Blurg"
|
46
|
+
#
|
3
47
|
class Group
|
4
48
|
GROUP_ID_REGEX = /^g\.[^\$]+/
|
5
49
|
include Padded
|
6
50
|
|
7
|
-
|
51
|
+
# The EtherpadLite::Instance object
|
52
|
+
attr_reader :instance
|
53
|
+
# The group id
|
54
|
+
attr_reader :id
|
55
|
+
# An optional identifier used to map the group to something outside Etherpad Lite
|
56
|
+
attr_reader :mapper
|
8
57
|
|
9
58
|
# Creates a new Group. Optionally, you may pass the :mapper option your third party system's group id.
|
10
59
|
# This will allow you to find your Group again later using the same identifier as your foreign system.
|
@@ -12,7 +61,7 @@ module EtherpadLite
|
|
12
61
|
#
|
13
62
|
# Options:
|
14
63
|
#
|
15
|
-
#
|
64
|
+
# mapper => your foreign group id
|
16
65
|
def self.create(instance, options={})
|
17
66
|
result = options[:mapper] \
|
18
67
|
? instance.client.createGroupIfNotExistsFor(options[:mapper]) \
|
@@ -24,7 +73,7 @@ module EtherpadLite
|
|
24
73
|
#
|
25
74
|
# Options:
|
26
75
|
#
|
27
|
-
#
|
76
|
+
# mapper => the foreign id it's mapped to
|
28
77
|
def initialize(instance, id, options={})
|
29
78
|
@instance = instance
|
30
79
|
@id = id
|
@@ -49,7 +98,7 @@ module EtherpadLite
|
|
49
98
|
#
|
50
99
|
# Options:
|
51
100
|
#
|
52
|
-
#
|
101
|
+
# text => 'initial Pad text'
|
53
102
|
def create_pad(id, options={})
|
54
103
|
options[:groupID] = @id
|
55
104
|
super groupify_pad_id(id), options
|
@@ -62,7 +111,7 @@ module EtherpadLite
|
|
62
111
|
|
63
112
|
# Returns an array of all the Pad ids in this Group.
|
64
113
|
def pad_ids
|
65
|
-
@instance.client.listPads(@id)[:padIDs]
|
114
|
+
@instance.client.listPads(@id)[:padIDs]
|
66
115
|
end
|
67
116
|
|
68
117
|
# Create a new session for author that will last length_in_minutes.
|
@@ -91,7 +140,7 @@ module EtherpadLite
|
|
91
140
|
|
92
141
|
# Prepend the group_id to the pad name
|
93
142
|
def groupify_pad_id(pad_id)
|
94
|
-
"#{@id}$#{pad_id}"
|
143
|
+
pad_id =~ GROUP_ID_REGEX ? pad_id : "#{@id}$#{pad_id}"
|
95
144
|
end
|
96
145
|
end
|
97
146
|
end
|
@@ -1,43 +1,35 @@
|
|
1
1
|
module EtherpadLite
|
2
|
-
# Aliases to common Etherpad Lite hosts
|
3
|
-
HOST_ALIASES = {:local => 'http://localhost:9001',
|
4
|
-
:public => 'http://beta.etherpad.org'}
|
5
|
-
|
6
2
|
# Returns an EtherpadLite::Instance object.
|
7
3
|
#
|
8
|
-
#
|
4
|
+
# ether1 = EtherpadLite.connect('https://etherpad.yoursite.com[https://etherpad.yoursite.com]', 'your api key')
|
5
|
+
#
|
6
|
+
# # An alias for http://localhost:9001
|
7
|
+
# ether2 = EtherpadLite.connect(:local, File.new('/path/to/APIKEY.txt'))
|
9
8
|
#
|
10
|
-
#
|
9
|
+
# # An alias for http://localhost:9001
|
10
|
+
# ether3 = EtherpadLite.connect(9001, File.new('/path/to/APIKEY.txt'))
|
11
11
|
def self.connect(host_or_alias, api_key_or_file)
|
12
|
-
|
13
|
-
host = if host_or_alias.is_a? Symbol
|
14
|
-
raise ArgumentError, %Q|Unknown host alias "#{host_or_alias}"| unless HOST_ALIASES.has_key? host_or_alias
|
15
|
-
HOST_ALIASES[host_or_alias]
|
16
|
-
else
|
17
|
-
host_or_alias
|
18
|
-
end
|
19
|
-
|
20
|
-
# Parse the api key
|
21
|
-
if api_key_or_file.is_a? File
|
22
|
-
api_key = api_key_or_file.read
|
23
|
-
api_key_or_file.close
|
24
|
-
else
|
25
|
-
api_key = api_key_or_file
|
26
|
-
end
|
27
|
-
|
28
|
-
Instance.new(host, api_key)
|
12
|
+
Instance.new(host_or_alias, api_key_or_file)
|
29
13
|
end
|
30
14
|
|
31
|
-
#
|
15
|
+
# EtherpadLite::Instance provides a high-level interface to the EtherpadLite::Client class. See the EtherpadLite module
|
16
|
+
# for examples of how to establish a connection.
|
32
17
|
class Instance
|
33
18
|
include Padded
|
34
|
-
|
35
|
-
|
19
|
+
# Stores the EtherpadLite::Client object used to power this Instance
|
36
20
|
attr_reader :client
|
37
21
|
|
38
22
|
# Instantiate a new Etherpad Lite Instance. The url should include the protocol (i.e. http or https).
|
39
|
-
|
40
|
-
|
23
|
+
#
|
24
|
+
# ether1 = EtherpadLite::Instance.new('https://etherpad.yoursite.com[https://etherpad.yoursite.com]', 'your api key')
|
25
|
+
#
|
26
|
+
# # An alias for http://localhost:9001
|
27
|
+
# ether2 = EtherpadLite::Instance.new(:local, File.new('/path/to/APIKEY.txt'))
|
28
|
+
#
|
29
|
+
# # An alias for http://localhost:9001
|
30
|
+
# ether3 = EtherpadLite::Instance.new(9001, File.new('/path/to/APIKEY.txt'))
|
31
|
+
def initialize(host_or_alias, api_key_or_file)
|
32
|
+
@client = Client.new(host_or_alias, api_key_or_file)
|
41
33
|
end
|
42
34
|
|
43
35
|
# Returns, creating if necessary, a Group mapped to your foreign system's group
|
@@ -55,7 +47,7 @@ module EtherpadLite
|
|
55
47
|
#
|
56
48
|
# Options:
|
57
49
|
#
|
58
|
-
#
|
50
|
+
# mapper => your foreign group id
|
59
51
|
def create_group(options={})
|
60
52
|
Group.create self, options
|
61
53
|
end
|
@@ -64,7 +56,7 @@ module EtherpadLite
|
|
64
56
|
#
|
65
57
|
# Options:
|
66
58
|
#
|
67
|
-
#
|
59
|
+
# name => the Author's name
|
68
60
|
def author(mapper, options={})
|
69
61
|
options[:mapper] = mapper
|
70
62
|
create_author options
|
@@ -80,7 +72,7 @@ module EtherpadLite
|
|
80
72
|
#
|
81
73
|
# Options:
|
82
74
|
#
|
83
|
-
#
|
75
|
+
# mapper => your foreign author id
|
84
76
|
#
|
85
77
|
# name => the Author's name
|
86
78
|
def create_author(options={})
|
@@ -92,6 +84,7 @@ module EtherpadLite
|
|
92
84
|
Session.new self, session_id
|
93
85
|
end
|
94
86
|
|
87
|
+
# Returns itself
|
95
88
|
def instance; self; end
|
96
89
|
end
|
97
90
|
end
|
@@ -1,15 +1,26 @@
|
|
1
1
|
module EtherpadLite
|
2
2
|
# An Etherpad Lite Pad
|
3
|
+
#
|
4
|
+
# This class allows you to interact with pads stored in an Etherpad Lite server. The README
|
5
|
+
# has some basic examples.
|
6
|
+
#
|
7
|
+
# Note that some functions are restricted to Group pads.
|
8
|
+
#
|
3
9
|
class Pad
|
4
|
-
|
10
|
+
# The EtherpadLite::Instance object
|
11
|
+
attr_reader :instance
|
12
|
+
# The pad id
|
13
|
+
attr_reader :id
|
14
|
+
# An optional pad revision number
|
15
|
+
attr_reader :rev
|
5
16
|
|
6
17
|
# Creates and returns a new Pad.
|
7
18
|
#
|
8
19
|
# Options:
|
9
20
|
#
|
10
|
-
#
|
21
|
+
# text => 'initial Pad text'
|
11
22
|
#
|
12
|
-
#
|
23
|
+
# groupID => group id of Group new Pad should belong to
|
13
24
|
def self.create(instance, id, options={})
|
14
25
|
if options[:groupID]
|
15
26
|
group = Group.new instance, options[:groupID]
|
@@ -18,7 +29,7 @@ module EtherpadLite
|
|
18
29
|
group = nil
|
19
30
|
instance.client.createPad(id, options[:text])
|
20
31
|
end
|
21
|
-
new instance, id, :group => group
|
32
|
+
new instance, id, :groupID => options[:groupID], :group => group
|
22
33
|
end
|
23
34
|
|
24
35
|
# Remove the group id portion of a Group Pad's id
|
@@ -30,12 +41,18 @@ module EtherpadLite
|
|
30
41
|
#
|
31
42
|
# Options:
|
32
43
|
#
|
33
|
-
#
|
44
|
+
# groupID => a group id
|
34
45
|
#
|
35
|
-
#
|
46
|
+
# group => an EtherpadLite::Group object
|
47
|
+
#
|
48
|
+
# rev => a pad revision number
|
36
49
|
def initialize(instance, id, options={})
|
37
50
|
@instance = instance
|
38
51
|
@id = id.to_s
|
52
|
+
if options[:groupID]
|
53
|
+
@group_id = options[:groupID]
|
54
|
+
@id = "#{@group_id}$#{@id}" unless @id =~ Group::GROUP_ID_REGEX
|
55
|
+
end
|
39
56
|
@group = options[:group]
|
40
57
|
@rev = options[:rev]
|
41
58
|
end
|
@@ -65,7 +82,7 @@ module EtherpadLite
|
|
65
82
|
#
|
66
83
|
# Options:
|
67
84
|
#
|
68
|
-
#
|
85
|
+
# rev => revision_number
|
69
86
|
def text(options={})
|
70
87
|
options[:rev] ||= @rev unless @rev.nil?
|
71
88
|
@instance.client.getText(@id, options[:rev])[:text]
|
@@ -76,6 +93,21 @@ module EtherpadLite
|
|
76
93
|
@instance.client.setText(@id, txt)
|
77
94
|
end
|
78
95
|
|
96
|
+
# Returns the Pad's text as HTML. Unless you specified a :rev when instantiating the Pad, or specify one here, this will return the latest revision.
|
97
|
+
#
|
98
|
+
# Options:
|
99
|
+
#
|
100
|
+
# rev => revision_number
|
101
|
+
def html(options={})
|
102
|
+
options[:rev] ||= @rev unless @rev.nil?
|
103
|
+
@instance.client.getHTML(@id, options[:rev])[:html]
|
104
|
+
end
|
105
|
+
|
106
|
+
# Writes HTML to the Pad. There is no 'save' method; it is written immediately.
|
107
|
+
def html=(html)
|
108
|
+
@instance.client.setHTML(@id, html)
|
109
|
+
end
|
110
|
+
|
79
111
|
# Returns an Array of all this Pad's revision numbers
|
80
112
|
def revision_numbers
|
81
113
|
max = @instance.client.getRevisionsCount(@id)[:revisions]
|
@@ -5,7 +5,12 @@ module EtherpadLite
|
|
5
5
|
# Returns the Pad with the given id, creating it if it doesn't already exist.
|
6
6
|
# This requires an HTTP request, so if you *know* the Pad already exists, use Instance#get_pad instead.
|
7
7
|
def pad(id, options={})
|
8
|
-
|
8
|
+
begin
|
9
|
+
Pad.create(instance, id, options)
|
10
|
+
# Pad alreaded exists
|
11
|
+
rescue ArgumentError
|
12
|
+
Pad.new(instance, id, options)
|
13
|
+
end
|
9
14
|
end
|
10
15
|
|
11
16
|
# Returns the Pad with the given id (presumed to already exist).
|
@@ -18,7 +23,7 @@ module EtherpadLite
|
|
18
23
|
#
|
19
24
|
# Options:
|
20
25
|
#
|
21
|
-
#
|
26
|
+
# text => 'initial Pad text'
|
22
27
|
def create_pad(id, options={})
|
23
28
|
Pad.create instance, id, options
|
24
29
|
end
|
@@ -1,7 +1,17 @@
|
|
1
1
|
module EtherpadLite
|
2
|
-
# An Etherpad Lite Session between a Group and an Author
|
2
|
+
# An Etherpad Lite Session between a Group and an Author. See those classes for examples of how to create a session.
|
3
|
+
#
|
4
|
+
# Sessions are useful for embedding an Etherpad Lite Pad into a external application. For public pads, sessions
|
5
|
+
# are not necessary. However Group pads require a Session to access to the pad via the Web UI.
|
6
|
+
#
|
7
|
+
# Generally, you will create the session server side, then pass its id to the embedded pad using a cookie. See the README
|
8
|
+
# for an example in a Rails app.
|
9
|
+
#
|
3
10
|
class Session
|
4
|
-
|
11
|
+
# The EtherpadLite::Instance object
|
12
|
+
attr_reader :instance
|
13
|
+
# The session id
|
14
|
+
attr_reader :id
|
5
15
|
|
6
16
|
# Creates a new Session between a Group and an Author. The session will expire after length_in_min.
|
7
17
|
def self.create(instance, group_id, author_id, length_in_min)
|
data/spec/author_spec.rb
CHANGED
@@ -2,7 +2,7 @@ require File.dirname(__FILE__) + '/spec_helper'
|
|
2
2
|
|
3
3
|
describe EtherpadLite::Author do
|
4
4
|
before do
|
5
|
-
@eth = EtherpadLite.connect TEST_CONFIG[:
|
5
|
+
@eth = EtherpadLite.connect TEST_CONFIG[:url], TEST_CONFIG[:api_key_file] || TEST_CONFIG[:api_key]
|
6
6
|
end
|
7
7
|
|
8
8
|
it "should be created" do
|
data/spec/config.yml
CHANGED
@@ -1,9 +1,4 @@
|
|
1
|
-
:
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
# Uncomment to test https connections
|
7
|
-
#:https:
|
8
|
-
# :url: https://localhost:9001
|
9
|
-
# :api_key: api key
|
1
|
+
:url: 9001
|
2
|
+
:api_key: #kvwTIROV9p2h2gjNRCrO8fVa6pNXSqOc
|
3
|
+
# Full filesystem path to APIKEY.txt, may be used instead of the above :api_key setting
|
4
|
+
:api_key_file: /home/jhollinger/devel/etherpad-lite/APIKEY.txt
|
data/spec/config.yml.example
CHANGED
@@ -1,9 +1,4 @@
|
|
1
|
-
:
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
# Uncomment to test https connections
|
7
|
-
#:https:
|
8
|
-
# :url: https://localhost:9001
|
9
|
-
# :api_key: api key
|
1
|
+
:url: http://localhost:9001
|
2
|
+
:api_key: your api key
|
3
|
+
# Full filesystem path to APIKEY.txt, may be used instead of the above :api_key setting
|
4
|
+
:api_key_file:
|
data/spec/group_spec.rb
CHANGED
@@ -2,7 +2,7 @@ require File.dirname(__FILE__) + '/spec_helper'
|
|
2
2
|
|
3
3
|
describe EtherpadLite::Group do
|
4
4
|
before do
|
5
|
-
@eth = EtherpadLite.connect TEST_CONFIG[:
|
5
|
+
@eth = EtherpadLite.connect TEST_CONFIG[:url], TEST_CONFIG[:api_key_file] || TEST_CONFIG[:api_key]
|
6
6
|
end
|
7
7
|
|
8
8
|
it "should be created" do
|
@@ -28,6 +28,12 @@ describe EtherpadLite::Group do
|
|
28
28
|
pad.id.should == "#{group.id}$Important Group Stuff"
|
29
29
|
end
|
30
30
|
|
31
|
+
it "should create another Group Pad" do
|
32
|
+
group = @eth.group 'Group A'
|
33
|
+
pad = @eth.create_pad 'Other Important Group Stuff', :groupID => group.id, :text => 'foo'
|
34
|
+
pad.text.should == "foo\n"
|
35
|
+
end
|
36
|
+
|
31
37
|
it "should create a Group Pad with the right name" do
|
32
38
|
group = @eth.group 'Group A'
|
33
39
|
pad = group.pad 'Important Group Stuff'
|
@@ -39,14 +45,34 @@ describe EtherpadLite::Group do
|
|
39
45
|
group.get_pad('Important Group Stuff').group_id.should == group.id
|
40
46
|
end
|
41
47
|
|
42
|
-
it "should find
|
48
|
+
it "should find another Group Pad with the right group" do
|
49
|
+
group = @eth.group 'Group A'
|
50
|
+
@eth.get_pad('Other Important Group Stuff', :groupID => group.id).group_id.should == group.id
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should find yet another Group Pad with the right group" do
|
54
|
+
group = @eth.group 'Group A'
|
55
|
+
@eth.get_pad("Other Important Group Stuff", :groupID => group.id).text.should == "foo\n"
|
56
|
+
end
|
57
|
+
|
58
|
+
it "should find another Group Pad with the right text" do
|
59
|
+
group = @eth.group 'Group A'
|
60
|
+
@eth.get_pad("#{group.id}$Other Important Group Stuff").text.should == "foo\n"
|
61
|
+
end
|
62
|
+
|
63
|
+
it "should find yet another Group Pad with the right text" do
|
64
|
+
group = @eth.group 'Group A'
|
65
|
+
@eth.get_pad("#{group.id}$Other Important Group Stuff").text.should == "foo\n"
|
66
|
+
end
|
67
|
+
|
68
|
+
it "should find a Group Pad with the right ids" do
|
43
69
|
group = @eth.group 'Group A'
|
44
|
-
group.pad_ids.should == [
|
70
|
+
group.pad_ids.should == ["#{group.id}$Important_Group_Stuff", "#{group.id}$Other_Important_Group_Stuff"]
|
45
71
|
end
|
46
72
|
|
47
73
|
it "should find a Group Pad with the right name" do
|
48
74
|
group = @eth.group 'Group A'
|
49
|
-
group.pads.first.name.should == "
|
75
|
+
group.pads.first.name.should == "Important_Group_Stuff"
|
50
76
|
end
|
51
77
|
|
52
78
|
it "should explicitly create a Group Pad" do
|
data/spec/instance_spec.rb
CHANGED
@@ -2,11 +2,21 @@ require File.dirname(__FILE__) + '/spec_helper'
|
|
2
2
|
|
3
3
|
describe EtherpadLite::Instance do
|
4
4
|
before do
|
5
|
-
@eth = EtherpadLite.connect TEST_CONFIG[:
|
5
|
+
@eth = EtherpadLite.connect TEST_CONFIG[:url], TEST_CONFIG[:api_key_file] || TEST_CONFIG[:api_key]
|
6
6
|
end
|
7
7
|
|
8
8
|
it "should have the right API key" do
|
9
|
-
|
9
|
+
api_key = if TEST_CONFIG[:api_key_file]
|
10
|
+
begin
|
11
|
+
TEST_CONFIG[:api_key_file].read
|
12
|
+
rescue IOError
|
13
|
+
TEST_CONFIG[:api_key_file].reopen(TEST_CONFIG[:api_key_file].path, mode='r')
|
14
|
+
TEST_CONFIG[:api_key_file].read
|
15
|
+
end
|
16
|
+
else
|
17
|
+
TEST_CONFIG[:api_key]
|
18
|
+
end
|
19
|
+
@eth.client.api_key.should == api_key
|
10
20
|
end
|
11
21
|
|
12
22
|
it "shouldn't be secure" do
|
data/spec/pad_spec.rb
CHANGED
@@ -2,7 +2,7 @@ require File.dirname(__FILE__) + '/spec_helper'
|
|
2
2
|
|
3
3
|
describe EtherpadLite::Pad do
|
4
4
|
before do
|
5
|
-
@eth = EtherpadLite.connect TEST_CONFIG[:
|
5
|
+
@eth = EtherpadLite.connect TEST_CONFIG[:url], TEST_CONFIG[:api_key_file] || TEST_CONFIG[:api_key]
|
6
6
|
end
|
7
7
|
|
8
8
|
it "should blow up when querying a non-existing pad" do
|
@@ -54,6 +54,12 @@ describe EtherpadLite::Pad do
|
|
54
54
|
pad.revision_numbers.last == 2
|
55
55
|
end
|
56
56
|
|
57
|
+
it "should set HTML" do
|
58
|
+
pad = @eth.get_pad 'another new pad'
|
59
|
+
pad.html = "<div><p>Here's some HTML.</p>\n<p>Please rewind it when you're finished.</p></div>"
|
60
|
+
pad.html.should == "Here's some HTML.<br>Please rewind it when you're finished.<br>"
|
61
|
+
end
|
62
|
+
|
57
63
|
it "should have the first revision" do
|
58
64
|
pad = @eth.get_pad 'another new pad'
|
59
65
|
pad.text(:rev => 1).should == "The initial text\n"
|
@@ -64,6 +70,11 @@ describe EtherpadLite::Pad do
|
|
64
70
|
pad.revisions[1].text.should == "The initial text\n"
|
65
71
|
end
|
66
72
|
|
73
|
+
it "should have the first revision as HTML" do
|
74
|
+
pad = @eth.get_pad 'another new pad'
|
75
|
+
pad.revisions[1].html.should == "The initial text<br>"
|
76
|
+
end
|
77
|
+
|
67
78
|
it "should have the same name and id" do
|
68
79
|
pad = @eth.get_pad 'another new pad'
|
69
80
|
pad.name.should == pad.id
|
data/spec/session_spec.rb
CHANGED
@@ -2,7 +2,7 @@ require File.dirname(__FILE__) + '/spec_helper'
|
|
2
2
|
|
3
3
|
describe EtherpadLite::Session do
|
4
4
|
before do
|
5
|
-
@eth = EtherpadLite.connect TEST_CONFIG[:
|
5
|
+
@eth = EtherpadLite.connect TEST_CONFIG[:url], TEST_CONFIG[:api_key_file] || TEST_CONFIG[:api_key]
|
6
6
|
end
|
7
7
|
|
8
8
|
it "should be created for a Group" do
|
data/spec/spec_helper.rb
CHANGED
@@ -1,18 +1,14 @@
|
|
1
1
|
require 'rspec'
|
2
2
|
|
3
3
|
# Load etherpad-lite
|
4
|
-
|
5
|
-
require
|
6
|
-
require File.dirname(__FILE__) + '/../lib/etherpad-lite/models/instance'
|
7
|
-
require File.dirname(__FILE__) + '/../lib/etherpad-lite/models/pad'
|
8
|
-
require File.dirname(__FILE__) + '/../lib/etherpad-lite/models/group'
|
9
|
-
require File.dirname(__FILE__) + '/../lib/etherpad-lite/models/author'
|
10
|
-
require File.dirname(__FILE__) + '/../lib/etherpad-lite/models/session'
|
4
|
+
$LOAD_PATH.unshift File.dirname(__FILE__) + '/..'
|
5
|
+
require 'etherpad-lite'
|
11
6
|
|
12
|
-
|
7
|
+
RSpec.configure do |c|
|
13
8
|
c.mock_with :rspec
|
14
9
|
end
|
15
10
|
|
16
11
|
# Load test config
|
17
12
|
require 'yaml'
|
18
13
|
TEST_CONFIG = YAML.load_file(File.dirname(__FILE__) + '/config.yml')
|
14
|
+
TEST_CONFIG[:api_key_file] = File.new(TEST_CONFIG[:api_key_file]) unless TEST_CONFIG[:api_key_file].nil?
|
metadata
CHANGED
@@ -1,83 +1,65 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: etherpad-lite
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
|
6
|
-
- 0
|
7
|
-
- 0
|
8
|
-
- 4
|
9
|
-
version: 0.0.4
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0.rc2
|
5
|
+
prerelease: 6
|
10
6
|
platform: ruby
|
11
|
-
authors:
|
7
|
+
authors:
|
12
8
|
- Jordan Hollinger
|
13
9
|
autorequire:
|
14
10
|
bindir: bin
|
15
11
|
cert_chain: []
|
16
|
-
|
17
|
-
date: 2011-09-12 00:00:00 -04:00
|
18
|
-
default_executable:
|
12
|
+
date: 2012-06-20 00:00:00.000000000 Z
|
19
13
|
dependencies: []
|
20
|
-
|
21
14
|
description: etherpad-lite is a Ruby interface to Etherpad Lite's HTTP JSON API
|
22
15
|
email: jordan@jordanhollinger.com
|
23
16
|
executables: []
|
24
|
-
|
25
17
|
extensions: []
|
26
|
-
|
27
|
-
extra_rdoc_files:
|
18
|
+
extra_rdoc_files:
|
28
19
|
- README.rdoc
|
29
|
-
files:
|
20
|
+
files:
|
30
21
|
- lib/etherpad-lite.rb
|
31
|
-
- lib/etherpad-lite/models.rb
|
32
|
-
- lib/etherpad-lite/models/session.rb
|
33
22
|
- lib/etherpad-lite/models/padded.rb
|
23
|
+
- lib/etherpad-lite/models/group.rb
|
24
|
+
- lib/etherpad-lite/models/pad.rb
|
34
25
|
- lib/etherpad-lite/models/author.rb
|
35
26
|
- lib/etherpad-lite/models/instance.rb
|
36
|
-
- lib/etherpad-lite/models/
|
37
|
-
- lib/etherpad-lite/models/group.rb
|
27
|
+
- lib/etherpad-lite/models/session.rb
|
38
28
|
- lib/etherpad-lite/client.rb
|
29
|
+
- lib/etherpad-lite/models.rb
|
30
|
+
- spec/pad_spec.rb
|
31
|
+
- spec/config.yml.example
|
32
|
+
- spec/config.yml
|
39
33
|
- spec/spec_helper.rb
|
40
34
|
- spec/instance_spec.rb
|
41
35
|
- spec/session_spec.rb
|
42
|
-
- spec/group_spec.rb
|
43
|
-
- spec/config.yml
|
44
|
-
- spec/config.yml.example
|
45
36
|
- spec/author_spec.rb
|
46
|
-
- spec/
|
37
|
+
- spec/group_spec.rb
|
47
38
|
- README.rdoc
|
48
39
|
- CHANGELOG
|
49
40
|
- LICENSE
|
50
|
-
has_rdoc: true
|
51
41
|
homepage: http://github.com/jhollinger/ruby-etherpad-lite
|
52
42
|
licenses: []
|
53
|
-
|
54
43
|
post_install_message:
|
55
44
|
rdoc_options: []
|
56
|
-
|
57
|
-
require_paths:
|
45
|
+
require_paths:
|
58
46
|
- lib
|
59
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
47
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
60
48
|
none: false
|
61
|
-
requirements:
|
62
|
-
- -
|
63
|
-
- !ruby/object:Gem::Version
|
64
|
-
|
65
|
-
|
66
|
-
version: "0"
|
67
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
49
|
+
requirements:
|
50
|
+
- - ! '>='
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: '0'
|
53
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
68
54
|
none: false
|
69
|
-
requirements:
|
70
|
-
- -
|
71
|
-
- !ruby/object:Gem::Version
|
72
|
-
|
73
|
-
- 0
|
74
|
-
version: "0"
|
55
|
+
requirements:
|
56
|
+
- - ! '>'
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
version: 1.3.1
|
75
59
|
requirements: []
|
76
|
-
|
77
60
|
rubyforge_project:
|
78
|
-
rubygems_version: 1.
|
61
|
+
rubygems_version: 1.8.21
|
79
62
|
signing_key:
|
80
63
|
specification_version: 3
|
81
64
|
summary: A Ruby client library for Etherpad Lite
|
82
65
|
test_files: []
|
83
|
-
|