Permalink
Browse files

Lotsa changes. All users are now represented with a WaveUser object, …

…for better or for worse. Also, the site has a navbar now. Proper threading will be soon now that I redid how the conversation is parsed/stored.
  • Loading branch information...
1 parent 891d7d5 commit e828dc7d29f8fdc233d296a15741f4e263328b5e @danopia committed Nov 16, 2009
View
@@ -1,3 +1,4 @@
rails/db/*.sqlite3
rails/log
doc
+geany_run_script.sh
View
@@ -4,34 +4,47 @@ module Sails
# Represents a certain version of a Blip at a certain point in time. Playback
# creates instances of this class for you. Mainly is a list of contents.
class Blip
- attr_accessor :name, :authors, :last_changed, :contents, :special, :annotations
+ attr_accessor :name, :authors, :last_changed, :contents, :special, :annotations, :parent, :threads
def initialize name
@name = name
@authors = []
@contents = ''
@special = []
@annotations = []
+ @threads = []
end
- # Hackity hack
- def create_fedone_line(author, text)
- arr = [
- {:element_start=>
- {:type=>"line",
- :attributes=>
- [{:value=>author, :key=>"by"}]}},
- {:element_end=>true},
- {:characters=>text}]
-
- arr.insert(0, {:retain_item_count=>item_count}) if @contents.size > 0
- arr
+ def parent_blip
+ return nil unless @parent
+ return nil unless @parent.parent.is_a? Blip
+ @parent.parent
end
def digest
@contents.gsub("\001", '')
end
+ def << thread
+ @threads << thread
+ end
+
+ def children
+ kids = []
+ threads.each do |thread|
+ kids += thread.to_arr
+ end
+ kids
+ end
+
+ def flatten
+ kids = []
+ threads.each do |thread|
+ kids += thread.flatten
+ end
+ kids
+ end
+
# Dumps the current version of this Blip instance to XML. Note that said
# XML probably won't be value XML in practice.
def to_xml
View
@@ -1,10 +1,6 @@
require 'rubygems'
require 'active_record'
require 'yaml'
-#require 'authlogic'
-#require 'models/user'
-
-puts 'hi'
module Sails
View
@@ -15,7 +15,7 @@ class Delta < BaseDelta
# version=. You should also try to set the time, if you can get it.
def initialize wave, author=nil
@wave = wave
- @author = author
+ self.author = author
@version = wave.newest_version
@time = Time.now.to_i * 1000
@commited = false
@@ -38,6 +38,13 @@ def local?
@server == @wave.provider.local
end
+ def author=(author)
+ author = "#{author.login}@#{@wave.provider.domain}" if author.is_a? User
+ author = @wave.provider.find_or_create_user author unless author.is_a? WaveUser
+
+ @author = author
+ end
+
# Parses an incoming delta, taking the wavelet name (from the XML attribute)
# and the bytestring (doesn't handle Base64). It will handle adding the delta
# to a wave, creating the wave if it doesn't exist, and sending out the delta
@@ -105,7 +112,7 @@ def self.parse provider, wavelet, data, applied=false
end
# Add an operation to the delta.
- def <<(operation)
+ def << operation
@operations << operation
@version += 1
end
@@ -115,7 +122,7 @@ def <<(operation)
def delta_data
hash = {
:applied_to => prev_version,
- :author => @author.downcase}
+ :author => @author.to_s}
hash[:operations] = @operations.map{|op|op.to_hash} if @operations.any?
hash
end
@@ -166,12 +173,6 @@ def to_s
# Get an "applied delta", ready to send out to slave servers.
def to_applied
return @to_applied if @to_applied && @frozen
- pp({
- :signed_delta => to_s,
- :applied_to => prev_version,
- :operations_applied => @operations.size, # operations applied
- :timestamp => @time#.to_i * 1000 # milliseconds not needed yet
- })
@to_applied = Sails::ProtoBuffer.encode(:applied_delta, {
:signed_delta => to_s,
:applied_to => prev_version,
@@ -202,7 +203,6 @@ def freeze
@hash = nil
@to_s = nil
@to_applied = nil
- #@signature = nil
end
alias commited? commited
@@ -228,17 +228,17 @@ def commit!
# Make a list of servers to send to
targets = []
people.each do |person|
- person =~ /^.+@(.+)$/
+ person.to_s =~ /^.+@(.+)$/
targets << $1 if $1
end
targets.uniq!
- # Don't send back to ourselfs
+ # Don't send back to ourself
targets.delete @wave.provider.domain
unless targets.empty?
- packet = "<request xmlns=\"urn:xmpp:receipts\"/><event xmlns=\"http://jabber.org/protocol/pubsub#event\"><items><item><wavelet-update xmlns=\"http://waveprotocol.org/protocol/0.2/waveserver\" wavelet-name=\"#{@wave.conv_root_path}\"><applied-delta><![CDATA[#{encode64(self.to_applied)}]]></applied-delta></wavelet-update></item></items></event>"
+ packet = "<request xmlns=\"urn:xmpp:receipts\"/><event xmlns=\"http://jabber.org/protocol/pubsub#event\"><items><item><wavelet-update xmlns=\"http://waveprotocol.org/protocol/0.2/waveserver\" wavelet-name=\"#{@wave.conv_root_path}\"><applied-delta><![CDATA[#{encode64(to_applied)}]]></applied-delta></wavelet-update></item></items></event>"
puts "Sending to #{targets.join(', ')}"
View
@@ -15,7 +15,7 @@ def initialize delta
def author= author
@delta.author = author
- @author = author
+ @author = @delta.author
end
def create_conv
@@ -105,10 +105,10 @@ def add operation
end
def add_user participant
- add Operations::AddUser.new(participant)
+ add Operations::AddUser.new(@wave.provider.find_or_create_user(participant))
end
def remove_user participant
- add Operations::RemoveUser.new(participant)
+ add Operations::RemoveUser.new(@wave.provider.find_or_create_user(participant))
end
def mutate blip, components=[]
blip = blip.name if blip.is_a? Sails::Blip
View
@@ -1,5 +1,7 @@
-module Sails::Operations
+module Sails
+
+module Operations
class Operation
end
@@ -29,7 +31,7 @@ def initialize(who=[])
class AddUser < UserOperation
# Create a hash, for use in ProtoBuffer encoding methods.
def to_hash
- {:added => @who.map{|who|who.downcase}}
+ {:added => @who.map{|who|who.to_s.downcase}}
end
# Human-readable string; i.e. "Added me@danopia.net to the wave"
@@ -91,3 +93,5 @@ def to_s
end # module
+end # module
+
View
@@ -5,7 +5,7 @@ module Sails
# back, version by version, to HEAD. At any step, you can grab participants,
# XML representation, etc.
class Playback
- attr_accessor :wave, :version, :participants, :blips, :conv
+ attr_accessor :wave, :version, :participants, :thread, :conv, :blips
# Creates a new Playback instance for a wave. Without a version param, it
# defaults to starting at version 0. This is useful for playing through a
@@ -15,19 +15,28 @@ def initialize(wave, version=0)
@wave = wave
@version = 0
@participants = []
- @blips = []
- @blips2 = []
@conv = []
+ @blips = {}
self.apply version if version != 0
end
+ def thread
+ @conv.first
+ end
+
# Returns true if this Playback instance is at the latest version of the
# wave.
def at_newest?
@version == @wave.newest_version
end
+ def has_user? address
+ @participants.select do |user|
+ user.to_s == address.to_s.downcase
+ end.any?
+ end
+
# Applies the specified delta, including any before it if necesary. Shortcuts
# are :next and :newest. You can also use a version number.
def apply(version)
@@ -61,20 +70,27 @@ def apply(version)
delta.operations.each do |op|
if op.is_a? Operations::AddUser
- @participants += op.who
- pp op.who
+ @participants += op.who.map do |user|
+ @wave.provider.find_or_create_user user
+ end
end
- @participants -= op.who if op.is_a? Operations::RemoveUser
+
+ if op.is_a? Operations::RemoveUser
+ @participants.delete_if do |user|
+ op.who.include? user.to_s
+ end
+ end
+
if op.is_a? Operations::Mutate
puts "Mutation to #{op.document_id}"
if op.document_id == 'conversation'
- self.apply_conv_mutate(op.components)
+ apply_conv_mutate op.components
else
if op.components.any?
- self.blip(op.document_id).apply_mutate(delta.author, op.components)
+ @blips[op.document_id].apply_mutate delta.author, op.components
else
+ @blips[op.document_id] = Blip.new op.document_id
puts "New blip #{op.document_id}"
- @blips2 << Blip.new(op.document_id)
end
end
end
@@ -84,77 +100,62 @@ def apply(version)
end
# Look up a blip or create it
- def [] blip_id
- blips = @blips2.flatten.select {|blip| blip.name == blip_id}
+ def [](blip_id)
+ blips = @thread.flatten.select {|blip| blip.name == blip_id}
return blips.first if blips.any?
Blip.new blip_id
end
alias blip []
- def parent blip
- blip find(blip.name, @blips)
- end
-
- def find needle, haystack
- haystack.each do |item|
- if item.is_a? Array
- result = find(needle, item)
- if result == true
- return haystack[haystack.index(item) - 1]
- elsif result
- return result
- end
- elsif item == needle
- return true
- end
- end
- nil
- end
-
protected
# Apply a mutation. Does NO version checking!
def apply_conv_mutate(operations)
- item = 0 # in the 'conv' array
+ index = 0
+ stack = []
+
operations.compact.each do |component|
if component[:retain_item_count]
- item += component[:retain_item_count]
+ component[:retain_item_count].times do
+ if @conv[index] == :end
+ stack.pop
+ else
+ stack << @conv[index]
+ end
+ index += 1
+ end
elsif component[:element_start]
- element = Element.new(component[:element_start][:type])
+
+ attributes = {}
(component[:element_start][:attributes] || []).each do |attribute|
- element[attribute[:key]] = attribute[:value]
+ attributes[attribute[:key]] = attribute[:value]
end
- @conv.insert(item, element)
- item += 1
+ item = nil
+ case component[:element_start][:type]
+ when 'conversation': item = Thread.new; @thread = item
+ when 'blip': item = @blips[attributes['id']]
+ when 'thread': item = Thread.new(stack.last, attributes['id'])
+ end
+
+ raise "wth is #{component[:element_start][:type]}" unless item
+
+ item.parent = stack.last || self
+ stack.last << item if stack.last
+ stack << item
+
+ @conv.insert index, item
+ index += 1
elsif component[:element_end]
- @conv.insert(item, :end)
- item += 1
- end
- end
-
- read_conv
- end
-
- def read_conv
- p @conv
- stack = [[]]
-
- @conv.each do |item|
- if item.is_a? Element
- next if item.type == 'conversation'
- stack.last << item['id']
- stack.push []
- elsif item == :end && stack.size >= 2
- arr = stack.pop
- stack.last << arr if arr.any?
+ @conv.insert index, :end
+ stack.pop
+ index += 1
+
end
end
-
- @blips = stack
end
end # class
Oops, something went wrong.

0 comments on commit e828dc7

Please sign in to comment.