The branch, frodo has been updated
       via  9c02c17d903ac4da238198d33b4709e0e31e0d9c (commit)
      from  e276b0420227cfdba557238e7ed737b5997a2053 (commit)

- Log -----------------------------------------------------------------
http://xbmc.git.sourceforge.net/git/gitweb.cgi?p=xbmc/plugins;a=commit;h=9c02c17d903ac4da238198d33b4709e0e31e0d9c

commit 9c02c17d903ac4da238198d33b4709e0e31e0d9c
Author: beenje <[email protected]>
Date:   Tue Feb 26 19:12:14 2013 +0100

    [plugin.video.fox.news] updated to version 3.0.0

diff --git a/plugin.video.fox.news/addon.xml b/plugin.video.fox.news/addon.xml
index dc4e611..4810832 100644
--- a/plugin.video.fox.news/addon.xml
+++ b/plugin.video.fox.news/addon.xml
@@ -1,21 +1,25 @@
-<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

-<addon id="plugin.video.fox.news"

-       name="Fox News"

-       version="2.0.7"

-       provider-name="divingmule">

-    <requires>

-        <import addon="xbmc.python" version="2.0"/>

-        <import addon="script.module.beautifulsoup" version="3.0.8"/>

-        <import addon="script.common.plugin.cache" version="0.9.1"/>

-    </requires>

-    <extension point="xbmc.python.pluginsource"

-               library="default.py">

-        <provides>video</provides>

-    </extension>

-    <extension point="xbmc.addon.metadata">

-        <platform>all</platform>

-        <language>en</language>

-        <summary lang="en">Fox News</summary>

-        <description lang="en">With this add-on you can watch all the videos 
from video.foxnews.com. Thanks to redeyed for the original plugin!</description>

-    </extension>

-</addon>

+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<addon id="plugin.video.fox.news"
+       name="Fox News"
+       version="3.0.0"
+       provider-name="divingmule">
+    <requires>
+      <import addon="xbmc.python" version="2.1.0"/>
+      <import addon="script.module.beautifulsoup" version="3.2.0"/>
+      <import addon="script.common.plugin.cache" version="2.5.1"/>
+    </requires>
+    <extension point="xbmc.python.pluginsource" library="default.py">
+      <provides>video</provides>
+    </extension>
+    <extension point="xbmc.addon.metadata">
+      <platform>all</platform>
+      <language>en</language>
+      <summary lang="en">Fox News</summary>
+      <description lang="en">
+        With this add-on you can watch all the videos from video.foxnews.com. 
Thanks to redeyed for the original plugin!
+      </description>
+      <forum>http://forum.xbmc.org/showthread.php?tid=57175</forum>
+      <source>https://code.google.com/p/foxnews-xbmc/source/checkout</source>
+      <license>GNU GENERAL PUBLIC LICENSE. Version 2, June 1991</license>
+    </extension>
+</addon>
diff --git a/plugin.video.fox.news/changelog.txt 
b/plugin.video.fox.news/changelog.txt
index cb08006..4ae5f9e 100644
--- a/plugin.video.fox.news/changelog.txt
+++ b/plugin.video.fox.news/changelog.txt
@@ -1,15 +1,19 @@
-Version 2.0.7

-fix website changes

-

-Version 2.0.6

-fix website changes

-

-Version 2.0.5

-fix for setting type change

-

-Version 2.0.4

-updated to reflect website changes

-

-Version 2.0.3

-fix for changes to the common cache plugin

+Version 3.0.0
+major version bump for frodo
+fix website changes
+
+Version 2.0.7
+fix website changes
+
+Version 2.0.6
+fix website changes
+
+Version 2.0.5
+fix for setting type change
+
+Version 2.0.4
+updated to reflect website changes
+
+Version 2.0.3
+fix for changes to the common cache plugin
 added a play mode for video directories
