diff --git a/addon.py b/addon.py index 7f51ef8..6067895 100644 --- a/addon.py +++ b/addon.py @@ -1,13 +1,17 @@ import xbmc import xbmcaddon import xbmcgui - +from threading import Thread +import os +import time __addon__ = xbmcaddon.Addon() __addonname__ = __addon__.getAddonInfo('name') __icon__ = __addon__.getAddonInfo('icon') __addonpath__ = __addon__.getAddonInfo('path').decode('utf-8') +__windowopen__ = True + #capture a couple of actions to close the window ACTION_PREVIOUS_MENU = 10 ACTION_BACK = 92 @@ -17,6 +21,7 @@ profileHandle = "" profileAvatarPath = "" friends = [] +wRinging = "" #--------------------------------------------------------------------------------------------------------------------- # @@ -28,31 +33,84 @@ def onAction( self, action ): self.close() def onClick(self, controlId): xbmc.log("Skype : action on click : " + str(controlId)) + if (controlId == 122): + friendHandle = self.friendsList.getSelectedItem().getProperty('friend_handle') + friendName = self.friendsList.getSelectedItem().getProperty('friend_name') + friendAvatar = self.friendsList.getSelectedItem().getProperty('friend_avatar') + callFriend(friendHandle, friendName, friendAvatar) def onInit(self): global profileName global profileAvatarPath global friends + self.groupFriends = self.getControl(120) + self.friendsList = self.getControl(122) + self.userNameControl = self.getControl(1) + self.avatarControl = self.getControl(2) self.updateUserInformation(profileName, profileAvatarPath) self.updateFriendsList(friends) xbmc.log("Skype : end of init") def onControl(self, control): xbmc.log("Skype : control on window : " + str(control.getId())) def updateUserInformation( self, name, avatar): - self.userNameControl = self.getControl(1) self.userNameControl.setLabel(profileName) - self.avatarControl = self.getControl(2) self.avatarControl.setImage(profileAvatarPath) xbmc.log("Skype : end of updateUserInformation") def updateFriendsList(self, friends): - self.friendsList = self.getControl(3) self.friendsList.reset() for f in friends: item = xbmcgui.ListItem(f.fullName) item.setIconImage(f.avatar) + item.setProperty('friend_handle', f.handle) + item.setProperty('friend_name', f.fullName) + item.setProperty('friend_avatar', f.avatar) #item.setPath('Notification(header,item #1 clicked)') self.friendsList.addItem( item ) xbmc.log("Skype : friends list updated") + self.setFocusId(122) + +#--------------------------------------------------------------------------------------------------------------------- +# +class RingingWindow( xbmcgui.WindowXMLDialog ): + def __init__( self, *args, **kwargs ): pass + def onClick(self, controlId): + xbmc.log("Skype : action on click : " + str(controlId)) + if (controlId == 133): + skypeAction = self.getControl(133).getSelectedItem().getProperty('skype_action') + xbmc.log("Skype : request action '" + skypeAction + "'") + if (skypeAction == "accept"): + runAccept() + if (skypeAction == "refuse"): + runRefuse() + def ringing(self, friendName, friendAvatar, mode): + self.show() + self.actionsList = self.getControl(133) + self.titleCtrl = self.getControl(132) + self.avatarCtrl = self.getControl(131) + self.friendNameCtrl = self.getControl(134) + self.actionsList.reset() + self.avatarCtrl.setImage(friendAvatar) + if (mode == "incoming"): + self.titleCtrl.setLabel("Incoming Call") + item = xbmcgui.ListItem("Accept") + item.setIconImage("accept.png") + item.setProperty('skype_action', "accept") + self.actionsList.addItem( item ) + + item = xbmcgui.ListItem("Refuse") + item.setIconImage("refuse.png") + item.setProperty('skype_action', "refuse") + self.actionsList.addItem( item ) + else: + self.titleCtrl.setLabel("Calling...") + + item = xbmcgui.ListItem("Cancel") + item.setIconImage("refuse.png") + item.setProperty('skype_action', "refuse") + self.actionsList.addItem( item ) + + self.friendNameCtrl.setLabel(friendName) + self.setFocusId(133) #--------------------------------------------------------------------------------------------------------------------- #Read Profile information and update global vars @@ -92,19 +150,105 @@ def loadFriends(): for f in friendNodes: handle = f.getElementsByTagName('handle')[0].childNodes[0].nodeValue avatar = f.getElementsByTagName('avatar')[0].childNodes[0].nodeValue - name = avatar + name = handle if len(f.getElementsByTagName('name')[0].childNodes) > 0: name = f.getElementsByTagName('name')[0].childNodes[0].nodeValue friends.append(skypeFriend(handle, name, avatar)) xbmc.log("Skype : " + str(len(friends)) + " friends found") +#--------------------------------------------------------------------------------------------------------------------- +# +def cleanUp(): + + filePath = __addon__.getSetting( 'skypexmlcontroller_var_path') + "kodi2skype\\action.xml" + if os.path.isfile(filePath): + os.remove(filePath) + +#--------------------------------------------------------------------------------------------------------------------- +# +def checkCallStatus( name, skypeWindow ): + time.sleep(10) + filePath = __addon__.getSetting( 'skypexmlcontroller_var_path') + "skype2kodi\\call.xml" + while __windowopen__ and (not xbmc.abortRequested): + if os.path.isfile(filePath): + from xml.dom import minidom + xmldoc = minidom.parse(filePath) + friendName = xmldoc.getElementsByTagName('name')[0].childNodes[0].nodeValue + friendAvatar = xmldoc.getElementsByTagName('avatar')[0].childNodes[0].nodeValue + callStatus = xmldoc.getElementsByTagName('status')[0].childNodes[0].nodeValue + xbmc.log("Skype : call status is " + callStatus + " with " + friendName) + + if (callStatus == 'incoming'): + wRinging.ringing(friendName, friendAvatar, 'incoming') + #xbmc.executebuiltin('Notification(Skype,' + friendName + ' is calling !, 1000, ' + friendAvatar + ')') + + if (callStatus == 'outgoing'): + wRinging.ringing(friendName, friendAvatar, 'outgoing') + #xbmc.executebuiltin('Notification(Skype, Calling ' + friendName + ', 1000, ' + friendAvatar + ')') + + #if (callStatus == 'active'): + # xbmc.executebuiltin('Notification(Skype, Call active with ' + friendName + ', 1000, ' + friendAvatar + ')') + + if (callStatus == 'finished'): + wRinging.close() + os.remove(filePath) + xbmc.executebuiltin('Notification(Skype, Call finished with ' + friendName + ', 3000, ' + friendAvatar + ')') + + + time.sleep(2) + +#--------------------------------------------------------------------------------------------------------------------- +# +def callFriend( friendHandle, friendName, friendAvatar): + xbmc.log("Skype : call friend " + friendHandle) + wRinging.ringing(friendName, friendAvatar, 'outgoing') + executeSkypeAction('call_friend', friendHandle) + +#--------------------------------------------------------------------------------------------------------------------- +# +def runAccept(): + executeSkypeAction('call_accept', '') + +#--------------------------------------------------------------------------------------------------------------------- +# +def runRefuse(): + executeSkypeAction('call_end', '') + wRinging.close() + +#--------------------------------------------------------------------------------------------------------------------- +# +def executeSkypeAction(method, param): + xbmc.log("Skype : execute action " + method + ' with param ' + param) + xml = '' + method + '' + param + '' + filePath = __addon__.getSetting( 'skypexmlcontroller_var_path') + "kodi2skype\\action.xml" + f = open(filePath, "wb") + f.write(xml) + f.close() + #--------------------------------------------------------------------------------------------------------------------- #Main +xbmc.log("Skype : action " + __name__) if ( __name__ == "__main__" ): - loadProfile() - loadFriends() + if len(sys.argv) > 1: + if sys.argv[1] == 'accept': + runAccept() + if sys.argv[1] == 'refuse': + runRefuse() + else: + cleanUp() + loadProfile() + loadFriends() + + W = SkypeWindow( "skype-main.xml", __addonpath__ ) + wRinging = RingingWindow( "skype-ringing.xml", __addonpath__ ) + + t1 = Thread( target=checkCallStatus,args=("thread skype.checkCallStatus", W) ) + t1.setDaemon( True ) + t1.start() - W = SkypeWindow( "skype-main.xml", __addonpath__ ) - W.doModal() - del W + __windowopen__ = True + W.doModal() + __windowopen__ = False + del W + del t1 diff --git a/resources/skins/Default/720p/font.xml b/resources/skins/Default/720p/font.xml new file mode 100644 index 0000000..cd17977 --- /dev/null +++ b/resources/skins/Default/720p/font.xml @@ -0,0 +1,9 @@ + + + + skype_font_list + trebuc.ttf + 24 + + + diff --git a/resources/skins/Default/720p/skype-main.xml b/resources/skins/Default/720p/skype-main.xml index 1a5b9b0..846dc78 100644 --- a/resources/skins/Default/720p/skype-main.xml +++ b/resources/skins/Default/720p/skype-main.xml @@ -5,19 +5,21 @@ - + + + Group for background and header 0 0 0 0 1280 - 720 + 770 background.jpeg - 1100 - 20 + 1080 + 30 140 62 skype-logo.png @@ -26,7 +28,7 @@ 90 30 500 - true + false left left false @@ -35,39 +37,39 @@ ff000000 - 20 - 20 + 40 + 30 62 62 - - scroll bar indicator for lists - 20 - 140 - 12 - 400 - scroll_bg.png - scroll_bar.png - scroll_bar_focus.png - - - - - vertical - false - 3 - + + + + + Group for friends list + 0 + 0 + - - 40 - 140 + + 30 + 160 1200 400 icon - 121 121 + horizontal true + + 10 + 10 + 130 + 130 + friend.png + 10 10 @@ -75,24 +77,46 @@ 130 ListItem.Icon + + 10 + 10 + 130 + 130 + contact_border.png + 30 140 100 22 - font13 - green + skype_font_list + FFB2D4F5 center ListItem.Label - 0 - 0 - 10 - 10 + 10 + 10 + 130 + 130 + friend.png + + + 10 + 10 + 130 + 130 ListItem.Icon + Conditional + + + 10 + 10 + 130 + 130 + contact_border_focus.png 30 @@ -100,17 +124,15 @@ 100 22 font13 - red center ListItem.Label + FFFFFFFF - - diff --git a/resources/skins/Default/720p/skype-ringing.xml b/resources/skins/Default/720p/skype-ringing.xml new file mode 100644 index 0000000..5d5357f --- /dev/null +++ b/resources/skins/Default/720p/skype-ringing.xml @@ -0,0 +1,117 @@ + + + + + + + 400 + 120 + + + background + 0 + 0 + 480 + 520 + popup.png + + + + title + 0 + 0 + 480 + 70 + true + center + center + true + FFFFFFFF + + + + friend Name + 0 + 300 + 480 + 70 + true + center + center + true + + FFFFFFFF + + + + + avatar + 140 + 100 + 200 + 200 + + + + 140 + 100 + 200 + 200 + contact_border.png + + + + Accept and refuse buttons + 12 + 400 + 456 + 88 + horizontal + + + 40 + 24 + 40 + 40 + ListItem.icon + + + 90 + 30 + 100 + 50 + font13 + left + ListItem.Label + + + + + 10 + 10 + 208 + 68 + button.png + + + 40 + 24 + 40 + 40 + ListItem.icon + + + 90 + 30 + 100 + 50 + font13 + left + ListItem.Label + + + + + + + diff --git a/resources/skins/Default/fonts/trebuc.ttf b/resources/skins/Default/fonts/trebuc.ttf new file mode 100644 index 0000000..59a52c7 Binary files /dev/null and b/resources/skins/Default/fonts/trebuc.ttf differ diff --git a/resources/skins/Default/fonts/trebucbd.ttf b/resources/skins/Default/fonts/trebucbd.ttf new file mode 100644 index 0000000..c5c6477 Binary files /dev/null and b/resources/skins/Default/fonts/trebucbd.ttf differ diff --git a/resources/skins/Default/fonts/trebucbi.ttf b/resources/skins/Default/fonts/trebucbi.ttf new file mode 100644 index 0000000..512d020 Binary files /dev/null and b/resources/skins/Default/fonts/trebucbi.ttf differ diff --git a/resources/skins/Default/fonts/trebucit.ttf b/resources/skins/Default/fonts/trebucit.ttf new file mode 100644 index 0000000..79eb431 Binary files /dev/null and b/resources/skins/Default/fonts/trebucit.ttf differ diff --git a/resources/skins/Default/media/accept.png b/resources/skins/Default/media/accept.png new file mode 100644 index 0000000..e48802b Binary files /dev/null and b/resources/skins/Default/media/accept.png differ diff --git a/resources/skins/Default/media/background.jpeg b/resources/skins/Default/media/background.jpeg index 073b72a..6257498 100644 Binary files a/resources/skins/Default/media/background.jpeg and b/resources/skins/Default/media/background.jpeg differ diff --git a/resources/skins/Default/media/button.png b/resources/skins/Default/media/button.png new file mode 100644 index 0000000..cebacaa Binary files /dev/null and b/resources/skins/Default/media/button.png differ diff --git a/resources/skins/Default/media/contact_border.png b/resources/skins/Default/media/contact_border.png new file mode 100644 index 0000000..9763dfb Binary files /dev/null and b/resources/skins/Default/media/contact_border.png differ diff --git a/resources/skins/Default/media/contact_border_focus.png b/resources/skins/Default/media/contact_border_focus.png new file mode 100644 index 0000000..004d02f Binary files /dev/null and b/resources/skins/Default/media/contact_border_focus.png differ diff --git a/resources/skins/Default/media/friend.png b/resources/skins/Default/media/friend.png new file mode 100644 index 0000000..bd31f33 Binary files /dev/null and b/resources/skins/Default/media/friend.png differ diff --git a/resources/skins/Default/media/popup.png b/resources/skins/Default/media/popup.png new file mode 100644 index 0000000..fea09ba Binary files /dev/null and b/resources/skins/Default/media/popup.png differ diff --git a/resources/skins/Default/media/refuse.png b/resources/skins/Default/media/refuse.png new file mode 100644 index 0000000..5e09347 Binary files /dev/null and b/resources/skins/Default/media/refuse.png differ