# Copyright (C) 2017 Lunatixz, lordindy # # # This file is part of TV Adverts. # # TV Adverts is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # TV Adverts is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with TV Adverts. If not, see . import urllib, urllib2, re, os, socket, json import xbmcplugin, xbmcgui, xbmcaddon, xbmc from BeautifulSoup import BeautifulSoup from simplecache import use_cache, SimpleCache ## GLOBALS ## baseurl='http://www.advertolog.com' TIMEOUT = 15 # Plugin Info ADDON_ID = 'plugin.video.adverts' REAL_SETTINGS = xbmcaddon.Addon(id=ADDON_ID) SETTINGS_LOC = REAL_SETTINGS.getAddonInfo('profile') ADDON_NAME = REAL_SETTINGS.getAddonInfo('name') ADDON_PATH = REAL_SETTINGS.getAddonInfo('path').decode('utf-8') ADDON_VERSION = REAL_SETTINGS.getAddonInfo('version') ICON = os.path.join(ADDON_PATH, 'icon.png') FANART = os.path.join(ADDON_PATH, 'fanart.jpg') # User Settings DEBUG = REAL_SETTINGS.getSetting('Enable_Debugging') == 'true' forceSet = REAL_SETTINGS.getSetting('force_preference') == "true" if xbmcgui.Window(10000).getProperty('PseudoTVRunning') == "True": forceSet = True socket.setdefaulttimeout(TIMEOUT) def log(msg, level=xbmc.LOGDEBUG): msg = stringify(msg[:1000]) if DEBUG == False and level == xbmc.LOGDEBUG: return if level == xbmc.LOGERROR: msg += ' ,' + traceback.format_exc() xbmc.log(ADDON_ID + '-' + ADDON_VERSION + '-' + msg, level) def ascii(string): if isinstance(string, basestring): if isinstance(string, unicode): string = string.encode('ascii', 'ignore') return string def uni(string): if isinstance(string, basestring): if isinstance(string, unicode): string = string.encode('utf-8', 'ignore' ) else: string = ascii(string) return string def stringify(string): if isinstance(string, list): string = stringify(string[0]) elif isinstance(string, (int, float, long, complex, bool)): string = str(string) elif isinstance(string, (str, unicode)): string = uni(string) elif not isinstance(string, (str, unicode)): string = ascii(string) if isinstance(string, basestring): return string return '' def cleanString(string): newstr = uni(string) newstr = newstr.replace('&', '&') newstr = newstr.replace('>', '>') newstr = newstr.replace('<', '<') newstr = newstr.replace('"', '"') return uni(newstr) def uncleanString(string): newstr = uni(string) newstr = newstr.replace('&', '&') newstr = newstr.replace('>', '>') newstr = newstr.replace('<', '<') newstr = newstr.replace('"', '"') return uni(newstr) def replaceXmlEntities(link): entities = ( ("%3A",":"),("%2F","/"),("%3D","="),("%3F","?"),("%26","&"),("%22","\""),("%7B","{"),("%7D",")"),("%2C",","),("%24","$"),("%23","#"),("%40","@") ); for entity in entities: link = link.replace(entity[0],entity[1]); return link; def get_params(): param=[] if len(sys.argv[2])>=2: params=sys.argv[2] cleanedparams=params.replace('?','') if (params[len(params)-1]=='/'): params=params[0:len(params)-2] pairsofparams=cleanedparams.split('&') param={} for i in range(len(pairsofparams)): splitparams={} splitparams=pairsofparams[i].split('=') if (len(splitparams))==2: param[splitparams[0]]=splitparams[1] return param class Adverts(): def __init__(self): self.cache = SimpleCache() # sites not updated regularly, no need to burden site. Cache for 14days @use_cache(14) def openURL(self, url): req = urllib2.Request(url) req.add_header('User-Agent', 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.9.0.3) Gecko/2008092417 Firefox/3.0.3') response = urllib2.urlopen(req).read() return response def CATEGORIES(self): self.addDir('Countries','http://www.advertolog.com/countries/',3) self.addDir('Brands','http://www.advertolog.com/brands/',4) self.addDir('Years','http://www.advertolog.com/countries/',8) self.addDir('Business Sectors','http://www.advertolog.com/business-sectors/',6) # self.addDir('Awards','http://www.advertolog.com/festivals-awards/',6) def BRANDORCOUNTRYPAGE(self, url): link = self.openURL(url) link=link.decode('utf-8') soup = BeautifulSoup(link,convertEntities=BeautifulSoup.HTML_ENTITIES) catlink=re.compile('TV & Cinema').findall(link) if catlink: url=baseurl+catlink[0] link = self.openURL(url) soup = BeautifulSoup(link) #find the adverts, if any if soup.find('ul', "col-media-list"): adverts=soup.find('ul', "col-media-list").findAll('li') for ad in adverts: if ad.find(text=" TV & Cinema"): name=ad.a.img["alt"].encode('UTF-8') adurl=ad.a["href"] thumbnail=ad.a.img["src"] if forceSet == True: self.VIDEOLINKS(baseurl+adurl,name,len(adverts)) else: self.addDir(name,baseurl+adurl,2,thumbnail) def BRANDORCOUNTRYYEAR(self, url): link = self.openURL(url) link=link.decode('utf-8') soup = BeautifulSoup(link,convertEntities=BeautifulSoup.HTML_ENTITIES) catlink=re.compile('TV & Cinema').findall(link) if catlink: url=baseurl+catlink[0] link = self.openURL(url) soup = BeautifulSoup(link) # find the year links, if any yearlink=soup.find(text='Year:') if yearlink: yearlink=soup.find(text='Year:').findNext('div').findAll('a') years=[] for links in yearlink: temp=re.compile('(.+?)').findall(str(links)) years.append(temp[0]) for yearurl, name in years: self.addDir(name,baseurl+yearurl,1) #Get the "Next Page" link, if any if soup.find(text=re.compile("Next \xbb\xbb")): if soup.find(text=re.compile("Next \xbb\xbb")).findPrevious('span').findAll('a'): nextpage=soup.find(text=re.compile("Next \xbb\xbb")).findPrevious('span').findAll('a') nextpage=re.compile('\[Next').findall(str(nextpage)) nextpage=baseurl+nextpage[0] self.addDir("''Next Page >>",nextpage,1) def VIDEOLINKS(self, url, name, total=1): link = self.openURL(url) soup = BeautifulSoup(link) found = False #GET THE VIDEO LINKS FROM THE PAGE, IF ANY #get the image image=re.compile('meta property="og:image" content="(.+?)" />').findall(link) if image: image[0]=replaceXmlEntities(image[0]) else: image='' #get the default video link (most are hidden due to subscription, but the low res video link is hidden in the header tag vid=re.compile('meta property="og:video" content="(.+?)" />').findall(link) if vid: vid[0]=replaceXmlEntities(vid[0]) vid[0]=re.sub('http.*?clip":{"url":','/',vid[0]) vid[0]=re.search('h.*?.mp4', vid[0]).group() vid = vid[0] #get alternate high res links if any vids=soup.find('ul',"resolutions") if vids: vids=soup.find('ul',"resolutions").findAll('a') if vids: vids=soup.find('ul',"resolutions").findAll('a') for url in vids: if forceSet == True: if url.string.lower() == REAL_SETTINGS.getSetting('limit_preferred_resolution').lower(): found = True self.addLink(name,url['name'],9,image[0],total) return else: self.addLink(url.string,url['name'],9,image[0],total) if not vids: # attempt to find stray low quality video if len(re.compile("url:'(.+?).mp4',").findall(link)) > 0: vid=((re.compile("url:'(.+?).mp4',").findall(link))[0]) + '.mp4' if len(vid) > 0: self.addLink('360p',vid,9,image[0]) else: self.addLink('SWF video unavailable','',9,image[0]) return self.addLink('video unavailable','',9,image[0]) def LISTCOUNTRIES(self, url, year=False): link = self.openURL(url) countries=re.compile('(.+?)').findall(link) for url,country in countries: if year: if forceSet == True: if country.lower() == REAL_SETTINGS.getSetting('limit_preferred_region').lower(): self.BRANDORCOUNTRYPAGE('http://www.advertolog.com/countries/'+url) break else: self.addDir(country,'http://www.advertolog.com/countries/'+url,7) else: if forceSet == True: if country.lower() == REAL_SETTINGS.getSetting('limit_preferred_region').lower(): self.BRANDORCOUNTRYPAGE('http://www.advertolog.com/countries/'+url) break else: self.addDir(country,'http://www.advertolog.com/countries/'+url,1) def LISTBRANDLETTERS(self, url): link = self.openURL(url) match=re.compile('

(.+?)

').findall(link) #Get the brand letters letters=re.compile('

(.+?)

').findall(link) letters=map(lambda x: x.lower(), letters) for letter in letters: self.addDir(letter.upper(),'http://www.advertolog.com/brands/letter-'+letter+'/',5) def LISTBRANDS(self, url): link = self.openURL(url) soup = BeautifulSoup(link,convertEntities=BeautifulSoup.HTML_ENTITIES) brands=re.compile('(.+?)').findall(link) for url, name in brands: self.addDir(name,baseurl+url,1) #Get the "Next Page" link, if any if soup.find(text=re.compile("Next ")): if soup.find(text=re.compile("Next ")).findPrevious('span').findAll('a'): nextpage=soup.find(text=re.compile("Next ")).findPrevious('span').findAll('a') nextpage=re.compile('\[Next ').findall(str(nextpage)) nextpage=baseurl+nextpage[0] self.addDir("''Next Page >>",nextpage,5) def LISTSECTORS(self, url): link = self.openURL(url) soup = BeautifulSoup(link,convertEntities=BeautifulSoup.HTML_ENTITIES) sectors=re.compile('\n (.+?)').findall(str(soup)) sectors.sort() for url, name in sectors: self.addDir(name,baseurl+url,1) def LinkPlay(self, name, url): listitem = xbmcgui.ListItem(name, path=url) xbmcplugin.setResolvedUrl(int(sys.argv[1]), True, listitem) def addLink(self, name, u, mode, thumb=ICON, total=0): name = uncleanString(name) log('addLink, name = ' + name) liz=xbmcgui.ListItem(name) liz.setProperty('IsPlayable', 'true') liz.setArt({'thumb':thumb,'fanart':FANART}) liz.setInfo( type="Video", infoLabels={"label":name,"title":name} ) u=sys.argv[0]+"?url="+urllib.quote_plus(u)+"&mode="+str(mode)+"&name="+urllib.quote_plus(name) xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]),url=u,listitem=liz,totalItems=total) def addDir(self, name, u, mode, thumb=ICON): name = uncleanString(name) log('addDir, name = ' + name) liz=xbmcgui.ListItem(name) liz.setProperty('IsPlayable', 'false') liz.setInfo(type="Video", infoLabels={"label":name,"title":name} ) liz.setArt({'thumb':thumb,'fanart':FANART}) u=sys.argv[0]+"?url="+urllib.quote_plus(u)+"&mode="+str(mode)+"&name="+urllib.quote_plus(name) xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]),url=u,listitem=liz,isFolder=True) params=get_params() url=None name=None mode=None try: url=urllib.unquote_plus(params["url"]) except: pass try: name=urllib.unquote_plus(params["name"]) except: pass try: mode=int(params["mode"]) except: pass log("Mode: "+str(mode)) log("URL : "+str(url)) log("Name: "+str(name)) if mode==None or url==None or len(url)<1: Adverts().CATEGORIES() elif mode==1: Adverts().BRANDORCOUNTRYPAGE(url) elif mode==2: Adverts().VIDEOLINKS(url,name) elif mode==3: Adverts().LISTCOUNTRIES(url) elif mode==4: Adverts().LISTBRANDLETTERS(url) elif mode==5: Adverts().LISTBRANDS(url) elif mode==6: Adverts().LISTSECTORS(url) elif mode==7: Adverts().BRANDORCOUNTRYYEAR(url) elif mode==8: Adverts().LISTCOUNTRIES(url,True) elif mode == 9: Adverts().LinkPlay(name, url) xbmcplugin.addSortMethod(int(sys.argv[1]), xbmcplugin.SORT_METHOD_LABEL ) xbmcplugin.addSortMethod(int(sys.argv[1]), xbmcplugin.SORT_METHOD_NONE ) xbmcplugin.endOfDirectory(int(sys.argv[1]), cacheToDisc=True)