Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- cat tunein-xbmc/resources/lib/streamtheworld.py
- #/*
- # *
- # * TuneIn Radio: TuneIn add-on for XBMC.
- # *
- # * Copyright (C) 2012 Diego Fernando Nieto
- # *
- # * This program 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.
- # *
- # * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
- # *
- # */
- from random import choice as choise
- import os
- import sys
- import urllib2
- import xml.dom.minidom as minidom
- class StreamTheWorld:
- ## Example XML document we are parsing follows, as the minidom code is so beautiful to follow
- # http://playerservices.streamtheworld.com/api/livestream?version=1.4&mount=CARACOL_RADIOAAC&lang=EN
- #
- #<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
- #<live_stream_config version="1.4">
- # <mountpoints>
- # <mountpoint>
- # <status>
- # <status-code>200</status-code>
- # <status-message>OK</status-message>
- # </status>
- #
- # <transports>
- # <transport>http</transport>
- # </transports>
- #
- # <servers>
- # <server sid="3653">
- # <ip>3653.live.streamtheworld.com</ip>
- # <ports>
- # <port type="http">80</port>
- # <port type="http">3690</port>
- # <port type="http">443</port>
- # </ports>
- # </server>
- #
- # <server sid="1351">
- # <ip>1351.live.streamtheworld.com</ip>
- # <ports>
- # <port type="http">80</port>
- # <port type="http">3690</port>
- # <port type="http">443</port>
- # </ports>
- # </server>
- # </servers>
- #
- # <mount>CARACOL_RADIOAAC</mount>
- # <format>FLV</format>
- # <bitrate>32000</bitrate>
- # <media-format container="flv" cuepoints="andoxml">
- # <audio index="0" samplerate="44100" codec="heaacv2" bitrate="32000" channels="2"/>
- # </media-format>
- # <authentication>0</authentication>
- # <timeout>0</timeout>
- # </mountpoint>
- # </mountpoints>
- #</live_stream_config>
- ''' Parse streamtheworld URL to HTTP Stream
- '''
- def __init__(self, cs):
- self.__cs__ = cs
- return
- def __validate_callsign(self, cs):
- '''
- Normal callsign format is 'WWWWAAA', where 'WWWW' is the radio station
- callsign and 'AAA' is always 'AAC'.
- '''
- if not cs or not isinstance(cs, str):
- raise ValueError('callsign \'%s\' is not a string.' % cs)
- if len(cs) < 6:
- raise ValueError('callsign \'%s\' is too short.' % cs)
- if not cs.endswith('AAC'):
- cs = cs + 'AAC'
- return cs
- def __make_request(self, callsign):
- ''' Make a Call to StreamTheWorld API v1.4
- '''
- host = 'playerservices.streamtheworld.com'
- req = urllib2.Request(
- 'http://%s/api/livestream?version=1.4&mount=%s&lang=en' %
- (host, callsign))
- req.add_header('User-Agent', 'Mozilla/5.0')
- return req
- def __t(self, element):
- '''get the text of a DOM element'''
- return element.firstChild.data
- def __check_status(self, ele):
- ''' should only be one status element inside a mountpoint
- '''
- status = ele.getElementsByTagName('status')[0]
- if self.__t(status.getElementsByTagName('status-code')[0]) != '200':
- msg = self.__t(status.getElementsByTagName('status-message')[0])
- raise Exception('Error locating stream: ' + msg)
- def __create_stream_urls(self, srcfile):
- ''' Return an array with all URLs
- '''
- doc = minidom.parse(srcfile)
- mp = doc.getElementsByTagName('mountpoint')[0]
- self.__check_status(mp)
- mt = self.__t(mp.getElementsByTagName('mount')[0])
- allurls = []
- for s in mp.getElementsByTagName('server'):
- # a thing of beauty, right?
- ip = self.__t(s.getElementsByTagName('ip')[0])
- ports = [self.__t(p) for p in s.getElementsByTagName('port')]
- # yes, it is always HTTP. We see ports 80, 443, and 3690 usually
- urls = ['http://%s:%s/%s' % (ip, p, mt) for p in ports]
- allurls.extend(urls)
- return allurls
- def get_stream_url(self, cs):
- ''' Get one URL from CS
- '''
- callsign = self.__validate_callsign(cs)
- req = self.__make_request(callsign)
- result = urllib2.urlopen(req)
- urls = self.__create_stream_urls(result)
- if len(urls) > 0:
- u = choise(urls)
- if not u.endswith('_SC'):
- u = u + '_SC'
- return u
- '''if __name__ == '__main__':
- if len(sys.argv) < 2:
- print 'usage: station callsign must be the first argument'
- sys.exit(1)
- __streamtheworld__ = StreamTheWorld(sys.argv[1])
- sys.exit(os.system('echo %s' % __streamtheworld__.get_stream_url(sys.argv[1])))
- sys.exit(1)
- '''
Add Comment
Please, Sign In to add comment