From 922e9a178b77a6de006f73df06f00f48f12b5f79 Mon Sep 17 00:00:00 2001 From: Andrew Walbran Date: Tue, 26 Aug 2008 23:03:17 +1200 Subject: [PATCH] Creating followers channel --- twitterpathy.rb | 163 +++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 155 insertions(+), 8 deletions(-) diff --git a/twitterpathy.rb b/twitterpathy.rb index 3f43054..fe39dc3 100755 --- a/twitterpathy.rb +++ b/twitterpathy.rb @@ -35,6 +35,13 @@ CONNECTION_STATUS_REASON_CERT_FINGERPRINT_MISMATCH = 11 CONNECTION_STATUS_REASON_CERT_SELF_SIGNED = 12 CONNECTION_STATUS_REASON_CERT_OTHER_ERROR = 13 +# TODO: other flags in this set +CHANNEL_GROUP_FLAG_PROPERTIES = 2048 + +#Handles used for contact lists, of type HANDLE_TYPE_LIST +LIST_HANDLE_FOLLOWERS = 1 +LIST_HANDLE_FRIENDS = 2 + class Twitterpathy < DBus::Object dbus_interface "org.freedesktop.Telepathy.ConnectionManager" do dbus_method :GetParameters, "in proto:s, out parameters:a(susv)" do |proto| @@ -62,7 +69,7 @@ class Twitterpathy < DBus::Object connection_service = $bus.request_service(service) #Create the connection object, and export it on the new service - connection = TwitterConnection.new(object, parameters['account'], parameters['password']) + connection = TwitterConnection.new(object, parameters['account'], parameters['password'], connection_service) connection_service.export(connection) #Send signal @@ -76,10 +83,13 @@ class Twitterpathy < DBus::Object end class TwitterConnection < DBus::Object - def initialize(path, account, password) - puts "initialize TwitterConnection(#{path}, #{account}, ***)" + attr_reader :me, :myfollowerhandles + + def initialize(path, account, password, connection_service) + puts "initialize TwitterConnection(#{path}, #{account}, ***, #{connection_service})" @account = account @password = password + @connection_service = connection_service @status = CONNECTION_STATUS_CONNECTING @handles = {HANDLE_TYPE_NONE => {}, HANDLE_TYPE_CONTACT => {}, HANDLE_TYPE_ROOM => {}, HANDLE_TYPE_LIST => {}, HANDLE_TYPE_GROUP => {}} super(path) @@ -96,9 +106,24 @@ class TwitterConnection < DBus::Object puts "Connected as #{@me.inspect}" + #Load followers + myfollowers = @twitter_client.my(:followers) + @myfollowerhandles = myfollowers.map{|follower| follower.id } + myfollowers.each do |follower| + @handles[HANDLE_TYPE_CONTACT][follower.id] = follower + end + + followers_channel_object = "/org/freedesktop/Telepathy/Connection/Twitterpathy/twitter/#{@account}/contactlist/followers" + followers_channel = FollowersChannel.new(followers_channel_object, self) + @connection_service.export(followers_channel) + + @channels = [[followers_channel_object, 'org.freedesktop.Telepathy.Channel.Type.ContactList', HANDLE_TYPE_LIST, LIST_HANDLE_FOLLOWERS]] + @handles[HANDLE_TYPE_LIST][LIST_HANDLE_FOLLOWERS] = followers_channel + @status = CONNECTION_STATUS_CONNECTED StatusChanged(@status, CONNECTION_STATUS_REASON_REQUESTED) + NewChannel(followers_channel_object, 'org.freedesktop.Telepathy.Channel.Type.ContactList', HANDLE_TYPE_LIST, LIST_HANDLE_FOLLOWERS, false) end dbus_method :Disconnect, '' do || @@ -138,9 +163,7 @@ class TwitterConnection < DBus::Object end dbus_method :ListChannels, 'out channels:a(osuu)' do || - # TODO - channels = [] - [channels] + [@channels] end dbus_method :ReleaseHandles, 'in handle_type:u, in handles:au' do |handle_type, handles| @@ -148,12 +171,18 @@ class TwitterConnection < DBus::Object end dbus_method :RequestChannel, 'in type:s, in handle_type:u, in handle:u, in suppress_handler:b, out channel:o' do |type, handle_type, handle, suppress_handler| - # TODO - channel = '' + if type == 'org.freedesktop.Telepathy.Channel.Type.ContactList' && handle_type == HANDLE_TYPE_LIST && handle == LIST_HANDLE_FOLLOWERS + channel = "/org/freedesktop/Telepathy/Connection/Twitterpathy/twitter/#{@account}/contactlist/followers" + else + # TODO: throw org.freedesktop.Telepathy.Error.NotImplemented or org.freedesktop.Telepathy.Error.InvalidHandle + channel = '' + end [channel] end dbus_method :RequestHandles, 'in handle_type:u, in names:as, out handles:au' do |handle_type, names| + puts "RequestHandles(#{handle_type.inspect}, #{names.inspect})" + if handle_type == HANDLE_TYPE_CONTACT handles = names.map {|name| # TODO: make this more efficient? @@ -173,6 +202,15 @@ class TwitterConnection < DBus::Object contact_handle } + elsif handle_type = HANDLE_TYPE_LIST + handles = names.map {|name| + if name == 'publish' + LIST_HANDLE_FOLLOWERS + else + # TODO + 0 + end + } else # TODO: other types handles = [] @@ -186,6 +224,115 @@ class TwitterConnection < DBus::Object end end +class FollowersChannel < DBus::Object + def initialize(path, connection) + @connection = connection + @properties = { + 'org.freedesktop.Telepathy.Channel' => { + 'ChannelType' => ['s', 'org.freedesktop.Telepathy.Channel.Type.ContactList'], + 'Interfaces' => ['as', ['org.freedesktop.Telepathy.Channel.Interface.Group']], + 'TargetHandle' => ['u', LIST_HANDLE_FOLLOWERS], + 'TargetID' => ['s', 'Followers'], + 'TargetHandleType' => ['u', HANDLE_TYPE_LIST] + }, + 'org.freedesktop.Telepathy.Channel.Interface.Group' => { + 'GroupFlags' => ['u', CHANNEL_GROUP_FLAG_PROPERTIES], + 'HandleOwners' => ['a{uu}', {}], + 'LocalPendingMembers' => ['a(uuus)', []], + 'Members' => ['au', connection.myfollowerhandles], + 'RemotePendingMembers' => ['au', []], + 'SelfHandle' => ['u', connection.me.id] + } + } + super(path) + end + + dbus_interface 'org.freedesktop.Telepathy.Channel' do + dbus_method :Close, '' do || + # TODO: throw org.freedesktop.Telepathy.Error.NotImplemented + end + + #Deprecated methods, just return appropriate properties + dbus_method :GetChannelType, 'out ChannelType:s' do || + [@properties['org.freedesktop.Telepathy.Channel']['ChannelType'][1]] + end + + dbus_method :GetHandle, 'out TargetHandleType:u, out TargetHandle:u' do || + [@properties['org.freedesktop.Telepathy.Channel']['TargetHandleType'][1], @properties['org.freedesktop.Telepathy.Channel']['TargetHandle'][1]] + end + + dbus_method :GetInterfaces, 'out Interfaces:as' do || + [@properties['org.freedesktop.Telepathy.Channel']['Interfaces'][1]] + end + + dbus_signal :Closed, '' + end + + # TODO: make a nice general way to add properties to classes + dbus_interface 'org.freedesktop.DBus.Properties' do + dbus_method :Get, 'in interface_name:s, in property_name:s, out value:v' do |interface_name, property_name| + value = @properties[interface_name][property_name] + [value] + end + + dbus_method :Set, 'in interface_name:s, in property_name:s, in value:v' do |interface_name, property_name, value| + end + + dbus_method :GetAll, 'in interface_name:s, out props:a{sv}' do |interface_name| + props = @properties[interface_name] + [props] + end + end + + dbus_interface 'org.freedesktop.Telepathy.Channel.Type.ContactList' do + end + + dbus_interface 'org.freedesktop.Telepathy.Channel.Interface.Group' do + dbus_method :AddMembers, 'in contacts:au, in message:s' do |contacts, message| + # TODO + end + + dbus_method :RemoveMembers, 'in contacts:au, in message:s' do |contacts, message| + # TODO + end + + dbus_method :RemoveMembersWithReason, 'in contacts:au, in message:s, in reason:u' do |contacts, message, reason| + # TODO + end + + #Deprecated methods + dbus_method :GetGroupFlags, 'out GroupFlags:u' do || + [@properties['org.freedesktop.Telepathy.Channel.Interface.Group']['GroupFlags'][1]] + end + + dbus_method :GetLocalPendingMembers, 'out LocalPendingMembers:au' do || + [@properties['org.freedesktop.Telepathy.Channel.Interface.Group']['LocalPendingMembers'][1].map{|member| member[0]}] + end + + dbus_method :GetLocalPendingMembersWithInfo, 'out LocalPendingMembers:a(uuus)' do || + [@properties['org.freedesktop.Telepathy.Channel.Interface.Group']['LocalPendingMembers'][1]] + end + + dbus_method :GetMembers, 'out Members:au' do || + puts "GetMembers, returning #{@properties['org.freedesktop.Telepathy.Channel.Interface.Group']['Members'][1].inspect}" + [@properties['org.freedesktop.Telepathy.Channel.Interface.Group']['Members'][1]] + end + + dbus_method :GetRemotePendingMembers, 'out RemotePendingMembers:au' do || + [@properties['org.freedesktop.Telepathy.Channel.Interface.Group']['RemotePendingMembers'][1]] + end + + dbus_method :GetSelfHandle, 'out SelfHandle:u' do || + [@properties['org.freedesktop.Telepathy.Channel.Interface.Group']['SelfHandle'][1]] + end + + dbus_signal :HandleOwnersChanged, 'added:a{uu}, removed:au' + dbus_signal :SelfHandleChanged, 'self_handle:u' + dbus_signal :GroupFlagsChanged, 'added:u, removed:u' + dbus_signal :MembersChanged, 'message:s, added:au, removed:au, local_pending:au, remote_pending:au, actor:u, reason:u' + end +end + $bus = DBus::SessionBus.instance service = $bus.request_service("org.freedesktop.Telepathy.ConnectionManager.Twitterpathy") -- 2.11.4.GIT