Use mobile.nolife-tv.com instead of online.nolife-tv.com. Add theme/type entries. These changes are inspired by XBMC NolifeTV plugin from Julien Gormotte: julien@gormotte.info videoob> ls ~ (theme) Par theme (nolifetv) ~ (type) Par type (nolifetv) ~ (latest) Latest NolifeTV videos (nolifetv) videoob> cd theme videoob:/theme> ls ~ (Actualités) Actualités (nolifetv) ~ (Fictions) Fictions (nolifetv) ~ (Musique) Musique (nolifetv) ~ (Nolife) Nolife (nolifetv) ~ (Culture & Style) Culture & Style (nolifetv) ~ (Jeu vidéo) Jeu vidéo (nolifetv) ~ (Sélection pour découvrir Nolife) Sélection pour découvrir Nolife (nolifetv) ~ (Japon) Japon (nolifetv) videoob:/theme> cd Japon videoob:/theme/Japon> ls ~ (77) Japan in Motion (nolifetv) ~ (68) J-Top (Speed run) (nolifetv) ~ (84) Nochan (nolifetv) ~ (49) OTO (nolifetv) ~ (100) toco toco (nolifetv) ~ (112) Nihongo ga dekimasu ka (nolifetv) ~ (57) Tôkyô Café (nolifetv) videoob:/theme/Japon> cd 57 Hint: There are more results available for nolifetv (use option -n or count command) 1 — Tôkyô Café - 239 - La statue Gundam à Odaiba (nolifetv) 2 — Tôkyô Café - 238 - UNCHAIN (nolifetv) 3 — Tôkyô Café - 237 - The End au Théâtre du Châtelet (nolifetv) 4 — Tôkyô Café - 236 - Scéance photo à Asobi Station dans le quartier de Harajuku avec YANO Anna (nolifetv) 5 — Tôkyô Café - 235 - Le TGS 2013 vu par Suzuka (nolifetv) 6 — Tôkyô Café - 234 - Street Live de Itowokashi à Tôkyô (chanson en intégralité) (nolifetv) 7 — Tôkyô Café - 234 - Street Live de Itowokashi à Tôkyô (nolifetv) 8 — Tôkyô Café - 233 - Tsume Fan Day (nolifetv) 9 — Tôkyô Café - 232 - Puzzle & Dragons (nolifetv) 10 — Tôkyô Café - 231 - Japan Expo 2013 (nolifetv) Signed-off-by: Clément Calmels <cboulte@gmail.com> Signed-off-by: Romain Bignon <romain@symlink.me>
136 lines
4.9 KiB
Python
136 lines
4.9 KiB
Python
# -*- coding: utf-8 -*-
|
|
|
|
# Copyright(C) 2011 Romain Bignon
|
|
#
|
|
# 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 <http://www.gnu.org/licenses/>.
|
|
|
|
|
|
from weboob.capabilities.collection import Collection
|
|
from weboob.capabilities.image import BaseImage
|
|
|
|
from weboob.tools.browser import BasePage
|
|
|
|
import re
|
|
from datetime import datetime, timedelta
|
|
|
|
from .video import NolifeTVVideo
|
|
|
|
__all__ = ['VideoPage', 'VideoListPage', 'FamilyPage', 'AboPage', 'LoginPage', 'HomePage']
|
|
|
|
class VideoPage(BasePage):
|
|
def get_video(self, video):
|
|
if not video:
|
|
video = NolifeTVVideo(self.group_dict['id'])
|
|
|
|
els = self.document.getroot().xpath('//div[@data-role="content"]')
|
|
if els and els[0] is not None:
|
|
h3 = els[0].find('h3')
|
|
if h3 is not None and h3.text:
|
|
video.title = unicode(h3.text)
|
|
|
|
h4 = els[0].find('h4')
|
|
if h4 is not None and h4.text:
|
|
video.title = video.title + u' - ' + h4.text
|
|
|
|
thumb = els[0].find('p/img')
|
|
if thumb is not None and thumb.get('src'):
|
|
video.thumbnail = BaseImage(thumb.attrib['src'])
|
|
video.thumbnail.url = video.thumbnail.id
|
|
|
|
ps = els[0].findall('p')
|
|
if len(ps) > 4:
|
|
if ps[4].text:
|
|
video.description = ps[4].text
|
|
if ps[0].text and ps[0].text != u'∞':
|
|
video.date = datetime.strptime(ps[0].text, '%d/%m/%Y').date()
|
|
|
|
for text in ps[2].xpath('.//text()'):
|
|
m = re.search(r'[^\d]*((\d+):)?(\d+)s?', text)
|
|
if m:
|
|
if m.group(2):
|
|
minutes = int(m.group(2))
|
|
else:
|
|
minutes = 0
|
|
video.duration = timedelta(minutes=minutes,
|
|
seconds=int(m.group(3)))
|
|
return video
|
|
|
|
class VideoListPage(BasePage):
|
|
def is_list_empty(self):
|
|
return self.document.getroot() == None
|
|
|
|
def iter_video(self, available_videos):
|
|
for el in self.document.getroot().xpath('//li/a'):
|
|
strongs = el.findall('p/strong')
|
|
if len(strongs) > 3 and strongs[0].text not in ['Autopromo', 'Annonce'] and strongs[1].text in available_videos:
|
|
m = re.search(r'emission-(\d+)', el.attrib['href'])
|
|
if m and m.group(1):
|
|
video = NolifeTVVideo(m.group(1))
|
|
h3 = el.find('h3')
|
|
if h3 is not None and h3.text:
|
|
video.title = unicode(h3.text)
|
|
if strongs[3].text:
|
|
video.title = video.title + ' - ' + strongs[3].text
|
|
yield video
|
|
|
|
class FamilyPage(BasePage):
|
|
def iter_category(self):
|
|
subs = list()
|
|
|
|
for el in self.document.xpath('//ul/li[@data-role="list-divider"]'):
|
|
if not el.text in subs:
|
|
yield Collection([el.text], unicode(el.text))
|
|
subs.append(el.text)
|
|
|
|
def iter_family(self, sub):
|
|
for el in self.document.xpath('//ul/li[@data-role="list-divider"]'):
|
|
if el.text != sub:
|
|
continue
|
|
|
|
while True:
|
|
el = el.getnext()
|
|
if el == None or el.get('data-role'):
|
|
break
|
|
h1 = el.find('.//h1')
|
|
id = h1.getparent().attrib['href']
|
|
m = re.search(r'famille-(\d+)', id)
|
|
if m and m.group(1):
|
|
yield Collection([m.group(1)], unicode(h1.text))
|
|
|
|
class AboPage(BasePage):
|
|
def get_available_videos(self):
|
|
available = ['[Gratuit]']
|
|
|
|
for text in self.document.xpath('//div[@data-role="content"]/center/text()'):
|
|
if 'Soutien' in text:
|
|
available.append('[Archive]')
|
|
available.append('[Standard]')
|
|
if 'Standard' in text:
|
|
available.append('[Standard]')
|
|
|
|
return available
|
|
|
|
|
|
class LoginPage(BasePage):
|
|
def login(self, username, password):
|
|
self.browser.select_form(name='login')
|
|
self.browser['username'] = str(username)
|
|
self.browser['password'] = str(password)
|
|
self.browser.submit()
|
|
|
|
class HomePage(BasePage):
|
|
def is_logged(self):
|
|
return len(self.document.xpath('//a[@href="deconnexion/"]')) == 1
|