\ No newline at end of file
diff --git a/plugin.video.fox.news/default.py b/plugin.video.fox.news/default.py
index d4cd6ae..8ebdf98 100644
--- a/plugin.video.fox.news/default.py
+++ b/plugin.video.fox.news/default.py
@@ -1,241 +1,292 @@
-import urllib

-import urllib2

-import os

-import xbmcplugin

-import xbmcgui

-import xbmcaddon

-import xbmcvfs

-import StorageServer

-from BeautifulSoup import BeautifulSoup

-try:

-    import json

-except:

-    import simplejson as json

-

-__settings__ = xbmcaddon.Addon(id='plugin.video.fox.news')

-__language__ = __settings__.getLocalizedString

-home = __settings__.getAddonInfo('path')

-icon = xbmc.translatePath( os.path.join( home, 'icon.png' ) )

-cache = StorageServer.StorageServer("foxnews", 24)

-quality = __settings__.getSetting('quality')

-

-

-def make_request(url, headers=None):

-        if headers is None:

-            headers = {'User-agent' : 'Mozilla/5.0 (Windows NT 6.1; WOW64; 
rv:15.0) Gecko/20100101 Firefox/15.0.1',

-                       'Referer' : 'http://video.foxnews.com'}

-        try:

-            req = urllib2.Request(url,None,headers)

-            response = urllib2.urlopen(req)

-            data = response.read()

-            response.close()

-            return data

-        except urllib2.URLError, e:

-            print 'We failed to open "%s".' % url

-            if hasattr(e, 'reason'):

-                print 'We failed to reach a server.'

-                print 'Reason: ', e.reason

-            if hasattr(e, 'code'):

-                print 'We failed with error code - %s.' % e.code

-

-

-def get_categories():

-        url = 'http://video.foxnews.com/playlist/latest-latest-news/'

-        data = make_request(url)

-        soup = BeautifulSoup(data, convertEntities=BeautifulSoup.HTML_ENTITIES)

-        add_dir(soup.body.h1.contents[0].strip(), '', 2, icon)

-        h = soup.find('div', attrs={'class' : 'all'})

-        for i in h.findNext('ul')('a'):

-            add_dir(i.string, i['href'], 1, icon)

-        cache.set("videos_dict", repr({ "videos": get_video_list(data) }))

-

-

-def get_sub_categories(url):

-        if url.startswith('//video.foxnews'):

-            url = 'http:'+url

-        elif url.startswith('/'):

-            url = 'http://video.foxnews.com'+url

-        data = make_request(url)

-        soup = BeautifulSoup(data, convertEntities=BeautifulSoup.HTML_ENTITIES)

-        featured_name = soup.body.h1.contents[0].strip()

-        add_dir(featured_name, '', 2, icon)

-        items = soup('div', attrs={'id' : 'shows'})[0]('a')

-        for i in items:

-            name = i.string

-            if name != featured_name:

-                href = 'http:'+i['href']

-                add_dir(name, href, 3, icon)

-        cache.set("videos_dict", repr({ "videos": get_video_list(data) }))

-

-

-def get_video_list(html, url=None):

-        if url is None:

-            soup = BeautifulSoup(html, 
convertEntities=BeautifulSoup.HTML_ENTITIES)

-        else:

-            soup = BeautifulSoup(make_request(url), 
convertEntities=BeautifulSoup.HTML_ENTITIES)

-        items = soup.find('div', attrs={'class' : 'pl'})('li')

-        video_list = []

-        for i in items:

-            href = i.a['href']

-            name = i.h2.a.string

-            thumb = i.img['src']

-            date = i.time.string

-            duration = i.strong.string

-            desc = i.span.string

-            if url is not None:

-                add_link(date, name, duration, href, thumb, desc)

-            else:

-                video_list.append((date, name, duration, href, thumb, desc))

-        if url is None:

-            return video_list

-

-

-def get_featured_videos():

-        for i in eval(cache.get("videos_dict"))['videos']:

-            add_link(i[0], i[1], i[2], i[3], i[4], i[5])

-

-

-def get_json_data(video_id):

-        url = 'http://video.foxnews.com/v/feed/video/%s.js?' %video_id

-        data = json.loads(make_request(url))

-        try:

-            video_url = 
data['channel']['item']['media-content']['@attributes']['url']

-            if video_url is None: raise

-            else: return video_url

-        except:

-            try:

-                video_url = 
data['channel']['item']['media-content']['mvn-fnc_mp4']

-                if video_url is None: raise

-                else: return video_url

-            except:

-                try:

-                    video_url = 
data['channel']['item']['media-content']['mvn-flv1200']

-                    if video_url is None: raise

-                    else: return video_url

-                except:

-                    print '-- No video_url --'

-                    return None

-

-

-def get_smil(video_id):

-        smil_url = 'http://video.foxnews.com/v/feed/video/%s.smil' %video_id

-        headers = {'Referer' : 
'http://video.foxnews.com/assets/akamai/FoxNewsPlayer.swf',

-                   'User-Agent' : 'Mozilla/5.0 (Windows NT 6.1; WOW64; 
rv:15.0) Gecko/20100101 Firefox/15.0.1'}

-        soup = BeautifulSoup(make_request(smil_url, headers))

-        try:

-            return soup.find('meta', attrs={'name' : 
"rtmpAuthBase"})['content'] + soup.find('video')['src']

-        except: return None

-

-

-def resolve_url(url):

-        quality_types = {'0' : '_FNC_HIGH.',

-                         '1' : '_FNC_MED.',

-                         '2' : '_FNC_MED_LOW.',

-                         '3' : '_FNC_LOW.'}

-        quality_type = quality_types[quality]

-        video_id = url.split('/v/')[1].split('/')[0]

-        vidoe_url = None

-        try:

-            video_url = get_smil(video_id)

-            if vidoe_url is None: raise

-        except:

-            try:

-                video_url = get_json_data(video_id)

-                if vidoe_url is None: raise

-            except: pass

-        if video_url is None:

-            succeeded = False

-            playback_url = ''

-        else:

-            succeeded = True

-        if succeeded:

-            if not quality_type in video_url:

-                for i in quality_types.values():

-                    if i in video_url:

-                        playback_url = video_url.replace(i, quality_type)

-                        break

-            else: playback_url = video_url

-        item = xbmcgui.ListItem(path=playback_url)

-        xbmcplugin.setResolvedUrl(int(sys.argv[1]), succeeded, item)

-

-

-

-def add_link(date, name, duration, href, thumb, desc):

-        description = date+'\n\n'+desc

-        u=sys.argv[0]+"?url="+urllib.quote_plus(href)+"&mode=4"

-        liz=xbmcgui.ListItem(name, iconImage="DefaultVideo.png", 
thumbnailImage=thumb)

-        liz.setInfo(type="Video", infoLabels={ "Title": name, "Plot": 
description, "Duration": duration})

-        liz.setProperty('IsPlayable', 'true')

-        
ok=xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]),url=u,listitem=liz)

-

-

-

-def add_dir(name,url,mode,iconimage):

-        
u=sys.argv[0]+"?url="+urllib.quote_plus(url)+"&mode="+str(mode)+"&name="+urllib.quote_plus(name)

-        ok=True

-        liz=xbmcgui.ListItem(name, iconImage="DefaultFolder.png", 
thumbnailImage=iconimage)

-        liz.setInfo( type="Video", infoLabels={ "Title": name } )

-        
ok=xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]),url=u,listitem=liz,isFolder=True)

-        return ok

-

-

-def get_params():

-        param=[]

-        paramstring=sys.argv[2]

-        if len(paramstring)>=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

-

-

-xbmcplugin.setContent(int(sys.argv[1]), 'movies')

-

-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

-

-print "Mode: "+str(mode)

-print "URL: "+str(url)

-print "Name: "+str(name)

-

-if mode==None:

-    get_categories()

-

-elif mode==1:

-    get_sub_categories(url)

-

-elif mode==2:

-    get_featured_videos()

-

-elif mode==3:

-    get_video_list(None, url)

-

-elif mode==4:

-    resolve_url(url)

-

+import urllib
+import urllib2
+import os
+import re
+import xbmcplugin
+import xbmcgui
+import xbmcaddon
+import xbmcvfs
+import StorageServer
+from BeautifulSoup import BeautifulSoup
+try:
+    import json
+except:
+    import simplejson as json
+
+__settings__ = xbmcaddon.Addon(id='plugin.video.fox.news')
+__language__ = __settings__.getLocalizedString
+home = __settings__.getAddonInfo('path')
+icon = xbmc.translatePath( os.path.join( home, 'icon.png' ) )
+cache = StorageServer.StorageServer("foxnews", 24)
+quality = __settings__.getSetting('quality')
+
+
+def make_request(url, headers=None):
+        if headers is None:
+            headers = {'User-agent' : 'Mozilla/5.0 (Windows NT 6.1; WOW64; 
rv:15.0) Gecko/20100101 Firefox/15.0.1',
+                       'Referer' : 'http://video.foxnews.com'}
+        try:
+            req = urllib2.Request(url,None,headers)
+            response = urllib2.urlopen(req)
+            data = response.read()
+            response.close()
+            return data
+        except urllib2.URLError, e:
+            print 'We failed to open "%s".' % url
+            if hasattr(e, 'reason'):
+                print 'We failed to reach a server.'
+                print 'Reason: ', e.reason
+            if hasattr(e, 'code'):
+                print 'We failed with error code - %s.' % e.code
+
+
+def get_categories():
+        # add_dir('Watch Live', '', 5, icon)
+        url = 'http://video.foxnews.com/playlist/latest-latest-news/'
+        data = make_request(url)
+        soup = BeautifulSoup(data, convertEntities=BeautifulSoup.HTML_ENTITIES)
+        add_dir(soup.body.h1.contents[0].strip(), '', 2, icon)
+        for i in soup.find('nav')('a'):
+            add_dir(i.string, i['href'], 1, icon)
+        cache.set("videos_dict", repr({ "videos": get_video_list(data) }))
+
+
+def get_sub_categories(url):
+        if url.startswith('//video.foxnews'):
+            url = 'http:'+url
+        elif url.startswith('/'):
+            url = 'http://video.foxnews.com'+url
+        data = make_request(url)
+        soup = BeautifulSoup(data, convertEntities=BeautifulSoup.HTML_ENTITIES)
+        featured_name = soup.body.h1.contents[0].strip()
+        add_dir(featured_name, '', 2, icon)
+        items = soup('div', attrs={'id' : 'shows'})[0]('a')
+        for i in items:
+            name = i.string
+            if name != featured_name:
+                href = 'http:'+i['href']
+                add_dir(name, href, 3, icon)
+        cache.set("videos_dict", repr({ "videos": get_video_list(data) }))
+
+
+def get_video_list(html, url=None):
+        if url is None:
+            soup = BeautifulSoup(html, 
convertEntities=BeautifulSoup.HTML_ENTITIES)
+        else:
+            soup = BeautifulSoup(make_request(url), 
convertEntities=BeautifulSoup.HTML_ENTITIES)
+        items = soup.find('div', attrs={'class' : 'pl'})('li')
+        video_list = []
+        for i in items:
+            href = i.a['href']
+            name = i.h2.a.string
+            thumb = i.img['src']
+            date = i.time.string
+            duration = i.strong.string
+            desc = i.span.string
+            if url is not None:
+                add_link(date, name, duration, href, thumb, desc)
+            else:
+                video_list.append((date, name, duration, href, thumb, desc))
+        if url is None:
+            return video_list
+
+
+def get_featured_videos():
+        for i in eval(cache.get("videos_dict"))['videos']:
+            add_link(i[0], i[1], i[2], i[3], i[4], i[5])
+
+
+def get_json_data(video_id):
+        url = 'http://video.foxnews.com/v/feed/video/%s.js?' %video_id
+        data = json.loads(make_request(url))
+        try:
+            video_url = 
data['channel']['item']['media-content']['@attributes']['url']
+            if video_url is None: raise
+            else: return video_url
+        except:
+            try:
+                video_url = 
data['channel']['item']['media-content']['mvn-fnc_mp4']
+                if video_url is None: raise
+                else: return video_url
+            except:
+                try:
+                    video_url = 
data['channel']['item']['media-content']['mvn-flv1200']
+                    if video_url is None: raise
+                    else: return video_url
+                except:
+                    print '-- No video_url --'
+                    return None
+
+
+def get_smil(video_id):
+        smil_url = 'http://video.foxnews.com/v/feed/video/%s.smil' %video_id
+        headers = {'Referer' : 
'http://video.foxnews.com/assets/akamai/FoxNewsPlayer.swf',
+                   'User-Agent' : 'Mozilla/5.0 (Windows NT 6.1; WOW64; 
rv:15.0) Gecko/20100101 Firefox/15.0.1'}
+        soup = BeautifulSoup(make_request(smil_url, headers))
+        try:
+            return soup.find('meta', attrs={'name' : 
"rtmpAuthBase"})['content'] + soup.find('video')['src']
+        except: return None
+
+
+def resolve_url(url):
+        quality_types = {'0' : '_FNC_HIGH.',
+                         '1' : '_FNC_MED.',
+                         '2' : '_FNC_MED_LOW.',
+                         '3' : '_FNC_LOW.'}
+        quality_type = quality_types[quality]
+        video_id = url.split('/v/')[1].split('/')[0]
+        vidoe_url = None
+        try:
+            video_url = get_smil(video_id)
+            if vidoe_url is None: raise
+        except:
+            try:
+                video_url = get_json_data(video_id)
+                if vidoe_url is None: raise
+            except: pass
+        if video_url is None:
+            succeeded = False
+            playback_url = ''
+        else:
+            succeeded = True
+        if succeeded:
+            if not quality_type in video_url:
+                for i in quality_types.values():
+                    if i in video_url:
+                        playback_url = video_url.replace(i, quality_type)
+                        break
+            else: playback_url = video_url
+        item = xbmcgui.ListItem(path=playback_url)
+        xbmcplugin.setResolvedUrl(int(sys.argv[1]), succeeded, item)
+
+
+def get_live_streams():
+        playlist_id = None
+        items = None
+        data = 
make_request('http://video.foxnews.com/playlist/live-landing-page/')
+        pattern = 'pageVars.playlistId = "(.+?)";'
+        match = re.findall(pattern, data)
+        if len(match) > 0:
+            playlist_id = match[0]
+        if playlist_id:
+            json_url = 
'http://video.foxnews.com/v/feed/playlist/%s.js?template=fox&callback=FOX_Header_Watch_Feed'
 %playlist_id
