Ruby4Skype 0.2.3 → 0.3.1

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.
Files changed (43) hide show
  1. data/LICENSE +3 -0
  2. data/README +14 -0
  3. data/Rakefile +67 -0
  4. data/lib/skypeapi.rb +570 -509
  5. data/lib/skypeapi/application.rb +79 -77
  6. data/lib/skypeapi/call.rb +243 -230
  7. data/lib/skypeapi/chat.rb +162 -172
  8. data/lib/skypeapi/chatmember.rb +26 -28
  9. data/lib/skypeapi/chatmessage.rb +81 -65
  10. data/lib/skypeapi/error.rb +8 -0
  11. data/lib/skypeapi/event.rb +25 -26
  12. data/lib/skypeapi/filetransfer.rb +47 -28
  13. data/lib/skypeapi/group.rb +72 -73
  14. data/lib/skypeapi/menuitem.rb +44 -44
  15. data/lib/skypeapi/message.rb +39 -41
  16. data/lib/skypeapi/object.rb +246 -82
  17. data/lib/skypeapi/os/etc.rb +48 -98
  18. data/lib/skypeapi/os/mac.rb +92 -4
  19. data/lib/skypeapi/os/notifier.rb +31 -0
  20. data/lib/skypeapi/os/window_event_queue.rb +198 -0
  21. data/lib/skypeapi/os/window_messagehandler.rb +120 -0
  22. data/lib/skypeapi/os/windows.rb +170 -306
  23. data/lib/skypeapi/profile.rb +190 -120
  24. data/lib/skypeapi/sharefunctions.rb +31 -23
  25. data/lib/skypeapi/sms.rb +87 -67
  26. data/lib/skypeapi/user.rb +159 -99
  27. data/lib/skypeapi/version.rb +3 -3
  28. data/lib/skypeapi/voicemail.rb +59 -52
  29. data/spec/matcher_be_boolean.rb +10 -0
  30. data/spec/skypeapi/application_spec.rb +76 -0
  31. data/spec/skypeapi/chat_spec.rb +356 -0
  32. data/spec/skypeapi/chatmember_spec.rb +42 -0
  33. data/spec/skypeapi/chatmessage_spec.rb +89 -0
  34. data/spec/skypeapi/event_spec.rb +31 -0
  35. data/spec/skypeapi/filetransfer_spec.rb +67 -0
  36. data/spec/skypeapi/group_spec.rb +16 -0
  37. data/spec/skypeapi/menuitem_spec.rb +37 -0
  38. data/spec/skypeapi/os/windows_spec.rb +305 -0
  39. data/spec/skypeapi/profile_spec.rb +22 -0
  40. data/spec/skypeapi/user_spec.rb +25 -0
  41. data/spec/skypeapi_spec.rb +528 -0
  42. metadata +32 -12
  43. data/lib/skypeapi/os/timer.rb +0 -108
@@ -1,10 +1,98 @@
1
+ require 'osx/cocoa'
2
+ OSX.require_framework 'Skype'
3
+
1
4
  module SkypeAPI
2
5
  module OS
3
6
  class Mac
4
- #sorry...
5
- def initialize
6
- raise SkypeAPIError::NotImplement
7
+ class Server < OSX::NSObject
8
+ def clientApplicationName
9
+ @client_application_name
10
+ end
11
+
12
+ addRubyMethod_withType 'skypeAttachResponse:', 'v@:i'
13
+ def skypeAttachResponse status
14
+ p [:skypeAttachResponse,status]
15
+ case status
16
+ when 0 #?
17
+ when 1 #sccess
18
+ @upper.attached = true
19
+ when 2 ####
20
+ end
21
+ end
22
+
23
+ #addRubyMethod_withType 'skypeBecameAviable:', 'v@:@'
24
+ def skypeBecameAvilable notification
25
+ p [:skypeBecameAvilable,notification]
26
+ end
27
+
28
+ #addRubyMethod_withType 'skypeBecameUnavialbe:', 'v@:@'
29
+ def skypeBecameUnavilable notification
30
+ p [:skypeBecameUnavilable,notification]
31
+ end
32
+
33
+ #addRubyMethod_withType 'skypeAttachResponse:', 'v@:@'
34
+ def skypeNotificationReceived notifation_string
35
+ p [:skypeNotificationReceived,notifation_string]
36
+ end
7
37
  end
