~ubuntu-branches/ubuntu/raring/tracker/raring

« back to all changes in this revision

Viewing changes to src/tracker-extract/tracker-albumart.c

  • Committer: Package Import Robot
  • Author(s): Michael Biebl
  • Date: 2011-08-26 00:26:14 UTC
  • mfrom: (4.3.17 sid)
  • Revision ID: package-import@ubuntu.com-20110826002614-4qjfs9jhh5gs4p13
Tags: 0.10.24-1
New upstream release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
28
28
#include <sys/types.h>
29
29
#include <utime.h>
30
30
#include <time.h>
 
31
#include <errno.h>
31
32
 
32
33
#include <glib.h>
33
34
#include <glib/gprintf.h>
67
68
                   gpointer      user_data);
68
69
 
69
70
 
 
71
static gchar *
 
72
checksum_for_data (GChecksumType  checksum_type,
 
73
                   const guchar  *data,
 
74
                   gsize          length)
 
75
{
 
76
        GChecksum *checksum;
 
77
        gchar *retval;
 
78
 
 
79
        checksum = g_checksum_new (checksum_type);
 
80
        if (!checksum) {
 
81
                return NULL;
 
82
        }
 
83
 
 
84
        g_checksum_update (checksum, data, length);
 
85
        retval = g_strdup (g_checksum_get_string (checksum));
 
86
        g_checksum_free (checksum);
 
87
 
 
88
        return retval;
 
89
}
 
90
 
 
91
static gboolean
 
92
file_get_checksum_if_exists (GChecksumType   checksum_type,
 
93
                             const gchar    *path,
 
94
                             gchar         **md5,
 
95
                             gboolean        check_jpeg,
 
96
                             gboolean       *is_jpeg)
 
97
{
 
98
        GFile *file = g_file_new_for_path (path);
 
99
        GFileInputStream *stream;
 
100
        GChecksum *checksum;
 
101
        gboolean retval;
 
102
 
 
103
        checksum = g_checksum_new (checksum_type);
 
104
 
 
105
        if (!checksum) {
 
106
                g_debug ("Can't create checksum engine");
 
107
                g_object_unref (file);
 
108
                return FALSE;
 
109
        }
 
110
 
 
111
        stream = g_file_read (file, NULL, NULL);
 
112
 
 
113
        if (stream) {
 
114
                gssize rsize;
 
115
                guchar buffer[1024];
 
116
 
 
117
                /* File exists & readable always means true retval */
 
118
                retval = TRUE;
 
119
 
 
120
                if (check_jpeg) {
 
121
                        if (g_input_stream_read_all (G_INPUT_STREAM (stream), buffer, 3, &rsize, NULL, NULL)) {
 
122
                                if (rsize >= 3 && buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff) {
 
123
                                        if (is_jpeg) {
 
124
                                                *is_jpeg = TRUE;
 
125
                                        }
 
126
                                        /* Add the read bytes to the checksum */
 
127
                                        g_checksum_update (checksum, buffer, rsize);
 
128
                                } else {
 
129
                                        /* Larger than 3 bytes but incorrect jpeg header */
 
130
                                        if (is_jpeg) {
 
131
                                                *is_jpeg = FALSE;
 
132
                                        }
 
133
                                        goto end;
 
134
                                }
 
135
                        } else {
 
136
                                /* Smaller than 3 bytes, not a jpeg */
 
137
                                if (is_jpeg) {
 
138
                                        *is_jpeg = FALSE;
 
139
                                }
 
140
                                goto end;
 
141
                        }
 
142
                }
 
143
 
 
144
                while ((rsize = g_input_stream_read (G_INPUT_STREAM (stream), buffer, 1024, NULL, NULL)) > 0) {
 
145
                        g_checksum_update (checksum, buffer, rsize);
 
146
                }
 
147
 
 
148
                if (md5) {
 
149
                        *md5 = g_strdup (g_checksum_get_string (checksum));
 
150
                }
 
151
 
 
152
        } else {
 
153
                g_debug ("%s isn't readable while calculating MD5 checksum", path);
 
154
                /* File doesn't exist or isn't readable */
 
155
                retval = FALSE;
 
156
        }
 
157
 
 
158
end:
 
159
 
 
160
        if (stream) {
 
161
                g_object_unref (stream);
 
162
        }
 
163
        g_checksum_free (checksum);
 
164
        g_object_unref (file);
 
165
 
 
166
        return retval;
 
167
}
 
