rave 0.1.2-java
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/bin/rave +28 -0
- data/lib/commands/appcfg.rb +9 -0
- data/lib/commands/create.rb +153 -0
- data/lib/commands/server.rb +8 -0
- data/lib/commands/task.rb +156 -0
- data/lib/commands/usage.rb +19 -0
- data/lib/commands/war.rb +28 -0
- data/lib/exceptions.rb +20 -0
- data/lib/ext/logger.rb +7 -0
- data/lib/gems.yaml +9 -0
- data/lib/jars/appengine-api-1.0-sdk-1.3.0.jar +0 -0
- data/lib/mixins/controller.rb +72 -0
- data/lib/mixins/data_format.rb +206 -0
- data/lib/mixins/logger.rb +19 -0
- data/lib/mixins/object_factory.rb +87 -0
- data/lib/mixins/time_utils.rb +19 -0
- data/lib/models/annotation.rb +148 -0
- data/lib/models/blip.rb +305 -0
- data/lib/models/component.rb +42 -0
- data/lib/models/context.rb +174 -0
- data/lib/models/document.rb +9 -0
- data/lib/models/element.rb +113 -0
- data/lib/models/event.rb +230 -0
- data/lib/models/operation.rb +79 -0
- data/lib/models/range.rb +14 -0
- data/lib/models/robot.rb +79 -0
- data/lib/models/user.rb +62 -0
- data/lib/models/wave.rb +45 -0
- data/lib/models/wavelet.rb +269 -0
- data/lib/ops/blip_ops.rb +233 -0
- data/lib/rave.rb +28 -0
- metadata +135 -0
data/lib/ops/blip_ops.rb
ADDED
@@ -0,0 +1,233 @@
|
|
1
|
+
module Rave
|
2
|
+
module Models
|
3
|
+
class Blip
|
4
|
+
# Reopen the blip class and add operation-related methods
|
5
|
+
|
6
|
+
VALID_FORMATS = [:plain, :html, :textile] # :nodoc: For set_text/append_text
|
7
|
+
|
8
|
+
# Clear the content.
|
9
|
+
def clear
|
10
|
+
return if content.empty? # No point telling the server to clear an empty blip.
|
11
|
+
delete_range(0..(@content.length))
|
12
|
+
end
|
13
|
+
|
14
|
+
# Insert text at an index.
|
15
|
+
def insert_text(index, text)
|
16
|
+
add_operation(:type => Operation::DOCUMENT_INSERT, :index => index, :property => text)
|
17
|
+
@content.insert(index, text)
|
18
|
+
# TODO: Shift annotations.
|
19
|
+
|
20
|
+
text
|
21
|
+
end
|
22
|
+
|
23
|
+
# Set the content text of the blip.
|
24
|
+
#
|
25
|
+
# === Options
|
26
|
+
# :+format+ - Format of the text, which can be any one of:
|
27
|
+
# * :+html+ - Text marked up with HTML.
|
28
|
+
# * :+plain+ - Plain text (default).
|
29
|
+
# * :+textile+ - Text marked up with textile.
|
30
|
+
#
|
31
|
+
# Returns: An empty string [String]
|
32
|
+
def set_text(text, options = {})
|
33
|
+
clear
|
34
|
+
append_text(text, options)
|
35
|
+
end
|
36
|
+
|
37
|
+
# Deletes the text in a given range and replaces it with the given text.
|
38
|
+
# Returns: The text altered [String]
|
39
|
+
def set_text_in_range(range, text)
|
40
|
+
raise ArgumentError.new("Requires a Range, not a #{range.class.name}") unless range.kind_of? Range
|
41
|
+
|
42
|
+
#Note: I'm doing this in the opposite order from the python API, because
|
43
|
+
# otherwise, if you are setting text at the end of the content, the cursor
|
44
|
+
# gets moved to the start of the range...
|
45
|
+
unless text.empty?
|
46
|
+
begin # Failures in this method should give us a range error.
|
47
|
+
insert_text(range.min, text)
|
48
|
+
rescue IndexError => e
|
49
|
+
raise RangeError.new(e.message)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
delete_range(range.min+text.length..range.max+text.length)
|
53
|
+
# TODO: Shift annotations.
|
54
|
+
|
55
|
+
text
|
56
|
+
end
|
57
|
+
|
58
|
+
# Appends text to the end of the blip's current content.
|
59
|
+
#
|
60
|
+
# === Options
|
61
|
+
# :+format+ - Format of the text, which can be any one of:
|
62
|
+
# * :+html+ - Text marked up with HTML.
|
63
|
+
# * :+plain+ - Plain text (default).
|
64
|
+
# * :+textile+ - Text marked up with textile.
|
65
|
+
#
|
66
|
+
# Returns: The new content string [String]
|
67
|
+
def append_text(text, options = {})
|
68
|
+
format = options[:format] || :plain
|
69
|
+
raise BadOptionError.new(:format, VALID_FORMATS, format) unless VALID_FORMATS.include? format
|
70
|
+
|
71
|
+
plain_text = text
|
72
|
+
|
73
|
+
if format == :textile
|
74
|
+
text = RedCloth.new(text).to_html
|
75
|
+
format = :html # Can now just treat it as HTML.
|
76
|
+
end
|
77
|
+
|
78
|
+
if format == :html
|
79
|
+
type = Operation::DOCUMENT_APPEND_MARKUP
|
80
|
+
plain_text = strip_html_tags(text)
|
81
|
+
else
|
82
|
+
type = Operation::DOCUMENT_APPEND
|
83
|
+
end
|
84
|
+
|
85
|
+
add_operation(:type => type, :property => text)
|
86
|
+
# TODO: Add annotations for the tags we removed?
|
87
|
+
@content += plain_text # Plain text added to text field.
|
88
|
+
|
89
|
+
@content.dup
|
90
|
+
end
|
91
|
+
|
92
|
+
# Deletes text in the given range.
|
93
|
+
# Returns: An empty string [String]
|
94
|
+
def delete_range(range)
|
95
|
+
raise ArgumentError.new("Requires a Range, not a #{range.class.name}") unless range.kind_of? Range
|
96
|
+
|
97
|
+
add_operation(:type => Operation::DOCUMENT_DELETE, :index => range.min, :property => range)
|
98
|
+
|
99
|
+
@content[range] = ''
|
100
|
+
# TODO: Shift and/or delete annotations.
|
101
|
+
|
102
|
+
''
|
103
|
+
end
|
104
|
+
|
105
|
+
# Annotates the entire content.
|
106
|
+
#
|
107
|
+
# NOT IMPLEMENTED
|
108
|
+
def annotate_document(name, value)
|
109
|
+
raise NotImplementedError
|
110
|
+
end
|
111
|
+
|
112
|
+
# Deletes the annotation with the given name.
|
113
|
+
#
|
114
|
+
# NOT IMPLEMENTED
|
115
|
+
def delete_annotation_by_name(name)
|
116
|
+
raise NotImplementedError
|
117
|
+
end
|
118
|
+
|
119
|
+
# Deletes the annotations with the given key in the given range.
|
120
|
+
#
|
121
|
+
# NOT IMPLEMENTED
|
122
|
+
def delete_annotation_in_range(range, name)
|
123
|
+
raise NotImplementedError
|
124
|
+
end
|
125
|
+
|
126
|
+
# Appends an inline blip to this blip.
|
127
|
+
# Returns: Blip created by operation [Blip]
|
128
|
+
def append_inline_blip
|
129
|
+
# TODO: What happens if there already is an element at end of content?
|
130
|
+
blip = Blip.new(:wave_id => @wave_id, :wavelet_id => @wavelet_id)
|
131
|
+
@context.add_blip(blip)
|
132
|
+
element = Element::InlineBlip.new('blipId' => blip.id)
|
133
|
+
element.context = @context
|
134
|
+
@elements[@content.length] = element
|
135
|
+
add_operation(:type => Operation::DOCUMENT_INLINE_BLIP_APPEND, :property => blip)
|
136
|
+
|
137
|
+
blip
|
138
|
+
end
|
139
|
+
|
140
|
+
# Deletes an inline blip from this blip.
|
141
|
+
# +value+:: Inline blip to delete [Blip]
|
142
|
+
#
|
143
|
+
# Returns: Blip ID of the deleted blip [String]
|
144
|
+
def delete_inline_blip(blip) # :nodoc:
|
145
|
+
element = @elements.values.find { |e| e.kind_of?(Element::InlineBlip) and e.blip == blip }
|
146
|
+
raise "Blip '#{blip.id}' is not an inline blip of blip '#{id}'" if element.nil?
|
147
|
+
#element.blip.destroy_me # TODO: How to deal with children?
|
148
|
+
@elements.delete_if { |pos, el| el == element }
|
149
|
+
add_operation(:type => Operation::DOCUMENT_INLINE_BLIP_DELETE, :property => blip.id)
|
150
|
+
|
151
|
+
blip.id
|
152
|
+
end
|
153
|
+
|
154
|
+
# Inserts an inline blip at the given position.
|
155
|
+
# Returns: Blip element created by operation [Blip]
|
156
|
+
def insert_inline_blip(position)
|
157
|
+
# TODO: Complain if element does exist at that position.
|
158
|
+
blip = Blip.new(:wave_id => @wave_id, :wavelet_id => @wavelet_id)
|
159
|
+
@context.add_blip(blip)
|
160
|
+
element = Element::InlineBlip.new('blipId' => blip.id)
|
161
|
+
element.context = @context
|
162
|
+
@elements[@content.length] = element
|
163
|
+
add_operation(:type => Operation::DOCUMENT_INLINE_BLIP_INSERT, :index => position, :property => blip)
|
164
|
+
|
165
|
+
blip
|
166
|
+
end
|
167
|
+
|
168
|
+
# Deletes an element at the given position.
|
169
|
+
def delete_element(position)
|
170
|
+
element = @elements[position]
|
171
|
+
case element
|
172
|
+
when Element::InlineBlip
|
173
|
+
return delete_inline_blip(element.blip)
|
174
|
+
when Element
|
175
|
+
@elements[position] = nil
|
176
|
+
add_operation(:type => Operation::DOCUMENT_ELEMENT_DELETE, :index => position)
|
177
|
+
else
|
178
|
+
raise "No element to delete at position #{position}"
|
179
|
+
end
|
180
|
+
|
181
|
+
self
|
182
|
+
end
|
183
|
+
|
184
|
+
# Inserts the given element in the given position.
|
185
|
+
def insert_element(position, element)
|
186
|
+
# TODO: Complain if element does exist at that position.
|
187
|
+
@elements[position] = element
|
188
|
+
add_operation(:type => Operation::DOCUMENT_ELEMENT_INSERT, :index => position, :property => element)
|
189
|
+
|
190
|
+
element
|
191
|
+
end
|
192
|
+
|
193
|
+
# Replaces the element at the given position with the given element.
|
194
|
+
def replace_element(position, element)
|
195
|
+
# TODO: Complain if element does not exist at that position.
|
196
|
+
@elements[position] = element
|
197
|
+
add_operation(:type => Operation::DOCUMENT_ELEMENT_REPLACE, :index => position, :property => element)
|
198
|
+
|
199
|
+
element
|
200
|
+
end
|
201
|
+
|
202
|
+
# Appends an element
|
203
|
+
def append_element(element)
|
204
|
+
# TODO: What happens if there already is an element at end of content?
|
205
|
+
@elements[@content.length] = element
|
206
|
+
add_operation(:type => Operation::DOCUMENT_ELEMENT_APPEND, :property => element)
|
207
|
+
|
208
|
+
element
|
209
|
+
end
|
210
|
+
|
211
|
+
protected
|
212
|
+
def add_operation(options) # :nodoc:
|
213
|
+
@context.add_operation(options.merge(:blip_id => @id, :wavelet_id => @wavelet_id, :wave_id => @wave_id))
|
214
|
+
end
|
215
|
+
|
216
|
+
# Strips all HTML tags from a string, returning what it would look like unformatted.
|
217
|
+
def strip_html_tags(text) # :nodoc:
|
218
|
+
# Replace existing newlines/tabs with spaces, since they don't affect layout.
|
219
|
+
str = text.gsub(/[\n\t]/, ' ')
|
220
|
+
# Replace all <br /> with a newline.
|
221
|
+
str.gsub!(/<br\s*\/>\s*/, "\n")
|
222
|
+
# Put newline where are </h?>, </p> </div>, unless at the end.
|
223
|
+
str.gsub!(/<\/(?:h\d|p|div)>\s*(?!$)/, "\n")
|
224
|
+
# Remove all tags.
|
225
|
+
str.gsub!(/<\/?[^<]*>/, '')
|
226
|
+
# Remove spaces at each end.
|
227
|
+
str.gsub!(/^ +| +$/, '')
|
228
|
+
# Compress all adjacent spaces into a single space.
|
229
|
+
str.gsub(/ {2,}/, ' ')
|
230
|
+
end
|
231
|
+
end
|
232
|
+
end
|
233
|
+
end
|
data/lib/rave.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'builder'
|
3
|
+
require 'json'
|
4
|
+
require 'redcloth'
|
5
|
+
|
6
|
+
here = File.dirname(__FILE__)
|
7
|
+
ext = File.join(here, "ext")
|
8
|
+
mixins = File.join(here, "mixins")
|
9
|
+
models = File.join(here, "models")
|
10
|
+
ops = File.join(here, "ops")
|
11
|
+
|
12
|
+
require File.join(here, 'exceptions')
|
13
|
+
|
14
|
+
%w( logger ).each do |dep|
|
15
|
+
require File.join(ext, dep)
|
16
|
+
end
|
17
|
+
|
18
|
+
%w( logger data_format controller time_utils object_factory ).each do |dep|
|
19
|
+
require File.join(mixins, dep)
|
20
|
+
end
|
21
|
+
|
22
|
+
%w( component user annotation blip context document event operation range robot wave wavelet element).each do |dep|
|
23
|
+
require File.join(models, dep)
|
24
|
+
end
|
25
|
+
|
26
|
+
%w( blip_ops ).each do |dep|
|
27
|
+
require File.join(ops, dep)
|
28
|
+
end
|
metadata
ADDED
@@ -0,0 +1,135 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rave
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.2
|
5
|
+
platform: java
|
6
|
+
authors:
|
7
|
+
- Jason Rush
|
8
|
+
- Jay Donnell
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
|
13
|
+
date: 2010-01-24 00:00:00 -07:00
|
14
|
+
default_executable:
|
15
|
+
dependencies:
|
16
|
+
- !ruby/object:Gem::Dependency
|
17
|
+
name: rack
|
18
|
+
type: :runtime
|
19
|
+
version_requirement:
|
20
|
+
version_requirements: !ruby/object:Gem::Requirement
|
21
|
+
requirements:
|
22
|
+
- - ">="
|
23
|
+
- !ruby/object:Gem::Version
|
24
|
+
version: "1.0"
|
25
|
+
version:
|
26
|
+
- !ruby/object:Gem::Dependency
|
27
|
+
name: builder
|
28
|
+
type: :runtime
|
29
|
+
version_requirement:
|
30
|
+
version_requirements: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - ">="
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: 2.1.2
|
35
|
+
version:
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: warbler
|
38
|
+
type: :runtime
|
39
|
+
version_requirement:
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
requirements:
|
42
|
+
- - ">="
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
version: 0.9.14
|
45
|
+
version:
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: RedCloth
|
48
|
+
type: :runtime
|
49
|
+
version_requirement:
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 4.2.2
|
55
|
+
version:
|
56
|
+
- !ruby/object:Gem::Dependency
|
57
|
+
name: json-jruby
|
58
|
+
type: :runtime
|
59
|
+
version_requirement:
|
60
|
+
version_requirements: !ruby/object:Gem::Requirement
|
61
|
+
requirements:
|
62
|
+
- - ">="
|
63
|
+
- !ruby/object:Gem::Version
|
64
|
+
version: 1.1.6
|
65
|
+
version:
|
66
|
+
description: A toolkit for building Google Wave robots in Ruby
|
67
|
+
email: diminish7@gmail.com
|
68
|
+
executables:
|
69
|
+
- rave
|
70
|
+
extensions: []
|
71
|
+
|
72
|
+
extra_rdoc_files: []
|
73
|
+
|
74
|
+
files:
|
75
|
+
- lib/exceptions.rb
|
76
|
+
- lib/gems.yaml
|
77
|
+
- lib/rave.rb
|
78
|
+
- lib/commands/appcfg.rb
|
79
|
+
- lib/commands/create.rb
|
80
|
+
- lib/commands/server.rb
|
81
|
+
- lib/commands/task.rb
|
82
|
+
- lib/commands/usage.rb
|
83
|
+
- lib/commands/war.rb
|
84
|
+
- lib/ext/logger.rb
|
85
|
+
- lib/jars/appengine-api-1.0-sdk-1.3.0.jar
|
86
|
+
- lib/mixins/controller.rb
|
87
|
+
- lib/mixins/data_format.rb
|
88
|
+
- lib/mixins/logger.rb
|
89
|
+
- lib/mixins/object_factory.rb
|
90
|
+
- lib/mixins/time_utils.rb
|
91
|
+
- lib/models/annotation.rb
|
92
|
+
- lib/models/blip.rb
|
93
|
+
- lib/models/component.rb
|
94
|
+
- lib/models/context.rb
|
95
|
+
- lib/models/document.rb
|
96
|
+
- lib/models/element.rb
|
97
|
+
- lib/models/event.rb
|
98
|
+
- lib/models/operation.rb
|
99
|
+
- lib/models/range.rb
|
100
|
+
- lib/models/robot.rb
|
101
|
+
- lib/models/user.rb
|
102
|
+
- lib/models/wave.rb
|
103
|
+
- lib/models/wavelet.rb
|
104
|
+
- lib/ops/blip_ops.rb
|
105
|
+
- bin/rave
|
106
|
+
has_rdoc: true
|
107
|
+
homepage: http://github.com/diminish7/rave
|
108
|
+
licenses: []
|
109
|
+
|
110
|
+
post_install_message:
|
111
|
+
rdoc_options: []
|
112
|
+
|
113
|
+
require_paths:
|
114
|
+
- lib
|
115
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
116
|
+
requirements:
|
117
|
+
- - ">="
|
118
|
+
- !ruby/object:Gem::Version
|
119
|
+
version: 1.8.6
|
120
|
+
version:
|
121
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
122
|
+
requirements:
|
123
|
+
- - ">="
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: "0"
|
126
|
+
version:
|
127
|
+
requirements: []
|
128
|
+
|
129
|
+
rubyforge_project: rave
|
130
|
+
rubygems_version: 1.3.5
|
131
|
+
signing_key:
|
132
|
+
specification_version: 3
|
133
|
+
summary: A Google Wave robot client API for Ruby
|
134
|
+
test_files: []
|
135
|
+
|