38
+
39
+ def initialize client_application_name='ruby4skype'
40
+ raise Skype::Error::NotImplement
41
+
42
+ @server = Server.alloc.init
43
+ @server.instance_variable_set :@upper, self
44
+ @server.instance_variable_set :@client_application_name, @client_application_name
45
+ OSX::SkypeAPI.setSkypeDelegate @server
46
+
47
+ @notify = Hash.new
48
+ @event = Hash.new do |h,k|
49
+ h[k] = Array.new
50
+ end
51
+
52
+ @attached = false
53
+ Thread.new do
54
+ OSX::NSRunLoop.currentRunLoop.run
55
+ end
56
+ end
57
+
58
+ attr_reader :attached
59
+
60
+ def attach
61
+ OSX::SkypeAPI.connect
62
+ end
63
+
64
+ def attach_wait
65
+ self.attach
66
+ loop do
67
+ break if @attached
68
+ sleep 0.123
69
+ end
70
+ end
71
+
72
+ def dettach
73
+ OSX::SkypeAPI.disconnect
74
+ end
75
+
76
+ def skype_runnging?
77
+ OSX::SkypeAPI.isSkypeRunnging
78
+ end
79
+
80
+ def invoke_prototype cmd
81
+ res = OSX::SkypeAPI.sendSkypeCommand(cmd)
82
+ @queue.push(proc{do_event(:sent, cmd)}) if exist_event? :sent
83
+ @queue.push(proc{do_event(:received, res)}) if exist_event? :received
84
+ return res
85
+ end
86
+
87
+ def invoke_callback cmd,cb=Proc.new
88
+ res = invoke_prototype cmd
89
+ cb.call res
90
+ end
91
+
92
+ def invoke_block cmd, waitLimit = WAIT_CMD_LIMIT
93
+ res = invoke_prototype cmd
94
+ end
95
+
8
96
  end
9
97
  end