168
 
 
169
static gboolean
 
170
convert_from_other_format (const gchar *found,
 
171
                           const gchar *target,
 
172
                           const gchar *album_path,
 
173
                           const gchar *artist)
 
174
{
 
175
        gboolean retval;
 
176
        gchar *sum1 = NULL;
 
177
        gchar *target_temp;
 
178
 
 
179
        target_temp = g_strdup_printf ("%s-tmp", target);
 
180
 
 
181
        retval = tracker_albumart_file_to_jpeg (found, target_temp);
 
182
 
 
183
        if (retval && (artist == NULL || g_strcmp0 (artist, " ") == 0)) {
 
184
                if (g_rename (target_temp, album_path) == -1) {
 
185
                        g_debug ("rename(%s, %s) error: %s", target_temp, album_path, g_strerror (errno));
 
186
                }
 
187
        } else if (retval && file_get_checksum_if_exists (G_CHECKSUM_MD5, target_temp, &sum1, FALSE, NULL)) {
 
188
                gchar *sum2 = NULL;
 
189
                if (file_get_checksum_if_exists (G_CHECKSUM_MD5, album_path, &sum2, FALSE, NULL)) {
 
190
                        if (g_strcmp0 (sum1, sum2) == 0) {
 
191
 
 
192
                                /* If album-space-md5.jpg is the same as found,
 
193
                                 * make a symlink */
 
194
 
 
195
                                if (symlink (album_path, target) != 0) {
 
196
                                        g_debug ("symlink(%s, %s) error: %s", album_path, target, g_strerror (errno));
 
197
                                        retval = FALSE;
 
198
                                } else {
 
199
                                        retval = TRUE;
 
200
                                }
 
201
 
 
202
                                g_unlink (target_temp);
 
203
 
 
204
                        } else {
 
205
 
 
206
                                /* If album-space-md5.jpg isn't the same as found,
 
207
                                 * make a new album-md5-md5.jpg (found -> target) */
 
208
 
 
209
                                if (g_rename (target_temp, album_path) == -1) {
 
210
                                        g_debug ("rename(%s, %s) error: %s", target_temp, album_path, g_strerror (errno));
 
211
                                }
 
212
                        }
 
213
                        g_free (sum2);
 
214
                } else {
 
215
 
 
216
                        /* If there's not yet a album-space-md5.jpg, make one,
 
217
                         * and symlink album-md5-md5.jpg to it */
 
218
 
 
219
                        g_rename (target_temp, album_path);
 
220
 
 
221
                        if (symlink (album_path, target) != 0) {
 
222
                                g_debug ("symlink(%s,%s) error: %s", album_path, target, g_strerror (errno));
 
223
                                retval = FALSE;
 
224
                        } else {
 
225
                                retval = TRUE;
 
226
                        }
 
227
 
 
228
                }
 
229
 
 
230
                g_free (sum1);
 
231
        } else if (retval) {
 
232
                g_debug ("Can't read %s while calculating checksum", target_temp);
 
233
                /* Can't read the file that it was converted to, strange ... */
 
234
                g_unlink (target_temp);
 
235
        }
 
236
 
 
237
        g_free (target_temp);
 
238
 
 
239
        return retval;
 
240
}
 
241
 
70
242
static gboolean
71
243
albumart_heuristic (const gchar *artist,
72
244
                    const gchar *album,
77
249
        GFile *file, *dirf;
78
250
        GDir *dir;
79
251
        GError *error = NULL;
80
 
        gchar *target = NULL;
 
252
        gchar *target = NULL, *album_path = NULL;
81
253
        gchar *dirname = NULL;
82
254
        const gchar *name;
83
255
        gboolean retval;
170
342
                return FALSE;
171
343
        }
172
344
 
173
 
        file = NULL;
174
345
        artist_strdown = artist_stripped ? g_utf8_strdown (artist_stripped, -1) : g_strdup ("");
175
346
        album_strdown = album_stripped ? g_utf8_strdown (album_stripped, -1) : g_strdup ("");
