~ubuntu-branches/ubuntu/karmic/kid3/karmic

« back to all changes in this revision

Viewing changes to kid3/discogsdialog.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Ana Beatriz Guerrero Lopez
  • Date: 2009-01-15 19:15:40 UTC
  • mfrom: (1.2.2 upstream)
  • mto: This revision was merged to the branch mainline in revision 21.
  • Revision ID: james.westby@ubuntu.com-20090115191540-gkr2szzjqbponmsg
Tags: upstream-1.1
ImportĀ upstreamĀ versionĀ 1.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
35
35
        0,
36
36
        0,
37
37
        "import-discogs",
38
 
        &Kid3App::s_discogsCfg
 
38
        &Kid3App::s_discogsCfg,
 
39
        true
39
40
};
40
41
 
41
42
 
70
71
        // <li><a href="/release/761529"><span style="font-size: 11pt;"><em>Amon</em> <em>Amarth</em> - The <em>Avenger</em></span></a><br>
71
72
        QString str = QString::fromUtf8(searchStr);
72
73
        QRegExp idTitleRe("<a href=\"/release/([0-9]+)\">(.+)</a>");
73
 
        QStringList lines = QCM_split(QRegExp("[\\r\\n]+"), str);
 
74
        QStringList lines = QCM_split("<p/>", str.remove('\n').remove('\r'));
74
75
        m_albumListBox->clear();
75
76
        for (QStringList::const_iterator it = lines.begin(); it != lines.end(); ++it) {
76
77
                if (idTitleRe.QCM_indexIn(*it) != -1) {
87
88
}
88
89
 
89
90
/**
 
91
 * Remove trailing stars and numbers like (2) from a string.
 
92
 *
 
93
 * @param str string
 
94
 *
 
95
 * @return fixed up string.
 
96
 */
 
97
static QString fixUpArtist(QString str)
 
98
{
 
99
        str.replace(QRegExp(",(\\S)"), ", \\1");
 
100
        str.replace("* / ", " / ");
 
101
        str.replace("*,", ",");
 
102
        str.remove(QRegExp("\\*$"));
 
103
        str.remove(QRegExp("[*\\s]*\\(\\d+\\)\\(tracks:[^)]+\\)"));
 
104
        str.replace(QRegExp("[*\\s]*\\((?:\\d+|tracks:[^)]+)\\) / "), " / ");
 
105
        str.replace(QRegExp("[*\\s]*\\((?:\\d+|tracks:[^)]+)\\),"), ",");
 
106
        return str.remove(QRegExp("[*\\s]*\\((?:\\d+|tracks:[^)]+)\\)$"));
 
107
}
 
108
 
 
109
 
 
110
/**
 
111
 * Add involved people to a frame.
 
112
 * The format used is (should be converted according to tag specifications):
 
113
 * involvee 1 (involvement 1)\n
 
114
 * involvee 2 (involvement 2)\n
 
115
 * ...
 
116
 * involvee n (involvement n)
 
117
 *
 
118
 * @param frames      frame collection
 
119
 * @param type        type of frame
 
120
 * @param involvement involvement (e.g. instrument)
 
121
 * @param involvee    name of involvee (e.g. musician)
 
122
 */
 
123
static void addInvolvedPeople(
 
124
        FrameCollection& frames, Frame::Type type,
 
125
        const QString& involvement, const QString& involvee)
 
126
{
 
127
        QString value = frames.getValue(type);
 
128
        if (!value.isEmpty()) value += Frame::stringListSeparator();
 
129
        value += involvement;
 
130
        value += Frame::stringListSeparator();
 
131
        value += involvee;
 
132
        frames.setValue(type, value);
 
133
}
 
134
 
 
135
/**
 
136
 * Set tags from a string with credits lines.
 
137
 * The string must have lines like "Composed By - Iommi", separated by \\n.
 
138
 *
 
139
 * @param str    credits string
 
140
 * @param frames tags will be added to these frames
 
141
 *
 
142
 * @return true if credits found.
 
143
 */
 
144
static bool parseCredits(const QString& str, FrameCollection& frames)
 
145
{
 
146
        bool result = false;
 
147
        QStringList lines = QCM_split("\n", str);
 
148
        for (QStringList::const_iterator it = lines.begin();
 
149
                         it != lines.end();
 
150
                         ++it) {
 
151
                int nameStart = (*it).QCM_indexOf(" - ");
 
152
                if (nameStart != -1) {
 
153
                        QString name(fixUpArtist((*it).mid(nameStart + 3)));
 
154
                        QStringList credits = QCM_split(", ", (*it).left(nameStart));
 
155
                        for (QStringList::const_iterator cit = credits.begin();
 
156
                                         cit != credits.end();
 
157
                                         ++cit) {
 
158
                                static const struct {
 
159
                                        const char* credit;
 
160
                                        Frame::Type type;
 
161
                                } creditToType[] = {
 
162
                                        { "Composed By", Frame::FT_Composer },
 
163
                                        { "Conductor", Frame::FT_Conductor },
 
164
                                        { "Orchestra", Frame::FT_AlbumArtist },
 
165
                                        { "Lyrics By", Frame::FT_Lyricist },
 
166
                                        { "Written-By", Frame::FT_Author },
 
167
                                        { "Written By", Frame::FT_Author },
 
168
                                        { "Remix", Frame::FT_Remixer },
 
169
                                        { "Music By", Frame::FT_Composer },
 
170
                                        { "Songwriter", Frame::FT_Composer }
 
171
                                };
 
172
                                bool found = false;
 
173
                                for (unsigned i = 0;
 
174
                                                 i < sizeof(creditToType) / sizeof(creditToType[0]);
 
175
                                                 ++i) {
 
176
                                        if (*cit == creditToType[i].credit) {
 
177
                                                frames.setValue(creditToType[i].type, name);
 
178
                                                found = true;
 
179
                                                break;
 
180
                                        }
 
181
                                }
 
182
                                if (found) {
 
183
                                        result = true;
 
184
                                } else {
 
185
                                        static const struct {
 
186
                                                const char* credit;
 
187
                                                const char* arrangement;
 
188
                                        } creditToArrangement[] = {
 
189
                                                { "Arranged By", "Arranger" },
 
190
                                                { "Mixed By", "Mixer" },
 
191
                                                { "DJ Mix", "DJMixer" },
 
192
                                                { "Dj Mix", "DJMixer" },
 
193
                                                { "Engineer", "Engineer" },
 
194
                                                { "Mastered By", "Engineer" },
 
195
                                                { "Producer", "Producer" },
 
196
                                                { "Co-producer", "Producer" },
 
197
                                                { "Executive Producer", "Producer" }
 
198
                                        };
 
199
                                        for (unsigned i = 0;
 
200
                                                         i < sizeof(creditToArrangement) / sizeof(creditToArrangement[0]);
 
201
                                                         ++i) {
 
202
                                                if ((*cit).startsWith(creditToArrangement[i].credit)) {
 
203
                                                        addInvolvedPeople(frames, Frame::FT_Arranger,
 
204
                                                                                                                                creditToArrangement[i].arrangement, name);
 
205
                                                        found = true;
 
206
                                                        break;
 
207
                                                }
 
208
                                        }
 
209
                                }
 
210
                                if (found) {
 
211
                                        result = true;
 
212
                                } else {
 
213
                                        static const char* const instruments[] = {
 
214
                                                "Performer", "Vocals", "Voice", "Featuring", "Choir", "Chorus",
 
215
                                                "Baritone", "Tenor", "Rap", "Scratches", "Drums", "Percussion",
 
216
                                                "Keyboards", "Cello", "Piano", "Organ", "Synthesizer", "Keys",
 
217
                                                "Wurlitzer", "Rhodes", "Harmonica", "Xylophone", "Guitar", "Bass",
 
218
                                                "Strings", "Violin", "Viola", "Banjo", "Harp", "Mandolin",
 
219
                                                "Clarinet", "Horn", "Cornet", "Flute", "Oboe", "Saxophone",
 
220
                                                "Trumpet", "Tuba", "Trombone"
 
221
                                        };
 
222
                                        for (unsigned i = 0;
 
223
                                                         i < sizeof(instruments) / sizeof(instruments[0]);
 
224
                                                         ++i) {
 
225
                                                if ((*cit).contains(instruments[i])) {
 
226
                                                        addInvolvedPeople(frames, Frame::FT_Performer, *cit, name);
 
227
                                                        found = true;
 
228
                                                        break;
 
229
                                                }
 
230
                                        }
 
231
                                }
 
232
                                if (found) {
 
233
                                        result = true;
 
234
                                }
 
235
                        }
 
236
                }
 
237
        }
 
238
        return result;
 
239
}
 
240
 
 
241
/**
90
242
 * Parse result of album request and populate m_trackDataVector with results.
91
243
 *
92
244
 * @param albumStr album data received
96
248
        QRegExp nlSpaceRe("[\r\n]+\\s*");
97
249
        QRegExp htmlTagRe("<[^>]+>");
98
250
        QString str = QString::fromUtf8(albumStr);
99
 
        StandardTags stHdr;
100
 
        stHdr.setInactive();
 
251
        FrameCollection framesHdr;
101
252
        /*
102
253
         * artist and album can be found in the title:
103
254
<title>Amon Amarth - The Avenger</title>
113
264
                        start = 0;
114
265
                        end = titleStr.QCM_indexOf(" - ", start);
115
266
                        if (end > start) {
116
 
                                stHdr.artist = titleStr.mid(start, end - start);
 
267
                                framesHdr.setArtist(fixUpArtist(titleStr.mid(start, end - start)));
117
268
                                start = end + 3; // skip " - "
118
269
                        }
119
 
                        stHdr.album = titleStr.mid(start);
 
270
                        framesHdr.setAlbum(titleStr.mid(start));
120
271
                }
121
272
        }
122
273
        /*
133
284
                        yearStr.replace(htmlTagRe, ""); // strip HTML tags
134
285
                        QRegExp yearRe("(\\d{4})"); // this should skip day and month numbers
135
286
                        if (yearRe.QCM_indexIn(yearStr) >= 0) {
136
 
                                stHdr.year = yearRe.cap(1).toInt();
 
287
                                framesHdr.setYear(yearRe.cap(1).toInt());
137
288
                        }
138
289
                }
139
290
        }
180
331
                }
181
332
        }
182
333
        if (genreNum != 255) {
183
 
                stHdr.genre = Genres::getName(genreNum);
 
334
                framesHdr.setGenre(Genres::getName(genreNum));
184
335
        } else if (!genreList.empty()) {
185
 
                stHdr.genre = genreList.front();
 
336
                framesHdr.setGenre(genreList.front());
 
337
        }
 
338
 
 
339
        const bool additionalTags = getAdditionalTags();
 
340
        if (additionalTags) {
 
341
                /*
 
342
                 * publisher can be found in "Label:"
 
343
                 */
 
344
                start = str.QCM_indexOf("Label:");
 
345
                if (start >= 0) {
 
346
                        start += 6; // skip "Label:"
 
347
                        end = str.QCM_indexOf("</tr>", start);
 
348
                        if (end > start) {
 
349
                                QString labelStr = str.mid(start, end - start);
 
350
                                labelStr.replace(nlSpaceRe, ""); // strip new lines and space after them
 
351
                                labelStr.replace(htmlTagRe, ""); // strip HTML tags
 
352
                                labelStr = fixUpArtist(labelStr);
 
353
                                if (labelStr != "Not On Label") {
 
354
                                        framesHdr.setValue(Frame::FT_Publisher, labelStr);
 
355
                                }
 
356
                        }
 
357
                }
 
358
 
 
359
                /*
 
360
                 * media can be found in "Format:"
 
361
                 */
 
362
                start = str.QCM_indexOf("Format:");
 
363
                if (start >= 0) {
 
364
                        start += 7; // skip "Format:"
 
365
                        end = str.QCM_indexOf("</tr>", start);
 
366
                        if (end > start) {
 
367
                                QString mediaStr = str.mid(start, end - start);
 
368
                                mediaStr.replace(nlSpaceRe, ""); // strip new lines and space after them
 
369
                                mediaStr.replace(htmlTagRe, ""); // strip HTML tags
 
370
                                framesHdr.setValue(Frame::FT_Media, mediaStr);
 
371
                        }
 
372
                }
 
373
 
 
374
                /*
 
375
                 * credits can be found in "Credits:"
 
376
                 */
 
377
                start = str.QCM_indexOf("Credits:");
 
378
                if (start >= 0) {
 
379
                        start += 8; // skip "Credits:"
 
380
                        end = str.QCM_indexOf("</tr>", start);
 
381
                        if (end > start) {
 
382
                                QString creditsStr = str.mid(start, end - start);
 
383
                                creditsStr.replace(nlSpaceRe, ""); // strip new lines and space after them
 
384
                                creditsStr.replace("<br>", "\n");
 
385
                                creditsStr.replace(htmlTagRe, ""); // strip HTML tags
 
386
                                parseCredits(creditsStr, framesHdr);
 
387
                        }
 
388
                }
186
389
        }
187
390
 
188
391
        /*
207
410
                        // strip whitespace
208
411
                        str.replace(nlSpaceRe, "");
209
412
 
210
 
                        StandardTags st(stHdr);
 
413
                        FrameCollection frames(framesHdr);
211
414
                        QRegExp titleTimeRe("(.+)\\s+\\((\\d+):(\\d+)\\)");
212
415
                        ImportTrackDataVector::iterator it = m_trackDataVector.begin();
213
416
                        bool atTrackDataListEnd = (it == m_trackDataVector.end());
221
424
                                        break;
222
425
                                }
223
426
                                QString title(str.mid(titleStart, end - titleStart));
 
427
                                if (additionalTags) {
 
428
                                        int artistStart = str.QCM_indexOf("<a href=\"/artist/", start);
 
429
                                        if (artistStart > start && artistStart < titleStart) {
 
430
                                                artistStart = str.QCM_indexOf('>', artistStart);
 
431
                                                if (artistStart > start && artistStart < titleStart) {
 
432
                                                        ++artistStart; // skip '>'
 
433
                                                        int artistEnd = str.QCM_indexOf("</a>", artistStart);
 
434
                                                        if (artistEnd > artistStart && artistEnd < titleStart) {
 
435
                                                                // use the artist in the header as the album artist
 
436
                                                                // and the artist in the track as the artist
 
437
                                                                frames.setArtist(
 
438
                                                                        fixUpArtist(str.mid(artistStart, artistEnd - artistStart)));
 
439
                                                                frames.setValue(Frame::FT_AlbumArtist, framesHdr.getArtist());
 
440
                                                        }
 
441
                                                }
 
442
                                        }
 
443
                                }
224
444
                                start = end + 10; // skip </td></tr>
225
445
                                if (title.QCM_indexOf("</") != -1 || title.QCM_indexOf("<a href") != -1) {
226
446
                                        // strange entry instead of track => skip
 
447
                                        if (additionalTags) {
 
448
                                                if (title.startsWith("<b>") && title.endsWith("</b>")) {
 
449
                                                        // a bold title is a set subtitle
 
450
                                                        QString subtitle(title.mid(3, title.length() - 7));
 
451
                                                        subtitle.remove(htmlTagRe); // strip HTML tags
 
452
                                                        // remove duration
 
453
                                                        subtitle.remove(QRegExp("\\s*\\(\\d+:\\d+\\)$"));
 
454
                                                        framesHdr.setValue(Frame::FT_Part, subtitle);
 
455
                                                        frames.setValue(Frame::FT_Part, subtitle);
 
456
                                                }
 
457
                                        }
227
458
                                        continue;
228
459
                                }
 
460
 
 
461
                                if (additionalTags) {
 
462
                                        int nextEnd, nextTitleStart = -1;
 
463
                                        if ((nextEnd = str.QCM_indexOf("</td></tr>", start)) > start &&
 
464
                                                        (nextTitleStart = str.QCM_lastIndexOf("<td>", nextEnd)) > start) {
 
465
                                                QString nextTitle(str.mid(nextTitleStart, nextEnd - nextTitleStart));
 
466
                                                if (nextTitle.QCM_indexOf("</") != -1 ||
 
467
                                                                nextTitle.QCM_indexOf("<a href") != -1) {
 
468
                                                        // additional track info like "Music By, Lyrics By - "
 
469
                                                        nextTitle.replace("<br>", "\n");
 
470
                                                        nextTitle.replace(htmlTagRe, ""); // strip HTML tags
 
471
                                                        nextTitle.remove("&nbsp;");
 
472
                                                        if (parseCredits(nextTitle, frames)) {
 
473
                                                                start = nextEnd + 10; // skip </td></tr>
 
474
                                                        }
 
475
                                                }
 
476
                                        }
 
477
                                }
 
478
 
229
479
                                int duration = 0;
230
480
                                if (titleTimeRe.exactMatch(title)) {
231
481
                                        duration = titleTimeRe.cap(2).toInt() * 60 +
232
482
                                                titleTimeRe.cap(3).toInt();
233
483
                                        title = titleTimeRe.cap(1);
234
484
                                }
235
 
                                st.track = trackNr;
236
 
                                st.title = title;
 
485
                                frames.setTrack(trackNr);
 
486
                                frames.setTitle(title);
237
487
                                if (atTrackDataListEnd) {
238
488
                                        ImportTrackData trackData;
239
 
                                        trackData.setStandardTags(st);
 
489
                                        trackData.setFrameCollection(frames);
240
490
                                        trackData.setImportDuration(duration);
241
491
                                        m_trackDataVector.push_back(trackData);
242
492
                                } else {
243
 
                                        (*it).setStandardTags(st);
 
493
                                        (*it).setFrameCollection(frames);
244
494
                                        (*it).setImportDuration(duration);
245
495
                                        ++it;
246
496
                                        atTrackDataListEnd = (it == m_trackDataVector.end());
247
497
                                }
248
498
                                ++trackNr;
249
 
                                st = stHdr;
 
499
                                frames = framesHdr;
250
500
                        }
251
501
 
252
502
                        // handle redundant tracks
253
 
                        st.setInactive();
 
503
                        frames.clear();
254
504
                        while (!atTrackDataListEnd) {
255
505
                                if ((*it).getFileDuration() == 0) {
256
506
                                        it = m_trackDataVector.erase(it);
257
507
                                } else {
258
 
                                        (*it).setStandardTags(st);
 
508
                                        (*it).setFrameCollection(frames);
259
509
                                        (*it).setImportDuration(0);
260
510
                                        ++it;
261
511
                                }