settings: provide a way to disable asking for locked screen's width
[ncmpcpp.git] / extras / artist_to_albumartist.cpp
blobb3c1fb7a48873de3142dff437032d53ea37719ad
1 /***************************************************************************
2 * Copyright (C) 2008-2011 by Andrzej Rybczak *
3 * electricityispower@gmail.com *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
19 ***************************************************************************/
21 #include <cstring>
22 #include <iostream>
24 #include "xiphcomment.h"
25 #include "id3v2tag.h"
26 #include "textidentificationframe.h"
27 #include "fileref.h"
28 #include "mpegfile.h"
29 #include "vorbisfile.h"
30 #include "flacfile.h"
32 using std::cout;
34 bool framelist_empty(const TagLib::ID3v2::FrameList &fl)
36 TagLib::ID3v2::FrameList::ConstIterator it = fl.begin();
37 while (it != fl.end())
38 if (!((*it++)->toString() == TagLib::String::null))
39 return false;
40 return true;
43 bool write_id3v2_aa(TagLib::ID3v2::Tag *tag, const TagLib::String &artist)
45 using TagLib::ID3v2::TextIdentificationFrame;
46 TagLib::ByteVector type = "TPE2";
47 if (!framelist_empty(tag->frameList(type)))
48 return false;
49 TextIdentificationFrame *frame = new TextIdentificationFrame(type, TagLib::String::UTF8);
50 frame->setText(artist);
51 tag->addFrame(frame);
52 return true;
55 bool write_xiphcomment_aa(TagLib::Ogg::XiphComment *tag, const TagLib::String &artist)
57 if (tag->contains("ALBUM ARTIST"))
58 return false;
59 tag->addField("ALBUM ARTIST", artist, true);
60 return true;
63 void convert(int n, char **files, bool dry_run)
65 if (n == 0)
67 cout << "No files to convert, exiting.\n";
68 return;
70 if (dry_run)
71 cout << "Dry run mode enabled, pretending to modify files.\n";
73 for (int i = 0; i < n; ++i)
75 cout << "Modifying " << files[i] << "... ";
77 TagLib::FileRef f(files[i]);
78 if (!f.isNull())
80 TagLib::String artist = f.tag()->artist();
81 if (!(artist == TagLib::String::null))
83 TagLib::MPEG::File *mp3_f = 0;
84 TagLib::Ogg::Vorbis::File *ogg_f = 0;
85 TagLib::FLAC::File *flac_f = 0;
87 bool success;
88 if ((mp3_f = dynamic_cast<TagLib::MPEG::File *>(f.file())))
90 success = write_id3v2_aa(mp3_f->ID3v2Tag(true), artist);
92 else if ((ogg_f = dynamic_cast<TagLib::Ogg::Vorbis::File *>(f.file())))
94 success = write_xiphcomment_aa(ogg_f->tag(), artist);
96 else if ((flac_f = dynamic_cast<TagLib::FLAC::File *>(f.file())))
98 success = write_xiphcomment_aa(flac_f->xiphComment(true), artist);
100 else
102 cout << "Not mp3/ogg/flac file, skipping.\n";
103 continue;
106 if (success)
108 if (!dry_run)
109 f.save();
110 cout << "Done.\n";
112 else
113 cout << "AlbumArtist is already here, skipping.\n";
115 else
116 cout << "Artist not found, skipping.\n";
118 else
119 cout << "Could not open file, skipping.\n";
123 int main(int argc, char **argv)
125 if (argc < 2)
127 cout << "This little program copies Artist tag (if present) to\n";
128 cout << "AlbumArtist (if not present) for given mp3/ogg/flac files.\n\n";
129 cout << "Usage: " << argv[0] << " [--dry-run] files\n";
131 else
133 bool dry_run = !strcmp(argv[1], "--dry-run");
134 convert(argc-1-dry_run, &argv[1+dry_run], dry_run);
136 return 0;