10
- end
98
+ end
@@ -0,0 +1,31 @@
1
+ module SkypeAPI
2
+ module OS
3
+ class Notifier
4
+ def notify
5
+ @notify ||= Hash.new
6
+ end
7
+
8
+ def add reg, block=Proc.new
9
+ notify[reg] = block
10
+ end
11
+
12
+ def del reg
13
+ notify.delete reg
14
+ end
15
+
16
+ def fire res
17
+ objects_notify_fire = false
18
+ notify.each do |reg, action|
19
+ if res =~ reg
20
+ action.call($1)
21
+ objects_notify_fire = true
22
+ end
23
+ end
24
+
25
+ unless objects_notify_fire
26
+ notify[nil].call(res) if notify[nil]
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,198 @@
1
+ require 'thread'
2
+
3
+ class BlockQueue < Queue #:nodoc: all
4
+ def push_block block=Proc.new
5
+ push block
6
+ end
7
+ end
8
+
9
+ module SkypeAPI
10
+ module OS
11
+ class WindowsEventQueue
12
+ def initialize windows
13
+ @windows = windows
14
+ @pause_count = 0
15
+ @pause_mutex = Mutex.new
16
+ end
17
+
18
+ attr_reader :windows
19
+
20
+ def queue
21
+ @queue ||= BlockQueue.new
22
+ end
23
+
24
+ def length
25
+ @queue.length
26
+ end
27
+
28
+ def received_count
29
+ @received_count ||= 0
30
+ end
31
+ attr_writer :received_count
32
+ private :received_count=
33
+
34
+ def callback
35
+ @callback ||= Hash.new
36
+ end
37
+
38
+ def set_notify_selector block=Proc.new
39
+ @notify_selector = block
40
+ end
41
+
42
+ attr_reader :notify_selector
43
+
44
+ def hook
45
+ @hook ||= Hash.new do |h,k|
46
+ h[k] = Array.new
47
+ end
48
+ end
49
+
50
+ private :queue, :hook, :windows
51
+
52
+ def add_hook sym, block=Proc.new
53
+ hook[sym].push block
54
+ end
55
+
56
+ def del_hook sym, block=nil
57
+ unless block
58
+ hook[sym] = Array.new
59
+ else
60
+ hook[sym].delete block
61
+ end
62
+ end
63
+
64
+ def exist_hook? sym
65
+ if hook[sym].length > 0
66
+ return true
67
+ else
68
+ return false
69
+ end
70
+ end
71
+
72
+ def get_hook sym
73
+ hook[sym] ? true : false
74
+ end
75
+
76
+ def push response
77
+ self.received_count += 1
78
+ response = response.chop
79
+ push_received_hook(response)
80
+
81
+ cmd_num, res = response_match(response)
82
+ if cmd_num
83
+ @windows.wmHandler.del_send_buffer cmd_num.to_i
84
+ set_cmd_response(cmd_num, res)
85
+ else
86
+ when_detached if response_detached?(res)
87
+ push_notify res
88
+ end
89
+ end
90
+
91
+ def push_hook sym, *args
92
+ queue.push_block{ call_hook(sym, *args) }
93
+ end
94
+
95
+ def push_block block=Proc.new
96
+ queue.push block
97
+ end
98
+
99
+ def start_messageloop
100
+ @messageloop_thread = Thread.new{messageloop}
101
+ end
102
+
103
+ def messageloop
104
+ @messageloop_flag = true
105
+ while callback = queue.shift
106
+ sleep 0.001 while paused?
107
+ break if callback == :exit
108
+ callback.call
109
+ end
110
+ @messageloop_flag = false
111
+ end
112
+
113
+ def messagepolling
114
+ until queue.empty?
115
+ sleep 0.001 while paused?
116
+ callback = queue.shift
117
+ break if callback == :exit
118
+ callback.call
119
+ end
120
+ end
121
+
122
+ def close
123
+ queue.clear
124
+ queue.push :exit
125
+ end
126
+
127
+ def paused?
128
+ @pause_count > 0
129
+ end
130
+
131
+ def pause &block
132
+ if block
133
+ _pause
134
+ block.call
135
+ play
136
+ else
137
+ _pause
138
+ end
139
+ end
140
+
141
+ def _pause
142
+ @pause_mutex.synchronized{@pause_count += 1}
143
+ end
144
+
145
+ def paly
146
+ @pause_mutex.synchronized{@pause_count -=1}
147
+ end
148
+
149
+ def push_detached_hook
150
+ #windows.attached = false
151
+ queue.push_block{ call_hook(:detached) }
152
+ #SkypeAPI.attach
153
+ end
154
+
155
+ private
156
+
157
+ def push_received_hook(response)
158
+ queue.push_block{ call_hook(:received, response) }
159
+ end
160
+
161
+ def response_match(res)
162
+ res =~ /^(#(\d+?) )?(.+?)$/m
163
+ return [$2, $3]
164
+ end
165
+
166
+ def when_detached
167
+ windows.attached = false
168
+ queue.push_block{ call_hook(:detached) }
169
+ SkypeAPI.attach
170
+ end
171
+
172
+ def set_cmd_response(cmd_num, res)
173
+ cmd_num = cmd_num.to_i
174
+ if callback[cmd_num]
175
+ cb = callback[cmd_num]
176
+ callback.delete(cmd_num)
177
+ #@windows.invoke_callback_mutex.synchronize do
178
+ cb.call(res)
179
+ @windows.cv.broadcast
180
+ #end
181
+ end
182
+ end
183
+
184
+ def response_detached? res
185
+ res == 'CONNSTATUS LOGGEDOUT'
186
+ end
187
+
188
+ def push_notify res
189
+ queue.push_block{notify_selector.call res} if notify_selector
190
+ end
191
+
192
+ def call_hook sym, *args
193
+ hook[sym].each{ |h| h.call *args }
194
+ end
195
+
196
+ end
197
+ end
198
+ end
@@ -0,0 +1,120 @@
1
+ module SkypeAPI
2
+ module OS
3
+ class MessageHandler < SWin::Window
4
+
5
+ def init skypeAPI, queue
6
+ @skypeAPI = skypeAPI
7
+ @queue = queue
8
+
9
+ @dwDiscoverMsg = RegisterWindowMessage.call("SkypeControlAPIDiscover");
10
+ raise SkypeAPI::Error::Attach.new("SkypeControlAPIDiscover nothing") unless @dwDiscoverMsg
11
+
12
+ @dwAttachMsg = RegisterWindowMessage.call("SkypeControlAPIAttach")
13
+ raise SkypeAPI::Error::Attach.new("SkypeControlAPIAttach nothing") unless @dwAttachMsg
14
+
15
+ addEvent(WM_COPYDATA)
16
+ addEvent(WM_USER_MSG)
17
+ addEvent @dwAttachMsg
18
+
19
+ create unless alive?
20
+ end
21
+
22
+ def attach
23
+ unless PostMessage.call(HWND_BROADCAST, @dwDiscoverMsg, hWnd, 0)
24
+ raise SkypeAPI::Error::Attach.new("SkypeControlAPIDiscover broadcast failure")
25
+ end
26
+ return true
27
+ end
28
+
29
+ def send_buffer
30
+ @send_buffer ||= Hash.new
31
+ end
32
+
33
+ def del_send_buffer num
34
+ @send_buffer.delete num
35
+ end
36
+
37
+ def invoke num, cmd
38
+ unless @hSkypeAPIWindowHandle
39
+ raise SkypeAPI::Error::Attach.new("NullPointerException SendSkype!")
40
+ return false
41
+ end
42
+
43
+ cmd = '#' + num.to_s + ' ' + cmd + "\0"
44
+ pCopyData = application.arg2cstructStr("LLS",0,cmd.length+1,cmd)
45
+ send_buffer[num] = cmd
46
+ unless PostMessage.call(hWnd, WM_USER_MSG, @hSkypeAPIWindowHandle, pCopyData)
47
+ @hSkypeAPIWindowHandle = nil
48
+ raise SkypeAPI::Error::Attach.new("Skype not ready")
49
+ end
50
+ @queue.push_hook(:sent, cmd.chop) if @queue.exist_hook? :sent
51
+ return true
52
+ end
53
+
54
+ def msghandler(sMsg)
55
+ case sMsg.msg
56
+ when @dwAttachMsg
57
+ case sMsg.lParam
58
+ when SKYPECONTROLAPI_ATTACH_SUCCESS
59
+ @hSkypeAPIWindowHandle = sMsg.wParam
60
+ invoke_protocol
61
+ @queue.push_hook(:attach,:success)
62
+
63
+ unless @skypeAPI.attached
64
+ if @skypeAPI.first_attached
65
+ @queue.push_hook(:attached)
66
+ else
67
+ @queue.push_hook(:reattached)
68
+ end
69
+ end
70
+
71
+ @skypeAPI.attached = true
72
+ @skypeAPI.first_attached = false
73
+ when SKYPECONTROLAPI_ATTACH_PENDING_AUTHORIZATION
74
+ @queue.push_hook(:attach,:authorize)
75
+ @queue.push_hook(:authorize)
76
+ when SKYPECONTROLAPI_ATTACH_REFUSED
77
+ @queue.push_hook(:attach,:refused)
78
+ @queue.push_hook(:refused)
79
+ @skypeAPI.attached = false
80
+ when SKYPECONTROLAPI_ATTACH_NOT_AVAILABLE
81
+ @queue.push_hook(:attach, :not_available)
82
+ @queue.push_hook(:not_available)
83
+ @skypeAPI.attached = false
84
+ when SKYPECONTROLAPI_ATTACH_API_AVAILABLE
85
+ @queue.push_hook(:attach, :available)
86
+ @queue.push_hook(:available)
87
+ else
88
+ @queue.push_hook(:attach,:unkown)
89
+ @queue.push_hook(:unkown)
90
+ end
91
+ sMsg.retval = 1
92
+ when WM_COPYDATA
93
+ if sMsg.wParam == @hSkypeAPIWindowHandle
94
+ retval = application.cstruct2array(sMsg.lParam,"LLL")
95
+ cmd = application.pointer2string(retval[2],retval[1])
96
+ @queue.push cmd
97
+ sMsg.retval = 1
98
+ end
99
+ when WM_USER_MSG
100
+ unless SendMessage.call(sMsg.wParam, WM_COPYDATA, sMsg.hWnd, sMsg.lParam)
101
+ raise SkypeAPI::Error::Attach.new("Skype not ready")
102
+ end
103
+ sMsg.retval = 1
104
+ else
105
+ super
106
+ end
107
+ end
108
+
109
+ def invoke_protocol
110
+ #@queue.push Proc.new{@skypeAPI.invoke_callback("PROTOCOL 9999"){}}
111
+ #@queue.push_block{@skypeAPI.invoke_callback("PROTOCOL 9999"){}}
112
+ @skypeAPI.__send__ :invoke_callback, "PROTOCOL 9999", Proc.new{}
113
+ #@queue.push_block{@skypeAPI.invoke_block("PROTOCOL 9999")}
114
+ #@skypeAPI.invoke_block("PROTOCOL 9999")
115
+ end
116
+ private :invoke_protocol
117
+ end
118
+
119
+ end
120
+ end