~ubuntu-branches/ubuntu/vivid/rawstudio/vivid

« back to all changes in this revision

Viewing changes to librawstudio/rs-library.c

  • Committer: Bazaar Package Importer
  • Author(s): Bernd Zeimetz
  • Date: 2011-07-28 17:36:32 UTC
  • mfrom: (2.1.11 upstream)
  • Revision ID: james.westby@ubuntu.com-20110728173632-5czluz9ye3c83zc5
Tags: 2.0-1
* [3750b2cf] Merge commit 'upstream/2.0'
* [63637468] Removing Patch, not necessary anymore.
* [2fb580dc] Add new build-dependencies.
* [c57d953b] Run dh_autoreconf due to patches in configure.in
* [13febe39] Add patch to remove the libssl requirement.
* [5ae773fe] Replace libjpeg62-dev by libjpeg8-dev :)
* [1969d755] Don't build static libraries.
* [7cfe0a2e] Add a patch to fix the plugin directory path.
  As plugins are shared libraries, they need to go into /usr/lib,
  not into /usr/share.
  Thanks to Andrew McMillan
* [c1d0d9dd] Don't install .la files for all plugins and libraries.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * * Copyright (C) 2006-2011 Anders Brander <anders@brander.dk>, 
 
3
 * * Anders Kvist <akv@lnxbx.dk> and Klaus Post <klauspost@gmail.com>
 
4
 *
 
5
 * This program is free software; you can redistribute it and/or
 
6
 * modify it under the terms of the GNU General Public License
 
7
 * as published by the Free Software Foundation; either version 2
 
8
 * of the License, or (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 Free Software
 
17
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 
18
 */
 
19
 
 
20
/* Documentation:
 
21
 * http://www.sqlite.org/capi3ref.html
 
22
 */
 
23
 
 
24
/* Database layout:
 
25
 *
 
26
 * library 
 
27
 *   id
 
28
 *   filename
 
29
 *   identifier
 
30
 *
 
31
 * tags
 
32
 *   id
 
33
 *   tagname
 
34
 *
 
35
 * phototags
 
36
 *   photo
 
37
 *   tag
 
38
 *   autotag
 
39
 *
 
40
 * version
 
41
 *   version
 
42
 */
 
43
/*
 
44
#include <glib.h>
 
45
#include <stdio.h>
 
46
#include <stdlib.h>
 
47
#include <sqlite3.h>
 
48
#include <string.h>
 
49
#include "rawstudio.h"
 
50
#include "rs-metadata.h"
 
51
#include "rs-library.h"
 
52
#include "application.h"
 
53
*/
 
54
 
 
55
#include "rs-library.h"
 
56
#include "conf_interface.h"
 
57
#include "config.h"
 
58
#include "gettext.h"
 
59
#include <libxml/encoding.h>
 
60
#include <libxml/xmlwriter.h>
 
61
#include <sqlite3.h>
 
62
 
 
63
#define LIBRARY_VERSION 2
 
64
#define TAGS_XML_FILE "tags.xml"
 
65
#define MAX_SEARCH_RESULTS 1000
 
66
#include "rs-types.h"
 
67
 
 
68
struct _RSLibrary {
 
69
        GObject parent;
 
70
        gboolean dispose_has_run;
 
71
 
 
72
        sqlite3 *db;
 
73
        gchar *error_init;
 
74
 
 
75
        /* This mutex must be used when inserting data in a table with an
 
76
           autocrementing column - which is ALWAYS for sqlite */
 
77
        GMutex *id_lock;
 
78
};
 
79
 
 
80
G_DEFINE_TYPE(RSLibrary, rs_library, G_TYPE_OBJECT)
 
81
 
 
82
static gint library_execute_sql(sqlite3 *db, const gchar *sql);
 
83
static void library_sqlite_error(sqlite3 *db, const gint result);
 
84
static gint library_create_tables(sqlite3 *db);
 
85
static gint library_find_tag_id(RSLibrary *library, const gchar *tagname);
 
86
static gint library_find_photo_id(RSLibrary *library, const gchar *photo);
 
87
static void library_photo_add_tag(RSLibrary *library, const gint photo_id, const gint tag_id, const gboolean autotag);
 
88
static gboolean library_is_photo_tagged(RSLibrary *library, const gint photo_id, const gint tag_id);
 
89
static gint library_add_photo(RSLibrary *library, const gchar *filename);
 
90
static gint library_add_tag(RSLibrary *library, const gchar *tagname);
 
91
static void library_delete_photo(RSLibrary *library, const gint photo_id);
 
92
static void library_delete_tag(RSLibrary *library, const gint tag_id);
 
93
static void library_photo_delete_tags(RSLibrary *library, const gint photo_id);
 
94
static void library_tag_delete_photos(RSLibrary *library, const gint tag_id);
 
95
static gboolean library_tag_is_used(RSLibrary *library, const gint tag_id);
 
96
static void library_photo_default_tags(RSLibrary *library, const gint photo_id, RSMetadata *metadata);
 
97
 
 
98
static GtkWidget *tag_search_entry = NULL;
 
99
 
 
100
static void
 
101
rs_library_dispose(GObject *object)
 
102
{
 
103
        RSLibrary *library = RS_LIBRARY(object);
 
104
 
 
105
        if (!library->dispose_has_run)
 
106
        {
 
107
                library->dispose_has_run = TRUE;
 
108
 
 
109
                sqlite3_close(library->db);
 
110
 
 
111
                g_mutex_free(library->id_lock);
 
112
        }
 
113
 
 
114
        G_OBJECT_CLASS(rs_library_parent_class)->dispose (object);
 
115
}
 
116
 
 
117
static void
 
118
rs_library_finalize(GObject *object)
 
119
{
 
120
        G_OBJECT_CLASS(rs_library_parent_class)->finalize (object);
 
121
}
 
122
 
 
123
static void
 
124
rs_library_class_init(RSLibraryClass *klass)
 
125
{
 
126
        GObjectClass *object_class = G_OBJECT_CLASS(klass);
 
127
 
 
128
        sqlite3_config(SQLITE_CONFIG_SERIALIZED);
 
129
        object_class->dispose = rs_library_dispose;
 
130
        object_class->finalize = rs_library_finalize;
 
131
}
 
132
 
 
133
gboolean
 
134
rs_library_has_database_connection(RSLibrary *library)
 
135
{
 
136
  if (library_execute_sql(library->db, "PRAGMA user_version;") == 0)
 
137
    return TRUE;
 
138
  else
 
139
    return FALSE;
 
140
}
 
141
 
 
142
gchar *
 
143
rs_library_get_init_error_msg(RSLibrary *library)
 
144
{
 
145
  return g_strdup(library->error_init);
 
146
}
 
147
 
 
148
static gint
 
149
library_set_version(sqlite3 *db, gint version)
 
150
{
 
151
        sqlite3_stmt *stmt;
 
152
        gint rc;
 
153
 
 
154
        rc = sqlite3_prepare_v2(db, "update version set version = ?1;", -1, &stmt, NULL);
 
155
        rc = sqlite3_bind_int(stmt, 1, version);
 
156
        rc = sqlite3_step(stmt);
 
157
        library_sqlite_error(db, rc);
 
158
        sqlite3_finalize(stmt);
 
159
 
 
160
        return SQLITE_OK;
 
161
}
 
162
 
 
163
static void
 
164
library_check_version(sqlite3 *db)
 
165
{
 
166
        sqlite3_stmt *stmt, *stmt_update;
 
167
        gint rc, version = 0, id;
 
168
        gchar *filename;
 
169
 
 
170
        rc = sqlite3_prepare_v2(db, "SELECT version FROM version", -1, &stmt, NULL);
 
171
        rc = sqlite3_step(stmt);
 
172
        if (rc == SQLITE_ROW)
 
173
                version = sqlite3_column_int(stmt, 0);
 
174
        rc = sqlite3_finalize(stmt);
 
175
 
 
176
        while (version < LIBRARY_VERSION)
 
177
        {
 
178
                switch (version)
 
179
                {
 
180
                case 0:
 
181
                        /* Alter table library - add identifier column */
 
182
                        sqlite3_prepare_v2(db, "alter table library add column identifier varchar(32)", -1, &stmt, NULL);
 
183
                        rc = sqlite3_step(stmt);
 
184
                        library_sqlite_error(db, rc);
 
185
                        sqlite3_finalize(stmt);
 
186
 
 
187
                        /* Run through all photos in library and insert unique identifier in library */
 
188
                        gchar *identifier;
 
189
                        sqlite3_prepare_v2(db, "select filename from library", -1, &stmt, NULL);
 
190
                        while (sqlite3_step(stmt) == SQLITE_ROW)
 
191
                        {
 
192
                                filename = (gchar *) sqlite3_column_text(stmt, 0);
 
193
                                if (g_file_test(filename, G_FILE_TEST_EXISTS))
 
194
                                {
 
195
                                        identifier = rs_file_checksum(filename);
 
196
                                        rc = sqlite3_prepare_v2(db, "update library set identifier = ?1 WHERE filename = ?2;", -1, &stmt_update, NULL);
 
197
                                        rc = sqlite3_bind_text(stmt_update, 1, identifier, -1, SQLITE_TRANSIENT);
 
198
                                        rc = sqlite3_bind_text(stmt_update, 2, filename, -1, SQLITE_TRANSIENT);
 
199
                                        rc = sqlite3_step(stmt_update);
 
200
                                        library_sqlite_error(db, rc);
 
201
                                        sqlite3_finalize(stmt_update);
 
202
                                        g_free(identifier);
 
203
                                }
 
204
                        }
 
205
                        sqlite3_finalize(stmt);
 
206
 
 
207
                        library_set_version(db, version+1);
 
208
                        break;
 
209
 
 
210
                case 1:
 
211
                        library_execute_sql(db, "BEGIN TRANSACTION;");
 
212
                        sqlite3_prepare_v2(db, "select id,filename from library", -1, &stmt, NULL);
 
213
                        while (sqlite3_step(stmt) == SQLITE_ROW)
 
214
                        {
 
215
                                id = (gint) sqlite3_column_int(stmt, 0);
 
216
                                filename = rs_normalize_path((gchar *) sqlite3_column_text(stmt, 1));
 
217
                                if (filename) /* FIXME: This will only work for paths that exists */
 
218
                                {
 
219
                                        rc = sqlite3_prepare_v2(db, "update library set filename = ?1 WHERE id = ?2;", -1, &stmt_update, NULL);
 
220
                                        rc = sqlite3_bind_text(stmt_update, 1, filename, -1, SQLITE_TRANSIENT);
 
221
                                        rc = sqlite3_bind_int(stmt_update, 2, id);
 
222
                                        rc = sqlite3_step(stmt_update);
 
223
                                        library_sqlite_error(db, rc);
 
224
                                        sqlite3_finalize(stmt_update);
 
225
                                        g_free(filename);
 
226
                                }
 
227
                        }
 
228
                        sqlite3_finalize(stmt);
 
229
                        library_set_version(db, version+1);
 
230
                        library_execute_sql(db, "COMMIT;");
 
231
                        break;
 
232
 
 
233
                default:
 
234
                        /* We should never hit this */
 
235
                        g_debug("Some error occured in library_check_version() - please notify developers");
 
236
                        break;
 
237
                }
 
238
 
 
239
                version++;
 
240
                g_debug("Updated library database to version %d", version);
 
241
        }
 
242
}
 
243
 
 
244
static void
 
245
rs_library_init(RSLibrary *library)
 
246
{
 
247
        int rc;
 
248
 
 
249
        gchar *database = g_strdup_printf("%s/.rawstudio/library.db", g_get_home_dir());
 
250
 
 
251
        /* If unable to create database we exit */
 
252
        if(sqlite3_open(database, &(library->db)))
 
253
        {
 
254
                gchar *msg = g_strdup_printf(_("Could not open database %s"), database);
 
255
                g_debug("sqlite3 debug: %s\n", msg);
 
256
                if (library->error_init)
 
257
                  g_free(library->error_init);
 
258
                library->error_init = g_strdup(msg);
 
259
                sqlite3_close(library->db);
 
260
        }
 
261
        g_free(database);
 
262
 
 
263
        if (rs_library_has_database_connection(library))
 
264
        {
 
265
          /* This is not FULL synchronous mode as default, since all data is re-creatable by local xml files.
 
266
             From the sqlite3 manual:
 
267
             With synchronous OFF (0), SQLite continues without syncing as soon as it has handed data off to 
 
268
             the operating system. If the application running SQLite crashes, the data will be safe, but the 
 
269
             database might become corrupted if the operating system crashes or the computer loses power before 
 
270
             that data has been written to the disk surface. On the other hand, 
 
271
             some operations are as much as 50 or more times faster with synchronous OFF. " */
 
272
          library_execute_sql(library->db, "PRAGMA synchronous = OFF;");
 
273
 
 
274
          /* Move our journal to memory, we're not doing banking for the Mafia */
 
275
          library_execute_sql(library->db, "PRAGMA journal_mode = memory;");
 
276
 
 
277
          /* Place temp tables in memory */
 
278
          library_execute_sql(library->db, "PRAGMA temp_store = memory;");
 
279
 
 
280
          rc = library_create_tables(library->db);
 
281
          library_sqlite_error(library->db, rc);
 
282
 
 
283
          library_check_version(library->db);
 
284
 
 
285
          library->id_lock = g_mutex_new();
 
286
        }
 
287
}
 
288
 
 
289
RSLibrary *
 
290
rs_library_get_singleton(void)
 
291
{
 
292
        static GStaticMutex singleton_lock = G_STATIC_MUTEX_INIT;
 
293
        static RSLibrary *singleton = NULL;
 
294
 
 
295
        g_static_mutex_lock(&singleton_lock);
 
296
        if (!singleton)
 
297
                singleton = g_object_new(RS_TYPE_LIBRARY, NULL);
 
298
        g_static_mutex_unlock(&singleton_lock);
 
299
 
 
300
        return singleton;
 
301
}
 
302
 
 
303
static gint
 
304
library_execute_sql(sqlite3 *db, const gchar *sql)
 
305
{
 
306
        sqlite3_stmt *statement;
 
307
 
 
308
        if(SQLITE_OK != sqlite3_prepare(db, sql, -1, &statement, 0))
 
309
                return sqlite3_errcode(db);
 
310
 
 
311
        while (SQLITE_ROW == sqlite3_step(statement));
 
312
 
 
313
        return sqlite3_finalize(statement);
 
314
}
 
315
 
 
316
static void
 
317
library_sqlite_error(sqlite3 *db, gint result)
 
318
{
 
319
        if (result != SQLITE_OK && result != SQLITE_DONE)
 
320
        {
 
321
                g_warning("sqlite3 warning: %s\n", sqlite3_errmsg(db));
 
322
        }
 
323
}
 
324
 
 
325
static gint
 
326
library_create_tables(sqlite3 *db)
 
327
{
 
328
        sqlite3_stmt *stmt;
 
329
        gint rc;
 
330
       
 
331
        /* Create table (library) to hold all known photos */
 
332
        sqlite3_prepare_v2(db, "create table library (id integer primary key, filename varchar(1024), identifier varchar(32))", -1, &stmt, NULL);
 
333
        rc = sqlite3_step(stmt);
 
334
        sqlite3_finalize(stmt);
 
335
 
 
336
        /* Create table (tags) with all known tags */
 
337
        sqlite3_prepare_v2(db, "create table tags (id integer primary key, tagname varchar(128))", -1, &stmt, NULL);
 
338
        rc = sqlite3_step(stmt);
 
339
        sqlite3_finalize(stmt);
 
340
 
 
341
        /* Create table (phototags) to bind tags and photos together */
 
342
        sqlite3_prepare_v2(db, "create table phototags (photo integer, tag integer, autotag integer)", -1, &stmt, NULL);
 
343
        rc = sqlite3_step(stmt);
 
344
        sqlite3_finalize(stmt);
 
345
 
 
346
        /* Create table (version) to help keeping track of database version */
 
347
        sqlite3_prepare_v2(db, "create table version (version integer)", -1, &stmt, NULL);
 
348
        rc = sqlite3_step(stmt);
 
349
        sqlite3_finalize(stmt);
 
350
 
 
351
        rc = sqlite3_prepare_v2(db, "select * from version", -1, &stmt, NULL);
 
352
        rc = sqlite3_step(stmt);
 
353
        sqlite3_finalize(stmt);
 
354
        if (rc != SQLITE_ROW)
 
355
        {
 
356
                /* Set current version */
 
357
                rc = sqlite3_prepare_v2(db, "insert into version (version) values (?1);", -1, &stmt, NULL);
 
358
                rc = sqlite3_bind_int(stmt, 1, LIBRARY_VERSION);
 
359
                rc = sqlite3_step(stmt);
 
360
                sqlite3_finalize(stmt);
 
361
 
 
362
                rc = sqlite3_prepare_v2(db, "select identifier from library", -1, &stmt, NULL);
 
363
                rc = sqlite3_step(stmt);
 
364
                sqlite3_finalize(stmt);
 
365
 
 
366
                /* Check if library.identifier exists */
 
367
                if (rc == SQLITE_MISUSE)
 
368
                {
 
369
                        library_set_version(db, 0);
 
370
                }
 
371
        }
 
372
 
 
373
        return SQLITE_OK;
 
374
}
 
375
 
 
376
static gint
 
377
library_find_tag_id(RSLibrary *library, const gchar *tagname)
 
378
{
 
379
        sqlite3 *db = library->db;
 
380
        sqlite3_stmt *stmt;
 
381
        gint rc, tag_id = -1;
 
382
 
 
383
        rc = sqlite3_prepare_v2(db, "SELECT id FROM tags WHERE tagname = ?1;", -1, &stmt, NULL);
 
384
        rc = sqlite3_bind_text(stmt, 1, tagname, -1, SQLITE_TRANSIENT);
 
385
        rc = sqlite3_step(stmt);
 
386
        if (rc == SQLITE_ROW)
 
387
                tag_id = sqlite3_column_int(stmt, 0);
 
388
        rc = sqlite3_finalize(stmt);
 
389
        return tag_id;
 
390
}
 
391
 
 
392
static gint
 
393
library_find_photo_id(RSLibrary *library, const gchar *photo)
 
394
{
 
395
        sqlite3 *db = library->db;
 
396
        sqlite3_stmt *stmt;
 
397
        gint rc, photo_id = -1;
 
398
 
 
399
        rc = sqlite3_prepare_v2(db, "SELECT id FROM library WHERE filename = ?1;", -1, &stmt, NULL);
 
400
        rc = sqlite3_bind_text(stmt, 1, photo, -1, SQLITE_TRANSIENT);
 
401
        library_sqlite_error(db, rc);
 
402
        rc = sqlite3_step(stmt);
 
403
        if (rc == SQLITE_ROW)
 
404
                photo_id = sqlite3_column_int(stmt, 0);
 
405
        rc = sqlite3_finalize(stmt);
 
406
        return photo_id;
 
407
}
 
408
 
 
409
static void
 
410
library_photo_add_tag(RSLibrary *library, const gint photo_id, const gint tag_id, const gboolean autotag)
 
411
{
 
412
        sqlite3 *db = library->db;
 
413
        gint rc;
 
414
        sqlite3_stmt *stmt;
 
415
 
 
416
        gint autotag_tag = 0;
 
417
        if (autotag)
 
418
                autotag_tag = 1;
 
419
 
 
420
        g_mutex_lock(library->id_lock);
 
421
        rc = sqlite3_prepare_v2(db, "INSERT INTO phototags (photo, tag, autotag) VALUES (?1, ?2, ?3);", -1, &stmt, NULL);
 
422
        rc = sqlite3_bind_int (stmt, 1, photo_id);
 
423
        rc = sqlite3_bind_int (stmt, 2, tag_id);
 
424
        rc = sqlite3_bind_int (stmt, 3, autotag_tag);
 
425
        rc = sqlite3_step(stmt);
 
426
        g_mutex_unlock(library->id_lock);
 
427
        if (rc != SQLITE_DONE)
 
428
                library_sqlite_error(db, rc);
 
429
        sqlite3_finalize(stmt);
 
430
}
 
431
 
 
432
static gboolean
 
433
library_is_photo_tagged(RSLibrary *library, gint photo_id, gint tag_id)
 
434
{
 
435
        sqlite3 *db = library->db;
 
436
        gint rc;
 
437
        sqlite3_stmt *stmt;
 
438
 
 
439
        rc = sqlite3_prepare_v2(db, "SELECT * FROM phototags WHERE photo = ?1 AND tag = ?2;", -1, &stmt, NULL);
 
440
        rc = sqlite3_bind_int (stmt, 1, photo_id);
 
441
        rc = sqlite3_bind_int (stmt, 2, tag_id);
 
442
        rc = sqlite3_step(stmt);
 
443
        sqlite3_finalize(stmt);
 
444
 
 
445
        if (rc == SQLITE_ROW)
 
446
                return TRUE;
 
447
        else
 
448
                return FALSE;
 
449
}
 
450
 
 
451
static void
 
452
got_checksum(const gchar *checksum, gpointer user_data)
 
453
{
 
454
        RSLibrary *library = rs_library_get_singleton();
 
455
        sqlite3 *db = library->db;
 
456
        sqlite3_stmt *stmt;
 
457
 
 
458
        sqlite3_prepare_v2(db, "UPDATE LIBRARY SET  identifier=?1 WHERE id=?2;", -1, &stmt, NULL);
 
459
        sqlite3_bind_text(stmt, 1, checksum, -1, SQLITE_TRANSIENT);
 
460
        sqlite3_bind_int(stmt, 2, GPOINTER_TO_INT(user_data));
 
461
        sqlite3_step(stmt);
 
462
        sqlite3_finalize(stmt);
 
463
}
 
464
 
 
465
static gint
 
466
library_add_photo(RSLibrary *library, const gchar *filename)
 
467
{
 
468
        gint id;
 
469
        sqlite3 *db = library->db;
 
470
        gint rc;
 
471
        sqlite3_stmt *stmt;
 
472
 
 
473
        g_mutex_lock(library->id_lock);
 
474
        sqlite3_prepare_v2(db, "INSERT INTO library (filename) VALUES (?1);", -1, &stmt, NULL);
 
475
        rc = sqlite3_bind_text(stmt, 1, filename, -1, SQLITE_TRANSIENT);
 
476
        rc = sqlite3_step(stmt);
 
477
        id = sqlite3_last_insert_rowid(db);
 
478
        g_mutex_unlock(library->id_lock);
 
479
        if (rc != SQLITE_DONE)
 
480
                library_sqlite_error(db, rc);
 
481
        sqlite3_finalize(stmt);
 
482
 
 
483
        rs_io_idle_read_checksum(filename, -1, got_checksum, GINT_TO_POINTER(id));
 
484
 
 
485
        return id;
 
486
}
 
487
 
 
488
static gint
 
489
library_add_tag(RSLibrary *library, const gchar *tagname)
 
490
{
 
491
        gint id;
 
492
        sqlite3 *db = library->db;
 
493
        gint rc;
 
494
        sqlite3_stmt *stmt;
 
495
 
 
496
        g_mutex_lock(library->id_lock);
 
497
        sqlite3_prepare_v2(db, "INSERT INTO tags (tagname) VALUES (?1);", -1, &stmt, NULL);
 
498
        rc = sqlite3_bind_text(stmt, 1, tagname, -1, SQLITE_TRANSIENT);
 
499
        rc = sqlite3_step(stmt);
 
500
        id = sqlite3_last_insert_rowid(db);
 
501
        g_mutex_unlock(library->id_lock);
 
502
        if (rc != SQLITE_DONE)
 
503
                library_sqlite_error(db, rc);
 
504
        sqlite3_finalize(stmt);
 
505
 
 
506
        return id;
 
507
}
 
508
 
 
509
static void 
 
510
library_delete_photo(RSLibrary *library, gint photo_id)
 
511
{
 
512
        sqlite3 *db = library->db;
 
513
        sqlite3_stmt *stmt;
 
514
        gint rc;
 
515
 
 
516
        rc = sqlite3_prepare_v2(db, "DELETE FROM library WHERE id = ?1;", -1, &stmt, NULL);
 
517
        rc = sqlite3_bind_int(stmt, 1, photo_id);
 
518
        library_sqlite_error(db, rc);
 
519
        rc = sqlite3_step(stmt);
 
520
        if (rc != SQLITE_DONE)
 
521
                library_sqlite_error(db, rc);
 
522
        rc = sqlite3_finalize(stmt);
 
523
}
 
524
 
 
525
static void 
 
526
library_delete_tag(RSLibrary *library, gint tag_id)
 
527
{
 
528
        sqlite3 *db = library->db;
 
529
        sqlite3_stmt *stmt;
 
530
        gint rc;
 
531
 
 
532
        rc = sqlite3_prepare_v2(db, "DELETE FROM library WHERE filename = ?1;", -1, &stmt, NULL);
 
533
        rc = sqlite3_bind_int(stmt, 1, tag_id);
 
534
        library_sqlite_error(db, rc);
 
535
        rc = sqlite3_step(stmt);
 
536
        if (rc != SQLITE_DONE)
 
537
                library_sqlite_error(db, rc);
 
538
        rc = sqlite3_finalize(stmt);
 
539
}
 
540
 
 
541
static void 
 
542
library_photo_delete_tags(RSLibrary *library, gint photo_id)
 
543
{
 
544
        sqlite3 *db = library->db;
 
545
        sqlite3_stmt *stmt;
 
546
        gint rc;
 
547
 
 
548
        rc = sqlite3_prepare_v2(db, "DELETE FROM phototags WHERE photo = ?1;", -1, &stmt, NULL);
 
549
        rc = sqlite3_bind_int(stmt, 1, photo_id);
 
550
        library_sqlite_error(db, rc);
 
551
        rc = sqlite3_step(stmt);
 
552
        if (rc != SQLITE_DONE)
 
553
                library_sqlite_error(db, rc);
 
554
        rc = sqlite3_finalize(stmt);
 
555
}
 
556
 
 
557
static void
 
558
library_tag_delete_photos(RSLibrary *library, gint tag_id)
 
559
{
 
560
        sqlite3 *db = library->db;
 
561
        sqlite3_stmt *stmt;
 
562
        gint rc;
 
563
 
 
564
        rc = sqlite3_prepare_v2(db, "DELETE FROM phototags WHERE tag = ?1;", -1, &stmt, NULL);
 
565
        rc = sqlite3_bind_int(stmt, 1, tag_id);
 
566
        library_sqlite_error(db, rc);
 
567
        rc = sqlite3_step(stmt);
 
568
        if (rc != SQLITE_DONE)
 
569
                library_sqlite_error(db, rc);
 
570
        rc = sqlite3_finalize(stmt);
 
571
}
 
572
 
 
573
static gboolean
 
574
library_tag_is_used(RSLibrary *library, gint tag_id)
 
575
{
 
576
        sqlite3 *db = library->db;
 
577
        gint rc;
 
578
        sqlite3_stmt *stmt;
 
579
 
 
580
        rc = sqlite3_prepare_v2(db, "SELECT * FROM phototags WHERE tag = ?1;", -1, &stmt, NULL);
 
581
        rc = sqlite3_bind_int (stmt, 1, tag_id);
 
582
        rc = sqlite3_step(stmt);
 
583
        sqlite3_finalize(stmt);
 
584
 
 
585
        if (rc == SQLITE_ROW)
 
586
                return TRUE;
 
587
        else
 
588
                return FALSE;
 
589
}
 
590
 
 
591
gint
 
592
rs_library_add_photo(RSLibrary *library, const gchar *filename)
 
593
{
 
594
        gint photo_id;
 
595
 
 
596
        g_assert(RS_IS_LIBRARY(library));
 
597
        if (!rs_library_has_database_connection(library)) return 0; /* FIXME */
 
598
 
 
599
        photo_id = library_find_photo_id(library, filename);
 
600
        if (photo_id == -1)
 
601
        {
 
602
                g_debug("Adding photo to library: %s",filename);
 
603
                photo_id = library_add_photo(library, filename);
 
604
        }
 
605
 
 
606
        return photo_id;
 
607
}
 
608
 
 
609
gint
 
610
rs_library_add_tag(RSLibrary *library, const gchar *tagname)
 
611
{
 
612
        gint tag_id;
 
613
 
 
614
        g_assert(RS_IS_LIBRARY(library));
 
615
        if (!rs_library_has_database_connection(library)) return 0; /* FIXME */
 
616
 
 
617
        tag_id = library_find_tag_id(library, tagname);
 
618
        if (tag_id == -1)
 
619
        {
 
620
                g_debug("Adding tag to tags: %s",tagname);
 
621
                tag_id = library_add_tag(library, tagname);
 
622
        }
 
623
 
 
624
        return tag_id;
 
625
}
 
626
 
 
627
void
 
628
rs_library_photo_add_tag(RSLibrary *library, const gchar *filename, gint tag_id, const gboolean autotag)
 
629
{
 
630
        g_assert(RS_IS_LIBRARY(library));
 
631
        if (!rs_library_has_database_connection(library)) return;
 
632
 
 
633
        gint photo_id;
 
634
 
 
635
        if (tag_id == -1)
 
636
        {
 
637
                g_warning("Tag not known...");
 
638
                return;
 
639
        }
 
640
 
 
641
        photo_id = library_find_photo_id(library, filename);
 
642
        if (photo_id == -1)
 
643
        {
 
644
                g_warning("Photo not known...");
 
645
                return;
 
646
        }
 
647
 
 
648
        if (!library_is_photo_tagged(library, photo_id, tag_id))
 
649
                library_photo_add_tag(library, photo_id, tag_id, autotag);
 
650
 
 
651
        return;
 
652
}
 
653
 
 
654
void
 
655
rs_library_delete_photo(RSLibrary *library, const gchar *photo)
 
656
{
 
657
        g_assert(RS_IS_LIBRARY(library));
 
658
        if (!rs_library_has_database_connection(library)) return;
 
659
 
 
660
        gint photo_id = -1;
 
661
 
 
662
        photo_id = library_find_photo_id(library, photo);
 
663
        if (photo_id == -1)
 
664
        {
 
665
                g_warning("Photo not known...");
 
666
                return;
 
667
        }
 
668
 
 
669
        library_photo_delete_tags(library, photo_id);
 
670
        library_delete_photo(library, photo_id);
 
671
        rs_library_backup_tags(library, photo);
 
672
}
 
673
 
 
674
gboolean
 
675
rs_library_delete_tag(RSLibrary *library, const gchar *tag, const gboolean force)
 
676
{
 
677
        g_assert(RS_IS_LIBRARY(library));
 
678
        if (!rs_library_has_database_connection(library)) return FALSE;
 
679
 
 
680
        gint tag_id = -1;
 
681
 
 
682
        tag_id = library_find_tag_id(library, tag);
 
683
        if (tag_id == -1)
 
684
        {
 
685
                g_warning("Tag not known...");
 
686
                return FALSE;
 
687
        }
 
688
 
 
689
        if (library_tag_is_used(library, tag_id))
 
690
                if (force)
 
691
                {
 
692
                        library_tag_delete_photos(library, tag_id);
 
693
                        library_delete_tag(library, tag_id);
 
694
                }
 
695
                else
 
696
                {
 
697
                        g_warning("Tag is in use...");
 
698
                        return FALSE;
 
699
                }
 
700
        else
 
701
                library_delete_tag(library, tag_id);
 
702
        return TRUE;
 
703
}
 
704
 
 
705
GList *
 
706
rs_library_search(RSLibrary *library, GList *tags)
 
707
{
 
708
        g_assert(RS_IS_LIBRARY(library));
 
709
        if (!rs_library_has_database_connection(library)) return NULL;
 
710
 
 
711
        sqlite3_stmt *stmt;
 
712
        gint rc;
 
713
        sqlite3 *db = library->db;
 
714
        gchar *tag;
 
715
        gint n, num_tags = g_list_length(tags);
 
716
        GList *photos = NULL;
 
717
        GTimer *gt = g_timer_new();
 
718
        gchar *filename;
 
719
 
 
720
        sqlite3_prepare_v2(db, "create temp table filter (photo integer)", -1, &stmt, NULL);
 
721
        rc = sqlite3_step(stmt);
 
722
        sqlite3_finalize(stmt);
 
723
        library_sqlite_error(db, rc);
 
724
       
 
725
        for (n = 0; n < num_tags; n++)
 
726
        {
 
727
                tag = (gchar *) g_list_nth_data(tags, n);
 
728
 
 
729
                g_mutex_lock(library->id_lock);
 
730
                sqlite3_prepare_v2(db, "insert into filter select phototags.photo from phototags, tags where phototags.tag = tags.id and lower(tags.tagname) = lower(?1) ;", -1, &stmt, NULL);
 
731
                rc = sqlite3_bind_text(stmt, 1, tag, -1, SQLITE_TRANSIENT);
 
732
                rc = sqlite3_step(stmt);
 
733
                sqlite3_finalize(stmt);
 
734
                g_mutex_unlock(library->id_lock);
 
735
        }
 
736
 
 
737
        sqlite3_prepare_v2(db, "create temp table result (photo integer, count integer)", -1, &stmt, NULL);
 
738
        rc = sqlite3_step(stmt);
 
739
        sqlite3_finalize(stmt);
 
740
        library_sqlite_error(db, rc);
 
741
 
 
742
        g_mutex_lock(library->id_lock);
 
743
        sqlite3_prepare_v2(db, "insert into result select photo, count(photo) from filter group by photo;", -1, &stmt, NULL);
 
744
        rc = sqlite3_step(stmt);
 
745
        sqlite3_finalize(stmt);
 
746
        g_mutex_unlock(library->id_lock);
 
747
        library_sqlite_error(db, rc);
 
748
 
 
749
        sqlite3_prepare_v2(db, "select library.filename from library,result where library.id = result.photo and result.count = ?1 order by library.filename;", -1, &stmt, NULL);
 
750
        rc = sqlite3_bind_int(stmt, 1, num_tags);
 
751
 
 
752
        gint count = 0;
 
753
        while (sqlite3_step(stmt) == SQLITE_ROW && count < MAX_SEARCH_RESULTS)
 
754
        {
 
755
                filename = g_strdup((gchar *) sqlite3_column_text(stmt, 0));
 
756
                if (g_file_test(filename, G_FILE_TEST_EXISTS))
 
757
                {
 
758
                        photos = g_list_append(photos, filename);
 
759
                        count++;
 
760
                }
 
761
        }                                      
 
762
        sqlite3_finalize(stmt);
 
763
        library_sqlite_error(db, rc);
 
764
 
 
765
        /* Empty filter */
 
766
        sqlite3_prepare_v2(db, "delete from filter;", -1, &stmt, NULL);
 
767
        rc = sqlite3_step(stmt);
 
768
        sqlite3_finalize(stmt);
 
769
        library_sqlite_error(db, rc);
 
770
 
 
771
        /* Empty result */
 
772
        sqlite3_prepare_v2(db, "delete from result;", -1, &stmt, NULL);
 
773
        rc = sqlite3_step(stmt);
 
774
        sqlite3_finalize(stmt);
 
775
        library_sqlite_error(db, rc);
 
776
 
 
777
        g_debug("Search in library took %.03f seconds", g_timer_elapsed(gt, NULL));
 
778
        g_timer_destroy(gt);
 
779
 
 
780
        return photos;
 
781
}
 
782
 
 
783
static void
 
784
library_photo_default_tags(RSLibrary *library, const gint photo_id, RSMetadata *metadata)
 
785
{
 
786
        g_assert(RS_IS_LIBRARY(library));
 
787
 
 
788
        GList *tags = NULL;
 
789
 
 
790
        if (metadata->make_ascii)
 
791
        {
 
792
                GList *temp = rs_split_string(metadata->make_ascii, " ");
 
793
                tags = g_list_concat(tags, temp);
 
794
        }
 
795
        if (metadata->model_ascii)
 
796
        {
 
797
                GList *temp = rs_split_string(metadata->model_ascii, " ");
 
798
                tags = g_list_concat(tags, temp);
 
799
        }
 
800
        if (metadata->lens_min_focal != -1 && metadata->lens_max_focal != -1)
 
801
        {
 
802
                gchar *lens = NULL;
 
803
                if (metadata->lens_min_focal == metadata->lens_max_focal)
 
804
                        lens = g_strdup_printf("%dmm",(gint) metadata->lens_min_focal);
 
805
                else
 
806
                        lens = g_strdup_printf("%d-%dmm",(gint) metadata->lens_min_focal, (gint) metadata->lens_max_focal);
 
807
                tags = g_list_append(tags, g_strdup(lens));
 
808
                g_free(lens);
 
809
        }
 
810
        if (metadata->focallength > 0)
 
811
        {
 
812
                gchar *text = NULL;
 
813
                if (metadata->focallength < 50)
 
814
                  text = g_strdup(_("wideangle"));
 
815
                else
 
816
                  text = g_strdup(_("telephoto"));
 
817
                tags = g_list_append(tags, g_strdup(text));
 
818
                g_free(text);
 
819
        }
 
820
        if (metadata->timestamp != -1)
 
821
        {
 
822
                gchar *year = NULL;
 
823
                gchar *month = NULL;
 
824
                GDate *date = g_date_new();
 
825
                g_date_set_time_t(date, metadata->timestamp);
 
826
                year = g_strdup_printf("%d", g_date_get_year(date));
 
827
                gint m = g_date_get_month(date);
 
828
 
 
829
                switch (m)
 
830
                {
 
831
                case 1:
 
832
                        month = g_strdup(_("January")); /* FIXME: There may be a better way to do this */
 
833
                        break;
 
834
                case 2:
 
835
                        month = g_strdup(_("February"));
 
836
                        break;
 
837
                case 3:
 
838
                        month = g_strdup(_("March"));
 
839
                        break;
 
840
                case 4:
 
841
                        month = g_strdup(_("April"));
 
842
                        break;
 
843
                case 5:
 
844
                        month = g_strdup(_("May"));
 
845
                        break;
 
846
                case 6:
 
847
                        month = g_strdup(_("June"));
 
848
                        break;
 
849
                case 7:
 
850
                        month = g_strdup(_("July"));
 
851
                        break;
 
852
                case 8:
 
853
                        month = g_strdup(_("August"));
 
854
                        break;
 
855
                case 9:
 
856
                        month = g_strdup(_("September"));
 
857
                        break;
 
858
                case 10:
 
859
                        month = g_strdup(_("October"));
 
860
                        break;
 
861
                case 11:
 
862
                        month = g_strdup(_("November"));
 
863
                        break;
 
864
                case 12:
 
865
                        month = g_strdup(_("December"));
 
866
                        break;
 
867
                }
 
868
 
 
869
                tags = g_list_append(tags, g_strdup(year));
 
870
                tags = g_list_append(tags, g_strdup(month));
 
871
 
 
872
                g_date_free(date);
 
873
                g_free(year);
 
874
                g_free(month);
 
875
        }
 
876
 
 
877
        gint i, j;
 
878
        library_execute_sql(library->db, "BEGIN TRANSACTION;");
 
879
        gint *used_tags = g_malloc(g_list_length(tags) * sizeof(gint));
 
880
        for(i = 0; i < g_list_length(tags); i++)
 
881
        {
 
882
                gchar *tag = (gchar *) g_list_nth_data(tags, i);
 
883
                gint tag_id = rs_library_add_tag(library, tag);
 
884
 
 
885
                /* Check if tag has already been added */
 
886
                gboolean used = FALSE;
 
887
                for (j = 0; j < i; j++)
 
888
                        if (tag_id == used_tags[j])
 
889
                                used = TRUE;
 
890
 
 
891
                if (!used)
 
892
                        library_photo_add_tag(library, photo_id, tag_id, TRUE);
 
893
                used_tags[i] = tag_id;
 
894
                g_free(tag);
 
895
        }
 
896
        g_free(used_tags);
 
897
        library_execute_sql(library->db, "COMMIT;");
 
898
        g_list_free(tags);
 
899
}
 
900
 
 
901
GList *
 
902
rs_library_photo_tags(RSLibrary *library, const gchar *photo, const gboolean autotag)
 
903
{
 
904
        g_assert(RS_IS_LIBRARY(library));
 
905
        if (!rs_library_has_database_connection(library)) return NULL;
 
906
 
 
907
        sqlite3_stmt *stmt;
 
908
        gint rc;
 
909
        sqlite3 *db = library->db;
 
910
        GList *tags = NULL;
 
911
 
 
912
        if (autotag)
 
913
        {
 
914
                sqlite3_prepare_v2(db, "select tags.tagname from library,phototags,tags WHERE library.id=phototags.photo and phototags.tag=tags.id and library.filename = ?1;", -1, &stmt, NULL);
 
915
                rc = sqlite3_bind_text(stmt, 1, photo, -1, NULL);
 
916
        }
 
917
        else
 
918
        {
 
919
                sqlite3_prepare_v2(db, "select tags.tagname from library,phototags,tags WHERE library.id=phototags.photo and phototags.tag=tags.id and library.filename = ?1 and phototags.autotag = 0;", -1, &stmt, NULL);
 
920
                rc = sqlite3_bind_text(stmt, 1, photo, -1, NULL);
 
921
        }
 
922
        while (sqlite3_step(stmt) == SQLITE_ROW)
 
923
                tags = g_list_append(tags, g_strdup((gchar *) sqlite3_column_text(stmt, 0)));
 
924
        sqlite3_finalize(stmt);
 
925
        library_sqlite_error(db, rc);
 
926
 
 
927
        return tags;
 
928
}
 
929
 
 
930
GList *
 
931
rs_library_find_tag(RSLibrary *library, const gchar *tag)
 
932
{
 
933
        g_assert(RS_IS_LIBRARY(library));
 
934
        if (!rs_library_has_database_connection(library)) return NULL;
 
935
 
 
936
        sqlite3_stmt *stmt;
 
937
        gint rc;
 
938
        sqlite3 *db = library->db;
 
939
        GList *tags = NULL;
 
940
 
 
941
        rc = sqlite3_prepare_v2(db, "select tags.tagname from tags WHERE tags.tagname like ?1 order by tags.tagname;", -1, &stmt, NULL);
 
942
        gchar *like = g_strdup_printf("%%%s%%", tag);
 
943
        rc = sqlite3_bind_text(stmt, 1, like, -1, NULL);
 
944
        library_sqlite_error(db, rc);
 
945
        
 
946
        while (sqlite3_step(stmt) == SQLITE_ROW)
 
947
                tags = g_list_append(tags, g_strdup((gchar *) sqlite3_column_text(stmt, 0)));
 
948
        sqlite3_finalize(stmt);
 
949
        library_sqlite_error(db, rc);
 
950
 
 
951
        g_free(like);
 
952
 
 
953
        return tags;
 
954
}
 
955
 
 
956
 
 
957
gboolean
 
958
rs_library_set_tag_search(gchar *str)
 
959
{
 
960
        if (!str)
 
961
                return FALSE;
 
962
        gtk_entry_set_text(GTK_ENTRY(tag_search_entry), str);
 
963
        return TRUE;
 
964
}
 
965
 
 
966
void
 
967
rs_library_add_photo_with_metadata(RSLibrary *library, const gchar *photo, RSMetadata *metadata)
 
968
{
 
969
        if (!rs_library_has_database_connection(library)) return;
 
970
 
 
971
        /* Bail out if we already know the photo */
 
972
        if (library_find_photo_id(library, photo) > -1)
 
973
                return;
 
974
 
 
975
        gint photo_id = library_add_photo(library, photo);
 
976
        library_photo_default_tags(library, photo_id, metadata);
 
977
}
 
978
 
 
979
static GStaticMutex backup_lock = G_STATIC_MUTEX_INIT;
 
980
 
 
981
void 
 
982
rs_library_backup_tags(RSLibrary *library, const gchar *photo_filename)
 
983
{
 
984
        if (!rs_library_has_database_connection(library)) return;
 
985
 
 
986
        sqlite3 *db = library->db;
 
987
        sqlite3_stmt *stmt;
 
988
        gint rc;
 
989
        gchar *filename = NULL, *checksum, *tag, *t_filename;
 
990
        gint autotag;
 
991
        gchar *directory = g_path_get_dirname(photo_filename);
 
992
        gchar *dotdir = rs_dotdir_get(photo_filename);
 
993
 
 
994
        g_static_mutex_lock (&backup_lock);
 
995
 
 
996
        if (!dotdir)
 
997
                return;
 
998
        GString *gs = g_string_new(dotdir);
 
999
        g_string_append(gs, G_DIR_SEPARATOR_S);
 
1000
        g_string_append(gs, TAGS_XML_FILE);
 
1001
        gchar *xmlfile = gs->str;
 
1002
        g_string_free(gs, FALSE);
 
1003
 
 
1004
        xmlTextWriterPtr writer;
 
1005
 
 
1006
        writer = xmlNewTextWriterFilename(xmlfile, 0);
 
1007
        if (!writer)
 
1008
        {
 
1009
                g_free(directory);
 
1010
                g_free(dotdir);
 
1011
                g_free(xmlfile);
 
1012
                g_static_mutex_unlock (&backup_lock);   
 
1013
                return;
 
1014
        }
 
1015
 
 
1016
        xmlTextWriterSetIndent(writer, 1);
 
1017
        xmlTextWriterStartDocument(writer, NULL, "UTF-8", NULL);
 
1018
        xmlTextWriterStartElement(writer, BAD_CAST "rawstudio-tags");
 
1019
        xmlTextWriterWriteFormatAttribute(writer, BAD_CAST "version", "%d", LIBRARY_VERSION);
 
1020
 
 
1021
        const gchar *temp = g_strdup_printf("%s/%%", directory);
 
1022
        rc = sqlite3_prepare_v2(db, "select library.filename,library.identifier,tags.tagname,phototags.autotag from library,phototags,tags where library.filename like ?1 and phototags.photo = library.id and tags.id = phototags.tag order by library.filename;", -1, &stmt, NULL);
 
1023
        rc = sqlite3_bind_text(stmt, 1, temp, -1, SQLITE_TRANSIENT);
 
1024
        library_sqlite_error(db, rc);
 
1025
        while (sqlite3_step(stmt) == SQLITE_ROW)
 
1026
        {
 
1027
                t_filename = g_path_get_basename((gchar *) sqlite3_column_text(stmt, 0));
 
1028
                if (g_strcmp0(t_filename, filename) != 0 || filename == NULL)
 
1029
                {
 
1030
                        if (filename != NULL)
 
1031
                                xmlTextWriterEndElement(writer);
 
1032
                        filename = t_filename;
 
1033
                        xmlTextWriterStartElement(writer, BAD_CAST "file");
 
1034
                        xmlTextWriterWriteFormatAttribute(writer, BAD_CAST "name", "%s", filename);
 
1035
                        checksum = (gchar *) sqlite3_column_text(stmt, 1);
 
1036
                        xmlTextWriterWriteFormatAttribute(writer, BAD_CAST "checksum", "%s", checksum);
 
1037
                }
 
1038
 
 
1039
                tag = (gchar *) sqlite3_column_text(stmt, 2);
 
1040
                autotag = (gint) sqlite3_column_int(stmt, 3);
 
1041
                xmlTextWriterStartElement(writer, BAD_CAST "tag");
 
1042
                xmlTextWriterWriteFormatAttribute(writer, BAD_CAST "name", "%s", tag);
 
1043
                xmlTextWriterWriteFormatAttribute(writer, BAD_CAST "auto", "%d", autotag);
 
1044
                xmlTextWriterEndElement(writer);
 
1045
        }
 
1046
        xmlTextWriterEndElement(writer);
 
1047
 
 
1048
        rc = sqlite3_finalize(stmt);
 
1049
 
 
1050
        xmlTextWriterEndDocument(writer);
 
1051
        xmlFreeTextWriter(writer);
 
1052
        g_free(directory);
 
1053
        g_free(dotdir);
 
1054
        g_free(xmlfile);
 
1055
        g_static_mutex_unlock (&backup_lock);   
 
1056
        return;
 
1057
}
 
1058
 
 
1059
void 
 
1060
rs_library_restore_tags(const gchar *directory)
 
1061
{
 
1062
        RSLibrary *library = rs_library_get_singleton();
 
1063
 
 
1064
        if (!rs_library_has_database_connection(library)) return;
 
1065
 
 
1066
        gchar *dotdir = rs_dotdir_get(directory);
 
1067
 
 
1068
        if (!dotdir)
 
1069
                return;
 
1070
        GString *gs = g_string_new(dotdir);
 
1071
        g_string_append(gs, G_DIR_SEPARATOR_S);
 
1072
        g_string_append(gs, TAGS_XML_FILE);
 
1073
        gchar *xmlfile = gs->str;
 
1074
        g_string_free(gs, FALSE);
 
1075
 
 
1076
        if (!g_file_test(xmlfile, G_FILE_TEST_EXISTS))
 
1077
        {
 
1078
                g_free(dotdir);
 
1079
                g_free(xmlfile);
 
1080
                return;
 
1081
        }
 
1082
 
 
1083
        xmlDocPtr doc;
 
1084
        xmlNodePtr cur, cur2;
 
1085
        xmlChar *val;
 
1086
        gint version = 0;
 
1087
 
 
1088
        gchar *filename, *identifier, *tagname;
 
1089
        gint autotag, photoid, tagid;
 
1090
 
 
1091
        doc = xmlParseFile(xmlfile);
 
1092
        if (!doc)
 
1093
                return;
 
1094
 
 
1095
        cur = xmlDocGetRootElement(doc);
 
1096
 
 
1097
        if ((!xmlStrcmp(cur->name, BAD_CAST "rawstudio-tags")))
 
1098
        {
 
1099
                val = xmlGetProp(cur, BAD_CAST "version");
 
1100
                if (val)
 
1101
                        version = atoi((gchar *) val);
 
1102
                if (version > LIBRARY_VERSION)
 
1103
                {
 
1104
                        xmlFree(val);
 
1105
                        g_free(dotdir);
 
1106
                        g_free(xmlfile);
 
1107
                        xmlFreeDoc(doc);
 
1108
                        return;
 
1109
                }
 
1110
        }
 
1111
 
 
1112
        cur = cur->xmlChildrenNode;
 
1113
        while(cur)
 
1114
        {
 
1115
                if ((!xmlStrcmp(cur->name, BAD_CAST "file")))
 
1116
                {
 
1117
                        val = xmlGetProp(cur, BAD_CAST "name");
 
1118
                        filename = g_build_filename(directory, val, NULL);
 
1119
                        xmlFree(val);
 
1120
 
 
1121
                        photoid = library_find_photo_id(library, filename);
 
1122
                        if ( photoid == -1 && g_file_test(filename, G_FILE_TEST_EXISTS))
 
1123
                        {
 
1124
                                photoid = rs_library_add_photo(library, filename);
 
1125
 
 
1126
                                val = xmlGetProp(cur, BAD_CAST "checksum");
 
1127
                                identifier = (gchar *) val;
 
1128
 
 
1129
                                cur2 = cur->xmlChildrenNode;
 
1130
                                while(cur2)
 
1131
                                {
 
1132
                                        if ((!xmlStrcmp(cur2->name, BAD_CAST "tag")))
 
1133
                                        {
 
1134
                                                val = xmlGetProp(cur2, BAD_CAST "name");
 
1135
                                                tagname =(gchar*) val;
 
1136
                                                tagid = library_find_tag_id(library, tagname);
 
1137
                                                if ( tagid == -1)
 
1138
                                                        tagid = rs_library_add_tag(library, tagname);
 
1139
 
 
1140
                                                val = xmlGetProp(cur2, BAD_CAST "auto");
 
1141
                                                autotag = atoi((gchar *) val);
 
1142
                                                xmlFree(val);
 
1143
 
 
1144
                                                library_photo_add_tag(library, photoid, tagid, (autotag == 1));
 
1145
 
 
1146
                                                xmlFree(tagname);
 
1147
                                        }
 
1148
                                        cur2 = cur2->next;
 
1149
                                }
 
1150
                                xmlFree(identifier);
 
1151
                        }
 
1152
                        g_free(filename);
 
1153
                }
 
1154
                cur = cur->next;
 
1155
        }
 
1156
 
 
1157
        g_free(dotdir);
 
1158
        g_free(xmlfile);
 
1159
        xmlFreeDoc(doc);
 
1160
        return;
 
1161
}