32 #include <QImageWriter>
68 qRegisterMetaType<V2ArtworkInfoList*>(
"V2ArtworkInfoList");
69 qRegisterMetaType<V2ArtworkInfo*>(
"V2ArtworkInfo");
81 const QString &sFileName )
83 QString sGroup = sStorageGroup;
87 LOG(VB_UPNP, LOG_WARNING,
88 "GetFile - StorageGroup missing... using 'Default'");
92 if (sFileName.isEmpty())
94 QString sMsg (
"GetFile - FileName missing." );
106 QString sFullFileName = storage.
FindFile( sFileName );
108 if (sFullFileName.isEmpty())
110 LOG(VB_UPNP, LOG_ERR,
111 QString(
"GetFile - Unable to find %1.").arg(sFileName));
120 if (QFile::exists( sFullFileName ))
122 return QFileInfo( sFullFileName );
125 LOG(VB_UPNP, LOG_ERR,
126 QString(
"GetFile - File Does not exist %1.").arg(sFullFileName));
136 const QString &sFileName,
140 QString sGroup = sStorageGroup;
142 if (sGroup.isEmpty())
144 LOG(VB_UPNP, LOG_WARNING,
145 "GetImageFile - StorageGroup missing... using 'Default'");
149 if (sFileName.isEmpty())
151 QString sMsg (
"GetImageFile - FileName missing." );
163 QString sFullFileName = storage.
FindFile( sFileName );
165 if (sFullFileName.isEmpty())
167 LOG(VB_UPNP, LOG_WARNING,
168 QString(
"GetImageFile - Unable to find %1.").arg(sFileName));
177 if (!QFile::exists( sFullFileName ))
179 LOG(VB_UPNP, LOG_WARNING,
180 QString(
"GetImageFile - File Does not exist %1.").arg(sFullFileName));
187 if ((nWidth == 0) && (nHeight == 0))
188 return QFileInfo( sFullFileName );
193 QString sNewFileName = QString(
"%1.%2x%3.jpg" )
194 .arg( sFullFileName )
202 if (QFile::exists( sNewFileName ))
203 return QFileInfo( sNewFileName );
209 auto *pImage =
new QImage( sFullFileName );
211 if (!pImage || pImage->isNull())
214 float fAspect = (float)(pImage->width()) / pImage->height();
217 nWidth = (int)std::rint(nHeight * fAspect);
220 nHeight = (int)std::rint(nWidth / fAspect);
222 QImage img = pImage->scaled( nWidth, nHeight, Qt::KeepAspectRatio,
223 Qt::SmoothTransformation);
225 QByteArray fname = sNewFileName.toLatin1();
226 img.save( fname.constData(),
"JPG", 60 );
230 return QFileInfo( sNewFileName );
240 if (sStorageGroup.isEmpty())
242 QString sMsg(
"GetDirList - StorageGroup missing.");
243 LOG(VB_UPNP, LOG_ERR, sMsg);
260 if (sStorageGroup.isEmpty())
262 QString sMsg(
"GetFileList - StorageGroup missing.");
263 LOG(VB_UPNP, LOG_ERR, sMsg);
278 const QString &sInetref,
291 if (sType.toLower() ==
"coverart")
296 else if (sType.toLower() ==
"fanart")
301 else if (sType.toLower() ==
"banner")
307 if (!map.contains(
type))
310 QUrl url(map.value(
type).url);
311 QString sFileName = url.path();
313 if (sFileName.isEmpty())
316 return GetImageFile( sgroup, sFileName, nWidth, nHeight);
325 const QDateTime &StartTime)
327 if ((RecordedId <= 0) &&
328 (chanid <= 0 || !StartTime.isValid()))
329 throw QString(
"Recorded ID or Channel ID and StartTime appears invalid.");
356 int nId,
int nWidth,
int nHeight )
358 LOG(VB_UPNP, LOG_INFO, QString(
"GetVideoArtwork ID = %1").arg(nId));
360 QString sgroup =
"Coverart";
361 QString column =
"coverfile";
363 if (sType.toLower() ==
"coverart")
366 column =
"coverfile";
368 else if (sType.toLower() ==
"fanart")
373 else if (sType.toLower() ==
"banner")
378 else if (sType.toLower() ==
"screenshot")
380 sgroup =
"Screenshots";
381 column =
"screenshot";
390 QString querystr = QString(
"SELECT %1 FROM videometadata WHERE "
391 "intid = :ITEMID").arg(column);
402 QString sFileName = query.
value(0).toString();
404 if (sFileName.isEmpty())
407 return GetImageFile( sgroup, sFileName, nWidth, nHeight );
426 LOG(VB_GENERAL, LOG_DEBUG, QString(
"GetAlbumArt: %1").arg(sFullFileName));
433 QString sNewFileName = QString(
"/tmp/%1.%2x%3.jpg" )
434 .arg( QFileInfo(sFullFileName).fileName() )
442 if (QFile::exists( sNewFileName ))
443 return QFileInfo( sNewFileName );
451 if (sFullFileName.startsWith(
"myth://"))
453 RemoteFile rf(sFullFileName,
false,
false, 0s);
457 img.loadFromData(data);
460 img.load(sFullFileName);
467 if ((nWidth == 0) && (nHeight == 0))
469 if (!sFullFileName.startsWith(
"myth://"))
471 QFileInfo fi(sFullFileName);
472 if (fi.suffix().toLower() ==
"jpg")
476 else if (nWidth > img.width() && nHeight > img.height())
486 float fAspect = (float)(img.width()) / img.height();
488 if ( nWidth == 0 || nWidth > img.width() )
489 nWidth = (
int)std::rint(nHeight * fAspect);
491 if ( nHeight == 0 || nHeight > img.height() )
492 nHeight = (int)std::rint(nWidth / fAspect);
494 img = img.scaled( nWidth, nHeight, Qt::KeepAspectRatio,
495 Qt::SmoothTransformation);
498 QString fname = sNewFileName.toLatin1().constData();
501 if (!img.save( fname,
"JPG" ))
504 return QFileInfo( sNewFileName );
513 const QDateTime &StartTime,
517 const QString &sFormat )
519 if ((nRecordedId <= 0) &&
520 (nChanId <= 0 || !StartTime.isValid()))
521 throw QString(
"Recorded ID or Channel ID and StartTime appears invalid.");
523 if (!sFormat.isEmpty()
524 && !QImageWriter::supportedImageFormats().contains(sFormat.toLower().toLocal8Bit()))
526 throw QString(
"GetPreviewImage: Specified 'Format' is not supported.");
542 LOG(VB_GENERAL, LOG_ERR,
543 QString(
"GetPreviewImage: No recording for '%1'")
552 QString(
"GetPreviewImage: Wrong Host '%1' request from '%2'")
556 LOG(VB_UPNP, LOG_ERR, sMsg);
561 QString sImageFormat = sFormat;
562 if (sImageFormat.isEmpty())
563 sImageFormat =
"PNG";
571 QString sPreviewFileName;
573 auto nSecs = std::chrono::seconds(nSecsIn);
577 sPreviewFileName = QString(
"%1.png").arg(sFileName);
581 sPreviewFileName = QString(
"%1.%2.png").arg(sFileName).arg(nSecsIn);
584 if (!QFile::exists( sPreviewFileName ))
589 if (!pginfo.
IsLocal() && sFileName.startsWith(
"/"))
597 previewgen->SetPreviewTimeAsSeconds( nSecs );
598 previewgen->SetOutputFilename ( sPreviewFileName );
600 bool ok = previewgen->Run();
602 previewgen->deleteLater();
608 bool bDefaultPixmap = (nWidth == 0) && (nHeight == 0);
610 QString sNewFileName;
613 sNewFileName = sPreviewFileName;
616 sNewFileName = QString(
"%1.%2.%3x%4.%5" )
619 .arg( nWidth == 0 ? -1 : nWidth )
620 .arg( nHeight == 0 ? -1 : nHeight )
621 .arg( sImageFormat.toLower() );
627 if (QFile::exists( sNewFileName ))
629 if (QFileInfo(sPreviewFileName).lastModified() <=
630 QFileInfo(sNewFileName).lastModified())
631 return QFileInfo( sNewFileName );
634 QImage image = QImage(sPreviewFileName);
642 image = image.scaledToHeight(nHeight, Qt::SmoothTransformation);
643 else if ( nHeight <= 0 )
644 image = image.scaledToWidth(nWidth, Qt::SmoothTransformation);
646 image = image.scaled(nWidth, nHeight, Qt::IgnoreAspectRatio,
647 Qt::SmoothTransformation);
649 image.save(sNewFileName, sImageFormat.toUpper().toLocal8Bit());
655 LOG(VB_GENERAL, LOG_ERR,
"Unable to change permissions on "
656 "preview image. Backends and frontends "
657 "running under different users will be "
658 "unable to access it");
662 if (QFile::exists( sNewFileName ))
663 return QFileInfo( sNewFileName );
667 previewgen->SetPreviewTimeAsSeconds( nSecs );
668 previewgen->SetOutputFilename ( sNewFileName );
669 previewgen->SetOutputSize (QSize(nWidth,nHeight));
671 bool ok = previewgen->Run();
673 previewgen->deleteLater();
678 return QFileInfo( sNewFileName );
687 const QDateTime &StartTime )
689 if ((nRecordedId <= 0) &&
690 (nChanId <= 0 || !StartTime.isValid()))
691 throw QString(
"Recorded ID or Channel ID and StartTime appears invalid.");
706 LOG(VB_UPNP, LOG_ERR, QString(
"GetRecording - for '%1' failed")
718 QString(
"GetRecording: Wrong Host '%1' request from '%2'.")
722 LOG(VB_UPNP, LOG_ERR, sMsg);
733 if (QFile::exists( sFileName ))
734 return QFileInfo( sFileName );
755 query.
prepare(
"SELECT CONCAT_WS('/', music_directories.path, "
756 "music_songs.filename) AS filename FROM music_songs "
757 "LEFT JOIN music_directories ON "
758 "music_songs.directory_id="
759 "music_directories.directory_id "
760 "WHERE music_songs.song_id = :KEY");
772 sFileName = query.
value(0).toString();
776 if (sFileName.isEmpty())
779 return GetFile(
"Music", sFileName );
798 query.
prepare(
"SELECT filename FROM videometadata WHERE intid = :KEY" );
808 sFileName = query.
value(0).toString();
811 if (sFileName.isEmpty())
814 if (!QFile::exists( sFileName ))
815 return GetFile(
"Videos", sFileName );
817 return QFileInfo( sFileName );
825 const QString &sFileName )
827 if ((sFileName.isEmpty()) ||
828 (sFileName.contains(
"/../")) ||
829 (sFileName.startsWith(
"../")))
831 LOG(VB_GENERAL, LOG_ERR,
832 QString(
"ERROR checking for file, filename '%1' "
833 "fails sanity checks").arg(sFileName));
837 QString storageGroup =
"Default";
839 if (!sStorageGroup.isEmpty())
840 storageGroup = sStorageGroup;
844 QString fullname = sgroup.
FindFile(sFileName);
859 QFileInfo finfo(sURL);
860 QString
filename = finfo.fileName();
865 if (outDir.isEmpty())
867 LOG(VB_GENERAL, LOG_ERR,
868 QString(
"Unable to determine directory "
869 "to write to in %1 write command").arg(sURL));
876 LOG(VB_GENERAL, LOG_ERR,
877 QString(
"ERROR: %1 write filename '%2' does not "
878 "pass sanity checks.").arg(sURL,
filename));