Package elisa :: Package plugins :: Package ugly :: Package shoutcast_plugin :: Module shoutcast_media
[hide private]
[frames] | no frames]

Source Code for Module elisa.plugins.ugly.shoutcast_plugin.shoutcast_media

  1  # -*- coding: utf-8 -*- 
  2  # Elisa - Home multimedia server 
  3  # Copyright (C) 2006-2008 Fluendo Embedded S.L. (www.fluendo.com). 
  4  # All rights reserved. 
  5  # 
  6  # This file is available under one of two license agreements. 
  7  # 
  8  # This file is licensed under the GPL version 3. 
  9  # See "LICENSE.GPL" in the root of this distribution including a special 
 10  # exception to use Elisa with Fluendo's plugins. 
 11  # 
 12  # The GPL part of Elisa is also available under a commercial licensing 
 13  # agreement from Fluendo. 
 14  # See "LICENSE.Elisa" in the root directory of this distribution package 
 15  # for details on that license. 
 16   
 17  """ 
 18  Shoutcast Media Provider 
 19  """ 
 20   
 21   
 22  __maintainer__ = 'Benjamin Kampmann <benjamin@fluendo.com>' 
 23   
 24  from elisa.base_components.media_provider import MediaProvider 
 25  from elisa.core.media_uri import MediaUri 
 26  from elisa.core import common 
 27   
 28  from elisa.extern.coherence.et import parse_xml 
 29   
 30  from elisa.core.bus import bus_message 
 31   
 32  from twisted.internet import defer, threads 
 33   
 34  import urllib2, re 
 35   
 36  # FIXME: use a non-blocking library to retrieve web pages (such as twisted.web 
 37  # or even simpler Elisa's media_manager) 
 38   
39 -class ShoutcastMedia(MediaProvider):
40 """ 41 This class implements support for the shoutcast servers and playlist 42 """ 43 44 shout_uri = "http://www.shoutcast.com/sbin/newxml.phtml" 45 pl_getter = re.compile('File.=(.*?)\n') 46 47 intresting_genres = set([ 'Alternativ', "Classical", "Comedy", "Country", 48 "Dance", "Funk", "Jazz", "Metal", "Mixed", 49 "Pop", "Rap", "RnB", "Rock", "Talk", "Techno", 50 "80s", "70s", "World"])
51 - def initialize(self):
52 self._all = [] 53 uri = "shoutcast:///" 54 action_type = bus_message.MediaLocation.ActionType.LOCATION_ADDED 55 msg = bus_message.InternetLocation(action_type, "Shoutcast", 56 'shoutcast', 57 uri, 58 media_types=['audio',], 59 theme_icon='shoutcast' 60 ) 61 common.application.bus.send_message(msg)
62
63 - def _read_url(self, url):
64 fread = urllib2.urlopen(url) 65 return fread.read()
66
68 return { 'shoutcast': 0 }
69
71 return []
72
73 - def _blocking_get_media_type(self, uri):
74 if self._blocking_is_directory(uri): 75 return {'file_type' : 'directory', 76 'mime_type' : 'mime_type'} 77 78 return {'file_type' : 'audio', 'mime_type' : 'mp3'}
79
80 - def _blocking_is_directory(self, uri):
81 if uri.host == 'PLAY': 82 return False 83 return True
84
85 - def get_media_type(self, uri):
86 d = threads.deferToThread(self._blocking_get_media_type, 87 uri) 88 return d
89 90
91 - def has_children_with_types(self, uri, media_types):
92 d = threads.deferToThread(self._blocking_has_children_with_types, 93 uri, media_types) 94 return d
95
96 - def _blocking_has_children_with_types(self, uri, media_types):
97 if self._blocking_is_directory(uri): 98 if 'audio' in media_types: 99 return True 100 return False
101
102 - def _blocking_get_direct_children(self, uri, list_of_children):
103 104 if self._blocking_is_directory(uri): 105 if uri.host == "ALL": 106 for sub_uri in self._all: 107 list_of_children.append( (sub_uri, {}) ) 108 elif uri.path == '/': 109 if len(self._all) == 0: 110 xml = parse_xml(self._read_url(self.shout_uri)) 111 112 for elem in xml.findall('genre'): 113 name = elem.get('name') 114 uri = MediaUri('shoutcast:///%s' % name) 115 uri.label = name 116 self._all.append(uri) 117 if name in self.intresting_genres: 118 list_of_children.append( (uri, {}) ) 119 else: 120 for uri in self._all: 121 if uri.label in self.intresting_genres: 122 list_of_children.append( (uri, {}) ) 123 124 all_uri = MediaUri('shoutcast://ALL/') 125 # FIXME: hardcoded is bad! 126 all_uri.label = "All Genres" 127 list_of_children.append( (all_uri, {})) 128 else: 129 # We have a genre 130 genre = uri.path[1:] 131 path = '%s?genre=%s' %(self.shout_uri, genre) 132 xml = parse_xml(self._read_url(path)) 133 134 tune_in = xml.find('tunein') 135 base = tune_in.get('base') 136 137 for elem in xml.findall('station'): 138 name = elem.get('name') 139 id = elem.get('id') 140 uri = MediaUri('shoutcast://PLAY%s' % base) 141 uri.set_param('id', id) 142 uri.label = name 143 144 list_of_children.append( (uri, {}) ) 145 if len(list_of_children) >= 20: 146 break 147 148 return list_of_children
149
150 - def get_direct_children(self, uri, l):
151 d = threads.deferToThread(self._blocking_get_direct_children, uri, l) 152 return d
153
154 - def get_real_uri(self, uri):
155 path = "http://www.shoutcast.com%s?id=%s" % (uri.path, 156 uri.get_param('id')) 157 data = self._read_url(path) 158 res = self.pl_getter.search(data) 159 if res: 160 link = res.groups()[0] 161 new_uri = MediaUri(link) 162 return new_uri 163 return uri
164