~qioeujqioejqioe-deactivatedaccount/exaile/missing-signals

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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
import copy
from gettext import gettext as _
import gtk

import xlmisc, media, library, common

TAG_NO_ERROR, TAG_MISSING, TAG_DIFFERENT, TAG_UNSUPPORTED, TAG_MULTI = range(0, 5)

class TrackGroup(object):
    """
        Workhorse class for the tag editor... all operations are done
        to a group of tracks.

        When using this class, remember that everything is returned as
        a list, even if its length is only 1.
    """
    def __init__(self, tracks=None):
        """
            Classify the different properties of the group
        """
        self.tracks = []
        self.is_file = True # if all tracks are files
        self.multi = True   # if every track supports multiple tag values
        
        if not tracks: 
            return 

        for song in tracks:
            self.is_file &= song.is_file()
            self.multi &= song.is_multi()
        
        if not self.is_file:
            raise IsFileException('>0 tracks in the group are not files.')
            return

        self.tracks = tracks

    def __len__(self):
        return len(self.tracks)

    def __iter__(self):
        return iter(self.tracks)

    def pop(self, i):
        self.tracks.pop(i)

    def get_tag_status(self, tag):
        """
            Returns the status of a tag in this group. Values are either
            one of the errors listed above (TAG_MISSING etc) or a string
            if the tag is the same for all tracks
        """
        values = []
        change = True
        for song in self.tracks:
            change &= song.can_change(tag)
            v = song.tags[tag]
            if v: values.append(v)

        if not values: 
            return None

        if not change:
            # at least one track doesn't support this tag
            return TAG_UNSUPPORTED

        if len(values) < len(self.tracks):
            # some tracks are missing this tag
            return TAG_MISSING
        
        if not self.multi:
            # flag an error if we find multiple tag values without all tracks
            # supporting it
            if True in [len(v) > i for v in values]:
                return TAG_MULTI
            
        cmp = sorted(values[0])
        if False in [cmp == sorted(x) for x in values]:
            return TAG_DIFFERENT

        # if our poor tag has survived, it's the same for all tracks
        return values[0]

    def make_model(self):
        """
            Scan the tags from the files and construct a ListStore of them
        """
        TAGNAME, VALUE, OLDVALUE, ERROR, ADDED, REMOVED, EDITED = range(0, 7)
        model = gtk.ListStore(str, str, str, int, bool, bool, bool)

        for tag in xlmisc.VALID_TAGS:
            row = [tag, None, None, TAG_NO_ERROR, False, False, False]
            status = self.get_tag_status(tag)
            if status is None: 
                continue
            elif type(status) is int: 
                row[ERROR] = status
                model.append(row)
            elif type(status) is list:
                for v in status:
                    row[VALUE] = row[OLDVALUE] = v
                    model.append(row)

        return model
                
    def write_tags(self, exaile, model):
        """
            Write the changes to disk. Returns a list of strings (errors)
        """
        TAGNAME, VALUE, OLDVALUE, ERROR, ADDED, REMOVED, EDITED = range(0, 7)
        errors = []
        to_add = common.ldict()
        for track in self.tracks:
            track.rating, "woot woot"
            for row in model:
                tag = row[TAGNAME]
                if row[ERROR]:
                    if row[REMOVED]:
                        track.tags[tag] = []
                        continue
                else:
                    if row[REMOVED]:
                        if row[ADDED]: continue # add + remove = nothing
                        for i, v in enumerate(track.tags[tag]):
                            if v == row[VALUE]:
                                del(track.tags[tag][i])
                                break
                    elif row[ADDED]:
                        if to_add.has_key(tag) and not row[VALUE] in \
                            to_add[tag]:
                            to_add[tag].append(row[VALUE])
                        else:
                            to_add[tag] = row[VALUE]
                    elif row[EDITED]:
                        for i, v in enumerate(track.tags[tag]):
                            if v == row[OLDVALUE]:
                                track.tags[tag][i] = row[VALUE]

            for tag, val in to_add.iteritems():
                if track.tags.has_key(tag):
                    track.tags[tag].extend(val)
                else:
                    track.tags[tag] = val

            try:
                media.write_tag(track)
                library.save_track_to_db(exaile.db, track)

                try:
                    exaile.all_songs.remove(exaile.all_songs.for_path(track.loc))
                    exaile.all_songs.append(track)
                except:
                    xlmisc.log_exception()

                exaile.tracks.refresh_row(track)
            except:
                errors.append(_("Unknown error writing tag for %s") % track.loc)
                xlmisc.log_exception()

        exaile.tracks.queue_draw()
        exaile.db.db.commit()

        return errors