176
347
 
207
378
                            (strstr (name_strdown, "front")) ||
208
379
                            (strstr (name_strdown, "folder")) ||
209
380
                            ((strstr (name_strdown, "albumart") && strstr (name_strdown, i == 0 ? "large" : "small")))) {
 
381
 
 
382
                                gchar *found;
 
383
 
 
384
                                found = g_build_filename (dirname, name, NULL);
 
385
 
210
386
                                if (g_str_has_suffix (name_strdown, "jpeg") ||
211
387
                                    g_str_has_suffix (name_strdown, "jpg")) {
 
388
 
 
389
                                        gboolean is_jpeg = FALSE;
 
390
                                        gchar *sum1 = NULL;
 
391
 
212
392
                                        if (!target) {
213
393
                                                tracker_albumart_get_path (artist_stripped,
214
394
                                                                           album_stripped,
218
398
                                                                           NULL);
219
399
                                        }
220
400
 
221
 
                                        if (!file && target) {
222
 
                                                file = g_file_new_for_path (target);
 
401
                                        if (!album_path) {
 
402
                                                tracker_albumart_get_path (" ",
 
403
                                                                           album_stripped,
 
404
                                                                           "album",
 
405
                                                                           NULL,
 
406
                                                                           &album_path,
 
407
                                                                           NULL);
223
408
                                        }
224
409
 
225
 
                                        if (file) {
 
410
 
 
411
                                        if (artist == NULL || g_strcmp0 (artist, " ") == 0) {
226
412
                                                GFile *found_file;
227
 
                                                gchar *found;
 
413
                                                GFile *target_file;
 
414
                                                GError *err = NULL;
228
415
 
229
 
                                                found = g_build_filename (dirname, name, NULL);
230
416
                                                g_debug ("Album art (JPEG) found in same directory being used:'%s'", found);
231
417
 
 
418
                                                target_file = g_file_new_for_path (target);
232
419
                                                found_file = g_file_new_for_path (found);
233
 
                                                g_free (found);
234
 
 
235
 
                                                retval = g_file_copy (found_file, file, 0, NULL, NULL, NULL, &error);
 
420
                                                retval = g_file_copy (found_file, target_file, 0, NULL, NULL, NULL, &err);
 
421
                                                if (err) {
 
422
                                                        g_debug ("%s", err->message);
 
423
                                                        g_clear_error (&err);
 
424
                                                }
236
425
                                                g_object_unref (found_file);
237
 
 
238
 
                                                g_clear_error (&error);
 
426
                                                g_object_unref (target_file);
 
427
                                        } else if (file_get_checksum_if_exists (G_CHECKSUM_MD5, found, &sum1, TRUE, &is_jpeg)) {
 
428
                                                if (is_jpeg) {
 
429
                                                        gchar *sum2 = NULL;
 
430
 
 
431
                                                        g_debug ("Album art (JPEG) found in same directory being used:'%s'", found);
 
432
 
 
433
                                                        if (file_get_checksum_if_exists (G_CHECKSUM_MD5, album_path, &sum2, FALSE, NULL)) {
 
434
                                                                if (g_strcmp0 (sum1, sum2) == 0) {
 
435
                                                                        /* If album-space-md5.jpg is the same as found,
 
436
                                                                         * make a symlink */
 
437
 
 
438
                                                                        if (symlink (album_path, target) != 0) {
 
439
                                                                                g_debug ("symlink(%s, %s) error: %s", album_path, target, g_strerror (errno));
 
440
                                                                                retval = FALSE;
 
441
                                                                        } else {
 
442
                                                                                retval = TRUE;
 
443
                                                                        }
 
444
                                                                } else {
 
445
                                                                        GFile *found_file;
 
446
                                                                        GFile *target_file;
 
447
                                                                        GError *err = NULL;
 
448
 
 
449
                                                                        /* If album-space-md5.jpg isn't the same as found,
 
450
                                                                         * make a new album-md5-md5.jpg (found -> target) */
 
451
 
 
452
                                                                        target_file = g_file_new_for_path (target);
 
453
                                                                        found_file = g_file_new_for_path (found);
 
454
                                                                        retval = g_file_copy (found_file, target_file, 0, NULL, NULL, NULL, &err);
 
455
                                                                        if (err) {
 
456
                                                                                g_debug ("%s", err->message);
 
457
                                                                                g_clear_error (&err);
 
458
                                                                        }
 
459
                                                                        g_object_unref (found_file);
 
460
                                                                        g_object_unref (target_file);
 
461
                                                                }
 
462
                                                                g_free (sum2);
 
463
                                                        } else {
 
464
                                                                GFile *found_file;
 
465
                                                                GError *err = NULL;
 
466
 
 
467
                                                                /* If there's not yet a album-space-md5.jpg, make one,
 
468
                                                                 * and symlink album-md5-md5.jpg to it */
 
469
 
 
470
                                                                file = g_file_new_for_path (album_path);
 
471
                                                                found_file = g_file_new_for_path (found);
 
472
                                                                retval = g_file_copy (found_file, file, 0, NULL, NULL, NULL, &err);
 
473
 
 
474
                                                                if (err == NULL) {
 
475
                                                                        if (symlink (album_path, target) != 0) {
 
476
                                                                                g_debug ("symlink(%s, %s) error: %s", album_path, target, g_strerror (errno));
 
477
                                                                                retval = FALSE;
 
478
                                                                        } else {
 
479
                                                                                retval = TRUE;
 
480
                                                                        }
 
481
                                                                } else {
 
482
                                                                        g_debug ("%s", err->message);
 
483
                                                                        g_clear_error (&err);
 
484
                                                                        retval = FALSE;
 
485
                                                                }
 
486
 
 
487
                                                                g_object_unref (found_file);
 
488
                                                                g_object_unref (file);
 
489
                                                        }
 
490
                                                } else {
 
491
                                                        g_debug ("Album art found in same directory but not a real JPEG file (trying to convert): '%s'", found);
 
492
                                                        retval = convert_from_other_format (found, target, album_path, artist);
 
493
                                                }
 
494
 
 
495
                                                g_free (sum1);
 
496
                                        } else {
 
497
                                                /* Can't read contents of the cover.jpg file ... */
 
498
                                                retval = FALSE;
239
499
                                        }
240
500
                                } else if (g_str_has_suffix (name_strdown, "png")) {
241
 
                                        gchar *found;
242
501
 
243
502
                                        if (!target) {
244
503
                                                tracker_albumart_get_path (artist_stripped,
249
508
                                                                           NULL);
250
509
                                        }
251
510
 
252
 
                                        found = g_build_filename (dirname, name, NULL);
 
511
                                        if (!album_path) {
 
512
                                                tracker_albumart_get_path (" ",
 
513
                                                                           album_stripped,
 
514
                                                                           "album",
 
515
                                                                           NULL,
 
516
                                                                           &album_path,
 
517
                                                                           NULL);
 
518
                                        }
 
519
 
253
520
                                        g_debug ("Album art (PNG) found in same directory being used:'%s'", found);
254
 
                                        retval = tracker_albumart_file_to_jpeg (found, target);
255
 
                                        g_free (found);
 
521
                                        retval = convert_from_other_format (found, target, album_path, artist);
256
522
                                }
 
523
 
 
524
                                g_free (found);
257
525
                        }
258
526
 
259
527
                        g_free (name_utf8);
272
540
 
273
541
        g_dir_close (dir);
274
542
 
275
 
        if (file) {
276
 
                g_object_unref (file);
277
 
        }
278
 
 
279
543
        g_free (target);
 
544
        g_free (album_path);
280
545
        g_free (dirname);
281
546
        g_free (artist_stripped);
282
547
        g_free (album_stripped);
302
567
 
303
568
        tracker_albumart_get_path (artist, album, "album", NULL, &local_path, NULL);
304
569
 
305
 
        retval = tracker_albumart_buffer_to_jpeg (buffer, len, mime, local_path);
 
570
        if (artist == NULL || g_strcmp0 (artist, " ") == 0) {
 
571
                retval = tracker_albumart_buffer_to_jpeg (buffer, len, mime, local_path);
 
572
        } else {
 
573
                gchar *album_path;
 
574
 
 
575
                tracker_albumart_get_path (" ", album, "album", NULL, &album_path, NULL);
 
576
 
 
577
                if (!g_file_test (album_path, G_FILE_TEST_EXISTS)) {
 
578
                        retval = tracker_albumart_buffer_to_jpeg (buffer, len, mime, album_path);
 
579
 
 
580
                        /* If album-space-md5.jpg doesn't exist, make one and make a symlink
 
581
                         * to album-md5-md5.jpg */
 
582
 
 
583
                        if (retval && symlink (album_path, local_path) != 0) {
 
584
                                g_debug ("symlink(%s, %s) error: %s", album_path, local_path, g_strerror (errno));
 
585
                                retval = FALSE;
 
586
                        } else {
 
587
                                retval = TRUE;
 
588
                        }
 
589
                } else {
 
590
                        gchar *sum2 = NULL;
 
591
                        
 
592
                        if (file_get_checksum_if_exists (G_CHECKSUM_MD5, album_path, &sum2, FALSE, NULL)) {
 
593
                                if ( !(g_strcmp0 (mime, "image/jpeg") == 0 || g_strcmp0 (mime, "JPG") == 0) ||
 
594
                               ( !(len > 2 && buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff) )) {
 
595
                                        gchar *sum1 = NULL;
 
596
                                        gchar *temp = g_strdup_printf ("%s-tmp", album_path);
 
597
 
 
598
                                        /* If buffer isn't a JPEG */
 
599
 
 
600
                                        retval = tracker_albumart_buffer_to_jpeg (buffer, len, mime, temp);
 
601
 
 
602
                                        if (retval && file_get_checksum_if_exists (G_CHECKSUM_MD5, temp, &sum1, FALSE, NULL)) {
 
603
                                                if (g_strcmp0 (sum1, sum2) == 0) {
 
604
 
 
605
                                                        /* If album-space-md5.jpg is the same as buffer, make a symlink
 
606
                                                         * to album-md5-md5.jpg */
 
607
 
 
608
                                                        g_unlink (temp);
 
609
                                                        if (symlink (album_path, local_path) != 0) {
 
610
                                                                g_debug ("symlink(%s, %s) error: %s", album_path, local_path, g_strerror (errno));
 
611
                                                                retval = FALSE;
 
612
                                                        } else {
 
613
                                                                retval = TRUE;
 
614
                                                        }
 
615
                                                } else {
 
616
                                                        /* If album-space-md5.jpg isn't the same as buffer, make a
 
617
                                                         * new album-md5-md5.jpg */
 
618
                                                        if (g_rename (temp, local_path) == -1) {
 
619
                                                                g_debug ("rename(%s, %s) error: %s", temp, local_path, g_strerror (errno));
 
620
                                                        }
 
621
                                                }
 
622
                                                g_free (sum1);
 
623
                                        } else {
 
624
                                                /* Can't read temp file ... */
 
625
                                                g_unlink (temp);
 
626
                                        }
 
627
 
 
628
                                        g_free (temp);
 
629
                                } else {
 
630
                                        gchar *sum1 = NULL;
 
631
 
 
632
                                        sum1 = checksum_for_data (G_CHECKSUM_MD5, buffer, len);
 
633
                                        /* If album-space-md5.jpg is the same as buffer, make a symlink
 
634
                                         * to album-md5-md5.jpg */
 
635
 
 
636
                                        if (g_strcmp0 (sum1, sum2) == 0) {
 
637
                                                if (symlink (album_path, local_path) != 0) {
 
638
                                                        g_debug ("symlink(%s, %s) error: %s", album_path, local_path, g_strerror (errno));
 
639
                                                        retval = FALSE;
 
640
                                                } else {
 
641
                                                        retval = TRUE;
 
642
                                                }
 
643
                                        } else {
 
644
                                                /* If album-space-md5.jpg isn't the same as buffer, make a
 
645
                                                 * new album-md5-md5.jpg */
 
646
                                                retval = tracker_albumart_buffer_to_jpeg (buffer, len, mime, local_path);
 
647
                                        }
 
648
                                        g_free (sum1);
 
649
                                }
 
650
                                g_free (sum2);
 
651
                        }
 
652
                        g_free (album_path);
 
653
                }
 
654
        }
306
655
 
307
656
        g_free (local_path);
308
657