diff --git a/weboob/applications/booblyrics/__init__.py b/weboob/applications/booblyrics/__init__.py new file mode 100644 index 00000000..e53eed79 --- /dev/null +++ b/weboob/applications/booblyrics/__init__.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- + +# Copyright(C) 2013 Julien Veyssier +# +# 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 .booblyrics import Booblyrics + +__all__ = ['Booblyrics'] diff --git a/weboob/applications/booblyrics/booblyrics.py b/weboob/applications/booblyrics/booblyrics.py new file mode 100644 index 00000000..b90d4f1f --- /dev/null +++ b/weboob/applications/booblyrics/booblyrics.py @@ -0,0 +1,108 @@ +# -*- coding: utf-8 -*- + +# Copyright(C) 2013 Julien Veyssier +# +# 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 __future__ import with_statement + +import sys + +from weboob.capabilities.lyrics import ICapLyrics +from weboob.tools.application.repl import ReplApplication +from weboob.capabilities.base import NotAvailable,NotLoaded +from weboob.tools.application.formatters.iformatter import IFormatter, PrettyFormatter +from weboob.core import CallErrors + + +__all__ = ['Booblyrics'] + + +class LyricsInfoFormatter(IFormatter): + MANDATORY_FIELDS = ('id', 'title', 'artist', 'content') + + def format_obj(self, obj, alias): + result = u'%s%s%s\n' % (self.BOLD, obj.title, self.NC) + result += 'ID: %s\n' % obj.fullid + result += 'Title: %s\n' % obj.title + result += 'Artist: %s\n' % obj.artist + result += '\n%sContent%s\n' % (self.BOLD, self.NC) + result += obj.content + return result + + +class LyricsListFormatter(PrettyFormatter): + MANDATORY_FIELDS = ('id', 'title', 'artist') + + def get_title(self, obj): + return obj.title + + def get_description(self, obj): + artist = u'' + if obj.artist != NotAvailable and obj.artist != NotLoaded: + artist = obj.artist + return '%s' % artist + + +class Booblyrics(ReplApplication): + APPNAME = 'booblyrics' + VERSION = '0.f' + COPYRIGHT = 'Copyright(C) 2013 Julien Veyssier' + DESCRIPTION = "Console application allowing to search for song lyrics on various websites." + SHORT_DESCRIPTION = "search and display song lyrics" + CAPS = ICapTorrent + EXTRA_FORMATTERS = {'lyrics_list': LyricsListFormatter, + 'lyrics_info': LyricsInfoFormatter, + } + COMMANDS_FORMATTERS = {'search': 'lyrics_list', + 'info': 'lyrics_info', + } + + def complete_info(self, text, line, *ignored): + args = line.split(' ') + if len(args) == 2: + return self._complete_object() + + def do_info(self, id): + """ + info ID + + Get information about song lyrics. + """ + + songlyrics = self.get_object(id, 'get_lyrics') + if not lyrics: + print >>sys.stderr, 'Song lyrics not found: %s' % id + return 3 + + self.start_format() + self.format(torrent) + self.flush() + + def do_search(self, pattern): + """ + search [PATTERN] + + Search lyrics. + """ + self.change_path([u'search']) + if not pattern: + pattern = None + + self.start_format(pattern=pattern) + for backend, songlyrics in self.do('iter_lyrics', pattern=pattern): + self.cached_format(songlyrics) + self.flush() diff --git a/weboob/capabilities/lyrics.py b/weboob/capabilities/lyrics.py new file mode 100644 index 00000000..505171a2 --- /dev/null +++ b/weboob/capabilities/lyrics.py @@ -0,0 +1,63 @@ +# -*- coding: utf-8 -*- + +# Copyright(C) 2013 +# +# 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 .base import IBaseCap, CapBaseObject, Field, StringField, FloatField, \ + DateField, IntField, UserError + + +__all__ = ['SongLyrics', 'ICapLyrics'] + + +class SongLyrics(CapBaseObject): + """ + Song lyrics object. + """ + title = StringField('Title of the song') + artist = StringField('Artist of the song') + content = StringField('Lyrics of the song') + + def __init__(self, id, title): + CapBaseObject.__init__(self, id) + self.title = title + + +class ICapLyrics(IBaseCap): + """ + Lyrics websites. + """ + def iter_lyrics(self, pattern): + """ + Search lyrics and iterate on results. + + :param pattern: pattern to search + :type pattern: str + :rtype: iter[:class:`SongLyrics`] + """ + raise NotImplementedError() + + def get_lyrics(self, _id): + """ + Get a lyrics object from an ID. + + :param _id: ID of lyrics + :type _id: str + :rtype: :class:`SongLyrics` + """ + raise NotImplementedError()