Skip to content

Instantly share code, notes, and snippets.

@ajesler
Created April 3, 2012 12:12
Show Gist options
  • Save ajesler/2291504 to your computer and use it in GitHub Desktop.
Save ajesler/2291504 to your computer and use it in GitHub Desktop.
Shows the last unread or total number of missed skype messages. Windows only.
require 'thread'
class ActionOnLatest
attr_accessor :queue, :mutex, :val
def initialize
@queue = Queue.new
@mutex = Mutex.new
end
def push(item)
@mutex.synchronize {
@val = item
puts "item='#{item}'"
@queue.clear
@queue.push 1
}
end
# callback should be a lambda
def loop(callback)
while 1 do
@queue.pop
item = nil
@mutex.synchronize {
item = @val
}
# now execute the callback with the val
callback.call(item)
end
end
end
# sample from http://blog.saush.com/2006/11/21/accessing-skype-apis-with-ruby/
# see also http://pastebin.com/hYM327Lv
require 'win32ole'
require 'badge.rb'
require 'action-on-latest.rb'
include B1236
# run like: ruby display-last-missed-message.rb "COM4"
# create the new Skype automation object
skype = WIN32OLE.new 'Skype4COM.Skype'
port = ARGV[0]
# create the badge controller
$BADGE = Badge.new port
$AOL = ActionOnLatest.new
$MESSAGE_COUNT = 0
# some constants for easy viewing
$RECEIVED= skype.Convert.TextToChatMessageStatus("RECEIVED")
$SAID = skype.Convert.TextToChatMessageType("SAID")
$READ = skype.Convert.TextToChatMessageStatus("READ")
t = Thread.new do
puts "Starting badge writer thread"
lam = lambda { |msg|
$BADGE.set_message msg
# the sleep is needed as the badge cant handle rapid updates.
sleep 1
}
$AOL.loop lam
end
# clear any existing message
puts "Clearing badge display..."
$AOL.push ""
puts "Attaching..."
# attach to Skype
skype.attach
puts "registering..."
# register to receive events from Skype
event = WIN32OLE_EVENT.new(skype, '_ISkypeEvents')
def set_message(message, fromUser)
if message == nil
display = ""
else
display = "#{fromUser} said #{message}"
end
puts "set_message [#{display}]"
$DISPLAYED_MESSAGE = { :fromUser => fromUser, :message => message}
$AOL.push display
end
def displayed_message_read(message, fromUser)
# timestamp could be useful here to make sure it is the correct message.
($DISPLAYED_MESSAGE[:fromUser] == fromUser && $DISPLAYED_MESSAGE[:message] == message)
end
def default_handler(event, *args)
#puts "#{event}"
case event
when "MessageStatus"
msg = args[0]
status = args[1]
#puts "status=#{status} : #{msg} [ Type=#{msg.Type}, from=#{msg.FromDisplayName}, body=#{msg.body} ]"
# if we read a message, check it is not being displayed, and if it is, clear the screen.
if msg.Type == $SAID && status == $READ
#puts "read message from #{msg.FromDisplayName}: #{msg.body}"
# check if we are currently showing this message
if displayed_message_read(msg.body, msg.FromDisplayName)
#puts "clearing message"
set_message(nil, nil)
end
end
if msg.Type == $SAID && status == $RECEIVED
message = msg.body
fromUser = msg.FromDisplayName
#puts "#{fromUser} said #{message}"
# display the message on the badge
set_message(message, fromUser)
end
end
end
# on any event at all, go to the default handler
event.on_event {|*args| default_handler(*args)}
# loop forever
catch(:done) do
loop do
WIN32OLE_EVENT.message_loop
end
end
require 'win32ole'
require 'badge.rb'
require 'action-on-latest.rb'
include B1236
# This should be run like so: ruby display-unread-message-count.rb "COM4"
# Make sure that the unread message count is 0 when you start this script.
# create the new Skype automation object
skype = WIN32OLE.new 'Skype4COM.Skype'
port = ARGV[0]
# create the badge controller
$BADGE = Badge.new port
$AOL = ActionOnLatest.new
$MESSAGE_COUNT = 0
# some constants for easy viewing
$RECEIVED= skype.Convert.TextToChatMessageStatus("RECEIVED")
$SAID = skype.Convert.TextToChatMessageType("SAID")
$READ = skype.Convert.TextToChatMessageStatus("READ")
t = Thread.new do
puts "Starting badge writer thread"
lam = lambda { |msg|
$BADGE.set_message msg
# the sleep is needed as the badge cant handle rapid updates.
sleep 1
}
$AOL.loop lam
end
# clear any existing message
puts "Clearing badge display..."
$AOL.push ""
puts "Attaching..."
# attach to Skype
skype.attach
puts "registering..."
# register to receive events from Skype
event = WIN32OLE_EVENT.new(skype, '_ISkypeEvents')
def update_display
if $MESSAGE_COUNT == 0
$AOL.push ""
else
message = "#{$MESSAGE_COUNT} unread message#{$MESSAGE_COUNT > 1 ? 's.' : '.'}"
$AOL.push message
end
end
def default_handler(event, *args)
#puts "#{event}"
case event
when "MessageStatus"
msg = args[0]
status = args[1]
if msg.Type == $SAID && status == $READ
$MESSAGE_COUNT -= 1
#puts "-1, now #{$MESSAGE_COUNT}"
update_display
end
if msg.Type == $SAID && status == $RECEIVED
$MESSAGE_COUNT += 1
#puts "+1, now #{$MESSAGE_COUNT}"
update_display
end
end
end
# on any event at all, go to the default handler
event.on_event {|*args| default_handler(*args)}
puts "Listening for events..."
# loop forever
catch(:done) do
loop do
WIN32OLE_EVENT.message_loop
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment