1 /*
2 * Copyright 2007-2016 Fabrice Colin
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 */
18
19 #include <stdio.h>
20 #include <unistd.h>
21 #include <fileref.h>
22 #include <tfile.h>
23 #include <tag.h>
24 #include <iostream>
25
26 #include "TagLibMusicFilter.h"
27
28 using std::string;
29 using std::clog;
30 using std::endl;
31
32 using namespace Dijon;
33
34 #ifdef _DYNAMIC_DIJON_FILTERS
get_filter_types(MIMETypes & mime_types)35 DIJON_FILTER_EXPORT bool get_filter_types(MIMETypes &mime_types)
36 {
37 mime_types.m_mimeTypes.clear();
38 mime_types.m_mimeTypes.insert("audio/mpeg");
39 mime_types.m_mimeTypes.insert("audio/x-mp3");
40 mime_types.m_mimeTypes.insert("application/ogg");
41 mime_types.m_mimeTypes.insert("audio/x-flac+ogg");
42 mime_types.m_mimeTypes.insert("audio/x-flac");
43
44 return true;
45 }
46
check_filter_data_input(int data_input)47 DIJON_FILTER_EXPORT bool check_filter_data_input(int data_input)
48 {
49 Filter::DataInput input = (Filter::DataInput)data_input;
50
51 if (input == Filter::DOCUMENT_FILE_NAME)
52 {
53 return true;
54 }
55
56 return false;
57 }
58
get_filter(void)59 DIJON_FILTER_EXPORT Filter *get_filter(void)
60 {
61 return new TagLibMusicFilter();
62 }
63 #endif
64
TagLibMusicFilter()65 TagLibMusicFilter::TagLibMusicFilter() :
66 Filter(),
67 m_parseDocument(false)
68 {
69 }
70
~TagLibMusicFilter()71 TagLibMusicFilter::~TagLibMusicFilter()
72 {
73 rewind();
74 }
75
is_data_input_ok(DataInput input) const76 bool TagLibMusicFilter::is_data_input_ok(DataInput input) const
77 {
78 if (input == DOCUMENT_FILE_NAME)
79 {
80 return true;
81 }
82
83 return false;
84 }
85
set_property(Properties prop_name,const string & prop_value)86 bool TagLibMusicFilter::set_property(Properties prop_name, const string &prop_value)
87 {
88 return false;
89 }
90
set_document_data(const char * data_ptr,off_t data_length)91 bool TagLibMusicFilter::set_document_data(const char *data_ptr, off_t data_length)
92 {
93 return false;
94 }
95
set_document_string(const string & data_str)96 bool TagLibMusicFilter::set_document_string(const string &data_str)
97 {
98 return false;
99 }
100
set_document_file(const string & file_path,bool unlink_when_done)101 bool TagLibMusicFilter::set_document_file(const string &file_path, bool unlink_when_done)
102 {
103 if (Filter::set_document_file(file_path, unlink_when_done) == true)
104 {
105 m_parseDocument = true;
106
107 return true;
108 }
109
110 return false;
111 }
112
set_document_uri(const string & uri)113 bool TagLibMusicFilter::set_document_uri(const string &uri)
114 {
115 return false;
116 }
117
has_documents(void) const118 bool TagLibMusicFilter::has_documents(void) const
119 {
120 return m_parseDocument;
121 }
122
next_document(void)123 bool TagLibMusicFilter::next_document(void)
124 {
125 if (m_parseDocument == true)
126 {
127 m_parseDocument = false;
128
129 m_content.clear();
130 m_metaData.clear();
131
132 TagLib::FileRef fileRef(m_filePath.c_str(), false);
133 if (fileRef.isNull() == false)
134 {
135 TagLib::Tag *pTag = fileRef.tag();
136
137 if ((pTag != NULL) &&
138 (pTag->isEmpty() == false))
139 {
140 char yearStr[64];
141
142 string trackTitle(pTag->title().toCString(true));
143 trackTitle += " ";
144 trackTitle += pTag->artist().toCString(true);
145
146 #ifdef DEBUG
147 clog << "TagLibMusicFilter::next_document: " << trackTitle.length() << " bytes of text" << endl;
148 #endif
149 m_content.append(trackTitle.c_str(), trackTitle.length());
150 m_content += " ";
151 m_content += pTag->album().toCString(true);
152 m_content += " ";
153 m_content += pTag->comment().toCString(true);
154 m_content += " ";
155 m_content += pTag->genre().toCString(true);
156 snprintf(yearStr, 64, " %u", pTag->year());
157 m_content += yearStr;
158
159 m_metaData["title"] = trackTitle;
160 m_metaData["ipath"] = "";
161 m_metaData["mimetype"] = "text/plain";
162 m_metaData["charset"] = "utf-8";
163 m_metaData["author"] = pTag->artist().toCString(true);
164 }
165 else
166 {
167 // This file doesn't have any tag
168 string::size_type filePos = m_filePath.find_last_of("/");
169 if ((filePos != string::npos) &&
170 (m_filePath.length() - filePos > 1))
171 {
172 m_metaData["title"] = m_filePath.substr(filePos + 1);
173 }
174 else
175 {
176 m_metaData["title"] = m_filePath;
177 }
178 m_metaData["ipath"] = "";
179 m_metaData["mimetype"] = "text/plain";
180 m_metaData["charset"] = "utf-8";
181 }
182
183 return true;
184 }
185 }
186
187 return false;
188 }
189
skip_to_document(const string & ipath)190 bool TagLibMusicFilter::skip_to_document(const string &ipath)
191 {
192 if (ipath.empty() == true)
193 {
194 return next_document();
195 }
196
197 return false;
198 }
199
get_error(void) const200 string TagLibMusicFilter::get_error(void) const
201 {
202 return "";
203 }
204
rewind(void)205 void TagLibMusicFilter::rewind(void)
206 {
207 Filter::rewind();
208
209 m_parseDocument = false;
210 }
211