1# -*- coding: utf-8 -*-
2
3# Copyright(C) 2013 Pierre Mazière
4#
5# This file is part of weboob.
6#
7# weboob is free software: you can redistribute it and/or modify
8# it under the terms of the GNU Lesser General Public License as published by
9# the Free Software Foundation, either version 3 of the License, or
10# (at your option) any later version.
11#
12# weboob is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU Lesser General Public License for more details.
16#
17# You should have received a copy of the GNU Lesser General Public License
18# along with weboob. If not, see <http://www.gnu.org/licenses/>.
19
20import re
21
22from weboob.tools.compat import unicode
23
24from .image import Thumbnail
25from .base import Field, StringField, IntField, BaseObject
26from .date import DeltaField
27from .file import CapFile, BaseFile
28
29
30__all__ = ['BaseAudio', 'CapAudio']
31
32
33def decode_id(decode_id):
34    def wrapper(func):
35        def inner(self, *args, **kwargs):
36            arg = unicode(args[0])
37            _id = decode_id(arg)
38            if _id is None:
39                return None
40
41            new_args = [_id]
42            new_args.extend(args[1:])
43            return func(self, *new_args, **kwargs)
44        return inner
45    return wrapper
46
47
48class Album(BaseObject):
49    """
50    Represent an album
51    """
52    title = StringField('album name')
53    author = StringField('artist name')
54    year = IntField('release year')
55    thumbnail = Field('Image associated to the album', Thumbnail)
56    tracks_list = Field('list of tracks', list)
57
58    @classmethod
59    def decode_id(cls, _id):
60        if _id:
61            m = re.match('^(album)\.(.*)', _id)
62            if m:
63                return m.group(2)
64            return _id
65
66
67class Playlist(BaseObject):
68    """
69    Represent a playlist
70    """
71    title = StringField('playlist name')
72    tracks_list = Field('list of tracks', list)
73
74    @classmethod
75    def decode_id(cls, _id):
76        if _id:
77            m = re.match('^(playlist)\.(.*)', _id)
78            if m:
79                return m.group(2)
80            return _id
81
82
83class BaseAudio(BaseFile):
84    """
85    Represent an audio file
86    """
87    duration =  DeltaField('file duration')
88    bitrate =   IntField('file bit rate in Kbps')
89    format =    StringField('file format')
90    thumbnail = Field('Image associated to the file', Thumbnail)
91
92    @classmethod
93    def decode_id(cls, _id):
94        if _id:
95            m = re.match('^(audio)\.(.*)', _id)
96            if m:
97                return m.group(2)
98            return _id
99
100
101class CapAudio(CapFile):
102    """
103    Audio file provider
104    """
105
106    @classmethod
107    def get_object_method(cls, _id):
108        m = re.match('^(\w+)\.(.*)', _id)
109        if m:
110            if m.group(1) == 'album':
111                return 'get_album'
112
113            elif m.group(1) == 'playlist':
114                return 'get_playlist'
115
116            else:
117                return 'get_audio'
118
119    def search_audio(self, pattern, sortby=CapFile.SEARCH_RELEVANCE):
120        """
121        search for a audio file
122
123        :param pattern: pattern to search on
124        :type pattern: str
125        :param sortby: sort by ...(use SEARCH_* constants)
126        :rtype: iter[:class:`BaseAudio`]
127        """
128        return self.search_file(pattern, sortby)
129
130    def search_album(self, pattern, sortby=CapFile.SEARCH_RELEVANCE):
131        """
132        search for an album
133        :param pattern: pattern to search on
134        :type pattern: str
135        :rtype: iter[:class:`Album`]
136        """
137        raise NotImplementedError()
138
139    def search_playlist(self, pattern, sortby=CapFile.SEARCH_RELEVANCE):
140        """
141        search for an album
142        :param pattern: pattern to search on
143        :type pattern: str
144        :rtype: iter[:class:`Playlist`]
145        """
146        raise NotImplementedError()
147
148    @decode_id(BaseAudio.decode_id)
149    def get_audio(self, _id):
150        """
151        Get an audio file from an ID.
152
153        :param id: audio file ID
154        :type id: str
155        :rtype: :class:`BaseAudio`]
156        """
157        return self.get_file(_id)
158
159    @decode_id(Playlist.decode_id)
160    def get_playlist(self, _id):
161        """
162        Get a playlist from an ID.
163
164        :param id: playlist ID
165        :type id: str
166        :rtype: :class:`Playlist`]
167        """
168        raise NotImplementedError()
169
170    @decode_id(Album.decode_id)
171    def get_album(self, _id):
172        """
173        Get an album from an ID.
174
175        :param id: album ID
176        :type id: str
177        :rtype: :class:`Album`]
178        """
179        raise NotImplementedError()
180