/* ============================================================ * * This file is a part of digiKam project * http://www.digikam.org * * Date : 2004-07-09 * Description : a kio-slave to process tag query on * digiKam albums. * * Copyright (C) 2004 by Renchi Raju * * This program is free software; you can redistribute it * and/or modify it under the terms of the GNU General * Public License as published by the Free Software Foundation; * either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * ============================================================ */ // C Ansi includes. extern "C" { #include #include #include #include } // C++ includes. #include #include #include // TQt incudes. #include #include #include #include #include // KDE includes. #include #include #include #include #include #include #include #include // Local includes. #include "digikam_export.h" #include "digikamtags.h" kio_digikamtagsProtocol::kio_digikamtagsProtocol(const TQCString &pool_socket, const TQCString &app_socket) : SlaveBase("kio_digikamtags", pool_socket, app_socket) { } kio_digikamtagsProtocol::~kio_digikamtagsProtocol() { } static TQValueList makeFilterList( const TQString &filter ) { TQValueList regExps; if ( filter.isEmpty() ) return regExps; TQChar sep( ';' ); int i = filter.find( sep, 0 ); if ( i == -1 && filter.find( ' ', 0 ) != -1 ) sep = TQChar( ' ' ); TQStringList list = TQStringList::split( sep, filter ); TQStringList::Iterator it = list.begin(); while ( it != list.end() ) { regExps << TQRegExp( (*it).stripWhiteSpace(), false, true ); ++it; } return regExps; } static bool matchFilterList( const TQValueList& filters, const TQString &fileName ) { TQValueList::ConstIterator rit = filters.begin(); while ( rit != filters.end() ) { if ( (*rit).exactMatch(fileName) ) return true; ++rit; } return false; } void kio_digikamtagsProtocol::special(const TQByteArray& data) { bool folders = (metaData("folders") == "yes"); TQString libraryPath; KURL kurl; TQString url; TQString filter; int getDimensions; int tagID; int recurseAlbums; int recurseTags; TQDataStream ds(data, IO_ReadOnly); ds >> libraryPath; ds >> kurl; ds >> filter; ds >> getDimensions; ds >> recurseAlbums; ds >> recurseTags; url = kurl.path(); TQValueList regex = makeFilterList(filter); if (m_libraryPath != libraryPath) { m_libraryPath = libraryPath; m_db.closeDB(); m_db.openDB(libraryPath); } TQByteArray ba; if (folders) // Special mode to stats all tag items { TQMap tagsStatMap; int tagID, imageID; TQStringList values, allTagIDs; // initialize allTagIDs with all existing tags from db to prevent // wrong tag counters m_db.execSql(TQString("SELECT id from Tags"), &allTagIDs); for ( TQStringList::iterator it = allTagIDs.begin(); it != allTagIDs.end(); ++it) { tagID = (*it).toInt(); tagsStatMap.insert(tagID, 0); } // now we can count the tags assigned to images m_db.execSql(TQString("SELECT ImageTags.tagid, Images.name FROM ImageTags, Images " "WHERE ImageTags.imageid=Images.id"), &values); for ( TQStringList::iterator it = values.begin(); it != values.end(); ) { tagID = (*it).toInt(); ++it; if ( matchFilterList( regex, *it ) ) { TQMap::iterator it2 = tagsStatMap.find(tagID); if ( it2 == tagsStatMap.end() ) tagsStatMap.insert(tagID, 1); else tagsStatMap.replace(tagID, it2.data() + 1); } ++it; } TQDataStream os(ba, IO_WriteOnly); os << tagsStatMap; } else { tagID = TQStringList::split('/',url).last().toInt(); TQStringList values; if (recurseTags) { // Obtain all images with the given tag, or with this tag as a parent. m_db.execSql( TQString( "SELECT DISTINCT Images.id, Images.name, Images.dirid, \n " " Images.datetime, Albums.url \n " " FROM Images, Albums \n " " WHERE Images.id IN \n " " (SELECT imageid FROM ImageTags \n " " WHERE tagid=%1 \n " " OR tagid IN (SELECT id FROM TagsTree WHERE pid=%2)) \n " " AND Albums.id=Images.dirid \n " ) .arg(tagID) .arg(tagID), &values ); } else { // Obtain all images with the given tag m_db.execSql( TQString( "SELECT DISTINCT Images.id, Images.name, Images.dirid, \n " " Images.datetime, Albums.url \n " " FROM Images, Albums \n " " WHERE Images.id IN \n " " (SELECT imageid FROM ImageTags \n " " WHERE tagid=%1) \n " " AND Albums.id=Images.dirid \n " ) .arg(tagID), &values ); } TQ_LLONG imageid; TQString name; TQString path; int dirid; TQString date; TQString purl; TQSize dims; int count = 0; TQDataStream* os = new TQDataStream(ba, IO_WriteOnly); struct stat stbuf; for (TQStringList::iterator it = values.begin(); it != values.end();) { imageid = (*it).toLongLong(); ++it; name = *it; ++it; dirid = (*it).toInt(); ++it; date = *it; ++it; purl = *it; ++it; if (!matchFilterList(regex, name)) continue; path = m_libraryPath + purl + '/' + name; if (::stat(TQFile::encodeName(path), &stbuf) != 0) continue; dims = TQSize(); if (getDimensions) { KFileMetaInfo metaInfo(path); if (metaInfo.isValid()) { if (metaInfo.containsGroup("Jpeg EXIF Data")) { dims = metaInfo.group("Jpeg EXIF Data"). item("Dimensions").value().toSize(); } else if (metaInfo.containsGroup("General")) { dims = metaInfo.group("General"). item("Dimensions").value().toSize(); } else if (metaInfo.containsGroup("Technical")) { dims = metaInfo.group("Technical"). item("Dimensions").value().toSize(); } } } *os << imageid; *os << dirid; *os << name; *os << date; *os << static_cast(stbuf.st_size); *os << dims; count++; if (count > 200) { delete os; os = 0; SlaveBase::data(ba); ba.resize(0); count = 0; os = new TQDataStream(ba, IO_WriteOnly); } } delete os; } SlaveBase::data(ba); finished(); } /* KIO slave registration */ extern "C" { DIGIKAM_EXPORT int kdemain(int argc, char **argv) { KLocale::setMainCatalogue("digikam"); TDEInstance instance( "kio_digikamtags" ); ( void ) TDEGlobal::locale(); kdDebug() << "*** kio_digikamtag started ***" << endl; if (argc != 4) { kdDebug() << "Usage: kio_digikamtags protocol domain-socket1 domain-socket2" << endl; exit(-1); } kio_digikamtagsProtocol slave(argv[2], argv[3]); slave.dispatchLoop(); kdDebug() << "*** kio_digikamtags finished ***" << endl; return 0; } }