void RecordingsResponder::replyEditedFileName(ostream& out, cxxtools::http::Request& request, cxxtools::http::Reply& reply) { QueryHandler q("/recordings/editedfile", request); const cRecording* recording = getRecordingByRequest(q); if (recording == NULL) { reply.httpReturn(404, "Requested recording not found!"); return; } RecordingList* recordingList = getRecordingList(out, q, reply); if (recordingList == NULL) { return; } #if APIVERSNUM > 20300 LOCK_RECORDINGS_READ; const cRecordings& recordings = *Recordings; #else cRecordings& recordings = Recordings; #endif const cRecording* editedFile = recordings.GetByName(cCutter::EditedFileName(recording->FileName())); if (editedFile == NULL) { reply.httpReturn(404, "Requested edited file not found!"); return; } recordingList->init(); recordingList->addRecording(editedFile, editedFile->Index(), NULL, ""); recordingList->setTotal(recordings.Count()); recordingList->finish(); delete recordingList; };
DTC::ProgramList* Dvr::GetUpcomingList( int nStartIndex, int nCount, bool bShowAll ) { RecordingList recordingList; RecordingList tmpList; bool hasConflicts; LoadFromScheduler(tmpList, hasConflicts); // Sort the upcoming into only those which will record RecordingList::iterator it = tmpList.begin(); for(; it < tmpList.end(); ++it) { if (!bShowAll && ((*it)->GetRecordingStatus() <= rsWillRecord) && ((*it)->GetRecordingStartTime() >= QDateTime::currentDateTime())) { recordingList.push_back(new RecordingInfo(**it)); } else if (bShowAll && ((*it)->GetRecordingStartTime() >= QDateTime::currentDateTime())) { recordingList.push_back(new RecordingInfo(**it)); } } // ---------------------------------------------------------------------- // Build Response // ---------------------------------------------------------------------- DTC::ProgramList *pPrograms = new DTC::ProgramList(); nStartIndex = min( nStartIndex, (int)recordingList.size() ); nCount = (nCount > 0) ? min( nCount, (int)recordingList.size() ) : recordingList.size(); int nEndIndex = min((nStartIndex + nCount), (int)recordingList.size() ); for( int n = nStartIndex; n < nEndIndex; n++) { ProgramInfo *pInfo = recordingList[ n ]; DTC::Program *pProgram = pPrograms->AddNewProgram(); FillProgramInfo( pProgram, pInfo, true ); } // ---------------------------------------------------------------------- pPrograms->setStartIndex ( nStartIndex ); pPrograms->setCount ( nCount ); pPrograms->setTotalAvailable( recordingList.size() ); pPrograms->setAsOf ( QDateTime::currentDateTime() ); pPrograms->setVersion ( MYTH_BINARY_VERSION ); pPrograms->setProtoVer ( MYTH_PROTO_VERSION ); return pPrograms; }
DTC::ProgramList* Dvr::GetConflictList( int nStartIndex, int nCount, int nRecordId ) { RecordingList recordingList; RecordingList tmpList; bool hasConflicts; if (nRecordId <= 0) nRecordId = -1; LoadFromScheduler(tmpList, hasConflicts, "", nRecordId); // Sort the upcoming into only those which are conflicts RecordingList::iterator it = tmpList.begin(); for(; it < tmpList.end(); ++it) { if (nRecordId > 0 && (*it)->GetRecordingRuleID() != static_cast<uint>(nRecordId)) continue; if (((*it)->GetRecordingStatus() == RecStatus::Conflict) && ((*it)->GetRecordingStartTime() >= MythDate::current())) { recordingList.push_back(new RecordingInfo(**it)); } } // ---------------------------------------------------------------------- // Build Response // ---------------------------------------------------------------------- DTC::ProgramList *pPrograms = new DTC::ProgramList(); nStartIndex = min( nStartIndex, (int)recordingList.size() ); nCount = (nCount > 0) ? min( nCount, (int)recordingList.size() ) : recordingList.size(); int nEndIndex = min((nStartIndex + nCount), (int)recordingList.size() ); for( int n = nStartIndex; n < nEndIndex; n++) { ProgramInfo *pInfo = recordingList[ n ]; DTC::Program *pProgram = pPrograms->AddNewProgram(); FillProgramInfo( pProgram, pInfo, true ); } // ---------------------------------------------------------------------- pPrograms->setStartIndex ( nStartIndex ); pPrograms->setCount ( nCount ); pPrograms->setTotalAvailable( recordingList.size() ); pPrograms->setAsOf ( MythDate::current() ); pPrograms->setVersion ( MYTH_BINARY_VERSION ); pPrograms->setProtoVer ( MYTH_PROTO_VERSION ); return pPrograms; }
void RecordingsResponder::initServerList(ostream& out, cxxtools::http::Request& request, cxxtools::http::Reply& reply, SyncMap* sync_map) { QueryHandler q("/recordings/sync", request); RecordingList* recordingList = getRecordingList(out, q, reply, false); if (recordingList == NULL) { return; } #if APIVERSNUM > 20300 LOCK_RECORDINGS_READ; const cRecordings& recordings = *Recordings; #else cRecordings& recordings = Recordings; #endif for (int i = 0; i < recordings.Count(); i++) { recordingList->addRecording(recordings.Get(i), i, sync_map, ""); } delete recordingList; };
DTC::ProgramList* Dvr::GetConflictList( int nStartIndex, int nCount, int nRecordId ) { RecordingList recordingList; // Auto-delete deque RecList tmpList; // Standard deque, objects must be deleted if (nRecordId <= 0) nRecordId = -1; // NOTE: Fetching this information directly from the schedule is // significantly faster than using ProgramInfo::LoadFromScheduler() Scheduler *scheduler = dynamic_cast<Scheduler*>(gCoreContext->GetScheduler()); if (scheduler) scheduler->GetAllPending(tmpList, nRecordId); // Sort the upcoming into only those which are conflicts RecList::iterator it = tmpList.begin(); for(; it < tmpList.end(); ++it) { if (((*it)->GetRecordingStatus() == RecStatus::Conflict) && ((*it)->GetRecordingStartTime() >= MythDate::current())) { recordingList.push_back(new RecordingInfo(**it)); } delete *it; *it = NULL; } // ---------------------------------------------------------------------- // Build Response // ---------------------------------------------------------------------- DTC::ProgramList *pPrograms = new DTC::ProgramList(); nStartIndex = min( nStartIndex, (int)recordingList.size() ); nCount = (nCount > 0) ? min( nCount, (int)recordingList.size() ) : recordingList.size(); int nEndIndex = min((nStartIndex + nCount), (int)recordingList.size() ); for( int n = nStartIndex; n < nEndIndex; n++) { ProgramInfo *pInfo = recordingList[ n ]; DTC::Program *pProgram = pPrograms->AddNewProgram(); FillProgramInfo( pProgram, pInfo, true ); } // ---------------------------------------------------------------------- pPrograms->setStartIndex ( nStartIndex ); pPrograms->setCount ( nCount ); pPrograms->setTotalAvailable( recordingList.size() ); pPrograms->setAsOf ( MythDate::current() ); pPrograms->setVersion ( MYTH_BINARY_VERSION ); pPrograms->setProtoVer ( MYTH_PROTO_VERSION ); return pPrograms; }
void RecordingsResponder::showRecordings(ostream& out, cxxtools::http::Request& request, cxxtools::http::Reply& reply) { QueryHandler q("/recordings", request); bool read_marks = q.getOptionAsString("marks") == "true"; string sync_id = q.getOptionAsString("syncId"); RecordingList* recordingList = getRecordingList(out, q, reply, read_marks); if (recordingList == NULL) { return; } SyncMap* sync_map = new SyncMap(q); int start_filter = q.getOptionAsInt("start"); int limit_filter = q.getOptionAsInt("limit"); const cRecording* recording = getRecordingByRequest(q); if ( start_filter >= 0 && limit_filter >= 1 ) { recordingList->activateLimit(start_filter, limit_filter); } recordingList->init(); #if APIVERSNUM > 20300 LOCK_RECORDINGS_READ; const cRecordings& recordings = *Recordings; #else cRecordings& recordings = Recordings; #endif if ( recording == NULL ) { for (int i = 0; i < recordings.Count(); i++) { recordingList->addRecording(recordings.Get(i), i, sync_map, ""); } } else { recordingList->addRecording(recording, recording->Index(), sync_map, ""); } recordingList->setTotal(recordings.Count()); recordingList->finish(); delete recordingList; if (sync_map->active()) { sync_map->write(); } delete sync_map; }
void RecordingsResponder::showRecordings(ostream& out, cxxtools::http::Request& request, cxxtools::http::Reply& reply) { QueryHandler q("/recordings", request); RecordingList* recordingList; bool read_marks = q.getOptionAsString("marks") == "true"; if ( q.isFormat(".json") ) { reply.addHeader("Content-Type", "application/json; charset=utf-8"); recordingList = (RecordingList*)new JsonRecordingList(&out, read_marks); } else if ( q.isFormat(".html") ) { reply.addHeader("Content-Type", "text/html; charset=utf-8"); recordingList = (RecordingList*)new HtmlRecordingList(&out, read_marks); } else if ( q.isFormat(".xml") ) { reply.addHeader("Content-Type", "text/xml; charset=utf-8"); recordingList = (RecordingList*)new XmlRecordingList(&out, read_marks); } else { reply.httpReturn(404, "Resources are not available for the selected format. (Use: .json or .html)"); return; } int start_filter = q.getOptionAsInt("start"); int limit_filter = q.getOptionAsInt("limit"); int requested_item = q.getParamAsInt(0); if ( start_filter >= 0 && limit_filter >= 1 ) { recordingList->activateLimit(start_filter, limit_filter); } recordingList->init(); cRecording* recording = NULL; for (int i = 0; i < Recordings.Count();i++) { if ( requested_item == i || requested_item < 0 ) { recording = Recordings.Get(i); recordingList->addRecording(recording, i); } } recordingList->setTotal(Recordings.Count()); recordingList->finish(); delete recordingList; }
void RecordingsResponder::sendSyncList(ostream& out, cxxtools::http::Request& request, cxxtools::http::Reply& reply, SyncMap* sync_map) { QueryHandler q("/recordings/sync", request); RecordingList* updates = getRecordingList(out, q, reply, false); if (updates == NULL) { return; } map<string, string> updatesList; map<string, string>::iterator itUpdates; updatesList = sync_map->getUpdates(); updates->init(); esyslog("restfulapi: recording updates: %d", (int)updatesList.size()); #if APIVERSNUM > 20300 LOCK_RECORDINGS_READ; const cRecordings& recordings = *Recordings; #else cRecordings& recordings = Recordings; #endif for (itUpdates = updatesList.begin(); itUpdates != updatesList.end(); itUpdates++) { if ( "delete" != itUpdates->second) { const cRecording* recording = recordings.GetByName(itUpdates->first.c_str()); updates->addRecording(recording, recording->Index(), NULL, itUpdates->second, true); } else { const cRecording* recording = new cRecording(itUpdates->first.c_str()); updates->addRecording(recording, -1, NULL, itUpdates->second, true); delete recording; } } updates->setTotal(updatesList.size()); updates->finish(); delete updates; };
PVR_ERROR DVBLinkClient::GetTimers(ADDON_HANDLE handle) { PVR_ERROR result = PVR_ERROR_FAILED; PLATFORM::CLockObject critsec(m_mutex); GetRecordingsRequest recordingsRequest; RecordingList recordings; DVBLinkRemoteStatusCode status; if ((status = m_dvblinkRemoteCommunication->GetRecordings(recordingsRequest, recordings)) != DVBLINK_REMOTE_STATUS_OK) { std::string error; m_dvblinkRemoteCommunication->GetLastError(error); XBMC->Log(LOG_ERROR, "Could not get timers (Error code : %d Description : %s)", (int)status, error.c_str()); return result; } XBMC->Log(LOG_INFO, "Found %d timers", recordings.size()); if (m_showinfomsg) { XBMC->QueueNotification(QUEUE_INFO, XBMC->GetLocalizedString(32007), recordings.size()); } for (size_t i=0; i < recordings.size(); i++) { Recording* rec = recordings[i]; PVR_TIMER xbmcTimer; memset(&xbmcTimer, 0, sizeof(PVR_TIMER)); //fake index xbmcTimer.iClientIndex = i; //misuse strDirectory to keep id of the timer std::string timer_hash = make_timer_hash(rec->GetID(), rec->GetScheduleID()); PVR_STRCPY(xbmcTimer.strDirectory, timer_hash.c_str()); xbmcTimer.iClientChannelUid = GetInternalUniqueIdFromChannelId(rec->GetChannelID()); xbmcTimer.state = PVR_TIMER_STATE_SCHEDULED; if (rec->IsActive) xbmcTimer.state = PVR_TIMER_STATE_RECORDING; if (rec->IsConflict) xbmcTimer.state = PVR_TIMER_STATE_CONFLICT_NOK; if (!rec->GetProgram().IsRecord) xbmcTimer.state = PVR_TIMER_STATE_CANCELLED; xbmcTimer.bIsRepeating = rec->GetProgram().IsRepeatRecord; xbmcTimer.iEpgUid = rec->GetProgram().GetStartTime(); xbmcTimer.startTime =rec->GetProgram().GetStartTime(); xbmcTimer.endTime = rec->GetProgram().GetStartTime() + rec->GetProgram().GetDuration(); PVR_STRCPY(xbmcTimer.strTitle, rec->GetProgram().GetTitle().c_str()); PVR_STRCPY(xbmcTimer.strSummary, rec->GetProgram().ShortDescription.c_str()); int genre_type, genre_subtype; SetEPGGenre(rec->GetProgram(), genre_type, genre_subtype); if (genre_type == EPG_GENRE_USE_STRING) { xbmcTimer.iGenreType = EPG_EVENT_CONTENTMASK_UNDEFINED; } else { xbmcTimer.iGenreType = genre_type; xbmcTimer.iGenreSubType = genre_subtype; } PVR->TransferTimerEntry(handle, &xbmcTimer); XBMC->Log(LOG_INFO, "Added EPG timer : %s", rec->GetProgram().GetTitle().c_str()); } m_timerCount = recordings.size(); result = PVR_ERROR_NO_ERROR; return result; }
/* move or copy recording */ void RecordingsResponder::moveRecording(ostream& out, cxxtools::http::Request& request, cxxtools::http::Reply& reply) { QueryHandler q("/recordings/move", request); string source = q.getBodyAsString("source"); string target = q.getBodyAsString("target"); bool copy_only = q.getBodyAsBool("copy_only"); #if APIVERSNUM > 20300 LOCK_RECORDINGS_WRITE; cRecordings& recordings = *Recordings; #else cThreadLock RecordingsLock(&Recordings); cRecordings& recordings = Recordings; #endif if (source.length() <= 0 || target.length() <= 0) { reply.httpReturn(404, "Missing file name!"); return; } else if (access(source.c_str(), F_OK) != 0) { reply.httpReturn(504, "Path is invalid!"); return; } const cRecording* recording = recordings.GetByName(source.c_str()); if (!recording) { reply.httpReturn(504, "Recording not found!"); return; } //string newname = VdrExtension::MoveRecording(recording, VdrExtension::FileSystemExchangeChars(target.c_str(), true), copy_only); string oldname = recording->FileName(); size_t found = oldname.find_last_of("/"); if (found == string::npos) { LOG_ERROR_STR(source.c_str()); reply.httpReturn(503, "File copy failed!"); return; } #if APIVERSNUM > 20101 string newname = string(cVideoDirectory::Name()) + "/" + VdrExtension::FileSystemExchangeChars(target.c_str(), true) + oldname.substr(found); #else string newname = string(VideoDirectory) + "/" + VdrExtension::FileSystemExchangeChars(target.c_str(), true) + oldname.substr(found); #endif if (!VdrExtension::MoveDirectory(oldname.c_str(), newname.c_str(), copy_only)) { esyslog("[Restfulapi]: renaming failed from '%s' to '%s'", oldname.c_str(), newname.c_str()); reply.httpReturn(503, "File copy failed!"); return; } if (!copy_only) recordings.DelByName(oldname.c_str()); recordings.AddByName(newname.c_str()); cRecordingUserCommand::InvokeCommand(*cString::sprintf("rename \"%s\"", *strescape(oldname.c_str(), "\\\"$'")), newname.c_str()); const cRecording* new_recording = recordings.GetByName(newname.c_str()); if (!new_recording) { LOG_ERROR_STR(newname.c_str()); reply.httpReturn(504, "Recording not found, after moving!"); return; } esyslog("restfulapi: %s, %d", new_recording->FileName(), new_recording->Index()); RecordingList* recordingList = getRecordingList(out, q, reply); if (recordingList == NULL) { return; } recordingList->addRecording(new_recording, new_recording->Index(), NULL, ""); recordingList->setTotal(recordings.Count()); recordingList->finish(); delete recordingList; }