summaryrefslogtreecommitdiff
path: root/nephilim/song.py
blob: 66b918f1847d489b26bf9bbb38e79ece8d4a619b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#
#    Copyright (C) 2009 Anton Khirnov <wyskas@gmail.com>
#
#    Nephilim is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    Nephilim 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 General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with Nephilim.  If not, see <http://www.gnu.org/licenses/>.
#

from PyQt5 import QtCore
import os
from   string import Template

from .common import sec2min

class Song(dict):
    """
    Song provides a dictionary-like wrapper around song metadata.
    Its instances are generated by MPClient, don't instantiate it
    directly.
    Access '?tag' to get always at least an empty string.
    """

    #### PUBLIC ####
    def __init__(self, data = {}):
        dict.__init__(self)
        for key in data:
            dict.__setitem__(self, key.lower(), data[key])
        if not 'file' in self:
            self['file'] = ''
    def __eq__(self, other):
        if not isinstance(other, Song):
            return NotImplemented
        return self['file'] == other['file']
    def __ne__(self, other):
        if not isinstance(other, Song):
            return NotImplemented
        return self['file'] != other['file']
    def __getitem__(self, key):
        key = key.lower()
        try:
            return dict.__getitem__(self, key)
        except KeyError:
            if key and key[0] == '?':
                key = key[1:]
                return self[key] if key in self else ''
            if key == 'tracknum':
                try:
                    return int(self['track'])
                except ValueError:
                    try:
                        return int(self['track'].split('/')[0])
                    except ValueError:
                        return 0
            elif key == 'length':
                return sec2min(int(self['time']))
            elif key == 'id':
                return '-1'
            elif key == 'title':
                return self['file']
            elif key == 'albumartist':
                return self['artist']
            elif key == 'songdir':
                return os.path.dirname(self['file'])

            raise KeyError
    def __contains__(self, item):
        if dict.__contains__(self, item.lower()):
            return True
        try:
            self[item]
            return True
        except KeyError:
            return False
    def __bool__(self):
        return bool(self['file'])

    def expand_tags(self, s):
        """Expands tags in form ${tag} in string s."""
        ret = Template(s)
        ret = ret.safe_substitute(self)
        return ret