00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 # include <Magick++.h>
00025 # include <QBuffer>
00026 # include <QBuffer>
00027 # include <QDir>
00028 # include <QImage>
00029 # include <QImageReader>
00030 # include <QSqlDatabase>
00031 # include <QSqlError>
00032 # include <QSqlQuery>
00033 # include "dbPhotoService.h"
00034
00035
00036 using namespace Magick;
00037
00038
00039 static QHash<QString, Image> photoCache;
00040 static QHash<QString, Image> photoResizeCache;
00041 static int maxPhotos = 250;
00042 static int maxResizePhotos = 1000;
00043 static QList<QString> photoList;
00044 static QList<QString> photoResizeList;
00045 static QMutex photoLock;
00046 static QMutex dbLock;
00047
00048 extern FILE *logfp;
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069 void DbPhotoService::setMaxCache(int n)
00070 {
00071 maxPhotos = n;
00072 maxResizePhotos = n * 5;
00073 }
00074
00075
00076
00077
00078
00079
00080
00081
00082 void DbPhotoService::clearLocks()
00083 {
00084 fprintf(logfp, "DbPhotoService::clearLocks(%s): Enter, unlocking db and photo locks\n", qPrintable(QString::number(currentThreadId())));
00085 fflush(logfp);
00086 # if 0
00087 if ( dbLock.isLocked() )
00088 dbLock.unlock();
00089 if ( photoLock.isLocked() )
00090 photoLock.unlock();
00091 # endif
00092 fprintf(logfp, "DbPhotoService::clearLocks(%s): Exit\n", qPrintable(QString::number(currentThreadId())));
00093 fflush(logfp);
00094 }
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105 void DbPhotoService::processRequest(QMap<QString, QVariant> *req, QMap<QString, QVariant> *rsp)
00106 {
00107 int t_height, t_width;
00108
00109 fprintf(logfp, "DbPhotoService::processRequest(%s): Enter\n", qPrintable(QString::number(currentThreadId())));
00110 fflush(logfp);
00111
00112 QMapIterator<QString, QVariant> i(*req);
00113 while (i.hasNext())
00114 {
00115 i.next();
00116 fprintf(logfp, "DbPhotoService::processRequest(%s): req: |%s| = |%s|\n", qPrintable(QString::number(currentThreadId())), qPrintable(i.key()), qPrintable(i.value().toString()));
00117 fflush(logfp);
00118 }
00119
00120
00121
00122
00123
00124
00125 QString method = req->value("Method").toString();
00126 QString resource = req->value("Resource").toString();
00127 QString args = req->value("Arguments").toString();
00128 QString host = req->value("Host").toString();
00129
00130
00131
00132
00133
00134 QMap<QString, QString> arguments = parseArguments(args);
00135
00136 QString fileType;
00137 QString fileBase;
00138
00139
00140
00141
00142 if ( method == "GET" )
00143 {
00144 QRegExp re("(.*)\\.(jpg|png|jpeg|ppm|xpm|xbm|bmp|htm|html|pl)");
00145 re.setCaseSensitive(false);
00146 re.setMinimal(true);
00147 if ( re.indexIn(resource) >= 0 )
00148 {
00149 fprintf(logfp, "DbPhotoService::processRequest(%s): Found name and extension\n", qPrintable(QString::number(currentThreadId())));
00150 fflush(logfp);
00151 fileType = re.cap(2).toLower();
00152 fileBase = re.cap(1);
00153 fileBase.remove(QRegExp("^/"));
00154 }
00155 else
00156 {
00157 fprintf(logfp, "DbPhotoService::processRequest(%s): Error in resource, exiting\n", qPrintable(QString::number(currentThreadId())));
00158 fflush(logfp);
00159 errorResponse(QcjHttpService::NotFound, "Requested resource not found");
00160 return;
00161 }
00162
00163
00164
00165
00166
00167
00168
00169 if ( fileType == "pl" )
00170 {
00171 fprintf(logfp, "DbPhotoService::processRequest(%s): have %s file type!\n", qPrintable(QString::number(currentThreadId())), qPrintable(fileType));
00172 fflush(logfp);
00173 if ( fileBase.toLower() == "import" )
00174 {
00175 fprintf(logfp, "DbPhotoService::processRequest(%s): request for import\n", qPrintable(QString::number(currentThreadId())));
00176 fflush(logfp);
00177 int count = 0;
00178 QString dir;
00179 QString sfilters;
00180 if ( arguments.contains("filters") )
00181 sfilters = arguments.value("filters");
00182 if ( arguments.contains("dir") )
00183 {
00184 dir = arguments.value("dir");
00185 fprintf(logfp, "DbPhotoService::processRequest(%s): Looking in directory |%s| for files\n", qPrintable(QString::number(currentThreadId())), qPrintable(dir));
00186 fflush(logfp);
00187 QDir dn(dir);
00188 if ( dn.exists() )
00189 {
00190 fprintf(logfp, "DbPhotoService::processRequest(%s): Getting filenames using filter of: |%s|\n", qPrintable(QString::number(currentThreadId())), qPrintable(sfilters));
00191 fflush(logfp);
00192
00193
00194 dbLock.lock();
00195 db = getServerParms(host);
00196 dbLock.unlock();
00197
00198 QMutexLocker lock(&photoLock);
00199 QStringList filters = sfilters.split(",");
00200 QStringList files = dn.entryList(filters, QDir::Files|QDir::Readable);
00201 QStringList::Iterator it = files.begin();
00202 while( it != files.end() ) {
00203 fprintf(logfp, "DbPhotoService::processRequest(%s): Have name: |%s|\n", qPrintable(QString::number(currentThreadId())), qPrintable(*it));
00204 QFileInfo fi(*it);
00205 QString fn = dn.absoluteFilePath(fi.fileName());
00206 QImage img;
00207 fprintf(logfp, "DbPhotoService::processRequest(%s): Reading image |%s|\n", qPrintable(QString::number(currentThreadId())), qPrintable(fn));
00208 if ( img.load(fn) )
00209 {
00210 QByteArray ba;
00211 QBuffer buffer(&ba);
00212 buffer.open(QIODevice::WriteOnly);
00213 fprintf(logfp, "DbPhotoService::processRequest(%s): Converting image to PNG\n", qPrintable(QString::number(currentThreadId())));
00214 img.save(&buffer, "PNG");
00215 buffer.close();
00216
00217 dbLock.lock();
00218 QSqlQuery q;
00219 QString sql = "insert into " + photoTable + " (fn, pic) values (:fn, :pic)";
00220 q.prepare(sql);
00221 q.bindValue(":pic", QVariant(ba));
00222 q.bindValue(":fn", QVariant(fn));
00223 fprintf(logfp, "DbPhotoService::processRequest(%s): Inserting picture into database using |%s|\n", qPrintable(QString::number(currentThreadId())), qPrintable(sql));
00224 if (! q.exec())
00225 {
00226 fprintf(logfp, "DbPhotoService::processRequest(%s): Error inserting picture: %s - %s\n", qPrintable(QString::number(currentThreadId())),
00227 qPrintable(q.lastError().driverText()),
00228 qPrintable(q.lastError().databaseText()));
00229 fprintf(logfp, "DbPhotoService::processRequest(%s): Query was |%s|\n", qPrintable(QString::number(currentThreadId())), qPrintable(q.executedQuery()));
00230 }
00231
00232 QStringList textKeys = img.textKeys();
00233 QStringListIterator keys(textKeys);
00234 fprintf(logfp, "DbPhotoService::processRequest(%s): Have %d text values\n", qPrintable(QString::number(currentThreadId())), textKeys.count());
00235 while (keys.hasNext())
00236 {
00237 QString name = keys.next();
00238 QString val = img.text(name);
00239 fprintf(logfp, "DbPhotoService::processRequest(%s): Have key: |%s|, value: |%s|\n", qPrintable(QString::number(currentThreadId())), qPrintable(name), qPrintable(val));
00240 q.prepare("insert into " + photoTable + "_text (photo, name, val) values (:fn, :name, :val)");
00241 q.bindValue(":fn", QVariant(fn));
00242 q.bindValue(":name", QVariant(name));
00243 q.bindValue(":val", QVariant(val));
00244 if (! q.exec())
00245 {
00246 fprintf(logfp, "DbPhotoService::processRequest(%s): Error inserting image: %s - %s", qPrintable(QString::number(currentThreadId())),
00247 qPrintable(q.lastError().driverText()),
00248 qPrintable(q.lastError().databaseText()));
00249 }
00250 }
00251 dbLock.unlock();
00252 }
00253 else
00254 {
00255 fprintf(logfp, "DbPhotoService::processRequest(%s): error reading picture\n", qPrintable(QString::number(currentThreadId())));
00256 }
00257 count++;
00258 fprintf(logfp, "DbPhotoService::processRequest(%s): Moving to next picture\n", qPrintable(QString::number(currentThreadId())));
00259 ++it;
00260 }
00261 }
00262 }
00263 else
00264 {
00265 fprintf(logfp, "DbPhotoService::processRequest(%s): Error in request, exiting\n", qPrintable(QString::number(currentThreadId())));
00266 fflush(logfp);
00267 errorResponse(QcjHttpService::NotFound, "Required parmaeter, dir, not specified");
00268 return;
00269 }
00270 fprintf(logfp, "DbPhotoService::processRequest(%s): Inserted %d photos\n", qPrintable(QString::number(currentThreadId())), count);
00271 fflush(logfp);
00272 QByteArray ba;
00273 QDataStream buf(&ba, QIODevice::WriteOnly);
00274 buf << "<html>\n";
00275 buf << " <body>\n";
00276 buf << " <h2>Inserted " + QString::number(count) + " Photos into the database successfully</h2>\n";
00277 buf << " </body>\n";
00278 buf << "</html>\n";
00279 rsp->insert("Status", QcjHttpService::OK);
00280 rsp->insert("Content-Length", QVariant(ba.size()));
00281 rsp->insert("Content-Type", QVariant("text/html"));
00282 rsp->insert("Request-Body", QVariant(ba));
00283 }
00284 else
00285 {
00286 errorResponse(QcjHttpService::BadRequest, "Requested action not recognized");
00287 }
00288 return;
00289 }
00290
00291
00292
00293
00294
00295
00296
00297 int width = 0;
00298 int height = 0;
00299 QString colors;
00300
00301
00302
00303
00304
00305 if ( arguments.contains("width") )
00306 width = arguments.value("width").toInt();
00307 if ( arguments.contains("height") )
00308 height = arguments.value("height").toInt();
00309 if ( arguments.contains("colors") )
00310 colors = arguments.value("colors");
00311
00312
00313
00314
00315
00316 QString url = req->value("Host").toString() + "/" + fileBase;
00317 fprintf(logfp, "DbPhotoService::processRequest(%s): file type = |%s|\n", qPrintable(QString::number(currentThreadId())), qPrintable(fileType));
00318 fflush(logfp);
00319 fprintf(logfp, "DbPhotoService::processRequest(%s): file base = |%s|\n", qPrintable(QString::number(currentThreadId())), qPrintable(fileBase));
00320 fflush(logfp);
00321
00322
00323
00324
00325 if ( fileType != "html" && fileType != "htm")
00326 {
00327
00328
00329
00330
00331
00332 fprintf(logfp, "DbPhotoService::processRequest(%s): locking db lock\n", qPrintable(QString::number(currentThreadId())));
00333 fflush(logfp);
00334 dbLock.lock();
00335 db = getServerParms(host);
00336
00337 if ( ! db.isOpen() || db.isOpenError() )
00338 {
00339 fprintf(logfp, "DbPhotoService::processRequest(%s): Error opening database\n", qPrintable(QString::number(currentThreadId())));
00340 fflush(logfp);
00341 errorResponse(QcjHttpService::ServiceUnavailable, "Could not connect to database");
00342 fprintf(logfp, "DbPhotoService::processRequest(%s): unlocking db lock\n", qPrintable(QString::number(currentThreadId())));
00343 fflush(logfp);
00344 dbLock.unlock();
00345 return;
00346 }
00347 fprintf(logfp, "DbPhotoService::processRequest(%s): unlocking db lock\n", qPrintable(QString::number(currentThreadId())));
00348 fflush(logfp);
00349 dbLock.unlock();
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359 QString url1 = url + "?width=" + QString::number(width) + "&height=" + QString::number(height);
00360 fprintf(logfp, "DbPhotoService::processRequest(%s): looking for url1 |%s| in resize cache\n", qPrintable(QString::number(currentThreadId())), qPrintable(url1));
00361 fflush(logfp);
00362
00363
00364
00365
00366
00367 Image image;
00368
00369 fprintf(logfp, "DbPhotoService::processRequest(%s): have method: |%s|\n", qPrintable(QString::number(currentThreadId())), qPrintable(method));
00370 fflush(logfp);
00371
00372 if ( ! photoResizeCache.contains(url1) )
00373 {
00374 fprintf(logfp, "DbPhotoService::processRequest(%s): looking for url |%s| in cache\n", qPrintable(QString::number(currentThreadId())), qPrintable(url));
00375 fflush(logfp);
00376
00377
00378
00379
00380 if ( photoCache.contains(url) )
00381 {
00382
00383
00384
00385
00386
00387 fprintf(logfp, "DbPhotoService::processRequest(%s): found resource in cache\n", qPrintable(QString::number(currentThreadId())));
00388 fflush(logfp);
00389
00390
00391
00392
00393 fprintf(logfp, "DbPhotoService::processRequest(%s): locking photo lock\n", qPrintable(QString::number(currentThreadId())));
00394 fflush(logfp);
00395 photoLock.lock();
00396
00397 image = photoCache.value(url);
00398 photoList.removeAll(url);
00399 photoList.insert(0, url);
00400
00401 fprintf(logfp, "DbPhotoService::processRequest(%s): unlocking photo lock\n", qPrintable(QString::number(currentThreadId())));
00402 fflush(logfp);
00403 photoLock.unlock();
00404
00405 }
00406 else
00407 {
00408 QByteArray ba;
00409
00410
00411
00412
00413 fprintf(logfp, "DbPhotoService::processRequest(%s): locking db lock\n", qPrintable(QString::number(currentThreadId())));
00414 fflush(logfp);
00415 dbLock.lock();
00416
00417
00418
00419
00420
00421 QString sql = sqlTemplate;
00422 fprintf(logfp, "DbPhotoService::processRequest(%s): sql = |%s|\n", qPrintable(QString::number(currentThreadId())), qPrintable(sql));
00423 fflush(logfp);
00424 QSqlQuery q(db);
00425 q.prepare(sqlTemplate);
00426
00427
00428
00429
00430 q.bindValue(":resource", fileBase + ".jpg");
00431 fprintf(logfp, "DbPhotoService::processRequest(%s): sql = |%s|\n", qPrintable(QString::number(currentThreadId())), qPrintable(q.lastQuery()));
00432 fflush(logfp);
00433 q.exec();
00434 fprintf(logfp, "DbPhotoService::processRequest(%s): fetching image\n", qPrintable(QString::number(currentThreadId())));
00435 fflush(logfp);
00436 if ( q.next() )
00437 {
00438
00439
00440
00441
00442 fprintf(logfp, "DbPhotoService::processRequest(%s): getting image\n", qPrintable(QString::number(currentThreadId())));
00443 fflush(logfp);
00444 ba = q.value(0).toByteArray();
00445 }
00446 else
00447 {
00448
00449
00450
00451
00452 fprintf(logfp, "DbPhotoService::processRequest(%s): Did not find resource\n", qPrintable(QString::number(currentThreadId())));
00453 fflush(logfp);
00454 errorResponse(QcjHttpService::NotFound, "Requested resource not found");
00455
00456 fprintf(logfp, "DbPhotoService::processRequest(%s): unlocking db lock\n", qPrintable(QString::number(currentThreadId())));
00457 fflush(logfp);
00458 dbLock.unlock();
00459 return;
00460 }
00461
00462
00463
00464
00465
00466 fprintf(logfp, "DbPhotoService::processRequest(%s): Unlocking db lock\n", qPrintable(QString::number(currentThreadId())));
00467 fflush(logfp);
00468
00469 dbLock.unlock();
00470
00471 fprintf(logfp, "DbPhotoService::processRequest(%s): locking photo lock\n", qPrintable(QString::number(currentThreadId())));
00472 fflush(logfp);
00473 photoLock.lock();
00474
00475
00476
00477
00478 image.read(Blob(ba.data(), ba.size()));
00479 Geometry geom(image.size());
00480
00481 fprintf(logfp, "DbPhotoService::processRequest(%s): unlocking photo lock\n", qPrintable(QString::number(currentThreadId())));
00482 fflush(logfp);
00483 photoLock.unlock();
00484
00485 fprintf(logfp, "DbPhotoService::processRequest(%s): Checking for resource in cache\n", qPrintable(QString::number(currentThreadId())));
00486 fflush(logfp);
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497 fprintf(logfp, "DbPhotoService::processRequest(%s): resizing image for the cache, cacheDimension = %d\n", qPrintable(QString::number(currentThreadId())), cacheDimension);
00498 fprintf(logfp, "DbPhotoService::processRequest(%s): original image, width = %d, height = %d\n", qPrintable(QString::number(currentThreadId())), geom.width(), geom.height());
00499 if ( geom.width() > cacheDimension || geom.height() > cacheDimension )
00500 {
00501 fprintf(logfp, "DbPhotoService::processRequest(%s): One side or another is larger than the cache size...\n", qPrintable(QString::number(currentThreadId())));
00502 if ( geom.width() > geom.height() )
00503 {
00504 t_height = (int)( (double)cacheDimension / (double)geom.width() * (double)geom.height() );
00505 geom.height(t_height);
00506 fprintf(logfp, "DbPhotoService::processRequest(%s): width larger, height scaled to %d\n", qPrintable(QString::number(currentThreadId())), t_height);
00507 geom.width(cacheDimension);
00508 }
00509 else if ( geom.height() > geom.width() )
00510 {
00511 t_width = (int)( (double)cacheDimension / (double)geom.height() * (double)geom.width() );
00512 geom.width(t_width);
00513 fprintf(logfp, "DbPhotoService::processRequest(%s): height larger, width scaled to %d\n", qPrintable(QString::number(currentThreadId())), t_width);
00514 geom.height(cacheDimension);
00515 }
00516 else
00517 {
00518 fprintf(logfp, "DbPhotoService::processRequest(%s): height == width\n", qPrintable(QString::number(currentThreadId())));
00519 geom.width(cacheDimension);
00520 geom.height(cacheDimension);
00521 }
00522 fprintf(logfp, "DbPhotoService::processRequest(%s): cached image size, width = %d, height = %d\n", qPrintable(QString::number(currentThreadId())), geom.width(), geom.height());
00523 fflush(logfp);
00524
00525 fprintf(logfp, "DbPhotoService::processRequest(%s): locking photo lock\n", qPrintable(QString::number(currentThreadId())));
00526 fflush(logfp);
00527 photoLock.lock();
00528
00529 image.zoom(geom);
00530
00531 fprintf(logfp, "DbPhotoService::processRequest(%s): unlocking photo lock\n", qPrintable(QString::number(currentThreadId())));
00532 fflush(logfp);
00533 photoLock.unlock();
00534
00535 fprintf(logfp, "DbPhotoService::processRequest(%s): cached Image scaled\n", qPrintable(QString::number(currentThreadId())));
00536 fflush(logfp);
00537 }
00538
00539
00540
00541
00542
00543 if ( photoList.contains(url) )
00544 {
00545 fprintf(logfp, "DbPhotoService::processRequest(%s): removing from cache, url |%s|\n", qPrintable(QString::number(currentThreadId())), qPrintable(url));
00546 fflush(logfp);
00547
00548
00549
00550 fprintf(logfp, "DbPhotoService::processRequest(%s): locking photo lock\n", qPrintable(QString::number(currentThreadId())));
00551 fflush(logfp);
00552 photoLock.lock();
00553
00554 photoList.removeAll(url);
00555
00556 fprintf(logfp, "DbPhotoService::processRequest(%s): unlocking photo lock\n", qPrintable(QString::number(currentThreadId())));
00557 fflush(logfp);
00558 photoLock.unlock();
00559 }
00560
00561
00562
00563
00564
00565
00566 if ( photoCache.size() > maxPhotos )
00567 {
00568 fprintf(logfp, "DbPhotoService::processRequest(%s): Removing items from cache, current size = %d\n", qPrintable(QString::number(currentThreadId())), photoCache.size());
00569 fflush(logfp);
00570
00571
00572
00573 fprintf(logfp, "DbPhotoService::processRequest(%s): locking photo lock\n", qPrintable(QString::number(currentThreadId())));
00574 fflush(logfp);
00575 photoLock.lock();
00576 while (photoCache.size() - maxPhotos)
00577 {
00578 QString name = photoList.takeLast();
00579 photoCache.remove(name);
00580 fprintf(logfp, "DbPhotoService::processRequest(%s): item removed current size = %d\n", qPrintable(QString::number(currentThreadId())), photoCache.size());
00581 fflush(logfp);
00582 }
00583 fprintf(logfp, "DbPhotoService::processRequest(%s): unlocking photo lock\n", qPrintable(QString::number(currentThreadId())));
00584 fflush(logfp);
00585 photoLock.unlock();
00586
00587 }
00588 fprintf(logfp, "DbPhotoService::processRequest(%s): Inserting resource into cache\n", qPrintable(QString::number(currentThreadId())));
00589 fflush(logfp);
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599 fprintf(logfp, "DbPhotoService::processRequest(%s): locking photo lock\n", qPrintable(QString::number(currentThreadId())));
00600 fflush(logfp);
00601 photoLock.lock();
00602
00603 photoCache.insert(url, image);
00604 photoList.insert(0, url);
00605
00606
00607
00608 fprintf(logfp, "DbPhotoService::processRequest(%s): unlocking photo lock\n", qPrintable(QString::number(currentThreadId())));
00609 fflush(logfp);
00610 photoLock.unlock();
00611
00612 }
00613
00614 fprintf(logfp, "DbPhotoService::processRequest(%s): Creating image\n", qPrintable(QString::number(currentThreadId())));
00615 fflush(logfp);
00616
00617 fprintf(logfp, "DbPhotoService::processRequest(%s): scaling image? width = %d, height = %d\n", qPrintable(QString::number(currentThreadId())), width, height);
00618 fflush(logfp);
00619
00620
00621
00622
00623
00624
00625
00626 Geometry geom(image.size());
00627 fprintf(logfp, "DbPhotoService::processRequest(%s): setting image geometry to requested size, image size currently width = %d, height = %d\n", qPrintable(QString::number(currentThreadId())), geom.width(), geom.height());
00628
00629 if ( width > 0 && height > 0 )
00630 {
00631 geom.width(width);
00632 geom.height(height);
00633 fprintf(logfp, "DbPhotoService::processRequest(%s): setting image geometery to width = %d, height = %d\n", qPrintable(QString::number(currentThreadId())), geom.width(), geom.height());
00634 geom.aspect(true);
00635 }
00636 else if ( width > 0 )
00637 {
00638 int height = geom.height();
00639 height = (int)( ((double)width / geom.width()) * height);
00640 geom.width(width);
00641 geom.height(height);
00642 fprintf(logfp, "DbPhotoService::processRequest(%s): setting image geometery to width = %d, height = %d\n", qPrintable(QString::number(currentThreadId())), geom.width(), geom.height());
00643 }
00644 else if (height > 0 )
00645 {
00646 int width = geom.width();
00647 geom.width(width);
00648 geom.height(height);
00649 fprintf(logfp, "DbPhotoService::processRequest(%s): setting image geometery to width = %d, height = %d\n", qPrintable(QString::number(currentThreadId())), geom.width(), geom.height());
00650 }
00651
00652
00653
00654
00655
00656
00657 fprintf(logfp, "DbPhotoService::processRequest(%s): Ensuring max size, maxDimension = %d\n", qPrintable(QString::number(currentThreadId())), maxDimension);
00658 fprintf(logfp, "DbPhotoService::processRequest(%s): image size now width = %d, height = %d\n", qPrintable(QString::number(currentThreadId())), geom.width(), geom.height());
00659 fflush(logfp);
00660 if ( geom.width() > maxDimension || geom.height() > maxDimension )
00661 {
00662 fprintf(logfp, "DbPhotoService::processRequest(%s): One side or another is too large...\n", qPrintable(QString::number(currentThreadId())));
00663
00664 if ( geom.width() > geom.height() )
00665 {
00666 t_height = (int)( (double)maxDimension / (double)geom.width() * (double)geom.height() );
00667 geom.height(t_height);
00668 fprintf(logfp, "DbPhotoService::processRequest(%s): width larger, height scaled to %d\n", qPrintable(QString::number(currentThreadId())), t_height);
00669 geom.width(maxDimension);
00670 }
00671 else if ( geom.height() > geom.width() )
00672 {
00673 t_width = (int)( (double)maxDimension / (double)geom.height() * (double)geom.width() );
00674 geom.width(t_width);
00675 fprintf(logfp, "DbPhotoService::processRequest(%s): height larger, width scaled to %d\n", qPrintable(QString::number(currentThreadId())), t_width);
00676 geom.height(maxDimension);
00677 }
00678 else
00679 {
00680 fprintf(logfp, "DbPhotoService::processRequest(%s): width == height\n", qPrintable(QString::number(currentThreadId())));
00681 geom.width(maxDimension);
00682 geom.height(maxDimension);
00683 }
00684
00685
00686
00687 fprintf(logfp, "DbPhotoService::processRequest(%s): locking photo lock\n", qPrintable(QString::number(currentThreadId())));
00688 fflush(logfp);
00689 photoLock.lock();
00690
00691 photoCache.insert(url, image);
00692 photoList.insert(0, url);
00693
00694 fprintf(logfp, "DbPhotoService::processRequest(%s): unlocking photo lock\n", qPrintable(QString::number(currentThreadId())));
00695 fflush(logfp);
00696 photoLock.unlock();
00697 }
00698 fprintf(logfp, "DbPhotoService::processRequest(%s): Scaling image, width = %d, height = %d\n", qPrintable(QString::number(currentThreadId())), geom.width(), geom.height());
00699 fflush(logfp);
00700
00701 fprintf(logfp, "DbPhotoService::processRequest(%s): locking photo lock\n", qPrintable(QString::number(currentThreadId())));
00702 fflush(logfp);
00703 photoLock.lock();
00704 image.zoom(geom);
00705 fprintf(logfp, "DbPhotoService::processRequest(%s): unlocking photo lock\n", qPrintable(QString::number(currentThreadId())));
00706 fflush(logfp);
00707 photoLock.unlock();
00708
00709
00710
00711
00712
00713 fprintf(logfp, "DbPhotoService::processRequest(%s): checking resize cache size, currently %d photos\n", qPrintable(QString::number(currentThreadId())), photoResizeCache.size());
00714 fflush(logfp);
00715
00716
00717
00718
00719 fprintf(logfp, "DbPhotoService::processRequest(%s): locking photo lock\n", qPrintable(QString::number(currentThreadId())));
00720 fflush(logfp);
00721 photoLock.lock();
00722
00723
00724
00725
00726
00727
00728 if ( photoResizeCache.size() > maxResizePhotos )
00729 {
00730 fprintf(logfp, "DbPhotoService::processRequest(%s): Removing items from resize cache, current size = %d\n", qPrintable(QString::number(currentThreadId())), photoResizeCache.size());
00731 fflush(logfp);
00732 while (photoResizeCache.size() - maxResizePhotos)
00733 {
00734 QString name = photoResizeList.takeLast();
00735 fprintf(logfp, "DbPhotoService::processRequest(%s): removing item |%s| from resize cache\n", qPrintable(QString::number(currentThreadId())), qPrintable(name));
00736 fflush(logfp);
00737 photoResizeCache.remove(name);
00738 fprintf(logfp, "DbPhotoService::processRequest(%s): item removed current size = %d\n", qPrintable(QString::number(currentThreadId())), photoResizeCache.size());
00739 fflush(logfp);
00740 }
00741 }
00742 fprintf(logfp, "DbPhotoService::processRequest(%s): Inserting resource with url of |%s| into resize cache\n", qPrintable(QString::number(currentThreadId())), qPrintable(url1));
00743 fflush(logfp);
00744 photoResizeCache.insert(url1, image);
00745 photoResizeList.insert(0, url1);
00746
00747 fprintf(logfp, "DbPhotoService::processRequest(%s): unlocking photo lock\n", qPrintable(QString::number(currentThreadId())));
00748 fflush(logfp);
00749 photoLock.unlock();
00750 }
00751
00752
00753
00754
00755
00756
00757
00758
00759 else
00760 {
00761 fprintf(logfp, "DbPhotoService::processRequest(%s): locking photo lock\n", qPrintable(QString::number(currentThreadId())));
00762 fflush(logfp);
00763 photoLock.lock();
00764 image = photoResizeCache.value(url1);
00765 photoResizeList.removeAll(url1);
00766 photoResizeList.insert(0, url1);
00767 fprintf(logfp, "DbPhotoService::processRequest(%s): unlocking photo lock\n", qPrintable(QString::number(currentThreadId())));
00768 fflush(logfp);
00769 photoLock.unlock();
00770 }
00771
00772
00773
00774
00775
00776
00777 fprintf(logfp, "DbPhotoService::processRequest(%s): Creating to send \n", qPrintable(QString::number(currentThreadId())));
00778 fflush(logfp);
00779 Blob imgBlob;
00780 fprintf(logfp, "DbPhotoService::processRequest(%s): Saving image with type |%s|\n", qPrintable(QString::number(currentThreadId())), qPrintable(fileType.toUpper()));
00781 fflush(logfp);
00782 image.magick(qPrintable(fileType.toUpper()));
00783
00784 fprintf(logfp, "DbPhotoService::processRequest(%s): colors = |%s|\n", qPrintable(QString::number(currentThreadId())), qPrintable(colors));
00785 fflush(logfp);
00786
00787
00788
00789
00790
00791 if ( colors == "monochrome" )
00792 {
00793 fprintf(logfp, "DbPhotoService::processRequest(%s): Making bw\n", qPrintable(QString::number(currentThreadId())));
00794 fflush(logfp);
00795 image.monochrome(true);
00796 image.type( GrayscaleType );
00797 }
00798 else if (colors.length() > 0 )
00799 {
00800 bool good;
00801 int x = colors.toInt(&good);
00802 if ( good )
00803 {
00804 fprintf(logfp, "DbPhotoService::processRequest(%s): Setting colors to: %d\n", qPrintable(QString::number(currentThreadId())), x);
00805 fflush(logfp);
00806 image.quantizeColors(x);
00807 image.quantize();
00808 }
00809 else
00810 {
00811 fprintf(logfp, "DbPhotoService::processRequest(%s): error converting size, x = %d\n", qPrintable(QString::number(currentThreadId())), x);
00812 fflush(logfp);
00813 }
00814 }
00815
00816
00817
00818
00819 fprintf(logfp, "DbPhotoService::processRequest(%s): Writing image to blob\n", qPrintable(QString::number(currentThreadId())));
00820 fflush(logfp);
00821
00822 fprintf(logfp, "DbPhotoService::processRequest(%s): locking photo lock\n", qPrintable(QString::number(currentThreadId())));
00823 fflush(logfp);
00824 photoLock.lock();
00825 image.write(&imgBlob);
00826 fprintf(logfp, "DbPhotoService::processRequest(%s): unlocking photo lock\n", qPrintable(QString::number(currentThreadId())));
00827 fflush(logfp);
00828 photoLock.unlock();
00829
00830 fprintf(logfp, "DbPhotoService::processRequest(%s): Image written\n", qPrintable(QString::number(currentThreadId())));
00831 fflush(logfp);
00832
00833 if ( fileType == "jpg" )
00834 fileType = "jpeg";
00835
00836
00837
00838
00839 QByteArray newImage((char*)imgBlob.data(), imgBlob.length());
00840
00841
00842
00843
00844 rsp->insert("Status", QcjHttpService::OK);
00845 rsp->insert("Content-Length", QVariant(newImage.size()));
00846 rsp->insert("Content-Type", QVariant("image/" + fileType));
00847 rsp->insert("Request-Body", QVariant(newImage));
00848 }
00849 }
00850 fprintf(logfp, "DbPhotoService::processRequest(%s): Exit\n", qPrintable(QString::number(currentThreadId())));
00851 fflush(logfp);
00852 }
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862 QSqlDatabase DbPhotoService::getServerParms(QString host)
00863 {
00864 QSqlDatabase rv;
00865
00866 fprintf(logfp, "DbPhotoService::getServerParms(%s): Enter, host = |%s|\n", qPrintable(QString::number(currentThreadId())), qPrintable(host));
00867 fflush(logfp);
00868 QDomElement docElem = doc.documentElement();
00869 QDomNode n = docElem.firstChild();
00870 while ( ! n.isNull() )
00871 {
00872 QDomElement e = n.toElement();
00873 fprintf(logfp, "DbPhotoService::getServerParms(%s): Have node: |%s|\n", qPrintable(QString::number(currentThreadId())), qPrintable(e.tagName()));
00874 fflush(logfp);
00875 if ( e.tagName() == "server" )
00876 {
00877 QString sName = e.attribute("name");
00878 fprintf(logfp, "DbPhotoService::getServerParms(%s): Have server tag, name = |%s|\n", qPrintable(QString::number(currentThreadId())), qPrintable(sName));
00879 fflush(logfp);
00880 if ( sName == host )
00881 {
00882
00883
00884
00885
00886 if ( dbCache.contains(host) && dbCache.value(host).isOpen() )
00887 {
00888 fprintf(logfp, "DbPhotoService::getServerParms(%s): Found database in cache\n", qPrintable(QString::number(currentThreadId())));
00889 fflush(logfp);
00890 rv = dbCache.value(host);
00891 }
00892
00893 if ( ! rv.isOpen() && dbCache.contains(host) )
00894 {
00895 fprintf(logfp, "DbPhotoService::getServerParms(%s): Removing database from cache\n", qPrintable(QString::number(currentThreadId())));
00896 fflush(logfp);
00897 dbCache.remove(host);
00898 }
00899
00900 QString type = e.attribute("type");
00901 fprintf(logfp, "DbPhotoService::getServerParms(%s): have type: |%s|\n", qPrintable(QString::number(currentThreadId())), qPrintable(type));
00902 fflush(logfp);
00903 if ( type.size() == 0 )
00904 type = "QPSQL";
00905
00906 fprintf(logfp, "DbPhotoService::getServerParms(%s): have type: |%s|\n", qPrintable(QString::number(currentThreadId())), qPrintable(type));
00907 fflush(logfp);
00908 if ( ! rv.isOpen() )
00909 rv = QSqlDatabase::addDatabase(type);
00910
00911 QDomNode n1 = e.firstChild();
00912 while ( ! n1.isNull() )
00913 {
00914
00915
00916
00917
00918
00919
00920
00921 QDomElement e1 = n1.toElement();
00922 if ( e1.tagName() == "database" )
00923 {
00924 QString name = e1.attribute("name");
00925
00926 fprintf(logfp, "DbPhotoService::getServerParms(%s): have database node, name = |%s|\n", qPrintable(QString::number(currentThreadId())), qPrintable(name));
00927 fflush(logfp);
00928 QDomNode n2 = e1.firstChild();
00929 while ( ! n2.isNull() )
00930 {
00931 QDomElement e2 = n2.toElement();
00932
00933
00934
00935
00936 if ( ! rv.isOpen() && e2.tagName() == "connection" )
00937 {
00938 fprintf(logfp, "DbPhotoService::getServerParms(%s): have connection node\n", qPrintable(QString::number(currentThreadId())));
00939 fflush(logfp);
00940 rv.setUserName(e2.attribute("user"));
00941 rv.setPassword(e2.attribute("password"));
00942 rv.setPort(e2.attribute("port").toInt());
00943 rv.setHostName(e2.attribute("host"));
00944 photoTable = e2.attribute("table");
00945 rv.setDatabaseName(name);
00946 fprintf(logfp, "DbPhotoService::getServerParms(%s): user: |%s|\n", qPrintable(QString::number(currentThreadId())), qPrintable(e2.attribute("user")));
00947 fprintf(logfp, "DbPhotoService::getServerParms(%s): password: |%s|\n", qPrintable(QString::number(currentThreadId())), qPrintable(e2.attribute("password")));
00948 fprintf(logfp, "DbPhotoService::getServerParms(%s): port: |%s|\n", qPrintable(QString::number(currentThreadId())), qPrintable(e2.attribute("port")));
00949 fprintf(logfp, "DbPhotoService::getServerParms(%s): host: |%s|\n", qPrintable(QString::number(currentThreadId())), qPrintable(e2.attribute("host")));
00950 fflush(logfp);
00951
00952 if ( ! rv.open() )
00953 {
00954 fprintf(logfp, "DbPhotoService::getServerParms(%s): failed opening db, %s - %s\n", qPrintable(QString::number(currentThreadId())),
00955 qPrintable(rv.lastError().databaseText()),
00956 qPrintable(rv.lastError().driverText()));
00957 fflush(logfp);
00958
00959 }
00960 else
00961 dbCache.insert(host, rv);
00962 }
00963 else if ( e2.tagName() == "sql" )
00964 {
00965 QDomNode cdata = n2.firstChild();
00966 if ( cdata.isText() )
00967 sqlTemplate = cdata.nodeValue();
00968 fprintf(logfp, "DbPhotoService::getServerParms(%s): sql: |%s|\n", qPrintable(QString::number(currentThreadId())), qPrintable(sqlTemplate));
00969 }
00970
00971 n2 = n2.nextSibling();
00972 }
00973 }
00974
00975
00976
00977
00978
00979 else if ( e1.tagName() == "html_template" )
00980 {
00981 QDomNode cdata = n1.firstChild();
00982 if ( cdata.isText() )
00983 htmlTemplate = cdata.nodeValue();
00984 }
00985
00986
00987
00988 else if ( e1.tagName() == "image" )
00989 {
00990 fprintf(logfp, "DbPhotoService::getServerParms(%s): have image node\n", qPrintable(QString::number(currentThreadId())));
00991 fflush(logfp);
00992 if ( e1.attribute("cache_dimension") != QString::null )
00993 cacheDimension = e1.attribute("cache_dimension").toInt();
00994 if ( e1.attribute("max_dimension") != QString::null )
00995 maxDimension = e1.attribute("max_dimension").toInt();
00996 fprintf(logfp, "DbPhotoService::getServerParms(%s): maxDimension = %d\n", qPrintable(QString::number(currentThreadId())), maxDimension);
00997 fprintf(logfp, "DbPhotoService::getServerParms(%s): cacheDimension = %d\n", qPrintable(QString::number(currentThreadId())), cacheDimension);
00998 }
00999 n1 = n1.nextSibling();
01000 }
01001 break;
01002 }
01003 }
01004 n = n.nextSibling();
01005 }
01006 fprintf(logfp, "DbPhotoService::getServerParms(%s): Exit, db is open? %d\n", qPrintable(QString::number(currentThreadId())), rv.isOpen());
01007 fflush(logfp);
01008 return(rv);
01009 }