diff --git a/modules/nectarine/__init__.py b/modules/nectarine/__init__.py new file mode 100644 index 00000000..bfdb52b5 --- /dev/null +++ b/modules/nectarine/__init__.py @@ -0,0 +1,3 @@ +from .backend import NectarineBackend + +__all__ = ['NectarineBackend'] diff --git a/modules/nectarine/backend.py b/modules/nectarine/backend.py new file mode 100644 index 00000000..9261be72 --- /dev/null +++ b/modules/nectarine/backend.py @@ -0,0 +1,58 @@ +# -*- coding: utf-8 -*- +# Copyright(C) 2013 Thomas Lecavelier +# +# 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.capabilities.radio import ICapRadio, Radio +from weboob.capabilities.collection import ICapCollection +from weboob.tools.backend import BaseBackend +from .browser import NectarineBrowser + +__all__ = ['NectarineBackend'] + +class NectarineBackend(BaseBackend, ICapRadio, ICapCollection): + NAME = 'nectarine' + MAINTAINER = u'Thomas Lecavelier' + EMAIL = 'thomas-weboob@lecavelier.name' + VERSION = '0.h' + DESCRIPTION = u'Nectarine Demoscene Radio' + # License of your module + LICENSE = 'AGPLv3+' + + BROWSER = NectarineBrowser + + def iter_resources(self, objs, split_path): + if Radio in objs: + self._restrict_level(split_path) + for radio in self.browser.iter_radios_list(): + self.browser.get_current_emission() + radio.current = self.browser.get_current_emission() + yield radio + + def iter_radios_search(self, pattern): + for radio in self.browser.iter_radios_list(): + if pattern.lower() in radio.title.lower() or pattern.lower() in radio.description.lower(): + self.browser.get_current_emission() + radio.current = self.browser.get_current_emission() + + yield radio + + def get_radio(self, radio): + if not isinstance(radio, Radio): + for rad in self.browser.iter_radios_list(): + if rad.id == radio: + return rad + return None diff --git a/modules/nectarine/browser.py b/modules/nectarine/browser.py new file mode 100644 index 00000000..70cbec4f --- /dev/null +++ b/modules/nectarine/browser.py @@ -0,0 +1,49 @@ +# * -*- coding: utf-8 -*- + +# Copyright(C) 2013 Thomas Lecavelier +# +# 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.tools.browser import BaseBrowser +from .pages import LivePage, StreamsPage + +__all__ = ['NectarineBrowser'] + +class NectarineBrowser(BaseBrowser): + DOMAIN = 'www.scenemusic.net' + PROTOCOL = 'https' + ENCODING = 'utf-8' + USER_AGENT = BaseBrowser.USER_AGENTS['desktop_firefox'] + PAGES = { + 'https://www\.scenemusic\.net/demovibes/xml/streams/': StreamsPage, + 'https://www\.scenemusic\.net/demovibes/xml/queue/': LivePage + } + + def home(self): + self.location('/demovibes/xml/streams/') + + assert self.is_on_page(StreamsPage) + + def iter_radios_list(self): + self.location('/demovibes/xml/streams/') + + assert self.is_on_page(StreamsPage) + return self.page.iter_radios_list() + + def get_current_emission(self): + self.location('/demovibes/xml/queue/') + assert self.is_on_page(LivePage) + return self.page.get_current_emission() diff --git a/modules/nectarine/favicon.png b/modules/nectarine/favicon.png new file mode 100644 index 00000000..870086b5 Binary files /dev/null and b/modules/nectarine/favicon.png differ diff --git a/modules/nectarine/pages.py b/modules/nectarine/pages.py new file mode 100644 index 00000000..43f0c0d3 --- /dev/null +++ b/modules/nectarine/pages.py @@ -0,0 +1,54 @@ +# * -*- coding: utf-8 -*- + +# Copyright(C) 2013 Thomas Lecavelier +# +# 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.tools.browser import BasePage +from weboob.capabilities.radio import Radio, Stream, Emission + +__all__ = ['LivePage', 'StreamsPage'] + +class StreamsPage(BasePage): + def iter_radios_list(self): + radio = Radio('necta') + radio.title = u'Nectarine' + radio.description = u'Nectarine Demoscene Radio' + radio.streams = [] + + index = -1 + + for el in self.document.xpath('//stream'): + index += 1 + stream_url = unicode(el.findtext('url')) + bitrate = unicode(el.findtext('bitrate')) + encode = unicode(el.findtext('type')) + country = unicode(el.findtext('country')).upper() + stream = Stream(index) + stream.title = ' '.join([radio.title, country, encode, bitrate, 'kbps']) + stream.url = stream_url + radio.streams.append(stream) + + yield radio + + + +class LivePage(BasePage): + def get_current_emission(self): + current = Emission(0) + current.artist = unicode(self.document.xpath('//playlist/now/entry/artist')[0].text) + current.title = unicode(self.document.xpath('//playlist/now/entry/song')[0].text) + return current diff --git a/modules/nectarine/test.py b/modules/nectarine/test.py new file mode 100644 index 00000000..d095e9f4 --- /dev/null +++ b/modules/nectarine/test.py @@ -0,0 +1,29 @@ +# -*- coding: utf-8 -*- + +# Copyright(C) 2013 Thomas Lecavelier +# +# 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.tools.test import BackendTest + + +class NectarineTest(BackendTest): + BACKEND = 'nectarine' + + def test_nectarine(self): + l = list(self.backend.iter_radios_search('')) + self.assertTrue(len(l) > 0)