1
/* ============================================================
2
* Author: Renchi Raju <renchi@pooh.tam.uiuc.edu>
6
* Copyright 2004 by Renchi Raju
8
* This program is free software; you can redistribute it
9
* and/or modify it under the terms of the GNU General
10
* Public License as published by the Free Software Foundation;
11
* either version 2, or (at your option)
14
* This program is distributed in the hope that it will be useful,
15
* but WITHOUT ANY WARRANTY; without even the implied warranty of
16
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
* GNU General Public License for more details.
19
* ============================================================ */
21
#include <kinstance.h>
27
#include <kstandarddirs.h>
28
#include <kio/global.h>
31
#include <qfileinfo.h>
43
#include <sys/types.h>
49
#include "digikamtags.h"
51
kio_digikamtagsProtocol::kio_digikamtagsProtocol(const QCString &pool_socket,
52
const QCString &app_socket)
53
: SlaveBase("kio_digikamtags", pool_socket, app_socket)
58
KConfig config("digikamrc");
59
config.setGroup("Album Settings");
60
m_libraryPath = config.readPathEntry("Album Path", QString::null);
61
if (m_libraryPath.isEmpty() || !QFileInfo(m_libraryPath).exists())
63
error(KIO::ERR_UNKNOWN, i18n("Digikam library path not set correctly."));
67
QString dbPath = m_libraryPath + "/digikam.db";
71
dbPath = QDir::homeDirPath() + "/.kde/share/apps/digikam/" +
72
KIO::encodeFileName(QDir::cleanDirPath(dbPath));
76
m_db = sqlite_open(QFile::encodeName(dbPath), 0, &errMsg);
79
error(KIO::ERR_UNKNOWN, i18n("Failed to open Digikam database."));
87
kio_digikamtagsProtocol::~kio_digikamtagsProtocol()
95
void kio_digikamtagsProtocol::stat(const KURL& url)
97
if (url.equals(KURL("digikamtags:/")))
103
// TODO: provide some protection here against rogue apps
108
void kio_digikamtagsProtocol::statRoot()
113
atom.m_uds = KIO::UDS_NAME;
117
atom.m_uds = KIO::UDS_FILE_TYPE;
118
atom.m_long = S_IFDIR;
121
atom.m_uds = KIO::UDS_ACCESS;
122
atom.m_long = S_IRUSR | S_IRGRP | S_IROTH |
123
S_IWUSR | S_IWGRP | S_IWOTH;
131
void kio_digikamtagsProtocol::statTag(const KURL &url)
136
atom.m_uds = KIO::UDS_NAME;
137
atom.m_str = url.fileName();
140
atom.m_uds = KIO::UDS_FILE_TYPE;
141
atom.m_long = S_IFDIR;
144
atom.m_uds = KIO::UDS_ACCESS;
145
atom.m_long = S_IRUSR | S_IRGRP | S_IROTH |
146
S_IWUSR | S_IWGRP | S_IWOTH;
153
void kio_digikamtagsProtocol::listDir(const KURL& url)
155
kdDebug() << k_funcinfo << url.url() << endl;
157
if (QDir::cleanDirPath(url.path()) == "/")
159
kdDebug() << "Listing root " << url.url() << endl;
163
execSql( QString("SELECT id, name "
164
"FROM Tags where pid=0 ORDER by name;"),
172
for (QStringList::iterator it = values.begin(); it != values.end(); )
174
id = (*it++).toInt();
180
atom.m_uds = KIO::UDS_NAME;
184
atom.m_uds = KIO::UDS_FILE_TYPE;
185
atom.m_long = S_IFDIR;
188
atom.m_uds = KIO::UDS_ACCESS;
189
atom.m_long = S_IRUSR | S_IRGRP | S_IROTH |
190
S_IWUSR | S_IWGRP | S_IWOTH;
193
atom.m_uds = KIO::UDS_URL;
194
xurl.setProtocol("digikamtags");
195
xurl.setPath(QString("/%1").arg(id));
196
atom.m_str = xurl.url();
199
listEntry(entry, false);
202
else if (url.protocol() == "digikamtags")
204
kdDebug() << "Listing child " << url.url() << endl;
206
int id = url.fileName().toInt();
210
listEntry(entry, true);
215
// list directories first
218
execSql( QString("SELECT id, name "
219
"FROM Tags where pid=%1 ORDER by name;")
220
.arg(QString::number(id)),
230
for (QStringList::iterator it = values.begin(); it != values.end(); )
232
childid = (*it++).toInt();
237
atom.m_uds = KIO::UDS_NAME;
241
atom.m_uds = KIO::UDS_FILE_TYPE;
242
atom.m_long = S_IFDIR;
245
atom.m_uds = KIO::UDS_ACCESS;
246
atom.m_long = S_IRUSR | S_IRGRP | S_IROTH |
247
S_IWUSR | S_IWGRP | S_IWOTH;
250
atom.m_uds = KIO::UDS_URL;
251
xurl.setProtocol("digikamtags");
252
xurl.setPath(url.path(1) + QString::number(childid));
253
atom.m_str = xurl.url();
256
listEntry(entry, false);
259
// if host app told us to recursively get items from
261
bool recurse = false;
262
if (url.queryItem("recurse") == "yes")
269
listDir(url, id, recurse);
276
listEntry(entry, true);
281
void kio_digikamtagsProtocol::listDir(const KURL& url, int tagid, bool recurse)
285
static const QString sqlStr = "SELECT dirid, name "
290
execSql( sqlStr.arg(tagid), &values );
300
for (QStringList::iterator it = values.begin(); it != values.end(); )
302
dirid = (*(it++)).toInt();
304
path = QDir::cleanDirPath( m_libraryPath + QString("/") +
305
m_albumMap[dirid] + "/" + name );
307
// check if this item is already between listed to avoid duplicate items
308
// (this problem arises when you have same item under different subtags)
309
if (std::binary_search(m_items.begin(), m_items.end(), path))
313
m_items.push_back(path);
316
if (::stat(QFile::encodeName(path), &st) != 0)
321
atom.m_uds = KIO::UDS_FILE_TYPE;
322
atom.m_long = S_IFREG;
325
atom.m_uds = KIO::UDS_ACCESS;
326
atom.m_long = st.st_mode & 07777;
329
atom.m_uds = KIO::UDS_SIZE;
330
atom.m_long = st.st_size;
331
entry.append( atom );
333
atom.m_uds = KIO::UDS_MODIFICATION_TIME;
334
atom.m_long = st.st_mtime;
335
entry.append( atom );
337
atom.m_uds = KIO::UDS_ACCESS_TIME;
338
atom.m_long = st.st_atime;
339
entry.append( atom );
341
atom.m_uds = KIO::UDS_URL;
342
xurl.setProtocol("file");
344
atom.m_str = xurl.url();
347
atom.m_uds = KIO::UDS_NAME;
348
atom.m_str = xurl.fileName();
349
entry.append( atom );
351
// TODO: for now we pass the dirid for this item
352
// as the xml_properties. once kde 3.2 becomes a
353
// requirement for kde, change this to UDS_EXTRA
354
atom.m_uds = KIO::UDS_XML_PROPERTIES;
355
atom.m_str = QString::number(dirid);
356
entry.append( atom );
358
listEntry(entry, false);
366
// recursively list files in subtags
368
execSql( QString("SELECT id, name FROM Tags where pid=%1;")
369
.arg(QString::number(tagid)),
372
if (values.isEmpty())
376
for (QStringList::iterator it = values.begin(); it != values.end(); )
378
childid = (*it++).toInt();
380
xurl.setProtocol("digikamtags");
381
xurl.setPath(url.path(1) + (*it++));
382
listDir(xurl, childid, recurse);
386
void kio_digikamtagsProtocol::buildAlbumMap()
390
static const QString sqlStr = "SELECT id, url FROM Albums;";
393
execSql(sqlStr, &values);
397
for (QStringList::iterator it = values.begin(); it != values.end(); )
399
id = (*it++).toInt();
401
m_albumMap.insert(id, url);
405
bool kio_digikamtagsProtocol::execSql(const QString& sql,
406
QStringList* const values,
410
kdDebug() << "SQL-query: " << sql << endl;
413
kdWarning() << k_funcinfo << "SQLite pointer == NULL"
423
//compile SQL program to virtual machine
424
error = sqlite_compile( m_db, sql.local8Bit(), &tail, &vm, &errorStr );
426
if ( error != SQLITE_OK ) {
427
kdWarning() << k_funcinfo << "sqlite_compile error: "
429
<< " on query: " << sql << endl;
430
sqlite_freemem( errorStr );
436
const char** colName;
437
//execute virtual machine by iterating over rows
439
error = sqlite_step( vm, &number, &value, &colName );
440
if ( error == SQLITE_DONE || error == SQLITE_ERROR )
442
//iterate over columns
443
for ( int i = 0; values && i < number; i++ ) {
444
*values << QString::fromLocal8Bit( value [i] );
448
//deallocate vm resources
449
sqlite_finalize( vm, &errorStr );
451
if ( error != SQLITE_DONE ) {
452
kdWarning() << k_funcinfo << "sqlite_step error: "
454
<< " on query: " << sql << endl;
461
/* KIO slave registration */
465
int kdemain(int argc, char **argv)
467
KLocale::setMainCatalogue("digikam");
468
KInstance instance( "kio_digikamtags" );
469
( void ) KGlobal::locale();
471
kdDebug() << "*** kio_digikamtag started ***" << endl;
474
kdDebug() << "Usage: kio_digikamtags protocol domain-socket1 domain-socket2"
479
kio_digikamtagsProtocol slave(argv[2], argv[3]);
480
slave.dispatchLoop();
482
kdDebug() << "*** kio_digikamtags finished ***" << endl;