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()