etherpad-lite 0.0.4 → 0.1.0.rc2
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.
- 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
|
-
|