#!/usr/bin/python # -*- coding: utf-8 -*- import socket import urllib import urllib2 import xbmcplugin import xbmcaddon import xbmcgui import sys import os import re import json import base64 import datetime import unicodedata import SimpleDownloader import requests import pickle from operator import itemgetter familyFilter = "1" socket.setdefaulttimeout(60) pluginhandle = int(sys.argv[1]) addon = xbmcaddon.Addon() addonID = addon.getAddonInfo('id') channelFavsFile = xbmc.translatePath("special://profile/addon_data/"+addonID+"/"+addonID+".favorites") familyFilterFile = xbmc.translatePath("special://profile/addon_data/"+addonID+"/family_filter_off") cookie_file = xbmc.translatePath("special://profile/addon_data/"+addonID+"/cookies") if os.path.exists(familyFilterFile): familyFilter = "0" while (not os.path.exists(xbmc.translatePath("special://profile/addon_data/"+addonID+"/settings.xml"))): addon.openSettings() forceViewModeNew = addon.getSetting("forceViewModeNew") == "true" viewModeNew = str(addon.getSetting("viewModeNew")) maxVideoQuality = addon.getSetting("maxVideoQuality") downloadDir = addon.getSetting("downloadDir") # qual = ["480p", "720p", "1080p"] qual = ["480", "720", "1080"] maxVideoQuality = qual[int(maxVideoQuality)] language = addon.getSetting("language") languages = ["en_EN", "ar_ES", "au_EN", "be_FR", "be_NL", "br_PT", "ca_EN", "ca_FR", "de_DE", "es_ES", "es_CA", "gr_EL", "fr_FR", "in_EN", "ie_EN", "it_IT", "mx_ES", "ma_FR", "nl_NL", "at_DE", "pl_PL", "pt_PT", "ru_RU", "ro_RO", "ch_FR", "ch_DE", "ch_IT", "tn_FR", "tr_TR", "en_GB", "en_US", "vn_VI", "jp_JP", "cn_ZH"] language = languages[int(language)] dmUser = addon.getSetting("dmUser") itemsPerPage = addon.getSetting("itemsPerPage") itemsPage = ["25", "50", "75", "100"] itemsPerPage = itemsPage[int(itemsPerPage)] urlMain = "https://api.dailymotion.com" def index(): if dmUser: addDir(translation(30034), "", "personalMain", "") else: addFavDir(translation(30024), "", "favouriteUsers", "") addDir(translation(30006), "", 'listChannels', "") addDir(translation(30007), "", 'sortUsers1', "") addDir(translation(30042), "ALL", 'listGroups', "") addDir(translation(30002), "", 'search', "") addDir(translation(30003), urlMain+"/videos?fields=id,thumbnail_large_url%2Ctitle%2Cviews_last_hour&filters=live&sort=visited-hour&limit="+itemsPerPage+"&family_filter="+familyFilter+"&localization="+language+"&page=1", 'listLive', "") addDir(translation(30039), '3D:ALL', 'sortVideos1', '', '') xbmcplugin.endOfDirectory(pluginhandle) def personalMain(): addDir(translation(30041), urlMain+"/user/"+dmUser+"/videos?fields=description,duration,id,owner.username,taken_time,thumbnail_large_url,title,views_total&sort=recent&limit="+itemsPerPage+"&family_filter="+familyFilter+"&localization="+language+"&page=1", 'listVideos', "") addDir(translation(30035), urlMain+"/user/"+dmUser+"/following?fields=username,avatar_large_url,videos_total,views_total&sort=popular&limit="+itemsPerPage+"&family_filter="+familyFilter+"&localization="+language+"&page=1", 'listUsers', "") addDir(translation(30036), urlMain+"/user/"+dmUser+"/subscriptions?fields=description,duration,id,owner.username,taken_time,thumbnail_large_url,title,views_total&sort=recent&limit="+itemsPerPage+"&family_filter="+familyFilter+"&localization="+language+"&page=1", 'listVideos', "") addDir(translation(30037), urlMain+"/user/"+dmUser+"/favorites?fields=description,duration,id,owner.username,taken_time,thumbnail_large_url,title,views_total&sort=recent&limit="+itemsPerPage+"&family_filter="+familyFilter+"&localization="+language+"&page=1", 'listVideos', "") addDir(translation(30038), urlMain+"/user/"+dmUser+"/playlists?fields=id,name,videos_total&sort=recent&limit="+itemsPerPage+"&family_filter="+familyFilter+"&localization="+language+"&page=1", 'listUserPlaylists', "") addDir(translation(30042), urlMain+"/user/"+dmUser+"/groups?fields=id,name,description&sort=recent&limit="+itemsPerPage+"&family_filter="+familyFilter+"&localization="+language+"&page=1", 'listGroups', "") xbmcplugin.endOfDirectory(pluginhandle) def listUserPlaylists(url): content = getUrl(url) content = json.loads(content) for item in content['list']: id = item['id'] title = item['name'].encode('utf-8') vids = item['videos_total'] addDir(title+" ("+str(vids)+")", urllib.quote_plus(str(id)+"_"+dmUser+"_"+title), 'showPlaylist', '') if content['has_more']: currentPage = content['page'] nextPage = currentPage+1 addDir(translation(30001)+" ("+str(nextPage)+")", url.replace("page="+str(currentPage), "page="+str(nextPage)), 'listUserPlaylists', "") xbmcplugin.endOfDirectory(pluginhandle) def listGroups(url): if url == "ALL": url = urlMain+"/groups?fields=id,name,description&sort=recent&filters=featured&limit="+itemsPerPage+"&family_filter="+familyFilter+"&localization="+language+"&page=1" content = getUrl(url) content = json.loads(content) for item in content['list']: id = item['id'] title = item['name'].encode('utf-8') desc = item['description'].encode('utf-8') addDir(title, "group:"+id, 'sortVideos1', '', desc) if content['has_more']: currentPage = content['page'] nextPage = currentPage+1 addDir(translation(30001)+" ("+str(nextPage)+")", url.replace("page="+str(currentPage), "page="+str(nextPage)), 'listGroups', "") xbmcplugin.endOfDirectory(pluginhandle) def showPlaylist(id): url = urlMain+"/playlist/"+id+"/videos?fields=description,duration,id,owner.username,taken_time,thumbnail_large_url,title,views_total&sort=recent&limit="+itemsPerPage+"&family_filter="+familyFilter+"&localization="+language+"&page=1" listVideos(url) def favouriteUsers(): xbmcplugin.addSortMethod(pluginhandle, xbmcplugin.SORT_METHOD_LABEL) if os.path.exists(channelFavsFile): fh = open(channelFavsFile, 'r') content = fh.read() match = re.compile('###USER###=(.+?)###THUMB###=(.*?)###END###', re.DOTALL).findall(content) for user, thumb in match: addUserFavDir(user, 'owner:'+user, 'sortVideos1', thumb) fh.close() xbmcplugin.endOfDirectory(pluginhandle) def listChannels(): content = getUrl(urlMain+"/channels?family_filter="+familyFilter+"&localization="+language) content = json.loads(content) for item in content['list']: id = item['id'] title = item['name'].encode('utf-8') desc = item['description'].encode('utf-8') addDir(title, 'channel:'+id, 'sortVideos1', '', desc) xbmcplugin.endOfDirectory(pluginhandle) def sortVideos1(url): type = url[:url.find(":")] id = url[url.find(":")+1:] if type == "3D": url = urlMain+"/videos?fields=description,duration,id,owner.username,taken_time,thumbnail_large_url,title,views_total&filters=3d&sort=recent&limit="+itemsPerPage+"&family_filter="+familyFilter+"&localization="+language+"&page=1" elif type == "group": url = urlMain+"/group/"+id+"/videos?fields=description,duration,id,owner.username,taken_time,thumbnail_large_url,title,views_total&sort=recent&limit="+itemsPerPage+"&family_filter="+familyFilter+"&localization="+language+"&page=1" else: url = urlMain+"/videos?fields=description,duration,id,owner.username,taken_time,thumbnail_large_url,title,views_total&"+type+"="+id+"&sort=recent&limit="+itemsPerPage+"&family_filter="+familyFilter+"&localization="+language+"&page=1" addDir(translation(30008), url, 'listVideos', "") addDir(translation(30009), url.replace("sort=recent", "sort=visited"), 'sortVideos2', "") addDir(translation(30020), url.replace("sort=recent", "sort=commented"), 'sortVideos2', "") addDir(translation(30010), url.replace("sort=recent", "sort=rated"), 'sortVideos2', "") if type == "owner": addDir("- "+translation(30038), urlMain+"/user/"+id+"/playlists?fields=id,name,videos_total&sort=recent&limit="+itemsPerPage+"&family_filter="+familyFilter+"&localization="+language+"&page=1", 'listUserPlaylists', "") xbmcplugin.endOfDirectory(pluginhandle) def sortVideos2(url): addDir(translation(30011), url.replace("sort=visited", "sort=visited-today").replace("sort=commented", "sort=commented-today").replace("sort=rated", "sort=rated-today"), "listVideos", "") addDir(translation(30012), url.replace("sort=visited", "sort=visited-week").replace("sort=commented", "sort=commented-week").replace("sort=rated", "sort=rated-week"), "listVideos", "") addDir(translation(30013), url.replace("sort=visited", "sort=visited-month").replace("sort=commented", "sort=commented-month").replace("sort=rated", "sort=rated-month"), "listVideos", "") addDir(translation(30014), url, 'listVideos', "") xbmcplugin.endOfDirectory(pluginhandle) def sortUsers1(): url = urlMain+"/users?fields=username,avatar_large_url,videos_total,views_total&sort=popular&limit="+itemsPerPage+"&family_filter="+familyFilter+"&localization="+language+"&page=1" addDir(translation(30040), url, 'sortUsers2', "") addDir(translation(30016), url+"&filters=featured", 'sortUsers2', "") addDir(translation(30017), url+"&filters=official", 'sortUsers2', "") addDir(translation(30018), url+"&filters=creative", 'sortUsers2', "") xbmcplugin.endOfDirectory(pluginhandle) def sortUsers2(url): addDir(translation(30019), url, 'listUsers', "") addDir(translation(30020), url.replace("sort=popular", "sort=commented"), 'listUsers', "") addDir(translation(30021), url.replace("sort=popular", "sort=rated"), 'listUsers', "") xbmcplugin.endOfDirectory(pluginhandle) def listVideos(url): xbmcplugin.setContent(pluginhandle, "episodes") content = getUrl(url) content = json.loads(content) count = 1 for item in content['list']: id = item['id'] title = item['title'].encode('utf-8') desc = item['description'].encode('utf-8') duration = item['duration'] user = item['owner.username'] date = item['taken_time'] thumb = item['thumbnail_large_url'] views = item['views_total'] duration = str(int(duration)/60+1) try: date = datetime.datetime.fromtimestamp(int(date)).strftime('%Y-%m-%d') except: date = "" temp = ("User: "+user+" | "+str(views)+" Views | "+date).encode('utf-8') try: desc = temp+"\n"+desc except: desc = "" if user == "hulu": pass elif user == "cracklemovies": pass elif user == "ARTEplus7": addLink(title, id, 'playArte', thumb.replace("\\", ""), user, desc, duration, date, count) count+=1 else: addLink(title, id, 'playVideo', thumb.replace("\\", ""), user, desc, duration, date, count) count+=1 if content['has_more']: currentPage = content['page'] nextPage = currentPage+1 addDir(translation(30001)+" ("+str(nextPage)+")", url.replace("page="+str(currentPage), "page="+str(nextPage)), 'listVideos', "") if forceViewModeNew: xbmc.executebuiltin('Container.SetViewMode('+viewModeNew+')') xbmcplugin.endOfDirectory(pluginhandle) def listUsers(url): content = getUrl(url) content = json.loads(content) for item in content['list']: user = item['username'].encode('utf-8') thumb = item['avatar_large_url'] videos = item['videos_total'] views = item['views_total'] addUserDir(user, 'owner:'+user, 'sortVideos1', thumb.replace("\\", ""), "Views: "+str(views)+"\nVideos: "+str(videos)) if content['has_more']: currentPage = content['page'] nextPage = currentPage+1 addDir(translation(30001)+" ("+str(nextPage)+")", url.replace("page="+str(currentPage), "page="+str(nextPage)), 'listUsers', "") xbmcplugin.endOfDirectory(pluginhandle) def listLive(url): #print 'live url ',url content = getUrl(url) content = json.loads(content) for item in content['list']: title = item['title'].encode('utf-8') id = item['id'] thumb = item['thumbnail_large_url'] views = item['views_last_hour'] addLiveLink(title, id, 'playLiveVideo', thumb.replace("\\", ""), views) if content['has_more']: currentPage = content['page'] nextPage = currentPage+1 addDir(translation(30001)+" ("+str(nextPage)+")", url.replace("page="+str(currentPage), "page="+str(nextPage)), 'listLive', "") xbmcplugin.endOfDirectory(pluginhandle) if forceViewModeNew: xbmc.executebuiltin('Container.SetViewMode('+viewModeNew+')') def search(): keyboard = xbmc.Keyboard('', translation(30002)) keyboard.doModal() if keyboard.isConfirmed() and keyboard.getText(): search_string = keyboard.getText().replace(" ", "+") listVideos(urlMain+"/videos?fields=description,duration,id,owner.username,taken_time,thumbnail_large_url,title,views_total&search="+search_string+"&sort=relevance&limit="+itemsPerPage+"&family_filter="+familyFilter+"&localization="+language+"&page=1") def playVideo(id,live=False): if live: url=getStreamUrl(id,live=True) else: url = getStreamUrl(id) print url if url and not '.f4mTester' in url: #print 'path found to beeeeeeeeeeee' , url listitem = xbmcgui.ListItem(path=url) xbmcplugin.setResolvedUrl(pluginhandle, True, listitem) elif url: xbmc.executebuiltin('XBMC.RunPlugin('+url+')') else: print 'No playable url found' def BW_choice(stream): bandwidth =[] if re.search('BANDWIDTH', stream) : print 'Getting bandwidth' needle = "BANDWIDTH=(\d+)\d{3}[^\n]*\W+([^\n]+.m3u8[^\n\r]*)" bw_url = re.compile(needle,re.DOTALL|re.IGNORECASE).findall(stream) elif re.search('RESOLUTION', stream): needle = 'RESOLUTION=(\d+)x\d{3}[^\n]*\W+([^\n]+.m3u8[^\n\r]*)' bw_url = re.compile(needle).findall(stream) if bw_url : newlist = sorted(bw_url, key=itemgetter(0),reverse=True) return newlist[0] [1].split('#cell')[0] def getStreamUrl(id,live=False): if familyFilter == "1": ff = "on" else: ff = "off" print 'The url is ::',url headers = {'User-Agent':'Android'} cookie = {'Cookie':"lang="+language+"; family_filter="+ff} r = requests.get("http://www.dailymotion.com/player/metadata/video/"+id,headers=headers,cookies=cookie) content = r.json() if content.get('error') is not None: Error = 'DailyMotion Says:[COLOR yellow]%s[/COLOR]' %(content['error']['title']) xbmc.executebuiltin('XBMC.Notification(Info:,'+ Error +' ,5000)') return else: cc= content['qualities'] #['380'][0]['url'] cc = cc.items() cc = sorted(cc, reverse=True) m_url = '' other_playable_url = [] for source,json_source in cc: for item in json_source: m_url = item.get('url',None) xbmc.log("DILYMOTION_Gates - m_url = %s" %m_url) if m_url: if not live: if source == "auto" : continue elif int(source) <= int(maxVideoQuality) : return m_url elif '.mnft' in m_url: continue else: if '.m3u8?auth' in m_url: m_url = m_url.split('?auth=') the_url = m_url[0] + '?redirect=0&auth=' + urllib.quote(m_url[1]) rr = requests.get(the_url,cookies=r.cookies.get_dict() ,headers=headers) if rr.headers.get('set-cookie'): print 'adding cookie to url' return rr.text.split('#cell')[0]+'|Cookie='+rr.headers['set-cookie'] else: return rr.text.split('#cell')[0] other_playable_url.append(m_url) if len(other_playable_url) >0: # probable not needed only for last resort for m_url in other_playable_url: if '.m3u8?auth' in m_url: sep_url = m_url.split('?auth=') the_url = sep_url[0] + '?redirect=0&auth=' + urllib.quote(sep_url[1]) rr = requests.get(the_url,cookies=r.cookies.get_dict() ,headers=headers) if rr.headers.get('set-cookie'): print 'adding cookie to url' return rr.text.split('#cell')[0]+'|Cookie='+rr.headers['set-cookie'] else: return rr.text.split('#cell')[0] def queueVideo(url, name): playlist = xbmc.PlayList(xbmc.PLAYLIST_VIDEO) listitem = xbmcgui.ListItem(name) playlist.add(url, listitem) def downloadVideo(id): downloader = SimpleDownloader.SimpleDownloader() content = getUrl2("http://www.dailymotion.com/embed/video/"+id) match = re.compile('(.+?)', re.DOTALL).findall(content) global downloadDir while not downloadDir: xbmc.executebuiltin('XBMC.Notification(Download:,'+translation(30110)+'!,5000)') addon.openSettings() downloadDir = addon.getSetting("downloadDir") url = getStreamUrl(id) filename = "" try: filename = (''.join(c for c in unicode(match[0], 'utf-8') if c not in '/\\:?"*|<>')).strip() except: filename = id filename+=".mp4" if not os.path.exists(os.path.join(downloadDir, filename)): params = { "url": url, "download_path": downloadDir } downloader.download(filename, params) else: xbmc.executebuiltin('XBMC.Notification(Download:,'+translation(30109)+'!,5000)') def playArte(id): try: content = getUrl("http://www.dailymotion.com/video/"+id) match = re.compile('', re.DOTALL).findall(content) lang = match[0][0] vid = match[0][1] url = "http://videos.arte.tv/"+lang+"/do_delegate/videos/"+vid+",view,asPlayerXml.xml" content = getUrl(url) match = re.compile('