rave 0.1.1 → 0.1.2
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 +27 -23
- data/lib/commands/appcfg.rb +9 -0
- data/lib/commands/create.rb +153 -147
- data/lib/commands/server.rb +7 -7
- data/lib/commands/task.rb +156 -0
- data/lib/commands/usage.rb +18 -12
- data/lib/commands/war.rb +27 -50
- data/lib/exceptions.rb +19 -5
- data/lib/ext/logger.rb +7 -0
- data/lib/gems.yaml +9 -0
- data/lib/jars/{appengine-api-1.0-sdk-1.2.1.jar → appengine-api-1.0-sdk-1.3.0.jar} +0 -0
- data/lib/mixins/controller.rb +72 -40
- data/lib/mixins/data_format.rb +206 -168
- 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 -18
- data/lib/models/blip.rb +305 -61
- data/lib/models/component.rb +42 -0
- data/lib/models/context.rb +174 -45
- data/lib/models/document.rb +8 -8
- data/lib/models/element.rb +113 -0
- data/lib/models/event.rb +230 -48
- data/lib/models/operation.rb +79 -89
- data/lib/models/range.rb +14 -0
- data/lib/models/robot.rb +78 -60
- data/lib/models/user.rb +62 -0
- data/lib/models/wave.rb +45 -19
- data/lib/models/wavelet.rb +269 -69
- data/lib/ops/blip_ops.rb +233 -134
- data/lib/rave.rb +27 -22
- metadata +96 -77
- data/lib/jars/jruby-core.jar +0 -0
- data/lib/jars/ruby-stdlib.jar +0 -0
data/lib/models/operation.rb
CHANGED
@@ -1,89 +1,79 @@
|
|
1
|
-
|
2
|
-
module
|
3
|
-
|
4
|
-
class Operation
|
5
|
-
attr_reader :
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
}
|
81
|
-
else
|
82
|
-
#TODO: What else needs to be in here?
|
83
|
-
raise "I don't know what that property is..."
|
84
|
-
end
|
85
|
-
end
|
86
|
-
|
87
|
-
end
|
88
|
-
end
|
89
|
-
end
|
1
|
+
module Rave
|
2
|
+
module Models
|
3
|
+
# Represents an operation to be applied on the server.
|
4
|
+
class Operation # :nodoc:
|
5
|
+
attr_reader :index, :property
|
6
|
+
|
7
|
+
def type; @type.dup; end
|
8
|
+
def wave_id; @wave_id.dup; end
|
9
|
+
def wavelet_id; @wavelet_id.dup; end
|
10
|
+
def blip_id; @blip_id.dup; end
|
11
|
+
|
12
|
+
JAVA_CLASS = 'com.google.wave.api.impl.OperationImpl' # :nodoc:
|
13
|
+
|
14
|
+
#Constants
|
15
|
+
# Types of operations
|
16
|
+
WAVELET_APPEND_BLIP = 'WAVELET_APPEND_BLIP'
|
17
|
+
WAVELET_ADD_PARTICIPANT = 'WAVELET_ADD_PARTICIPANT'
|
18
|
+
WAVELET_REMOVE_PARTICIPANT = 'WAVELET_REMOVE_PARTICIPANT'
|
19
|
+
WAVELET_CREATE = 'WAVELET_CREATE'
|
20
|
+
WAVELET_REMOVE_SELF = 'WAVELET_REMOVE_SELF'
|
21
|
+
WAVELET_DATADOC_SET = 'WAVELET_DATADOC_SET'
|
22
|
+
WAVELET_SET_TITLE = 'WAVELET_SET_TITLE'
|
23
|
+
BLIP_CREATE_CHILD = 'BLIP_CREATE_CHILD'
|
24
|
+
BLIP_DELETE = 'BLIP_DELETE'
|
25
|
+
DOCUMENT_ANNOTATION_DELETE = 'DOCUMENT_ANNOTATION_DELETE'
|
26
|
+
DOCUMENT_ANNOTATION_SET = 'DOCUMENT_ANNOTATION_SET'
|
27
|
+
DOCUMENT_ANNOTATION_SET_NORANGE = 'DOCUMENT_ANNOTATION_SET_NORANGE'
|
28
|
+
DOCUMENT_APPEND = 'DOCUMENT_APPEND' # Plain text
|
29
|
+
DOCUMENT_APPEND_MARKUP = 'DOCUMENT_APPEND_MARKUP' # HTML
|
30
|
+
DOCUMENT_APPEND_STYLED_TEXT = 'DOCUMENT_APPEND_STYLED_TEXT'
|
31
|
+
DOCUMENT_INSERT = 'DOCUMENT_INSERT'
|
32
|
+
DOCUMENT_DELETE = 'DOCUMENT_DELETE'
|
33
|
+
DOCUMENT_REPLACE = 'DOCUMENT_REPLACE'
|
34
|
+
DOCUMENT_ELEMENT_APPEND = 'DOCUMENT_ELEMENT_APPEND'
|
35
|
+
DOCUMENT_ELEMENT_DELETE = 'DOCUMENT_ELEMENT_DELETE'
|
36
|
+
DOCUMENT_ELEMENT_INSERT = 'DOCUMENT_ELEMENT_INSERT'
|
37
|
+
DOCUMENT_ELEMENT_INSERT_AFTER = 'DOCUMENT_ELEMENT_INSERT_AFTER'
|
38
|
+
DOCUMENT_ELEMENT_INSERT_BEFORE = 'DOCUMENT_ELEMENT_INSERT_BEFORE'
|
39
|
+
DOCUMENT_ELEMENT_REPLACE = 'DOCUMENT_ELEMENT_REPLACE'
|
40
|
+
DOCUMENT_INLINE_BLIP_APPEND = 'DOCUMENT_INLINE_BLIP_APPEND'
|
41
|
+
DOCUMENT_INLINE_BLIP_DELETE = 'DOCUMENT_INLINE_BLIP_DELETE'
|
42
|
+
DOCUMENT_INLINE_BLIP_INSERT = 'DOCUMENT_INLINE_BLIP_INSERT'
|
43
|
+
DOCUMENT_INLINE_BLIP_INSERT_AFTER_ELEMENT = 'DOCUMENT_INLINE_BLIP_INSERT_AFTER_ELEMENT'
|
44
|
+
|
45
|
+
#Options include:
|
46
|
+
# - :type
|
47
|
+
# - :wave_id
|
48
|
+
# - :wavelet_id
|
49
|
+
# - :blip_id
|
50
|
+
# - :index
|
51
|
+
# - :property
|
52
|
+
def initialize(options = {})
|
53
|
+
@type = options[:type]
|
54
|
+
@wave_id = options[:wave_id]
|
55
|
+
@wavelet_id = options[:wavelet_id] || ''
|
56
|
+
@blip_id = options[:blip_id] || ''
|
57
|
+
@index = options[:index] || -1
|
58
|
+
@property = options[:property]
|
59
|
+
end
|
60
|
+
|
61
|
+
#Serialize the operation to json
|
62
|
+
def to_json
|
63
|
+
hash = {
|
64
|
+
'blipId' => @blip_id,
|
65
|
+
'index' => @index,
|
66
|
+
'waveletId' => @wavelet_id,
|
67
|
+
'waveId' => @wave_id,
|
68
|
+
'type' => @type,
|
69
|
+
'javaClass' => JAVA_CLASS
|
70
|
+
}
|
71
|
+
|
72
|
+
hash['property'] = @property unless @property.nil?
|
73
|
+
|
74
|
+
hash.to_json
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
data/lib/models/range.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
# Extend a standard Range so that it can be serialized easily
|
2
|
+
|
3
|
+
class Range # :nodoc:
|
4
|
+
JAVA_CLASS = 'com.google.wave.api.Range'
|
5
|
+
|
6
|
+
# Convert to a hash for sending in an operation.
|
7
|
+
def to_json
|
8
|
+
{
|
9
|
+
'javaClass' => JAVA_CLASS,
|
10
|
+
'start' => min,
|
11
|
+
'end' => max
|
12
|
+
}.to_json
|
13
|
+
end
|
14
|
+
end
|
data/lib/models/robot.rb
CHANGED
@@ -1,61 +1,79 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
#
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
@
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
1
|
+
require 'singleton'
|
2
|
+
require 'yaml'
|
3
|
+
|
4
|
+
module Rave
|
5
|
+
module Models
|
6
|
+
# Contains Robot data, event handlers and cron jobs.
|
7
|
+
class Robot < User
|
8
|
+
include Rave::Mixins::DataFormat
|
9
|
+
include Rave::Mixins::Controller
|
10
|
+
include Singleton
|
11
|
+
|
12
|
+
CONFIG_FILE = 'config.yaml' # :nodoc:
|
13
|
+
|
14
|
+
# Version of the robot, as in the yaml config [String]
|
15
|
+
def version # :nodoc:
|
16
|
+
@version.dup
|
17
|
+
end
|
18
|
+
|
19
|
+
def initialize() # :nodoc:
|
20
|
+
config = config_from_file
|
21
|
+
super(config)
|
22
|
+
@handlers = {}
|
23
|
+
@cron_jobs = []
|
24
|
+
@version = config[:version] || '1'
|
25
|
+
register_default_handlers
|
26
|
+
end
|
27
|
+
|
28
|
+
# Read options from user-edited yaml config file.
|
29
|
+
def config_from_file # :nodoc:
|
30
|
+
config = YAML::load(File.open(CONFIG_FILE))
|
31
|
+
hash = {}
|
32
|
+
config['robot'].each_pair { |k, v| hash[k.to_sym] = v }
|
33
|
+
hash
|
34
|
+
end
|
35
|
+
|
36
|
+
# Register a handler. Multiple handlers may be applied to a single event.
|
37
|
+
# +event_type+:: Must be one of Rave::Models::Event::*::TYPE [String]
|
38
|
+
def register_handler(event_type, handler)
|
39
|
+
raise Rave::InvalidEventException.new("Unknown event: #{event_type}") unless Rave::Models::Event.valid_type?(event_type)
|
40
|
+
raise Rave::InvalidHandlerException.new("Unknown handler: #{handler}") unless self.respond_to?(handler)
|
41
|
+
@handlers[event_type] ||= []
|
42
|
+
@handlers[event_type] << handler unless @handlers[event_type].include?(handler)
|
43
|
+
end
|
44
|
+
|
45
|
+
#Dispatches events to the appropriate handler
|
46
|
+
def handle_event(event, context) # :nodoc:
|
47
|
+
#Ignore unhandled events
|
48
|
+
if (handlers = @handlers[event.type])
|
49
|
+
handlers.each do |handler|
|
50
|
+
self.send(handler, event, context)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
#Registers a cron job
|
56
|
+
def register_cron_job(handler, seconds)
|
57
|
+
@cron_jobs << { :path => "/_wave/cron/#{handler}", :handler => handler, :seconds => seconds }
|
58
|
+
end
|
59
|
+
|
60
|
+
# Creates a new wave with initial participants set.
|
61
|
+
# +participants+:: Humans and/or robots to start in the new wave [Array of String/User]
|
62
|
+
# Returns: The new wave, which contains a root wavelet which itself contains a root blip [Wave]
|
63
|
+
def create_wavelet(participants)
|
64
|
+
@context.create_wavelet(participants)
|
65
|
+
end
|
66
|
+
|
67
|
+
protected
|
68
|
+
#Register any handlers that are defined through naming convention
|
69
|
+
def register_default_handlers # :nodoc:
|
70
|
+
Event.types.each do |type|
|
71
|
+
listener = type.downcase.to_sym
|
72
|
+
if respond_to?(listener)
|
73
|
+
register_handler(type, listener)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
61
79
|
end
|
data/lib/models/user.rb
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
module Rave
|
2
|
+
module Models
|
3
|
+
# A wave client, acting as a wave creator, blip contributor and/or a wavelet participant.
|
4
|
+
class User < Component
|
5
|
+
ROBOT_PATTERN = /@appspot\.com$/ # :nodoc:
|
6
|
+
NOBODY_ID = "@@@nobody@@@" # :nodoc: Used as a default in certain circumstances.
|
7
|
+
|
8
|
+
# Url link to the profile of the User [String].
|
9
|
+
# NOTE: Due to a limitation in Wave, for all users except the local robot
|
10
|
+
# the url will be empty.
|
11
|
+
def profile_url # :nodoc:
|
12
|
+
@profile_url.dup
|
13
|
+
end
|
14
|
+
|
15
|
+
# Url link to the image of the User [String].
|
16
|
+
# NOTE: Due to a limitation in Wave, for all users except the local robot
|
17
|
+
# the url will be empty.
|
18
|
+
def image_url # :nodoc:
|
19
|
+
@image_url.dup
|
20
|
+
end
|
21
|
+
|
22
|
+
# Unlike other components, Users are never generated [Boolean].
|
23
|
+
def generated? # :nodoc:
|
24
|
+
false
|
25
|
+
end
|
26
|
+
|
27
|
+
# - :id
|
28
|
+
# - :name
|
29
|
+
# - :profile_url
|
30
|
+
# - :image_url
|
31
|
+
# - :context
|
32
|
+
def initialize(options = {}) # :nodoc:
|
33
|
+
options[:id].downcase! if options[:id]
|
34
|
+
super(options)
|
35
|
+
@name = options[:name]
|
36
|
+
@profile_url = options[:profile_url] || ''
|
37
|
+
@image_url = options[:image_url] || ''
|
38
|
+
end
|
39
|
+
|
40
|
+
# Printable name of the User [String].
|
41
|
+
# NOTE: Due to a limitation in Wave, for all users except the local robot
|
42
|
+
# the name is the same as the @id.
|
43
|
+
def name # :nodoc:
|
44
|
+
@name || @id
|
45
|
+
end
|
46
|
+
|
47
|
+
# Is the User a robot client rather than a human client? [Boolean]
|
48
|
+
def robot? # :nodoc:
|
49
|
+
not (@id =~ ROBOT_PATTERN).nil?
|
50
|
+
end
|
51
|
+
|
52
|
+
# Convert to string [String]
|
53
|
+
def to_s
|
54
|
+
@id
|
55
|
+
end
|
56
|
+
|
57
|
+
def to_json # :nodoc:
|
58
|
+
@id.to_json
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
data/lib/models/wave.rb
CHANGED
@@ -1,19 +1,45 @@
|
|
1
|
-
|
2
|
-
module
|
3
|
-
|
4
|
-
class Wave
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
#
|
11
|
-
# - :
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
1
|
+
module Rave
|
2
|
+
module Models
|
3
|
+
# Represents a Wave
|
4
|
+
class Wave < Component
|
5
|
+
# IDs for all wavelets that are part of the wave [Array of String]
|
6
|
+
def wavelet_ids # :nodoc:
|
7
|
+
@wavelet_ids.map { |id| id.dup }
|
8
|
+
end
|
9
|
+
|
10
|
+
#Options include:
|
11
|
+
# - :wavelet_ids
|
12
|
+
# - :id
|
13
|
+
def initialize(options = {}) # :nodoc:
|
14
|
+
if options[:id].nil? and options[:context]
|
15
|
+
super(:id => "#{GENERATED_PREFIX}_wave_#{unique_id}", :context => options[:context])
|
16
|
+
else
|
17
|
+
super(options)
|
18
|
+
end
|
19
|
+
|
20
|
+
@wavelet_ids = options[:wavelet_ids] || []
|
21
|
+
end
|
22
|
+
|
23
|
+
# All wavelets that are part of the wave [Array of Wavelet]
|
24
|
+
def wavelets # :nodoc:
|
25
|
+
@wavelet_ids.map { |id| @context.wavelets[id] }
|
26
|
+
end
|
27
|
+
|
28
|
+
# The root wavelet (it will be nil if the event refers to a private subwavelet) [Wavelet]
|
29
|
+
def root_wavelet # :nodoc:
|
30
|
+
wavelets.find { |wavelet| wavelet and wavelet.root? }
|
31
|
+
end
|
32
|
+
|
33
|
+
def print_structure(indent = 0) # :nodoc:
|
34
|
+
str = ''
|
35
|
+
str << "#{' ' * indent}Wave:#{@id}\n"
|
36
|
+
|
37
|
+
wavelets.each do |wavelet|
|
38
|
+
str << wavelet.print_structure(indent + 1)
|
39
|
+
end
|
40
|
+
|
41
|
+
str
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|