// Delete a recording bool filmonAPIdeleteRecording(unsigned int recordingId) { bool res = false; std::cerr << "FilmonAPI: number recordings is " << recordings.size() << std::endl; for (unsigned int i = 0; i < recordings.size(); i++) { std::cerr << "FilmonAPI: looking for recording " << intToString(recordingId) << std::endl; if ((recordings[i].strRecordingId).compare(intToString(recordingId)) == 0) { std::string params = "record_id=" + recordings[i].strRecordingId; res = filmonRequest("tv/api/dvr/remove", sessionKeyParam + "&" + params); if (res) { Json::Value root; Json::Reader reader; reader.parse(&response.memory[0], &response.memory[(long) response.size - 1], root); if (root["success"].asBool()) { recordings.erase(recordings.begin() + i); std::cerr << "FilmonAPI: deleted recording" << std::endl; } else { res = false; } clearResponse(); } break; } std::cerr << "FilmonAPI: found recording " << recordings[i].strRecordingId << std::endl; } return res; }
void XMLHttpRequest::abort() { WTF_LOG(Network, "XMLHttpRequest %p abort()", this); // internalAbort() calls dropProtection(), which may release the last reference. RefPtr<XMLHttpRequest> protect(this); bool sendFlag = m_loader; // Response is cleared next, save needed progress event data. long long expectedLength = m_response.expectedContentLength(); long long receivedLength = m_receivedLength; if (!internalAbort()) return; clearResponse(); // Clear headers as required by the spec m_requestHeaders.clear(); if (!((m_state <= OPENED && !sendFlag) || m_state == DONE)) { ASSERT(!m_loader); handleRequestError(0, EventTypeNames::abort, receivedLength, expectedLength); } m_state = UNSENT; }
// SWF player URL void filmonAPIgetswfPlayer() { swfPlayer = std::string( "/tv/modules/FilmOnTV/files/flashapp/filmon/FilmonPlayer.swf?v=56"); bool res = filmonRequest("tv/", ""); if (res == true) { char *resp = (char *) malloc(response.size); strcpy(resp, response.memory); char *token = strtok(resp, " "); while (token != NULL) { if (strcmp(token, "flash_config") == 0) { token = strtok(NULL, " "); token = strtok(NULL, " "); break; } token = strtok(NULL, " "); } Json::Value root; Json::Reader reader; if (reader.parse(std::string(token), root)) { Json::Value streamer = root["streamer"]; swfPlayer = streamer.asString(); std::cerr << "FilmonAPI: parsed flash config " << swfPlayer << std::endl; } clearResponse(); } swfPlayer = std::string("http://www.filmon.com") + swfPlayer; std::cerr << "FilmonAPI: swfPlayer is " << swfPlayer << std::endl; }
void XMLHttpRequest::handleDidFailGeneric() { clearResponse(); clearRequest(); m_error = true; }
// Delete a timer bool filmonAPIdeleteTimer(unsigned int timerId, bool bForceDelete) { bool res = true; for (unsigned int i = 0; i < timers.size(); i++) { std::cerr << "FilmonAPI: looking for timer " << timerId << std::endl; if (timers[i].iClientIndex == timerId) { time_t t = time(0); if ((t >= timers[i].startTime && t <= timers[i].endTime && bForceDelete) || t < timers[i].startTime || t > timers[i].endTime) { std::string params = "record_id=" + intToString(timerId); res = filmonRequest("tv/api/dvr/remove", sessionKeyParam + "&" + params); if (res) { Json::Value root; Json::Reader reader; reader.parse(&response.memory[0], &response.memory[(long) response.size - 1], root); if (root["success"].asBool()) { timers.erase(timers.begin() + i); std::cerr << "FilmonAPI: deleted timer" << std::endl; } else { res = false; } clearResponse(); } } break; } std::cerr << "FilmonAPI: found timer " << timerId << std::endl; } return res; }
void XMLHttpRequest::genericError() { clearResponse(); clearRequest(); m_error = true; changeState(DONE); }
void XMLHttpRequest::genericError() { clearResponse(); clearRequest(); m_error = true; // The spec says we should "Synchronously switch the state to DONE." and then "Synchronously dispatch a readystatechange event on the object" // but this does not match Firefox. }
void XMLHttpRequest::open(const String& method, const KURL& url, bool async, ExceptionCode& ec) { internalAbort(); State previousState = m_state; m_state = UNSENT; m_error = false; m_uploadComplete = false; // clear stuff from possible previous load clearResponse(); clearRequest(); ASSERT(m_state == UNSENT); if (!isValidHTTPToken(method)) { ec = SYNTAX_ERR; return; } if (!isAllowedHTTPMethod(method)) { ec = SECURITY_ERR; return; } if (!scriptExecutionContext()->contentSecurityPolicy()->allowConnectFromSource(url)) { // FIXME: Should this be throwing an exception? ec = SECURITY_ERR; return; } // Newer functionality is not available to synchronous requests in window contexts, as a spec-mandated // attempt to discourage synchronous XHR use. responseType is one such piece of functionality. // We'll only disable this functionality for HTTP(S) requests since sync requests for local protocols // such as file: and data: still make sense to allow. if (!async && scriptExecutionContext()->isDocument() && url.protocolIsInHTTPFamily() && m_responseTypeCode != ResponseTypeDefault) { logConsoleError(scriptExecutionContext(), "Synchronous HTTP(S) requests made from the window context cannot have XMLHttpRequest.responseType set."); ec = INVALID_ACCESS_ERR; return; } m_method = uppercaseKnownHTTPMethod(method); m_url = url; m_async = async; ASSERT(!m_loader); // Check previous state to avoid dispatching readyState event // when calling open several times in a row. if (previousState != OPENED) changeState(OPENED); else m_state = OPENED; }
// Keepalive bool filmonAPIkeepAlive(void) { bool res = filmonRequest("tv/api/keep-alive", sessionKeyParam); if (!res) { // Login again if it failed filmonAPIlogout(); filmonAPIlogin(filmonUsername, filmonpassword); } else { clearResponse(); } return res; }
void XMLHttpRequest::open(const String& method, const KURL& url, bool async, ExceptionCode& ec) { internalAbort(); State previousState = m_state; m_state = UNSENT; m_error = false; #if ENABLE(XHR_RESPONSE_BLOB) m_asBlob = false; #endif m_uploadComplete = false; // clear stuff from possible previous load clearResponse(); clearRequest(); ASSERT(m_state == UNSENT); if (!isValidToken(method)) { ec = SYNTAX_ERR; return; } // Method names are case sensitive. But since Firefox uppercases method names it knows, we'll do the same. String methodUpper(method.upper()); if (methodUpper == "TRACE" || methodUpper == "TRACK" || methodUpper == "CONNECT") { ec = SECURITY_ERR; return; } m_url = url; if (methodUpper == "COPY" || methodUpper == "DELETE" || methodUpper == "GET" || methodUpper == "HEAD" || methodUpper == "INDEX" || methodUpper == "LOCK" || methodUpper == "M-POST" || methodUpper == "MKCOL" || methodUpper == "MOVE" || methodUpper == "OPTIONS" || methodUpper == "POST" || methodUpper == "PROPFIND" || methodUpper == "PROPPATCH" || methodUpper == "PUT" || methodUpper == "UNLOCK") m_method = methodUpper; else m_method = method; m_async = async; ASSERT(!m_loader); // Check previous state to avoid dispatching readyState event // when calling open several times in a row. if (previousState != OPENED) changeState(OPENED); else m_state = OPENED; }
int eraseLastResponse(struct response_set *responses) { if (!responses) return -1; if (responses->last_response) { struct response *newtail; if (responses->last_response->prev) responses->last_response->prev->next=NULL; newtail=responses->last_response->prev; if (responses->responses==responses->last_response) responses->responses=NULL; clearResponse(&responses->last_response); responses->last_response=newtail; responses->response_count--; } return 0; }
// Session bool filmonAPIgetSessionKey(void) { bool res = filmonRequest("tv/api/init?channelProvider=ipad&app_id=IGlsbSBuVCJ7UDwZBl0eBR4JGgEBERhRXlBcWl0CEw=="); if (res == true) { Json::Value root; Json::Reader reader; reader.parse(&response.memory[0], &response.memory[(long) response.size - 1], root); Json::Value sessionKey = root["session_key"]; sessionKeyParam = "session_key="; sessionKeyParam.append(sessionKey.asString()); std::cerr << "FilmonAPI: got session key '" << sessionKey.asString() << "'" << std::endl; clearResponse(); } return res; }
void XMLHttpRequest::open(const String& method, const KURL& url, bool async, ExceptionCode& ec) { internalAbort(); State previousState = m_state; m_state = UNSENT; m_error = false; m_responseTypeCode = ResponseTypeDefault; m_uploadComplete = false; // clear stuff from possible previous load clearResponse(); clearRequest(); ASSERT(m_state == UNSENT); if (!isValidHTTPToken(method)) { ec = SYNTAX_ERR; return; } if (!isAllowedHTTPMethod(method)) { ec = SECURITY_ERR; return; } if (!scriptExecutionContext()->contentSecurityPolicy()->allowConnectFromSource(url)) { // FIXME: Should this be throwing an exception? ec = SECURITY_ERR; return; } m_method = uppercaseKnownHTTPMethod(method); m_url = url; m_async = async; ASSERT(!m_loader); // Check previous state to avoid dispatching readyState event // when calling open several times in a row. if (previousState != OPENED) changeState(OPENED); else m_state = OPENED; }
// Make a request bool filmonRequest(std::string path, std::string params) { curlResult = CURLE_OK; std::string request = FILMON_URL; int retries = REQUEST_RETRIES; long http_code = 0; // Add params request.append(path); if (params.length() > 0) { request.append("?"); request.append(params); } // Allow request retries do { std::cerr << "FilmonAPI: request is '" << request << "'" << std::endl; response.memory = (char*) (malloc(1)); response.size = 0; if (curl) { curl_easy_setopt(curl, CURLOPT_URL, request.c_str()); curlResult = curl_easy_perform(curl); if (curlResult == CURLE_OK) { curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code); } } std::cerr << "FilmonAPI: response is " << std::string(response.memory).substr(0, RESPONSE_OUTPUT_LENGTH) << std::endl; if (curlResult != CURLE_OK || http_code != 200) { std::cerr << "FilmonAPI: request failure with HTTP code " << http_code << std::endl; clearResponse(); usleep(REQUEST_RETRY_TIMEOUT); } } while (http_code != 200 && --retries > 0); if (curlResult == CURLE_OK && http_code == 200) { return true; } else { filmonAPIDelete(); filmonAPICreate(); return false; } }
// Login subscriber bool filmonAPIlogin(std::string username, std::string password) { bool res = filmonAPIgetSessionKey(); if (res) { std::cerr << "FilmonAPI: logging in user" << std::endl; filmonUsername = username; filmonpassword = password; // Password is MD5 hex CryptoPP::Weak1::MD5 hash; byte digest[CryptoPP::Weak1::MD5::DIGESTSIZE]; hash.CalculateDigest(digest, (byte*) password.c_str(), password.length()); CryptoPP::HexEncoder encoder; std::string md5pwd; encoder.Attach(new CryptoPP::StringSink(md5pwd)); encoder.Put(digest, sizeof(digest)); encoder.MessageEnd(); toLowerCase(md5pwd); std::string params = "login="******"&password="******"tv/api/login", sessionKeyParam + "&" + params); if (res) { Json::Value root; Json::Reader reader; reader.parse(&response.memory[0], &response.memory[(long) response.size - 1], root); // Favorite channels channelList.clear(); Json::Value favouriteChannels = root["favorite-channels"]; unsigned int channelCount = favouriteChannels.size(); for (unsigned int channel = 0; channel < channelCount; channel++) { Json::Value chId = favouriteChannels[channel]["channel"]["id"]; channelList.push_back(chId.asUInt()); std::cerr << "FilmonAPI: added channel " << chId.asUInt() << std::endl; } clearResponse(); } } return res; }
// Channel groups std::vector<FILMON_CHANNEL_GROUP> filmonAPIgetChannelGroups() { bool res = filmonRequest("tv/api/groups", sessionKeyParam); if (res == true) { Json::Value root; Json::Reader reader; reader.parse(&response.memory[0], &response.memory[(long) response.size - 1], root); for (unsigned int i = 0; i < root.size(); i++) { Json::Value groupName = root[i]["group"]; Json::Value groupId = root[i]["group_id"]; Json::Value channels = root[i]["channels"]; FILMON_CHANNEL_GROUP group; group.bRadio = false; group.iGroupId = stringToInt(groupId.asString()); group.strGroupName = groupName.asString(); std::vector<unsigned int> members; unsigned int membersCount = channels.size(); for (unsigned int j = 0; j < membersCount; j++) { Json::Value member = channels[j]; unsigned int ch = stringToInt(member.asString()); if (std::find(channelList.begin(), channelList.end(), ch) != channelList.end()) { members.push_back(ch); std::cerr << "FilmonAPI: added channel " << ch << " to group " << group.strGroupName << std::endl; } } if (members.size() > 0) { group.members = members; groups.push_back(group); std::cerr << "FilmonAPI: added group " << group.strGroupName << std::endl; } } clearResponse(); } return groups; }
// Logout user void filmonAPIlogout(void) { bool res = filmonRequest("tv/api/logout"); if (res == true) { clearResponse(); } }
void XMLHttpRequest::open(const AtomicString& method, const KURL& url, bool async, ExceptionState& exceptionState) { WTF_LOG(Network, "XMLHttpRequest %p open('%s', '%s', %d)", this, method.string().utf8().data(), url.elidedString().utf8().data(), async); if (!internalAbort()) return; State previousState = m_state; m_state = UNSENT; m_error = false; m_uploadComplete = false; // clear stuff from possible previous load clearResponse(); clearRequest(); ASSERT(m_state == UNSENT); if (!isValidHTTPToken(method)) { exceptionState.throwDOMException(SyntaxError, "'" + method + "' is not a valid HTTP method."); return; } if (!isAllowedHTTPMethod(method)) { exceptionState.throwSecurityError("'" + method + "' HTTP method is unsupported."); return; } if (!ContentSecurityPolicy::shouldBypassMainWorld(executionContext()) && !executionContext()->contentSecurityPolicy()->allowConnectToSource(url)) { // We can safely expose the URL to JavaScript, as these checks happen synchronously before redirection. JavaScript receives no new information. exceptionState.throwSecurityError("Refused to connect to '" + url.elidedString() + "' because it violates the document's Content Security Policy."); return; } if (!async && executionContext()->isDocument()) { if (document()->settings() && !document()->settings()->syncXHRInDocumentsEnabled()) { exceptionState.throwDOMException(InvalidAccessError, "Synchronous requests are disabled for this page."); return; } // Newer functionality is not available to synchronous requests in window contexts, as a spec-mandated // attempt to discourage synchronous XHR use. responseType is one such piece of functionality. // We'll only disable this functionality for HTTP(S) requests since sync requests for local protocols // such as file: and data: still make sense to allow. if (url.protocolIsInHTTPFamily() && m_responseTypeCode != ResponseTypeDefault) { exceptionState.throwDOMException(InvalidAccessError, "Synchronous HTTP requests from a document must not set a response type."); return; } // Similarly, timeouts are disabled for synchronous requests as well. if (m_timeoutMilliseconds > 0) { exceptionState.throwDOMException(InvalidAccessError, "Synchronous requests must not set a timeout."); return; } } m_method = uppercaseKnownHTTPMethod(method); m_url = url; m_async = async; ASSERT(!m_loader); // Check previous state to avoid dispatching readyState event // when calling open several times in a row. if (previousState != OPENED) changeState(OPENED); else m_state = OPENED; }
void XMLHttpRequest::open(const String& method, const KURL& url, bool async, ExceptionCode& ec) { internalAbort(); State previousState = m_state; m_state = UNSENT; m_error = false; m_uploadComplete = false; // clear stuff from possible previous load clearResponse(); clearRequest(); ASSERT(m_state == UNSENT); if (!isValidHTTPToken(method)) { ec = SYNTAX_ERR; return; } if (!isAllowedHTTPMethod(method)) { ec = SECURITY_ERR; return; } // FIXME: Convert this to check the isolated world's Content Security Policy once webkit.org/b/104520 is solved. bool shouldBypassMainWorldContentSecurityPolicy = false; if (scriptExecutionContext()->isDocument()) { Document* document = static_cast<Document*>(scriptExecutionContext()); shouldBypassMainWorldContentSecurityPolicy = document->frame()->script()->shouldBypassMainWorldContentSecurityPolicy(); } if (!shouldBypassMainWorldContentSecurityPolicy && !scriptExecutionContext()->contentSecurityPolicy()->allowConnectToSource(url)) { // FIXME: Should this be throwing an exception? ec = SECURITY_ERR; return; } if (!async && scriptExecutionContext()->isDocument()) { if (document()->settings() && !document()->settings()->syncXHRInDocumentsEnabled()) { logConsoleError(scriptExecutionContext(), "Synchronous XMLHttpRequests are disabled for this page."); ec = INVALID_ACCESS_ERR; return; } // Newer functionality is not available to synchronous requests in window contexts, as a spec-mandated // attempt to discourage synchronous XHR use. responseType is one such piece of functionality. // We'll only disable this functionality for HTTP(S) requests since sync requests for local protocols // such as file: and data: still make sense to allow. if (url.protocolIsInHTTPFamily() && m_responseTypeCode != ResponseTypeDefault) { logConsoleError(scriptExecutionContext(), "Synchronous HTTP(S) requests made from the window context cannot have XMLHttpRequest.responseType set."); ec = INVALID_ACCESS_ERR; return; } #if ENABLE(XHR_TIMEOUT) // Similarly, timeouts are disabled for synchronous requests as well. if (m_timeoutMilliseconds > 0) { logConsoleError(scriptExecutionContext(), "Synchronous XMLHttpRequests must not have a timeout value set."); ec = INVALID_ACCESS_ERR; return; } #endif } m_method = uppercaseKnownHTTPMethod(method); m_url = url; m_async = async; ASSERT(!m_loader); // Check previous state to avoid dispatching readyState event // when calling open several times in a row. if (previousState != OPENED) changeState(OPENED); else m_state = OPENED; }
// Channel bool filmonAPIgetChannel(unsigned int channelId, FILMON_CHANNEL *channel) { bool res = filmonRequest("tv/api/channel/" + intToString(channelId), sessionKeyParam); if (res == true) { Json::Value root; Json::Reader reader; reader.parse(&response.memory[0], &response.memory[(long) response.size - 1], root); Json::Value title = root["title"]; Json::Value group = root["group"]; Json::Value icon = root["extra_big_logo"]; Json::Value streams = root["streams"]; Json::Value tvguide = root["tvguide"]; std::string streamURL; unsigned int streamCount = streams.size(); unsigned int stream = 0; for (stream = 0; stream < streamCount; stream++) { std::string quality = streams[stream]["quality"].asString(); if (quality.compare(std::string("high")) == 0 || quality.compare(std::string("480p")) == 0 || quality.compare(std::string("HD")) == 0) { std::cerr << "FilmonAPI: high quality stream found: " << quality << std::endl; break; } else { std::cerr << "FilmonAPI: low quality stream found: " << quality << std::endl; } } std::string chTitle = title.asString(); std::string iconPath = icon.asString(); streamURL = streams[stream]["url"].asString(); if (streamURL.find("rtmp://") == 0) { streamURL = filmonAPIgetRtmpStream(streamURL, streams[stream]["name"].asString()); std::cerr << "FilmonAPI: RTMP stream available: " << streamURL << std::endl; } else { std::cerr << "FilmonAPI: HLS stream available: " << streamURL << std::endl; } // Fix channel names logos if (chTitle.compare(std::string("CBEEBIES/BBC Four")) == 0) { chTitle = std::string("BBC Four/CBEEBIES"); iconPath = std::string( "https://dl.dropboxusercontent.com/u/3129606/tvicons/BBC%20FOUR.png"); } if (chTitle.compare(std::string("CBBC/BBC Three")) == 0) { chTitle = std::string("BBC Three/CBBC"); iconPath = std::string( "https://dl.dropboxusercontent.com/u/3129606/tvicons/BBC%20THREE.png"); } std::cerr << "FilmonAPI: title is " << chTitle << std::endl; channel->bRadio = false; channel->iUniqueId = channelId; channel->iChannelNumber = channelId; channel->iEncryptionSystem = 0; channel->strChannelName = chTitle; channel->strIconPath = iconPath; channel->strStreamURL = streamURL; (channel->epg).clear(); // Get EPG std::cerr << "FilmonAPI: building EPG" << std::endl; unsigned int entries = 0; unsigned int programmeCount = tvguide.size(); std::string offAir = std::string("OFF_AIR"); for (unsigned int p = 0; p < programmeCount; p++) { Json::Value broadcastId = tvguide[p]["programme"]; std::string programmeId = broadcastId.asString(); Json::Value startTime = tvguide[p]["startdatetime"]; Json::Value endTime = tvguide[p]["enddatetime"]; Json::Value programmeName = tvguide[p]["programme_name"]; Json::Value plot = tvguide[p]["programme_description"]; Json::Value images = tvguide[p]["images"]; FILMON_EPG_ENTRY epgEntry; if (programmeId.compare(offAir) != 0) { epgEntry.strTitle = programmeName.asString(); epgEntry.iBroadcastId = stringToInt(programmeId); if (plot.isNull() != true) { epgEntry.strPlot = plot.asString(); } if (!images.empty()) { Json::Value programmeIcon = images[0]["url"]; epgEntry.strIconPath = programmeIcon.asString(); } else { epgEntry.strIconPath = ""; } } else { epgEntry.strTitle = offAir; epgEntry.iBroadcastId = 0; epgEntry.strPlot = ""; epgEntry.strIconPath = ""; } epgEntry.iChannelId = channelId; if (startTime.isString()) { epgEntry.startTime = stringToInt(startTime.asString()); epgEntry.endTime = stringToInt(endTime.asString()); } else { epgEntry.startTime = startTime.asUInt(); epgEntry.endTime = endTime.asUInt(); } epgEntry.strPlotOutline = ""; epgEntry.iGenreType = filmonAPIgetGenre(group.asString()); epgEntry.iGenreSubType = 0; (channel->epg).push_back(epgEntry); entries++; } std::cerr << "FilmonAPI: number of EPG entries is " << entries << std::endl; clearResponse(); } return res; }
// Gets all timers and recordings bool filmonAPIgetRecordingsTimers(bool completed) { bool res = filmonRequest("tv/api/dvr/list", sessionKeyParam); if (res == true) { Json::Value root; Json::Reader reader; reader.parse(&response.memory[0], &response.memory[(long) response.size - 1], root); // Usage Json::Value total = root["userStorage"]["total"]; Json::Value used = root["userStorage"]["recorded"]; storageTotal = (long long int) (total.asFloat() * FILMON_ONE_HOUR_RECORDING_SIZE); // bytes storageUsed = (long long int) (used.asFloat() * FILMON_ONE_HOUR_RECORDING_SIZE); // bytes std::cerr << "FilmonAPI: recordings total is " << storageTotal << std::endl; std::cerr << "FilmonAPI: recordings used is " << storageUsed << std::endl; bool timersCleared = false; bool recordingsCleared = false; Json::Value recordingsTimers = root["recordings"]; for (unsigned int recordingId = 0; recordingId < recordingsTimers.size(); recordingId++) { std::string recTimId = recordingsTimers[recordingId]["id"].asString(); std::string recTimTitle = recordingsTimers[recordingId]["title"].asString(); unsigned int recTimStart = stringToInt( recordingsTimers[recordingId]["time_start"].asString()); unsigned int recDuration = stringToInt( recordingsTimers[recordingId]["length"].asString()); Json::Value status = recordingsTimers[recordingId]["status"]; if (completed && status.asString().compare(std::string(RECORDED_STATUS)) == 0) { if (recordingsCleared == false) { recordings.clear(); recordingsCleared = true; } FILMON_RECORDING recording; recording.strRecordingId = recTimId; recording.strTitle = recTimTitle; recording.strStreamURL = recordingsTimers[recordingId]["download_link"].asString(); recording.strPlot = recordingsTimers[recordingId]["description"].asString(); recording.recordingTime = recTimStart; recording.iDuration = recDuration; recording.strIconPath = recordingsTimers[recordingId]["images"]["channel_logo"].asString(); recording.strThumbnailPath = recordingsTimers[recordingId]["images"]["poster"].asString(); recordings.push_back(recording); std::cerr << "FilmonAPI: found completed recording " << recording.strTitle << std::endl; } else if (status.asString().compare(std::string(TIMER_STATUS)) == 0) { if (timersCleared == false) { timers.clear(); timersCleared = true; } FILMON_TIMER timer; timer.iClientIndex = stringToInt(recTimId); timer.iClientChannelUid = stringToInt( recordingsTimers[recordingId]["channel_id"].asString()); timer.startTime = recTimStart; timer.endTime = timer.startTime + recDuration; timer.strTitle = recTimTitle; timer.state = FILMON_TIMER_STATE_NEW; timer.strSummary = recordingsTimers[recordingId]["description"].asString(); setTimerDefaults(&timer); time_t t = time(0); if (t >= timer.startTime && t <= timer.endTime) { std::cerr << "FilmonAPI: found active timer " << timer.strTitle << std::endl; timer.state = FILMON_TIMER_STATE_RECORDING; } else if (t < timer.startTime) { std::cerr << "FilmonAPI: found scheduled timer " << timer.strTitle << std::endl; timer.state = FILMON_TIMER_STATE_SCHEDULED; } else if (t > timer.endTime) { std::cerr << "FilmonAPI: found completed timer " << timer.strTitle << std::endl; timer.state = FILMON_TIMER_STATE_COMPLETED; } timers.push_back(timer); } } clearResponse(); } return res; }
// Add a timer bool filmonAPIaddTimer(int channelId, time_t startTime, time_t endTime) { bool res = filmonRequest("tv/api/tvguide/" + intToString(channelId), sessionKeyParam); if (res) { Json::Value root; Json::Reader reader; reader.parse(&response.memory[0], &response.memory[(long) response.size - 1], root); for (unsigned int i = 0; i < root.size(); i++) { Json::Value start = root[i]["startdatetime"]; Json::Value end = root[i]["enddatetime"]; time_t epgStartTime = 0; time_t epgEndTime = 0; if (start.isString()) { epgStartTime = stringToInt(start.asString()); epgEndTime = stringToInt(end.asString()); } else { epgStartTime = start.asUInt(); epgEndTime = end.asUInt(); } if (epgStartTime == startTime || epgEndTime == endTime) { Json::Value broadcastId = root[i]["programme"]; std::string programmeId = broadcastId.asString(); Json::Value progName = root[i]["programme_name"]; Json::Value progDesc = root[i]["programme_description"]; std::string programmeName = progName.asString(); std::string programmeDesc = progDesc.asString(); std::string params = "channel_id=" + intToString(channelId) + "&programme_id=" + programmeId + "&start_time=" + intToString(epgStartTime); res = filmonRequest("tv/api/dvr/add", sessionKeyParam + "&" + params); if (res) { Json::Value root; Json::Reader reader; reader.parse(&response.memory[0], &response.memory[(long) response.size - 1], root); if (root["success"].asBool()) { FILMON_TIMER timer; timer.iClientIndex = stringToInt(programmeId); timer.iClientChannelUid = channelId; timer.startTime = epgStartTime; timer.endTime = epgEndTime; timer.strTitle = programmeName; timer.strSummary = programmeDesc; time_t t = time(0); if (t >= epgStartTime && t <= epgEndTime) { timer.state = FILMON_TIMER_STATE_RECORDING; } else { timer.state = FILMON_TIMER_STATE_SCHEDULED; } setTimerDefaults(&timer); timers.push_back(timer); std::cerr << "FilmonAPI: added timer" << std::endl; } else { res = false; } } break; } } clearResponse(); } return res; }
void XMLHttpRequest::open(const String& method, const URL& url, bool async, ExceptionCode& ec) { if (!internalAbort()) return; State previousState = m_state; m_state = UNSENT; m_error = false; m_sendFlag = false; m_uploadComplete = false; // clear stuff from possible previous load clearResponse(); clearRequest(); ASSERT(m_state == UNSENT); if (!isValidHTTPToken(method)) { ec = SYNTAX_ERR; return; } if (!isAllowedHTTPMethod(method)) { ec = SECURITY_ERR; return; } if (!async && scriptExecutionContext()->isDocument()) { if (document()->settings() && !document()->settings()->syncXHRInDocumentsEnabled()) { logConsoleError(scriptExecutionContext(), "Synchronous XMLHttpRequests are disabled for this page."); ec = INVALID_ACCESS_ERR; return; } // Newer functionality is not available to synchronous requests in window contexts, as a spec-mandated // attempt to discourage synchronous XHR use. responseType is one such piece of functionality. // We'll only disable this functionality for HTTP(S) requests since sync requests for local protocols // such as file: and data: still make sense to allow. if (url.protocolIsInHTTPFamily() && m_responseType != ResponseType::EmptyString) { logConsoleError(scriptExecutionContext(), "Synchronous HTTP(S) requests made from the window context cannot have XMLHttpRequest.responseType set."); ec = INVALID_ACCESS_ERR; return; } // Similarly, timeouts are disabled for synchronous requests as well. if (m_timeoutMilliseconds > 0) { logConsoleError(scriptExecutionContext(), "Synchronous XMLHttpRequests must not have a timeout value set."); ec = INVALID_ACCESS_ERR; return; } } m_method = uppercaseKnownHTTPMethod(method); m_url = url; scriptExecutionContext()->contentSecurityPolicy()->upgradeInsecureRequestIfNeeded(m_url, ContentSecurityPolicy::InsecureRequestType::Load); m_async = async; ASSERT(!m_loader); // Check previous state to avoid dispatching readyState event // when calling open several times in a row. if (previousState != OPENED) changeState(OPENED); else m_state = OPENED; }