+            j_data = 
json.loads(make_request(json_url).strip('FOX_Header_Watch_Feed(')[:-1])
+            items = j_data['channel']['item']
+        if items:
+            for i in items:
+                title = i['title']
+                smil = i['enclosure']['@attributes']['url']
+                thumb = 
i['media-group']['media-thumbnail']['@attributes']['url']
+                print (title, smil, thumb)
+                u=sys.argv[0]+"?url="+urllib.quote_plus(smil)+"&mode=6"
+                liz=xbmcgui.ListItem(title, iconImage="DefaultVideo.png", 
thumbnailImage=thumb)
+                liz.setInfo(type="Video", infoLabels={"Title": title})
+                liz.setProperty('IsPlayable', 'true')
+                
ok=xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]),url=u,listitem=liz)
+
+
+def resolve_live_url(url):
+        resolved_url = ''
+        succeeded = False
+        soup = BeautifulSoup(make_request(url))
+        base = soup.find('meta', attrs={'name': "httpBase"})['content']
+        renditions = []
+        for i in soup('video'):
+            renditions.append({'bitrate': i['system-bitrate'], 'href': 
i['src']})
+        sorted_renditions = sorted(renditions, key=lambda k: 
int(k['bitrate']), reverse=True)
+        if len(sorted_renditions) == 4:
+            resolved_url = base + sorted_renditions[int(quality)]['href']
+        else:
+            resolved_url = base + sorted_renditions[0]['href']
+        if resolved_url != '':
+            succeeded = True
+        item = xbmcgui.ListItem(path=resolved_url)
+        xbmcplugin.setResolvedUrl(int(sys.argv[1]), succeeded, item)
+
+
+
+def add_link(date, name, duration, href, thumb, desc):
+        description = date+'\n\n'+desc
+        u=sys.argv[0]+"?url="+urllib.quote_plus(href)+"&mode=4"
+        liz=xbmcgui.ListItem(name, iconImage="DefaultVideo.png", 
thumbnailImage=thumb)
+        liz.setInfo(type="Video", infoLabels={ "Title": name, "Plot": 
description, "Duration": duration})
+        liz.setProperty('IsPlayable', 'true')
+        
ok=xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]),url=u,listitem=liz)
+
+
+
+def add_dir(name,url,mode,iconimage):
+        
u=sys.argv[0]+"?url="+urllib.quote_plus(url)+"&mode="+str(mode)+"&name="+urllib.quote_plus(name)
+        ok=True
+        liz=xbmcgui.ListItem(name, iconImage="DefaultFolder.png", 
thumbnailImage=iconimage)
+        liz.setInfo( type="Video", infoLabels={ "Title": name } )
+        
ok=xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]),url=u,listitem=liz,isFolder=True)
+        return ok
+
+
+def get_params():
+        param=[]
+        paramstring=sys.argv[2]
+        if len(paramstring)>=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
+
+
+xbmcplugin.setContent(int(sys.argv[1]), 'movies')
+
+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
+
+print "Mode: "+str(mode)
+print "URL: "+str(url)
+print "Name: "+str(name)
+
+if mode==None:
+    get_categories()
+
+elif mode==1:
+    get_sub_categories(url)
+
+elif mode==2:
+    get_featured_videos()
+
+elif mode==3:
+    get_video_list(None, url)
+
+elif mode==4:
+    resolve_url(url)
+
+elif mode==5:
+    get_live_streams()
+
+elif mode==6:
+    resolve_live_url(url)
+
 xbmcplugin.endOfDirectory(int(sys.argv[1]))
