bool Dvr::DeleteRecording(int RecordedId, int chanid, const QDateTime &recstarttsRaw, bool forceDelete, bool allowRerecord) { if ((RecordedId <= 0) && (chanid <= 0 || !recstarttsRaw.isValid())) throw QString("Recorded ID or Channel ID and StartTime appears invalid."); // TODO Should use RecordingInfo ProgramInfo pi; if (RecordedId > 0) pi = ProgramInfo(RecordedId); else pi = ProgramInfo(chanid, recstarttsRaw.toUTC()); if (pi.GetChanID() && pi.HasPathname()) { QString cmd = QString("DELETE_RECORDING %1 %2 %3 %4") .arg(pi.GetChanID()) .arg(pi.GetRecordingStartTime(MythDate::ISODate)) .arg(forceDelete ? "FORCE" : "NO_FORCE") .arg(allowRerecord ? "FORGET" : "NO_FORGET"); MythEvent me(cmd); gCoreContext->dispatch(me); return true; } return false; }
QFileInfo Content::GetRecording( int nRecordedId, int nChanId, const QDateTime &recstarttsRaw ) { if ((nRecordedId <= 0) && (nChanId <= 0 || !recstarttsRaw.isValid())) throw QString("Recorded ID or Channel ID and StartTime appears invalid."); // ------------------------------------------------------------------ // Read Recording From Database // ------------------------------------------------------------------ // TODO Should use RecordingInfo ProgramInfo pginfo; if (nRecordedId > 0) pginfo = ProgramInfo(nRecordedId); else pginfo = ProgramInfo(nChanId, recstarttsRaw.toUTC()); if (!pginfo.GetChanID()) { LOG(VB_UPNP, LOG_ERR, QString("GetRecording - for '%1' failed") .arg(nRecordedId)); return QFileInfo(); } if (pginfo.GetHostname().toLower() != gCoreContext->GetHostName().toLower()) { // We only handle requests for local resources QString sMsg = QString("GetRecording: Wrong Host '%1' request from '%2'.") .arg( gCoreContext->GetHostName()) .arg( pginfo.GetHostname() ); LOG(VB_UPNP, LOG_ERR, sMsg); throw HttpRedirectException( pginfo.GetHostname() ); } QString sFileName( GetPlaybackURL(&pginfo) ); // ---------------------------------------------------------------------- // check to see if the file exists // ---------------------------------------------------------------------- if (QFile::exists( sFileName )) return QFileInfo( sFileName ); return QFileInfo(); }
ProgramInfo ProgramInfo::FromSam(const std::string& sam) { // pop off '@PG\t', then split rest of line into tokens const std::vector<std::string>& tokens = internal::Split(sam.substr(4), '\t'); if (tokens.empty()) return ProgramInfo(); ProgramInfo prog; std::map<std::string, std::string> custom; // iterate over tokens for (const std::string& token : tokens) { const std::string& tokenTag = token.substr(0,2); const std::string& tokenValue = token.substr(3); // set program contents if (tokenTag == internal::token_ID) prog.Id(tokenValue); else if (tokenTag == internal::token_CL) prog.CommandLine(tokenValue); else if (tokenTag == internal::token_DS) prog.Description(tokenValue); else if (tokenTag == internal::token_PN) prog.Name(tokenValue); else if (tokenTag == internal::token_PP) prog.PreviousProgramId(tokenValue); else if (tokenTag == internal::token_VN) prog.Version(tokenValue); // otherwise, "custom" tag else custom[tokenTag] = tokenValue; } prog.CustomTags(custom); return prog; }
DTC::ArtworkInfoList* Content::GetRecordingArtworkList( int RecordedId, int chanid, const QDateTime &recstarttsRaw) { if ((RecordedId <= 0) && (chanid <= 0 || !recstarttsRaw.isValid())) throw QString("Recorded ID or Channel ID and StartTime appears invalid."); // TODO Should use RecordingInfo ProgramInfo pginfo; if (RecordedId > 0) pginfo = ProgramInfo(RecordedId); else pginfo = ProgramInfo(chanid, recstarttsRaw.toUTC()); return GetProgramArtworkList(pginfo.GetInetRef(), pginfo.GetSeason()); }
DTC::Program* Dvr::GetRecorded(int RecordedId, int chanid, const QDateTime &recstarttsRaw) { if ((RecordedId <= 0) && (chanid <= 0 || !recstarttsRaw.isValid())) throw QString("Recorded ID or Channel ID and StartTime appears invalid."); // TODO Should use RecordingInfo ProgramInfo pi; if (RecordedId > 0) pi = ProgramInfo(RecordedId); else pi = ProgramInfo(chanid, recstarttsRaw.toUTC()); DTC::Program *pProgram = new DTC::Program(); FillProgramInfo( pProgram, &pi, true ); return pProgram; }
DTC::ArtworkInfoList* Content::GetRecordingArtworkList( int nChanId, const QDateTime &dStartTime ) { if (nChanId <= 0 || !dStartTime.isValid()) throw( QString("Channel ID or StartTime appears invalid.")); ProgramInfo pInfo = ProgramInfo(nChanId, dStartTime); return GetProgramArtworkList(pInfo.GetInetRef(), pInfo.GetSeason()); }
bool Dvr::UpdateRecordedWatchedStatus ( int RecordedId, int chanid, const QDateTime &recstarttsRaw, bool watched) { if ((RecordedId <= 0) && (chanid <= 0 || !recstarttsRaw.isValid())) throw QString("Recorded ID or Channel ID and StartTime appears invalid."); // TODO Should use RecordingInfo ProgramInfo pi; if (RecordedId > 0) pi = ProgramInfo(RecordedId); else pi = ProgramInfo(chanid, recstarttsRaw.toUTC()); pi.SaveWatched(watched); return true; }
bool GetProgramInfo(const MythUtilCommandLineParser &cmdline, ProgramInfo &pginfo) { if (cmdline.toBool("video")) { QString video = cmdline.toString("video"); pginfo = ProgramInfo(video); return true; } if (!cmdline.toBool("chanid")) { LOG(VB_GENERAL, LOG_ERR, "No chanid specified"); return false; } if (!cmdline.toBool("starttime")) { LOG(VB_GENERAL, LOG_ERR, "No start time specified"); return false; } uint chanid = cmdline.toUInt("chanid"); QDateTime starttime = cmdline.toDateTime("starttime"); QString startstring = starttime.toString("yyyyMMddhhmmss"); const ProgramInfo tmpInfo(chanid, starttime); if (!tmpInfo.GetChanID()) { LOG(VB_GENERAL, LOG_ERR, QString("No program data exists for channel %1 at %2") .arg(chanid).arg(startstring)); return false; } pginfo = tmpInfo; return true; }
std::string CommandLine::toString() const { return ProgramInfo(argc(), argv()).commandLine(); }
QFileInfo Content::GetPreviewImage( int nRecordedId, int nChanId, const QDateTime &recstarttsRaw, int nWidth, int nHeight, int nSecsIn, const QString &sFormat ) { if ((nRecordedId <= 0) && (nChanId <= 0 || !recstarttsRaw.isValid())) throw QString("Recorded ID or Channel ID and StartTime appears invalid."); if (!sFormat.isEmpty() && !QImageWriter::supportedImageFormats().contains(sFormat.toLower().toLocal8Bit())) { throw "GetPreviewImage: Specified 'Format' is not supported."; } // ---------------------------------------------------------------------- // Read Recording From Database // ---------------------------------------------------------------------- // TODO Should use RecordingInfo ProgramInfo pginfo; if (nRecordedId > 0) pginfo = ProgramInfo(nRecordedId); else pginfo = ProgramInfo(nChanId, recstarttsRaw.toUTC()); if (!pginfo.GetChanID()) { LOG(VB_GENERAL, LOG_ERR, QString("GetPreviewImage: No recording for '%1'") .arg(nRecordedId)); return QFileInfo(); } if (pginfo.GetHostname().toLower() != gCoreContext->GetHostName().toLower()) { QString sMsg = QString("GetPreviewImage: Wrong Host '%1' request from '%2'") .arg( gCoreContext->GetHostName()) .arg( pginfo.GetHostname() ); LOG(VB_UPNP, LOG_ERR, sMsg); throw HttpRedirectException( pginfo.GetHostname() ); } QString sImageFormat = sFormat; if (sImageFormat.isEmpty()) sImageFormat = "PNG"; QString sFileName = GetPlaybackURL(&pginfo); // ---------------------------------------------------------------------- // check to see if default preview image is already created. // ---------------------------------------------------------------------- QString sPreviewFileName; if (nSecsIn <= 0) { nSecsIn = -1; sPreviewFileName = QString("%1.png").arg(sFileName); } else { sPreviewFileName = QString("%1.%2.png").arg(sFileName).arg(nSecsIn); } if (!QFile::exists( sPreviewFileName )) { // ------------------------------------------------------------------ // Must generate Preview Image, Generate Image and save. // ------------------------------------------------------------------ if (!pginfo.IsLocal() && sFileName.startsWith("/")) pginfo.SetPathname(sFileName); if (!pginfo.IsLocal()) return QFileInfo(); PreviewGenerator *previewgen = new PreviewGenerator( &pginfo, QString(), PreviewGenerator::kLocal); previewgen->SetPreviewTimeAsSeconds( nSecsIn ); previewgen->SetOutputFilename ( sPreviewFileName ); bool ok = previewgen->Run(); previewgen->deleteLater(); if (!ok) return QFileInfo(); } bool bDefaultPixmap = (nWidth == 0) && (nHeight == 0); QString sNewFileName; if (bDefaultPixmap) sNewFileName = sPreviewFileName; else { sNewFileName = QString( "%1.%2.%3x%4.%5" ) .arg( sFileName ) .arg( nSecsIn ) .arg( nWidth == 0 ? -1 : nWidth ) .arg( nHeight == 0 ? -1 : nHeight ) .arg( sImageFormat.toLower() ); // ---------------------------------------------------------------------- // check to see if scaled preview image is already created and isn't // out of date // ---------------------------------------------------------------------- if (QFile::exists( sNewFileName )) { if (QFileInfo(sPreviewFileName).lastModified() <= QFileInfo(sNewFileName).lastModified()) return QFileInfo( sNewFileName ); } QImage image = QImage(sPreviewFileName); if (image.isNull()) return QFileInfo(); // We can just re-scale the default (full-size version) to avoid // a preview generator run if ( nWidth <= 0 ) image = image.scaledToHeight(nHeight, Qt::SmoothTransformation); else if ( nHeight <= 0 ) image = image.scaledToWidth(nWidth, Qt::SmoothTransformation); else image = image.scaled(nWidth, nHeight, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); image.save(sNewFileName, sImageFormat.toUpper().toLocal8Bit()); // Let anybody update it bool ret = makeFileAccessible(sNewFileName.toLocal8Bit().constData()); if (!ret) { LOG(VB_GENERAL, LOG_ERR, "Unable to change permissions on " "preview image. Backends and frontends " "running under different users will be " "unable to access it"); } } if (QFile::exists( sNewFileName )) return QFileInfo( sNewFileName ); PreviewGenerator *previewgen = new PreviewGenerator( &pginfo, QString(), PreviewGenerator::kLocal); previewgen->SetPreviewTimeAsSeconds( nSecsIn ); previewgen->SetOutputFilename ( sNewFileName ); previewgen->SetOutputSize (QSize(nWidth,nHeight)); bool ok = previewgen->Run(); previewgen->deleteLater(); if (!ok) return QFileInfo(); return QFileInfo( sNewFileName ); }
DTC::LiveStreamInfo *Content::AddRecordingLiveStream( int nRecordedId, int nChanId, const QDateTime &recstarttsRaw, int nMaxSegments, int nWidth, int nHeight, int nBitrate, int nAudioBitrate, int nSampleRate ) { if ((nRecordedId <= 0) && (nChanId <= 0 || !recstarttsRaw.isValid())) throw QString("Recorded ID or Channel ID and StartTime appears invalid."); // ------------------------------------------------------------------ // Read Recording From Database // ------------------------------------------------------------------ // TODO Should use RecordingInfo ProgramInfo pginfo; if (nRecordedId > 0) pginfo = ProgramInfo(nRecordedId); else pginfo = ProgramInfo(nChanId, recstarttsRaw.toUTC()); if (!pginfo.GetChanID()) { LOG(VB_UPNP, LOG_ERR, QString("AddRecordingLiveStream - for %1, %2 failed") .arg(QString::number(nRecordedId))); return NULL; } if (pginfo.GetHostname().toLower() != gCoreContext->GetHostName().toLower()) { // We only handle requests for local resources QString sMsg = QString("GetRecording: Wrong Host '%1' request from '%2'.") .arg( gCoreContext->GetHostName()) .arg( pginfo.GetHostname() ); LOG(VB_UPNP, LOG_ERR, sMsg); throw HttpRedirectException( pginfo.GetHostname() ); } QString sFileName( GetPlaybackURL(&pginfo) ); // ---------------------------------------------------------------------- // check to see if the file exists // ---------------------------------------------------------------------- if (!QFile::exists( sFileName )) { LOG( VB_UPNP, LOG_ERR, QString("AddRecordingLiveStream - for %1, %2 failed") .arg( nChanId ) .arg( recstarttsRaw.toUTC().toString() )); return NULL; } QFileInfo fInfo( sFileName ); return AddLiveStream( pginfo.GetStorageGroup(), fInfo.fileName(), pginfo.GetHostname(), nMaxSegments, nWidth, nHeight, nBitrate, nAudioBitrate, nSampleRate ); }