1 /* EasyTAG - Tag editor for audio files
2 * Copyright (C) 2014-2015 David King <amigadave@amigadave.com>
3 * Copyright (C) 2001-2003 Jerome Couderc <easytag@gmail.com>
4 * Copyright (C) 2002-2003 Artur Polaczyñski <artii@o2.pl>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 */
20
21 #include "config.h"
22
23 #include <glib/gi18n.h>
24 #include <glib/gstdio.h>
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <errno.h>
28
29 #include "ape_tag.h"
30 #include "et_core.h"
31 #include "misc.h"
32 #include "setting.h"
33 #include "charset.h"
34 #include "libapetag/apetaglib.h"
35
36 /*************
37 * Functions *
38 *************/
39
40 /*
41 * set_string_field:
42 * @field: (inout): pointer to a location in which to store the field value
43 * @string: (transfer none): the string to copy and store in @field
44 *
45 * Copy @string and store it in @field, first validating that the string is
46 * valid UTF-8.
47 */
48 static void
set_string_field(gchar ** field,gchar * string)49 set_string_field (gchar **field,
50 gchar *string)
51 {
52 if (!et_str_empty (string))
53 {
54 if (g_utf8_validate (string, -1, NULL))
55 {
56 *field = g_strdup (string);
57 }
58 else
59 {
60 /* Unnecessarily validates the field again, but this should not be
61 * the common case. */
62 *field = Try_To_Validate_Utf8_String (string);
63 }
64 }
65 }
66
67 /*
68 * Note:
69 * - if field is found but contains no info (strlen(str)==0), we don't read it
70 */
71 gboolean
ape_tag_read_file_tag(GFile * file,File_Tag * FileTag,GError ** error)72 ape_tag_read_file_tag (GFile *file,
73 File_Tag *FileTag,
74 GError **error)
75 {
76 FILE *fp;
77 gchar *filename;
78 gchar *string = NULL;
79 gchar *string1 = NULL;
80 apetag *ape_cnt;
81
82 g_return_val_if_fail (file != NULL && FileTag != NULL, FALSE);
83 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
84
85 filename = g_file_get_path (file);
86
87 if ((fp = g_fopen (filename, "rb")) == NULL)
88 {
89 g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errno),
90 _("Error while opening file: %s"),
91 g_strerror (errno));
92 g_free (filename);
93 return FALSE;
94 }
95
96 ape_cnt = apetag_init();
97 apetag_read_fp (ape_cnt, fp, filename, 0); /* read all tags ape,id3v[12]*/
98
99 g_free (filename);
100
101 /* Title */
102 string = apefrm_getstr (ape_cnt, APE_TAG_FIELD_TITLE);
103 set_string_field (&FileTag->title, string);
104
105 /* Artist */
106 string = apefrm_getstr (ape_cnt, APE_TAG_FIELD_ARTIST);
107 set_string_field (&FileTag->artist, string);
108
109 /* Album artist. */
110 string = apefrm_getstr (ape_cnt, APE_TAG_FIELD_ALBUMARTIST);
111 set_string_field (&FileTag->album_artist, string);
112
113 /* Album */
114 string = apefrm_getstr (ape_cnt, APE_TAG_FIELD_ALBUM);
115 set_string_field (&FileTag->album, string);
116
117 /* Disc Number and Disc Total */
118 string = apefrm_getstr (ape_cnt, APE_TAG_FIELD_PART);
119
120 if (string)
121 {
122 string = Try_To_Validate_Utf8_String (string);
123
124 string1 = strchr (string, '/');
125
126 if (string1)
127 {
128 FileTag->disc_total = et_disc_number_to_string (atoi (string1
129 + 1));
130 *string1 = '\0';
131 }
132
133 FileTag->disc_number = et_disc_number_to_string (atoi (string));
134
135 g_free (string);
136 }
137 else
138 {
139 FileTag->disc_number = FileTag->disc_total = NULL;
140 }
141
142 /* Year */
143 string = apefrm_getstr (ape_cnt, APE_TAG_FIELD_YEAR);
144 set_string_field (&FileTag->year, string);
145
146 /* Track and Total Track */
147 string = apefrm_getstr (ape_cnt, APE_TAG_FIELD_TRACK);
148
149 if (string)
150 {
151 string = Try_To_Validate_Utf8_String(string);
152
153 string1 = strchr (string, '/');
154
155 if (string1)
156 {
157 FileTag->track_total = et_track_number_to_string (atoi (string1
158 + 1));
159 *string1 = '\0';
160 }
161 FileTag->track = et_track_number_to_string (atoi (string));
162
163 g_free(string);
164 } else
165 {
166 FileTag->track = FileTag->track_total = NULL;
167 }
168
169 /* Genre */
170 string = apefrm_getstr (ape_cnt, APE_TAG_FIELD_GENRE);
171 set_string_field (&FileTag->genre, string);
172
173 /* Comment */
174 string = apefrm_getstr (ape_cnt, APE_TAG_FIELD_COMMENT);
175 set_string_field (&FileTag->comment, string);
176
177 /* Composer */
178 string = apefrm_getstr (ape_cnt, APE_TAG_FIELD_COMPOSER);
179 set_string_field (&FileTag->composer, string);
180
181 /* Original artist */
182 string = apefrm_getstr (ape_cnt, "Original Artist");
183 set_string_field (&FileTag->orig_artist, string);
184
185 /* Copyright */
186 string = apefrm_getstr (ape_cnt, APE_TAG_FIELD_COPYRIGHT);
187 set_string_field (&FileTag->copyright, string);
188
189 /* URL */
190 string = apefrm_getstr (ape_cnt, APE_TAG_FIELD_RELATED_URL);
191 set_string_field (&FileTag->url, string);
192
193 /* Encoded by */
194 string = apefrm_getstr (ape_cnt, "Encoded By");
195 set_string_field (&FileTag->encoded_by, string);
196
197 apetag_free (ape_cnt);
198 fclose (fp);
199
200 return TRUE;
201 }
202
203 gboolean
ape_tag_write_file_tag(const ET_File * ETFile,GError ** error)204 ape_tag_write_file_tag (const ET_File *ETFile,
205 GError **error)
206 {
207 const File_Tag *FileTag;
208 const gchar *filename_in;
209 //FILE *file_in;
210 gchar *string;
211 //GList *list;
212 apetag *ape_mem;
213
214 g_return_val_if_fail (ETFile != NULL && ETFile->FileTag != NULL, FALSE);
215 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
216
217 FileTag = (File_Tag *)ETFile->FileTag->data;
218 filename_in = ((File_Name *)ETFile->FileNameCur->data)->value;
219
220 ape_mem = apetag_init ();
221
222 /* TODO: Pointless, as g_set_error() will try to malloc. */
223 if (!ape_mem)
224 {
225 g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_NOMEM, "%s",
226 g_strerror (ENOMEM));
227 return FALSE;
228 }
229
230 /*********
231 * Title *
232 *********/
233 if (!et_str_empty (FileTag->title))
234 apefrm_add(ape_mem, 0, APE_TAG_FIELD_TITLE, FileTag->title);
235 else
236 apefrm_remove(ape_mem,APE_TAG_FIELD_TITLE);
237
238
239 /**********
240 * Artist *
241 **********/
242 if (!et_str_empty (FileTag->artist))
243 apefrm_add(ape_mem, 0, APE_TAG_FIELD_ARTIST, FileTag->artist);
244 else
245 apefrm_remove(ape_mem,APE_TAG_FIELD_ARTIST);
246
247 /* Album artist. */
248 if (!et_str_empty (FileTag->album_artist))
249 {
250 apefrm_add (ape_mem, 0, APE_TAG_FIELD_ALBUMARTIST,
251 FileTag->album_artist);
252 }
253 else
254 {
255 apefrm_remove (ape_mem, APE_TAG_FIELD_ALBUMARTIST);
256 }
257
258 /*********
259 * Album *
260 *********/
261 if (!et_str_empty (FileTag->album))
262 apefrm_add(ape_mem, 0, APE_TAG_FIELD_ALBUM, FileTag->album);
263 else
264 apefrm_remove(ape_mem,APE_TAG_FIELD_ALBUM);
265
266 /******************************
267 * Disc Number and Disc Total *
268 ******************************/
269 if (!et_str_empty (FileTag->disc_number))
270 {
271 if (!et_str_empty (FileTag->disc_total))
272 {
273 string = g_strconcat (FileTag->disc_number, "/",
274 FileTag->disc_total, NULL);
275 }
276 else
277 {
278 string = g_strconcat (FileTag->disc_number, NULL);
279 }
280
281 apefrm_add (ape_mem, 0, APE_TAG_FIELD_PART, string);
282 g_free (string);
283 }
284 else
285 {
286 apefrm_remove (ape_mem, APE_TAG_FIELD_PART);
287 }
288
289 /********
290 * Year *
291 ********/
292 if (!et_str_empty (FileTag->year))
293 apefrm_add(ape_mem, 0, APE_TAG_FIELD_YEAR, FileTag->year);
294 else
295 apefrm_remove(ape_mem,APE_TAG_FIELD_YEAR);
296
297 /*************************
298 * Track and Total Track *
299 *************************/
300 if (!et_str_empty (FileTag->track))
301 {
302 if (!et_str_empty (FileTag->track_total))
303 string = g_strconcat(FileTag->track,"/",FileTag->track_total,NULL);
304 else
305 string = g_strconcat(FileTag->track,NULL);
306 apefrm_add(ape_mem, 0, APE_TAG_FIELD_TRACK, string);
307 g_free(string);
308 } else
309 apefrm_remove(ape_mem,APE_TAG_FIELD_TRACK);
310
311 /*********
312 * Genre *
313 *********/
314 if (!et_str_empty (FileTag->genre))
315 apefrm_add(ape_mem, 0, APE_TAG_FIELD_GENRE, FileTag->genre);
316 else
317 apefrm_remove(ape_mem,APE_TAG_FIELD_GENRE);
318
319 /***********
320 * Comment *
321 ***********/
322 if (!et_str_empty (FileTag->comment))
323 apefrm_add (ape_mem, 0, APE_TAG_FIELD_COMMENT, FileTag->comment);
324 else
325 apefrm_remove(ape_mem,APE_TAG_FIELD_COMMENT);
326
327 /************
328 * Composer *
329 ************/
330 if (!et_str_empty (FileTag->composer))
331 apefrm_add(ape_mem, 0, APE_TAG_FIELD_COMPOSER, FileTag->composer);
332 else
333 apefrm_remove(ape_mem,APE_TAG_FIELD_COMPOSER);
334
335 /*******************
336 * Original artist *
337 *******************/
338 if (!et_str_empty (FileTag->orig_artist))
339 apefrm_add(ape_mem, 0, "Original Artist", FileTag->orig_artist);
340 else
341 apefrm_remove(ape_mem,"Original Artist");
342
343 /*************
344 * Copyright *
345 *************/
346 if (!et_str_empty (FileTag->copyright))
347 apefrm_add(ape_mem, 0, APE_TAG_FIELD_COPYRIGHT, FileTag->copyright);
348 else
349 apefrm_remove(ape_mem,APE_TAG_FIELD_COPYRIGHT);
350
351 /*******
352 * URL *
353 *******/
354 if (!et_str_empty (FileTag->url))
355 apefrm_add(ape_mem, 0, APE_TAG_FIELD_RELATED_URL, FileTag->url);
356 else
357 apefrm_remove(ape_mem,APE_TAG_FIELD_RELATED_URL);
358
359 /**************
360 * Encoded by *
361 **************/
362 if (!et_str_empty (FileTag->encoded_by))
363 apefrm_add(ape_mem, 0, "Encoded By", FileTag->encoded_by);
364 else
365 apefrm_remove(ape_mem,"Encoded By");
366
367 /* reread all tag-type again excl. changed frames by apefrm_remove() */
368 if (apetag_save (filename_in, ape_mem, APE_TAG_V2 + SAVE_NEW_OLD_APE_TAG)
369 != 0)
370 {
371 g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED, "%s",
372 _("Failed to write APE tag"));
373 apetag_free (ape_mem);
374 return FALSE;
375 }
376
377 apetag_free(ape_mem);
378
379 return TRUE;
380 }
381