\ No newline at end of file
diff --git a/plugin.video.fox.news/resources/settings.xml 
b/plugin.video.fox.news/resources/settings.xml
index a986c34..9a4c247 100644
--- a/plugin.video.fox.news/resources/settings.xml
+++ b/plugin.video.fox.news/resources/settings.xml
@@ -1,3 +1,3 @@
-<settings>

-   <setting id="quality" type="enum" lvalues="30002|30003|30004|30005" 
values="0|1|2|3" label="30001" default="0"/>

+<settings>
+   <setting id="quality" type="enum" lvalues="30002|30003|30004|30005" 
values="0|1|2|3" label="30001" default="0"/>
 </settings>
\ No newline at end of file

-----------------------------------------------------------------------

Summary of changes:
 plugin.video.fox.news/addon.xml              |   46 ++-
 plugin.video.fox.news/changelog.txt          |   32 +-
 plugin.video.fox.news/default.py             |  531 ++++++++++++++------------
 plugin.video.fox.news/resources/settings.xml |    4 +-
 4 files changed, 336 insertions(+), 277 deletions(-)


hooks/post-receive
-- 
Plugins

------------------------------------------------------------------------------
Everyone hates slow websites. So do we.
Make your web apps faster with AppDynamics
Download AppDynamics Lite for free today:
http://p.sf.net/sfu/appdyn_d2d_feb
_______________________________________________
Xbmc-addons mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/xbmc-addons

Reply via email to