diff --git a/modules/radiofrance/browser.py b/modules/radiofrance/browser.py
index 32ccc8c8..05f174a0 100644
--- a/modules/radiofrance/browser.py
+++ b/modules/radiofrance/browser.py
@@ -17,172 +17,20 @@
# You should have received a copy of the GNU Affero General Public License
# along with weboob. If not, see .
-from weboob.deprecated.browser import Browser, Page
-from weboob.tools.json import json
-from weboob.capabilities.video import BaseVideo
-from weboob.deprecated.browser.decorators import id2url
+from weboob.browser import PagesBrowser, URL
+from .pages import PlayerPage, TimelinePage
-from time import time
-import re
-from urlparse import parse_qs
+__all__ = ['RadioFranceBrowser']
-__all__ = ['RadioFranceBrowser', 'RadioFranceVideo']
+class RadioFranceBrowser(PagesBrowser):
+ timeline = URL('sites/default/files/(?P.*).json', TimelinePage)
+ player_page = URL('(?P.*)', PlayerPage)
+ def get_radio_url(self, radio, player):
+ self.BASEURL = 'http://www.%s.fr/' % radio
+ return self.player_page.go(player=player).get_url()
-class RadioFranceVideo(BaseVideo):
- RADIO_DOMAINS = ('franceinter', 'franceculture', 'fipradio', 'franceinfo')
-
- def __init__(self, *args, **kwargs):
- BaseVideo.__init__(self, *args, **kwargs)
- self.ext = u'mp3'
-
- @classmethod
- def id2url(cls, _id):
- radio_id, replay_id = _id.split('-', 2)
- radio_domain = 'fipradio' if radio_id == 'fip' else radio_id
- return 'http://www.%s.fr/player/reecouter?play=%s' % \
- (radio_domain, replay_id)
-
-
-class PlayerPage(Page):
- URL = r'^http://www\.(?P%s)\.fr/player/reecouter\?play=(?P\d+)$' \
- % '|'.join(RadioFranceVideo.RADIO_DOMAINS)
- MP3_REGEXP = re.compile(r'sites%2Fdefault.+.(?:MP3|mp3)')
-
- def get_url(self):
- radio_domain = self.groups[0]
- player = self.parser.select(self.document.getroot(), '#rfPlayer embed', 1)
- urlparams = parse_qs(player.attrib['src'])
- return 'http://www.%s.fr/%s' % (radio_domain, urlparams['urlAOD'][0])
-
-
-class ReplayPage(Page):
- URL = r'^http://www\.(?P%s)\.fr/(?:emission|diffusion)-.+$' \
- % '|'.join(RadioFranceVideo.RADIO_DOMAINS)
- # the url does not always end with id-yyy-mm-dd, sometimes no mm or dd
- URL2 = r'^http://www\.(?P%s)\.fr/[a-z\-]+/[0-9a-z\-]+/[0-9a-z\-]+-[0-9\-]+' \
- % 'franceinfo'
-
- def get_id(self):
- radio_domain = self.groups[0]
- for node in self.parser.select(self.document.getroot(), 'div.node-rf_diffusion'):
- match = re.match(r'^node-(\d+)$', node.attrib.get('id', ''))
- if match:
- player_id = match.groups()[0]
- return (radio_domain, player_id)
- # if we failed, try another way (used in FIP)
- # but it might not be as accurate for others
- # (some pages have more than one of these)
- # so it's only used as a fallback
- for node in self.parser.select(self.document.getroot(), 'a.rf-player-open'):
- match = re.match(r'^/player/reecouter\?play=(\d+)$', node.attrib.get('href', ''))
- if match:
- player_id = match.groups()[0]
- return (radio_domain, player_id)
- # at least for franceinfo
- for node in self.parser.select(self.document.getroot(), '#article .emission-player a.play'):
- match = re.match(r'^song-(\d+)$', node.attrib.get('rel', ''))
- if match:
- player_id = match.groups()[0]
- return (radio_domain, player_id)
-
-
-class DataPage(Page):
- def get_current(self):
- document = self.document
- title = ''
- for metas in self.parser.select(document.getroot(), 'div.metas'):
- ftitle = unicode(metas.text_content()).strip()
- if ftitle:
- title = ftitle
- # Another format (used by FIP)
- artist = document.findtext('//div[@class="metas"]//span[@class="author"]')
- if artist:
- artist = unicode(artist).strip()
- ftitle = document.findtext('//div[@class="subtitle"]')
- title = unicode(ftitle).strip() if ftitle else title
- else:
- artist = ''
-
- return (artist, title)
-
-
-class RssPage(Page):
- def get_title(self):
- titles = []
- for heading in self.parser.select(self.document.getroot(), 'h1, h2, h3, h4'):
- # Remove newlines/multiple spaces
- words = heading.text_content()
- if words:
- for word in unicode(words).split():
- titles.append(word)
- if len(titles):
- return ' '.join(titles)
-
-
-class RadioFranceBrowser(Browser):
- DOMAIN = None
- ENCODING = 'UTF-8'
- PAGES = {r'http://.*/player/direct': DataPage,
- r'http://players.tv-radio.com/radiofrance/metadatas/([a-z]+)RSS.html': RssPage,
- PlayerPage.URL: PlayerPage,
- ReplayPage.URL: ReplayPage,
- ReplayPage.URL2: ReplayPage}
-
- def id2domain(self, _id):
- """
- Get the main website domain for a Radio ID.
- """
- # FIP is the only one to use "fip" but "fipradio" for the domain.
- if _id == 'fip':
- _id = 'fipradio'
- return 'www.%s.fr' % _id
-
- def get_current_playerjs(self, _id):
- self.location('http://%s/player/direct' % self.id2domain(_id))
- assert self.is_on_page(DataPage)
-
- return self.page.get_current()
-
- def get_current_rss(self, _id):
- self.location('http://players.tv-radio.com/radiofrance/metadatas/%sRSS.html' % _id)
- assert self.is_on_page(RssPage)
-
- return self.page.get_title()
-
- def get_current_direct(self, _id):
- json_data = self.openurl('http://%s/sites/default/files/direct.json?_=%s' % (self.id2domain(_id), int(time())))
- data = json.load(json_data)
- title = unicode(data['rf_titre_antenne']['titre'])
- artist = unicode(data['rf_titre_antenne']['interprete'])
- return (artist, title)
-
- def get_current_direct_large(self, _id):
- json_data = self.openurl('http://%s/sites/default/files/import_si/si_titre_antenne/FIP_player_current.json'
- % self.id2domain(_id))
- data = json.load(json_data)
- artist = unicode(data['current']['song']['interpreteMorceau'])
- title = unicode(data['current']['song']['titre'])
- return (artist, title)
-
- @id2url(RadioFranceVideo.id2url)
- def get_video(self, url):
- radio_domain = replay_id = None
- match = re.match(PlayerPage.URL, url)
- if match:
- radio_domain, replay_id = match.groups()
- elif re.match(ReplayPage.URL, url) or re.match(ReplayPage.URL2, url):
- self.location(url)
- assert self.is_on_page(ReplayPage)
- radio_domain, replay_id = self.page.get_id()
- if radio_domain and replay_id:
- radio_id = 'fip' if radio_domain == 'fipradio' else radio_domain
- _id = '%s-%s' % (radio_id, replay_id)
- return RadioFranceVideo(_id)
-
- @id2url(RadioFranceVideo.id2url)
- def get_url(self, url):
- self.location(url)
- assert self.is_on_page(PlayerPage)
- return self.page.get_url()
+ def get_current(self, radio, json_url):
+ self.BASEURL = 'http://www.%s.fr/' % radio
+ return self.timeline.go(json_url=json_url).get_current()
diff --git a/modules/radiofrance/module.py b/modules/radiofrance/module.py
index 3bf271ab..673859f1 100644
--- a/modules/radiofrance/module.py
+++ b/modules/radiofrance/module.py
@@ -19,20 +19,21 @@
from weboob.capabilities.base import NotLoaded
-from weboob.capabilities.video import CapVideo
from weboob.capabilities.radio import CapRadio, Radio
from weboob.capabilities.audiostream import BaseAudioStream
from weboob.tools.capabilities.streaminfo import StreamInfo
from weboob.capabilities.collection import CapCollection, CollectionNotFound, Collection
from weboob.tools.backend import Module
-from .browser import RadioFranceBrowser, RadioFranceVideo
+from .browser import RadioFranceBrowser
+import time
+from datetime import datetime
__all__ = ['RadioFranceModule']
-class RadioFranceModule(Module, CapRadio, CapCollection, CapVideo):
+class RadioFranceModule(Module, CapRadio, CapCollection):
NAME = 'radiofrance'
MAINTAINER = u'Laurent Bachelier'
EMAIL = 'laurent@bachelier.name'
@@ -41,166 +42,113 @@ class RadioFranceModule(Module, CapRadio, CapCollection, CapVideo):
LICENSE = 'AGPLv3+'
BROWSER = RadioFranceBrowser
- _MP3_URL = u'http://mp3.live.tv-radio.com/%s/all/%s.mp3'
- _MP3_HD_URL = u'http://mp3.live.tv-radio.com/%s/all/%shautdebit.mp3'
- _RADIOS = {'franceinter': (u'France Inter', True),
- 'franceculture': (u'France Culture', True),
- 'franceinfo': (u'France Info', False),
- 'fbidf': (u'France Bleu Île-de-France (Paris)', True),
- 'fip': (u'FIP', True),
- 'francemusique': (u'France Musique', True),
- 'lemouv': (u'Le Mouv\'', True),
- 'fbalsace': (u'France Bleu Alsace (Strasbourg)', False),
- 'fbarmorique': (u'France Bleu Armorique (Rennes)', False),
- 'fbauxerre': (u'France Bleu Auxerre', False),
- 'fbazur': (u'France Bleu Azur (Nice)', False),
- 'fbbassenormandie': (u'France Bleu Basse Normandie (Caen)', False),
- 'fbbearn': (u'France Bleu Bearn (Pau)', False),
- 'fbbelfort': (u'France Bleu Belfort', False),
- 'fbberry': (u'France Bleu Berry (Châteauroux)', False),
- 'fbbesancon': (u'France Bleu Besancon', False),
- 'fbbourgogne': (u'France Bleu Bourgogne (Dijon)', False),
- 'fbbreizizel': (u'France Bleu Breiz Izel (Quimper)', False),
- 'fbchampagne': (u'France Bleu Champagne (Reims)', False),
- 'fbcotentin': (u'France Bleu Cotentin (Cherbourg)', False),
- 'fbcreuse': (u'France Bleu Creuse (Gueret)', False),
- 'fbdromeardeche': (u'France Bleu Drome Ardeche (Valence)', False),
- 'fbfrequenzamora': (u'France Bleu Frequenza Mora (Bastia - Corse)', False),
- 'fbgardlozere': (u'France Bleu Gard Lozère (Nîmes)', False),
- 'fbgascogne': (u'France Bleu Gascogne (Mont-de-Marsan)', False),
- 'fbgironde': (u'France Bleu Gironde (Bordeaux)', False),
- 'fbhautenormandie': (u'France Bleu Haute Normandie (Rouen)', False),
- 'fbherault': (u'France Bleu Hérault (Montpellier)', False),
- 'fbisere': (u'France Bleu Isère (Grenoble)', False),
- 'fblarochelle': (u'France Bleu La Rochelle', False),
- 'fblimousin': (u'France Bleu Limousin (Limoges)', False),
- 'fbloireocean': (u'France Bleu Loire Océan (Nantes)', False),
- 'fblorrainenord': (u'France Bleu Lorraine Nord (Metz)', False),
- 'fbmayenne': (u'France Bleu Mayenne (Laval)', False),
- 'fbnord': (u'France Bleu Nord (Lille)', False),
- 'fborleans': (u'France Bleu Orléans', False),
- 'fbpaysbasque': (u'France Bleu Pays Basque (Bayonne)', False),
- 'fbpaysdauvergne': (u'France Bleu Pays d\'Auvergne (Clermont-Ferrand)', False),
- 'fbpaysdesavoie': (u'France Bleu Pays de Savoie (Chambery)', False),
- 'fbperigord': (u'France Bleu Périgord (Périgueux)', False),
- 'fbpicardie': (u'France Bleu Picardie (Amiens)', False),
- 'fbpoitou': (u'France Bleu Poitou (Poitiers)', False),
- 'fbprovence': (u'France Bleu Provence (Aix-en-Provence)', False),
- 'fbroussillon': (u'France Bleu Roussillon (Perpigan)', False),
- 'fbsudlorraine': (u'France Bleu Sud Lorraine (Nancy)', False),
- 'fbtoulouse': (u'France Bleu Toulouse', False),
- 'fbtouraine': (u'France Bleu Touraine (Tours)', False),
- 'fbvaucluse': (u'France Bleu Vaucluse (Avignon)', False),
+ _RADIOS = {'franceinter': (u'France Inter', 'player', 'lecteur_commun_json/timeline'),
+ 'franceculture': (u'France Culture', 'player', 'lecteur_commun_json/timeline'),
+ 'franceinfo': (u'France Info', 'player', 'lecteur_commun_json/timeline'),
+ 'fbidf': (u'France Bleu Île-de-France (Paris)', 'station/france-bleu-107-1', 'lecteur_commun_json/timeline-9753'),
+ 'fipradio': (u'FIP', 'player', 'import_si/si_titre_antenne/FIP_player_current'),
+ 'francemusique': (u'France Musique', 'player', 'lecteur_commun_json/reecoute-%s' % int(time.mktime(datetime.now().replace(hour=14, minute=0, second=0).timetuple()))),
+ 'mouv': (u'Le Mouv\'', 'player', 'lecteur_commun_json/timeline'),
+ 'fbalsace': (u'France Bleu Alsace (Strasbourg)', 'player/station/france-bleu-alsace', 'lecteur_commun_json/timeline-13085'),
+ 'fbarmorique': (u'France Bleu Armorique (Rennes)', 'player/station/france-bleu-armorique', 'lecteur_commun_json/timeline-13087'),
+ 'fbauxerre': (u'France Bleu Auxerre', 'player/station/france-bleu-auxerre', 'lecteur_commun_json/timeline-11219'),
+ 'fbazur': (u'France Bleu Azur (Nice)', 'player/station/france-bleu-azur', 'lecteur_commun_json/timeline-13089'),
+ 'fbbassenormandie': (u'France Bleu Basse Normandie (Caen)', 'player/station/france-bleu-bassenormandie', 'lecteur_commun_json/timeline-13091'),
+ 'fbbearn': (u'France Bleu Bearn (Pau)', 'player/station/france-bleu-bearn', 'lecteur_commun_json/timeline-13093'),
+ 'fbbelfort': (u'France Bleu Belfort', 'player/station/france-bleu-belfort', 'lecteur_commun_json/timeline-13095'),
+ 'fbberry': (u'France Bleu Berry (Châteauroux)', 'player/station/france-bleu-berry', 'lecteur_commun_json/timeline-11223'),
+ 'fbbesancon': (u'France Bleu Besancon', 'player/station/france-bleu-besancon', 'lecteur_commun_json/timeline-13097'),
+ 'fbbourgogne': (u'France Bleu Bourgogne (Dijon)', 'player/station/france-bleu-bourgogne', 'lecteur_commun_json/timeline-13099'),
+ 'fbbreizizel': (u'France Bleu Breiz Izel (Quimper)', 'player/station/france-bleu-breizizel', 'lecteur_commun_json/timeline-13101'),
+ 'fbchampagne': (u'France Bleu Champagne (Reims)', 'player/station/france-bleu-champagne', 'lecteur_commun_json/timeline-13103'),
+ 'fbcotentin': (u'France Bleu Cotentin (Cherbourg)', 'player/station/france-bleu-cotentin', 'lecteur_commun_json/timeline-13105'),
+ 'fbcreuse': (u'France Bleu Creuse (Gueret)', 'player/station/france-bleu-creuse', 'lecteur_commun_json/timeline-13107'),
+ 'fbdromeardeche': (u'France Bleu Drome Ardeche (Valence)', 'player/station/france-bleu-dromeardeche', 'lecteur_commun_json/timeline-13109'),
+ 'fbelsass': (u'France Bleu Elsass', '/player/station/france-bleu-elsass', 'lecteur_commun_json/timeline-19370'),
+ 'fbgardlozere': (u'France Bleu Gard Lozère (Nîmes)', 'player/station/france-bleu-gardlozere', 'lecteur_commun_json/timeline-13111'),
+ 'fbgascogne': (u'France Bleu Gascogne (Mont-de-Marsan)', 'player/station/france-bleu-gascogne', 'lecteur_commun_json/timeline-13113'),
+ 'fbgironde': (u'France Bleu Gironde (Bordeaux)', 'player/station/france-bleu-gironde', 'lecteur_commun_json/timeline-13115'),
+ 'fbhautenormandie': (u'France Bleu Haute Normandie (Rouen)', 'player/station/france-bleu-hautenormandie', 'lecteur_commun_json/timeline-13117'),
+ 'fbherault': (u'France Bleu Hérault (Montpellier)', 'player/station/france-bleu-herault', 'lecteur_commun_json/timeline-11231'),
+ 'fbisere': (u'France Bleu Isère (Grenoble)', 'player/station/france-bleu-isere', 'lecteur_commun_json/timeline-13119'),
+ 'fblarochelle': (u'France Bleu La Rochelle', 'player/station/france-bleu-larochelle', 'lecteur_commun_json/timeline-13121'),
+ 'fblimousin': (u'France Bleu Limousin (Limoges)', 'player/station/france-bleu-limousin', 'lecteur_commun_json/timeline-13123'),
+ 'fbloireocean': (u'France Bleu Loire Océan (Nantes)', 'player/station/france-bleu-loireocean', 'lecteur_commun_json/timeline-13125'),
+ 'fblorrainenord': (u'France Bleu Lorraine Nord (Metz)', 'player/station/france-bleu-lorrainenord', 'lecteur_commun_json/timeline-13127'),
+ 'fbmaine': (u'France Bleu Maine', '/player/station/france-bleu-maine', 'lecteur_commun_json/timeline-13129'),
+ 'fbmayenne': (u'France Bleu Mayenne (Laval)', 'player/station/france-bleu-mayenne', 'lecteur_commun_json/timeline-13131'),
+ 'fbnord': (u'France Bleu Nord (Lille)', 'player/station/france-bleu-nord', 'lecteur_commun_json/timeline-11235'),
+ 'fborleans': (u'France Bleu Orléans', 'player/station/france-bleu-orleans', 'lecteur_commun_json/timeline-13133'),
+ 'fbpaysbasque': (u'France Bleu Pays Basque (Bayonne)', 'player/station/france-bleu-paysbasque', 'lecteur_commun_json/timeline-13135'),
+ 'fbpaysdauvergne': (u'France Bleu Pays d\'Auvergne (Clermont-Ferrand)', 'player/station/france-bleu-paysdauvergne', 'lecteur_commun_json/timeline-11237'),
+ 'fbpaysdesavoie': (u'France Bleu Pays de Savoie (Chambery)', 'player/station/france-bleu-paysdesavoie', 'lecteur_commun_json/timeline-11239'),
+ 'fbperigord': (u'France Bleu Périgord (Périgueux)', 'player/station/france-bleu-perigord', 'lecteur_commun_json/timeline-13137'),
+ 'fbpicardie': (u'France Bleu Picardie (Amiens)', 'player/station/france-bleu-picardie', 'lecteur_commun_json/timeline-13139'),
+ 'fbpoitou': (u'France Bleu Poitou (Poitiers)', 'player/station/france-bleu-poitou', 'lecteur_commun_json/timeline-13141'),
+ 'fbprovence': (u'France Bleu Provence (Aix-en-Provence)', 'player/station/france-bleu-provence', 'lecteur_commun_json/timeline-11241'),
+ 'fbrcfm': (u'France Bleu RCFM', 'player/station/france-bleu-rcfm', 'lecteur_commun_json/timeline-13143'),
+ 'fbsaintetienneloire': (u'France Bleu Saint-Etienne Loire', 'player/station/france-bleu-saint-etienne-loire', 'lecteur_commun_json/timeline-60434'),
+ 'fbroussillon': (u'France Bleu Roussillon', 'player/station/france-bleu-roussillon', 'lecteur_commun_json/timeline-11243'),
+ 'fbsudlorraine': (u'France Bleu Sud Lorraine (Nancy)', 'player/station/france-bleu-sudlorraine', 'lecteur_commun_json/timeline-13145'),
+ 'fbtoulouse': (u'France Bleu Toulouse', 'player/station/france-bleu-toulouse', 'lecteur_commun_json/timeline-13147'),
+ 'fbtouraine': (u'France Bleu Touraine (Tours)', 'player/station/france-bleu-touraine', 'lecteur_commun_json/timeline-13149'),
+ 'fbvaucluse': (u'France Bleu Vaucluse (Avignon)', 'player/station/france-bleu-vaucluse', 'lecteur_commun_json/timeline-13151'),
}
- _PLAYERJS_RADIOS = ('franceinter',
- 'franceculture',
- 'franceinfo',
- 'lemouv',
- )
-
- _DIRECTJSON_RADIOS = ('lemouv', )
- _LARGEDIRECTJSON_RADIOS = ('fip', )
- _RSS_RADIOS = ('francemusique', )
-
def iter_resources(self, objs, split_path):
if Radio in objs:
if split_path == [u'francebleu']:
- for _id in sorted(self._RADIOS.iterkeys()):
+ for _id, item in sorted(self._RADIOS.iteritems()):
if _id.startswith('fb'):
- yield self.get_radio(_id)
+ yield Collection([_id], iter(item).next())
elif len(split_path) == 0:
- for _id in sorted(self._RADIOS.iterkeys()):
+ for _id, item in sorted(self._RADIOS.iteritems()):
if not _id.startswith('fb'):
- yield self.get_radio(_id)
+ yield Collection([_id], iter(item).next())
yield Collection([u'francebleu'], u'France Bleu')
else:
raise CollectionNotFound(split_path)
- def iter_radios_search(self, pattern):
- for radio in self.iter_resources_flat((Radio, ), []):
- if pattern.lower() in radio.title.lower() or pattern.lower() in radio.description.lower():
- yield radio
-
def get_radio(self, radio):
+
+ def create_stream(url, hd=True):
+ stream = BaseAudioStream(0)
+ if hd:
+ stream.bitrate = 128
+ else:
+ stream.bitrate = 32
+ url = url.replace('midfi128', 'lofi32')
+
+ stream.format = u'mp3'
+ stream.title = u'%s kbits/s' % (stream.bitrate)
+ stream.url = url
+ return stream
+
if not isinstance(radio, Radio):
radio = Radio(radio)
if radio.id not in self._RADIOS:
return None
- title, hd = self._RADIOS[radio.id]
+ title, player_url, json_url = self._RADIOS[radio.id]
radio.title = title
radio.description = title
+ radio_name = radio.id if not radio.id.startswith('fb') else 'francebleu'
+ url = self.browser.get_radio_url(radio_name, player_url)
- if hd:
- url = self._MP3_HD_URL % (radio.id, radio.id)
- else:
- url = self._MP3_URL % (radio.id, radio.id)
-
- # This should be asked demand, but is required for now as Radioob
- # does not require it.
self.fillobj(radio, ('current', ))
-
- stream = BaseAudioStream(0)
- if hd:
- stream.bitrate = 128
- else:
- stream.bitrate = 32
- stream.format = u'mp3'
- stream.title = u'%s kbits/s' % (stream.bitrate)
- stream.url = url
- radio.streams = [stream]
+ radio.streams = [create_stream(url), create_stream(url, False)]
return radio
def fill_radio(self, radio, fields):
if 'current' in fields:
- artist = title = None
- if radio.id in self._PLAYERJS_RADIOS:
- artist, title = self.browser.get_current_playerjs(radio.id)
- if title.endswith(u'par %s' % artist):
- artist = None
- if radio.id in self._DIRECTJSON_RADIOS:
- dartist, dtitle = self.browser.get_current_direct(radio.id)
- if dartist:
- artist = dartist
- if dtitle:
- if title:
- title = u"%s [%s]" % (dtitle, title)
- else:
- title = dtitle
- elif radio.id in self._LARGEDIRECTJSON_RADIOS:
- dartist, dtitle = self.browser.get_current_direct_large(radio.id)
- if dartist:
- artist = dartist
- if dtitle:
- title = dtitle
- if radio.id in self._RSS_RADIOS:
- title = self.browser.get_current_rss(radio.id)
- if title:
- if not radio.current or radio.current is NotLoaded:
- radio.current = StreamInfo(0)
- radio.current.what = title
- radio.current.who = artist
+ title, player_url, json_url = self._RADIOS[radio.id]
+ radio_name = radio.id if not radio.id.startswith('fb') else 'francebleu'
+ artist, title = self.browser.get_current(radio_name, json_url)
+ if not radio.current or radio.current is NotLoaded:
+ radio.current = StreamInfo(0)
+ radio.current.what = title
+ radio.current.who = artist
return radio
- # TODO
- # http://www.franceculture.fr/recherche/key%3DYOURSEARCH%2526type%3Demission
- # http://www.franceinter.fr/recherche/key%3DYOURSEARCH%2526tri%3Dpertinence%2526theme%3Ddefault%2526type%3Demission
- #def search_videos(self, *args, **kwargs):
- # return []
-
- def get_video(self, _id):
- with self.browser:
- video = self.browser.get_video(_id)
- return video
-
- def fill_video(self, video, fields):
- if 'url' in fields:
- with self.browser:
- video.url = unicode(self.browser.get_url(video.id))
-
- return video
-
- OBJECTS = {Radio: fill_radio,
- RadioFranceVideo: fill_video}
+ OBJECTS = {Radio: fill_radio}
diff --git a/modules/radiofrance/pages.py b/modules/radiofrance/pages.py
new file mode 100644
index 00000000..de02d79e
--- /dev/null
+++ b/modules/radiofrance/pages.py
@@ -0,0 +1,62 @@
+# -*- coding: utf-8 -*-
+
+# Copyright(C) 2013 Bezleputh
+#
+# This file is part of weboob.
+#
+# weboob is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# weboob 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 Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with weboob. If not, see .
+
+from weboob.browser.pages import HTMLPage, JsonPage
+from weboob.browser.filters.standard import CleanText
+import time
+
+
+class PlayerPage(HTMLPage):
+ def get_url(self):
+ return CleanText('//a[@id="player"][1]/@href')(self.doc)
+
+
+class TimelinePage(JsonPage):
+ def get_current(self):
+ if 'current' in self.doc:
+ emission_title = self.doc['current']['emission']['titre']
+ song_title = self.doc['current']['song']['titre']
+ title = '%s: %s' % (emission_title, song_title)
+ person = self.doc['current']['song']['interpreteMorceau']
+ return person, title
+ elif 'diffusions' in self.doc:
+ now = int(time.time())
+ for item in self.doc['diffusions']:
+ if item['debut'] < now and item['fin'] > now:
+ title = u'%s: %s' % (item['title_emission'], item['title_diff'])
+ person = u''
+ return person, title
+ return u'', u''
+ else:
+ now = int(time.time())
+ for item in self.doc:
+ if item['debut'] < now and item['fin'] > now:
+ emission = ''
+ if 'diffusions' in item and item['diffusions']:
+ emission = item['diffusions'][0]['title']
+
+ title = item['title_emission']
+ if emission:
+ title = u'%s: %s' % (title, emission)
+
+ person = u''
+ if 'personnes' in item:
+ person = u','.join(item['personnes'])
+ return person, title
+ return u'', u''
diff --git a/modules/radiofrance/test.py b/modules/radiofrance/test.py
index 8cfdfa59..3c2e1cf9 100644
--- a/modules/radiofrance/test.py
+++ b/modules/radiofrance/test.py
@@ -29,35 +29,18 @@ class RadioFranceTest(BackendTest):
def test_get_radios(self):
l = list(self.backend.iter_resources(objs=[Radio], split_path=[]))
self.assertTrue(0 < len(l) < 30)
+ for radio in l:
+ name = radio.split_path[-1]
+ if name != 'francebleu':
+ streams = self.backend.get_radio(name).streams
+ self.assertTrue(len(streams) > 0)
+
l = list(self.backend.iter_resources(objs=[Radio], split_path=['francebleu']))
self.assertTrue(len(l) > 30)
+
+ for radio in l:
+ streams = self.backend.get_radio(radio.split_path[-1]).streams
+ self.assertTrue(len(streams) > 0)
+
l = list(self.backend.iter_resources(objs=[BaseVideo], split_path=[]))
self.assertEquals(len(l), 0)
-
- def test_get_video(self):
- # this should be available up to 24/10/2014 15h00
- urls = ('http://www.franceinter.fr/emission-vivre-avec-les-betes-y-arthus-bertrand-felins-g-tsai-s-envoler-conte-boreal-reha-hutin-30-m',
- 'http://www.franceinter.fr/player/reecouter?play=263735',
- 'franceinter-263735')
- for url in urls:
- vid = self.backend.get_video(url)
- assert vid.id == urls[-1]
- self.backend.fillobj(vid, ['url'])
- assert vid.url.lower().endswith('.mp3')
-
- # france culture (no expiration known)
- vid = self.backend.get_video('http://www.franceculture.fr/emission-la-dispute-expositions-paul-strand-youssef-nabil-et-dorothee-smith-2012-02-01')
- assert vid.id
- self.backend.fillobj(vid, ['url'])
- assert vid.url.lower().endswith('.mp3')
-
- # fip (no expiration known)
- # getting the proper ID is hard, hence the tests with many urls for the same content
- urls = ('http://www.fipradio.fr/diffusion-club-jazzafip-du-13-mars',
- 'http://www.fipradio.fr/player/reecouter?play=20686',
- 'fip-20686')
- for url in urls:
- vid = self.backend.get_video(url)
- assert vid.id == urls[-1]
- self.backend.fillobj(vid, ['url'])
- assert vid.url.lower().endswith('.mp3')