You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
326 lines
9.0 KiB
326 lines
9.0 KiB
/* ============================================================
|
|
*
|
|
* 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 <renchi@pooh.tam.uiuc.edu>
|
|
*
|
|
* 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 <unistd.h>
|
|
#include <sys/stat.h>
|
|
#include <sys/types.h>
|
|
#include <sys/time.h>
|
|
}
|
|
|
|
// C++ includes.
|
|
|
|
#include <cstdlib>
|
|
#include <cstdio>
|
|
#include <ctime>
|
|
|
|
// TQt incudes.
|
|
|
|
#include <tqfile.h>
|
|
#include <tqfileinfo.h>
|
|
#include <tqstring.h>
|
|
#include <tqdir.h>
|
|
#include <tqregexp.h>
|
|
|
|
// KDE includes.
|
|
|
|
#include <kinstance.h>
|
|
#include <kdebug.h>
|
|
#include <kurl.h>
|
|
#include <klocale.h>
|
|
#include <kglobal.h>
|
|
#include <kstandarddirs.h>
|
|
#include <tdeio/global.h>
|
|
#include <tdefilemetainfo.h>
|
|
|
|
// 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<TQRegExp> makeFilterList( const TQString &filter )
|
|
{
|
|
TQValueList<TQRegExp> 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<TQRegExp>& filters,
|
|
const TQString &fileName )
|
|
{
|
|
TQValueList<TQRegExp>::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<TQRegExp> 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<int, int> 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<int, int>::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<size_t>(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;
|
|
}
|
|
}
|
|
|