File: exaile_parser.py

package info (click to toggle)
exaile 4.2.1%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 16,452 kB
  • sloc: python: 39,785; javascript: 9,262; makefile: 268; sh: 138
file content (117 lines) | stat: -rw-r--r-- 4,443 bytes parent folder | download | duplicates (2)
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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# Copyright (C) 2008 Erik Hetzner
#              2010 Brian Parma

# This file is part of Spydaap. Spydaap 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.

# Spydaap 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 Spydaap. If not, see <https://www.gnu.org/licenses/>.

import spydaap.parser
from spydaap.daap import do
import logging

logger = logging.getLogger(__name__)


class ExaileParser(spydaap.parser.Parser):
    _string_map = {
        'title': 'dmap.itemname',
        'artist': 'daap.songartist',
        'composer': 'daap.songcomposer',
        'genre': 'daap.songgenre',
        'album': 'daap.songalbum',
    }

    _int_map = {
        'bpm': 'daap.songbeatsperminute',
        # not used by exaile client, and not parsed right anyway (ie: '2010-01-01')
        #        'date': 'daap.songyear', #TODO
        'year': 'daap.songyear',
        'tracknumber': 'daap.songtracknumber',
        'tracktotal': 'daap.songtrackcount',
        'discnumber': 'daap.songdiscnumber',
    }

    def understands(self, filename):
        return True

    #   return self.file_re.match(filename)

    # returns a list in exaile
    def handle_int_tags(self, map, md, daap):
        for k in md.list_tags():
            if k in map:
                try:
                    tn = str(md.get_tag_raw(k)[0])
                    if '/' in tn:
                        num, tot = tn.split('/')
                        if num == '':  # empty tags
                            num = 0
                        daap.append(do(map[k], int(num)))
                        # set total?
                    else:
                        daap.append(do(map[k], int(tn)))
                except Exception:
                    logger.exception(
                        'exception caught parsing tag: %s=%s from %s', k, tn, md
                    )

    # We can't use functions in __init__ because exaile tracks no longer
    # give us access to .tags
    def handle_string_tags(self, map, md, daap):
        for k in md.list_tags():
            if k in map:
                try:
                    tag = [t.encode("utf-8", "replace") for t in md.get_tag_raw(k)]
                    tag = [t for t in tag if t != ""]
                    daap.append(do(map[k], b"/".join(tag)))
                except Exception:
                    logger.exception("error decoding tags")

    def parse(self, trk):
        try:
            # trk = mutagen.File(filename)
            d = []
            if len(trk.list_tags()) > 0:
                if 'title' in trk.list_tags():
                    name = trk.get_tag_raw('title')[0].encode("utf-8", "replace")
                else:
                    name = str(trk)

                self.handle_string_tags(self._string_map, trk, d)
                self.handle_int_tags(self._int_map, trk, d)
            #                self.handle_rating(trk, d)
            else:
                name = str(trk)
            # statinfo = os.stat(filename)

            _len = trk.get_tag_raw('__length')
            if _len is None:  # don't parse songs that don't have length
                return (None, None)

            d.extend(
                [  # do('daap.songsize', trk.get_size()),
                    # do('daap.songdateadded', statinfo.st_ctime),
                    # do('daap.songdatemodified', statinfo.st_ctime),
                    do('daap.songtime', _len * 1000),
                    #                      do('daap.songbitrate', trk.get_tag_raw('__bitrate') / 1000),
                    #                      do('daap.songsamplerate', ogg.info.sample_rate), # todo ??
                    do(
                        'daap.songformat', trk.get_local_path().split('.')[-1]
                    ),  # todo ??
                    do('daap.songdescription', 'Exaile Streaming Audio'),
                ]
            )
            return (d, name)

        except Exception:
            logger.exception('caught exception while processing %s', trk)
            return (None, None)