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.
digikam/digikam/tdeioslave/digikamdates.cpp

314 lines
8.6 KiB

/* ============================================================
*
* This file is a part of digiKam project
* http://www.digikam.org
*
* Date : 2005-04-21
* Description : a kio-slave to process date query on
* digiKam albums.
*
* Copyright (C) 2005 by Renchi Raju <renchi@pooh.tam.uiuc.edu>
* Copyright (C) 2006-2008 by Gilles Caulier <caulier dot gilles at gmail dot com>
*
* 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 includes.
#include <tqfile.h>
#include <tqdatastream.h>
#include <tqregexp.h>
#include <tqbuffer.h>
// KDE includes.
#include <tdeio/global.h>
#include <kglobal.h>
#include <klocale.h>
#include <kinstance.h>
#include <tdefilemetainfo.h>
#include <kdebug.h>
// Local includes.
#include "digikam_export.h"
#include "digikamdates.h"
kio_digikamdates::kio_digikamdates(const TQCString &pool_socket,
const TQCString &app_socket)
: SlaveBase("kio_digikamdates", pool_socket, app_socket)
{
}
kio_digikamdates::~kio_digikamdates()
{
}
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_digikamdates::special(const TQByteArray& data)
{
bool folders = (metaData("folders") == "yes");
TQString libraryPath;
KURL kurl;
TQString url;
TQString filter;
int getDimensions;
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 dates from collection
{
TQMap<TQDateTime, int> datesStatMap;
TQStringList values;
TQString name, dateStr;
TQDateTime dateTime;
m_db.execSql( "SELECT name, datetime FROM Images;", &values );
for ( TQStringList::iterator it = values.begin(); it != values.end(); )
{
name = *it;
++it;
dateStr = *it;
++it;
if ( !matchFilterList( regex, name ) )
continue;
dateTime = TQDateTime::fromString( dateStr, Qt::ISODate );
if ( !dateTime.isValid() )
continue;
TQMap<TQDateTime, int>::iterator it2 = datesStatMap.find(dateTime);
if ( it2 == datesStatMap.end() )
{
datesStatMap.insert( dateTime, 1 );
}
else
{
datesStatMap.replace( dateTime, it2.data() + 1 );
}
}
TQDataStream os(ba, IO_WriteOnly);
os << datesStatMap;
}
else
{
TQStringList subpaths = TQStringList::split("/", url, false);
if (subpaths.count() == 4)
{
int yrStart = TQString(subpaths[0]).toInt();
int moStart = TQString(subpaths[1]).toInt();
int yrEnd = TQString(subpaths[2]).toInt();
int moEnd = TQString(subpaths[3]).toInt();
TQString moStartStr, moEndStr;
moStartStr.sprintf("%.2d", moStart);
moEndStr.sprintf("%.2d", moEnd);
TQStringList values;
m_db.execSql(TQString("SELECT Images.id, Images.name, Images.dirid, \n "
" Images.datetime, Albums.url \n "
"FROM Images, Albums \n "
"WHERE Images.datetime < '%1-%2-01' \n "
"AND Images.datetime >= '%3-%4-01' \n "
"AND Albums.id=Images.dirid \n "
"ORDER BY Albums.id;")
.arg(yrEnd, 4)
.arg(moEndStr, 2)
.arg(yrStart, 4)
.arg(moStartStr, 2),
&values, false);
TQ_LLONG imageid;
TQString name;
TQString path;
int dirid;
TQString date;
TQString purl;
TQSize dims;
struct stat stbuf;
int count = 0;
TQDataStream* os = new TQDataStream(ba, IO_WriteOnly);
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_digikamdates" );
TDEGlobal::locale();
if (argc != 4) {
kdDebug() << "Usage: kio_digikamdates protocol domain-socket1 domain-socket2"
<< endl;
exit(-1);
}
kio_digikamdates slave(argv[2], argv[3]);
slave.dispatchLoop();
return 0;
}
}