Skip to content

Instantly share code, notes, and snippets.

@emk
Created September 5, 2009 11:28
Show Gist options
  • Save emk/181379 to your computer and use it in GitHub Desktop.
Save emk/181379 to your computer and use it in GitHub Desktop.
A port of the Google Wave FedOne Echoey.java agent to Ruby
# Copyright 2009 Google Inc. (original Java code)
# Copyright 2009 Eric Kidd (Ruby translation)
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# Usage: jruby rechoey.rb rechoey@domain server port
require 'java'
require 'dist/fedone-agent-api-0.2.jar'
import 'com.google.common.collect.ImmutableMap'
import 'org.waveprotocol.wave.examples.fedone.agents.agent.AbstractAgent'
import 'org.waveprotocol.wave.examples.fedone.agents.agent.AgentConnection'
import 'org.waveprotocol.wave.examples.fedone.waveclient.common.ClientUtils'
import 'org.waveprotocol.wave.examples.fedone.waveclient.console.ConsoleUtils'
import 'org.waveprotocol.wave.model.document.operation.DocOpCursor'
import 'org.waveprotocol.wave.model.document.operation.impl.AttributesImpl'
import 'org.waveprotocol.wave.model.document.operation.impl.BufferedDocOpImpl'
import 'org.waveprotocol.wave.model.operation.wave.WaveletDocumentOperation'
# This is a simple translation of the Java Echoey code.
class REchoey < AbstractAgent
def initialize(username, hostname, port=9876)
super(AgentConnection.new_connection(username, hostname, port))
end
def doc_size wavelet, doc_name
doc = wavelet.documents.get(doc_name)
doc ? ClientUtils.find_document_size(doc) : 0
end
def append_lines(wavelet, lines)
# Build the operation we want to perform on the document.
builder = BufferedDocOpImpl::DocOpBuilder.new
size = doc_size(wavelet, "main")
builder.retain(size) if size > 0
line_attrs = ImmutableMap.of(ConsoleUtils::LINE_AUTHOR, participant_id)
builder.element_start(ConsoleUtils::LINE, AttributesImpl.new(line_attrs))
builder.element_end
lines.each {|line| builder.characters(line) unless line.empty? }
# Send the operation.
op = WaveletDocumentOperation.new("main", builder.finish)
send_wavelet_operation(wavelet.wavelet_name, op)
end
def append_line(wavelet, line)
append_lines(wavelet, [line])
end
def onDocumentChanged(wavelet, operation)
extractor = TextExtractor.new
operation.operation.apply(extractor)
append_lines(wavelet, extractor.lines)
end
def onParticipantAdded(wavelet, participant)
append_line(wavelet, "#{participant.address} was added to this wavelet.")
end
def onParticipantRemoved(wavelet, participant)
append_line(wavelet, "#{participant.added} was removed from this wavelet.")
end
def onSelfAdded(wavelet)
append_line(wavelet, "I'm listening.")
end
def onSelfRemoved(wavelet)
append_line(wavelet, "Goodbye.")
end
# Iterate over a document operation and extract all the newly-inserted text.
class TextExtractor
include DocOpCursor
attr_reader :lines
def initialize()
@lines = []
end
def annotationBoundary(map) end
def characters(chars)
lines << chars
end
def deleteCharacters(chars) end
def deleteElementEnd() end
def deleteElementStart(type, attrs) end
def elementEnd() end
def elementStart(type, attrs) end
def replaceAttributes(oldAttrs, newAttrs) end
def retain(itemCount) end
def updateAttributes(attrUpdate) end
end
end
# Parse our command-line arguments and run rechoey.
if ARGV.length != 3
STDERR.puts "Usage: jruby rechoey.rb user@domain server port"
exit 1
end
username, hostname, port = ARGV
e = REchoey.new(username, hostname, port.to_i)
e.run
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment