diff options
author | Lunatixz <Lunatixz@users.noreply.github.com> | 2017-04-07 08:03:12 -0400 |
---|---|---|
committer | enen92 <enen92@users.noreply.github.com> | 2017-04-07 13:03:12 +0100 |
commit | 89e8ce3561db84ed89e0e76a258004d9730c89f6 (patch) | |
tree | 4411aba73a12087336fc3cee7f6d9e861c00d996 /plugin.video.adverts | |
parent | 33c17f210d144270c5275ea5600762ac83b429b1 (diff) |
[plugin.video.adverts] 0.1.4 (#1120)
Watch TV ads from Advertolog.
Diffstat (limited to 'plugin.video.adverts')
-rw-r--r-- | plugin.video.adverts/addon.xml | 26 | ||||
-rw-r--r-- | plugin.video.adverts/default.py | 371 | ||||
-rw-r--r-- | plugin.video.adverts/fanart.jpg | bin | 0 -> 87822 bytes | |||
-rw-r--r-- | plugin.video.adverts/icon.png | bin | 0 -> 3745 bytes | |||
-rw-r--r-- | plugin.video.adverts/resources/language/resource.language.en_gb/strings.po | 34 | ||||
-rw-r--r-- | plugin.video.adverts/resources/settings.xml | 6 |
6 files changed, 437 insertions, 0 deletions
diff --git a/plugin.video.adverts/addon.xml b/plugin.video.adverts/addon.xml new file mode 100644 index 0000000..66d6f04 --- /dev/null +++ b/plugin.video.adverts/addon.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8" standalone="yes"?> +<addon id="plugin.video.adverts" name="AdverToLog" version="0.1.4" provider-name="Lunatixz"> + <requires> + <import addon="xbmc.python" version="2.25.0"/> + <import addon="script.module.beautifulsoup" version="3.2.1"/> + <import addon="script.module.requests" version="2.7.0"/> + <import addon="script.module.simplecache" version="1.0.0"/> + </requires> + <extension point="xbmc.python.pluginsource" library="default.py"> + <provides>video</provides> + </extension> + <extension point="xbmc.addon.metadata"> + <summary lang="en_GB">Watch TV ads from Advertolog.</summary> + <description lang="en_GB">Watch TV ads categorized by country, business, year from Advertolog.</description> + <platform>all</platform> + <license>GNU GENERAL PUBLIC LICENSE. Version 3, June 2007</license> + <source>https://github.com/Lunatixz/XBMC_Addons/tree/master/plugin.video.adverts</source> + <website>http://www.advertolog.com</website> + <forum>http://forum.kodi.tv/showthread.php?tid=311064</forum> + <news></news> + <assets> + <icon>icon.png</icon> + <fanart>fanart.jpg</fanart> + </assets> + </extension> +</addon>
\ No newline at end of file diff --git a/plugin.video.adverts/default.py b/plugin.video.adverts/default.py new file mode 100644 index 0000000..98be2bb --- /dev/null +++ b/plugin.video.adverts/default.py @@ -0,0 +1,371 @@ +# 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 <http://www.gnu.org/licenses/>. + +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('<a href="(.+?)" >TV & Cinema</a>').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('<a href="(.+?)" >TV & Cinema</a>').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('<a href="(.+?)">(.+?)</a>').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('\[<a href="(.+?)">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('<a href="/countries/(.+?)">(.+?)</a>').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('<h3 style="font-weight:bold; font-size:24px;"><a href=".+?" style="text-decoration:none">(.+?)</a></h3>').findall(link) + #Get the brand letters + letters=re.compile('<h3 style="font-weight:bold; font-size:24px;"><a href=".+?" style="text-decoration:none">(.+?)</a></h3>').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('<a href="(.+?)" id="CompanyListingTitle_.+?">(.+?)</a>').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('\[<a href="(.+?)">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('<a href="(.+?)/">\n (.+?)</a>').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)
\ No newline at end of file diff --git a/plugin.video.adverts/fanart.jpg b/plugin.video.adverts/fanart.jpg Binary files differnew file mode 100644 index 0000000..bb445ec --- /dev/null +++ b/plugin.video.adverts/fanart.jpg diff --git a/plugin.video.adverts/icon.png b/plugin.video.adverts/icon.png Binary files differnew file mode 100644 index 0000000..5b0713d --- /dev/null +++ b/plugin.video.adverts/icon.png diff --git a/plugin.video.adverts/resources/language/resource.language.en_gb/strings.po b/plugin.video.adverts/resources/language/resource.language.en_gb/strings.po new file mode 100644 index 0000000..55415c8 --- /dev/null +++ b/plugin.video.adverts/resources/language/resource.language.en_gb/strings.po @@ -0,0 +1,34 @@ +# Kodi Media Center language file +# Addon Name: AdverToLog +# Addon id: plugin.video.adverts +# Addon Provider: Lunatixz +msgid "" +msgstr "" +"Project-Id-Version: plugin.video.adverts\n" +"Report-Msgid-Bugs-To: http://forum.kodi.tv/showthread.php?tid=311064\n" +"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: Lunatixz Translation Team\n" +"Language-Team: English (http://www.transifex.com/projects/p/xbmc-addons/language/en/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: en\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +msgctxt "#30000" +msgid "Enable Debugging [Log errors]" +msgstr "" + +msgctxt "#30001" +msgid "Filter results for Preferred Region & Resolution" +msgstr "" + +msgctxt "#30002" +msgid "Preferred Resolution" +msgstr "" + +msgctxt "#30003" +msgid "Preferred Region" +msgstr "" + diff --git a/plugin.video.adverts/resources/settings.xml b/plugin.video.adverts/resources/settings.xml new file mode 100644 index 0000000..74b8869 --- /dev/null +++ b/plugin.video.adverts/resources/settings.xml @@ -0,0 +1,6 @@ +<settings> + <setting id="limit_preferred_region" type="select" label="30003" values="Andorra|United Arab Emirates|Afghanistan|Antigua and Barbuda|Anguilla|Albania|Armenia|Netherlands Antilles|Angola|Antarctica|Argentina|American Samoa|Austria|Australia|Aruba|Aland|Azerbaijan|Bosnia and Herzegovina|Barbados|Bangladesh|Belgium|Burkina Faso|Bulgaria|Bahrain|Burundi|Benin|Saint Barthelemy|Bermuda|Brunei|Bolivia|Brazil|Bahamas|Bhutan|Bouvet Island|Botswana|Belarus|Belize|Canada|Cocos (Keeling) Islands|Congo (Kinshasa)|Central African Republic|Congo (Brazzaville)|Switzerland|Cote dIvoire|Cook Islands|Chile|Cameroon|China|Colombia|Costa Rica|Cuba|Cape Verde|Christmas Island|Cyprus|Czech Republic|Germany|Djibouti|Denmark|Dominica|Dominican Republic|Algeria|Ecuador|Estonia|Egypt|Western Sahara|Eritrea|Spain|Ethiopia|Finland|Fiji|Falkland Islands|Micronesia|Faroe Islands|France|Gabon|United Kingdom|Grenada|Georgia|French Guiana|Guernsey|Ghana|Gibraltar|Greenland|Gambia|Guinea|Guadeloupe|Equatorial Guinea|Greece|South Georgia and South Sandwich Islands|Guatemala|Guam|Guinea-Bissau|Guyana|Hong Kong|Heard and McDonald Islands|Honduras|Croatia|Haiti|Hungary|Indonesia|name|English country name| |Ireland|Israel|Isle of Man|India|British Indian Ocean Territory|Iraq|Iran|Iceland|Italy|Jersey|Jamaica|Jordan|Japan|Kenya|Kyrgyzstan|Cambodia|Kiribati|Comoros|Saint Kitts and Nevis|North Korea|South Korea|Kuwait|Cayman Islands|Kazakhstan|Laos|Lebanon|Saint Lucia|Liechtenstein|Sri Lanka|Liberia|Lesotho|Lithuania|Luxembourg|Latvia|Libya|Morocco|Monaco|Moldova|Montenegro|Saint Martin|Madagascar|Marshall Islands|Macedonia|Mali|Myanmar|Mongolia|Macau|Northern Mariana Islands|Martinique|Mauritania|Montserrat|Malta|Mauritius|Maldives|Malawi|Mexico|Malaysia|Mozambique|Namibia|New Caledonia|Niger|Norfolk Island|Nigeria|Nicaragua|Netherlands|Norway|Nepal|Nauru|Niue|New Zealand|Oman|Panama|Peru|French Polynesia|Papua New Guinea|Philippines|Pakistan|Poland|Saint Pierre and Miquelon|Pitcairn|Puerto Rico|Palestine|Portugal|Palau|Paraguay|Qatar|Reunion|Romania|Serbia|Russian Federation|Rwanda|Saudi Arabia|Solomon Islands|Seychelles|Sudan|Sweden|Singapore|Saint Helena|Slovenia|Svalbard and Jan Mayen Islands|name|English country name| |Slovakia|Sierra Leone|San Marino|Senegal|Somalia|Suriname|Sao Tome and Principe|El Salvador|Syria|Swaziland|Turks and Caicos Islands|Chad|French Southern Lands|Togo|Thailand|Tajikistan|Tokelau|Timor-Leste|Turkmenistan|Tunisia|Tonga|Turkey|Trinidad and Tobago|Tuvalu|Taiwan|Tanzania|Ukraine|Uganda|United States Minor Outlying Islands|United States|Uruguay|Uzbekistan|Vatican City|Saint Vincent and the Grenadines|Venezuela|British Virgin Islands|Virgin Islands US|Vietnam|Vanuatu|Wallis and Futuna Islands|Samoa|Yemen|Mayotte|South Africa|Zambia|Zimbabwe" default="United States"/> + <setting id="limit_preferred_resolution" type="select" label="30002" values="1080p HD|720p HD|480p|360p" default="720p HD"/> + <setting id="force_preference" type="bool" label="30001" default="false"/> + <setting id="Enable_Debugging" type="bool" label="30000" default="false" /> +</settings>
\ No newline at end of file |