void PublishToMePlugin::checkDownloadLink() { QNetworkReply *reply = qobject_cast<QNetworkReply*>(sender()); if (!reply) { emit error(tr("Network error")); return; } const QString redirect = getRedirect(reply); if (!redirect.isEmpty()) { if (FILE_REGEXP.indexIn(redirect) == 0) { emit downloadRequest(QNetworkRequest(redirect)); } else if (m_redirects < MAX_REDIRECTS) { followRedirect(redirect, SLOT(checkDownloadLink())); } else { emit error(tr("Maximum redirects reached")); } reply->deleteLater(); return; } switch (reply->error()) { case QNetworkReply::NoError: break; case QNetworkReply::OperationCanceledError: reply->deleteLater(); return; default: emit error(reply->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toString()); reply->deleteLater(); return; } const QString response = QString::fromUtf8(reply->readAll()); if (FILE_REGEXP.indexIn(response) != -1) { QString url = FILE_REGEXP.cap(); if (url.startsWith("/")) { url.prepend(reply->url().scheme() + "://" + reply->url().authority()); } emit downloadRequest(QNetworkRequest(url)); } else { emit error(tr("Unknown error")); } reply->deleteLater(); }
void PublishToMePlugin::checkUrlIsValid() { QNetworkReply *reply = qobject_cast<QNetworkReply*>(sender()); if (!reply) { emit error(tr("Network error")); return; } const QString redirect = getRedirect(reply); if (!redirect.isEmpty()) { if (FILE_REGEXP.indexIn(redirect) == 0) { emit urlChecked(UrlResult(reply->request().url().toString(), redirect.mid(redirect.lastIndexOf("/") + 1))); } else if (m_redirects < MAX_REDIRECTS) { followRedirect(redirect, SLOT(checkUrlIsValid())); } else { emit error(tr("Maximum redirects reached")); } reply->deleteLater(); return; } switch (reply->error()) { case QNetworkReply::NoError: break; case QNetworkReply::OperationCanceledError: reply->deleteLater(); return; default: emit error(reply->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toString()); reply->deleteLater(); return; } const QString response = QString::fromUtf8(reply->readAll()); const QString fileName = response.section("icon-download-alt\" style=\"\"></i>", 1, 1) .section("</div>", 0, 0).trimmed(); if (fileName.isEmpty()) { emit error(tr("File not found")); } else { emit urlChecked(UrlResult(reply->request().url().toString(), fileName)); } reply->deleteLater(); }
void MybbFeedRequest::checkLogin() { QNetworkReply *reply = qobject_cast<QNetworkReply*>(sender()); if (!reply) { setErrorString(tr("Network error")); setStatus(Error); emit finished(this); return; } QString redirect = getRedirect(reply); if (!redirect.isEmpty()) { reply->deleteLater(); if (m_redirects < MAX_REDIRECTS) { followRedirect(redirect, SLOT(checkLogin())); } else { setErrorString(tr("Maximum redirects reached")); setStatus(Error); emit finished(this); } return; } switch (reply->error()) { case QNetworkReply::NoError: #ifdef MYBB_DEBUG qDebug() << "MybbFeedRequest::checkLogin(). OK"; #endif getPage(m_settings.value("url").toString()); reply->deleteLater(); break; case QNetworkReply::OperationCanceledError: setErrorString(QString()); setStatus(Canceled); emit finished(this); break; default: #ifdef MYBB_DEBUG qDebug() << "MybbFeedRequest::checkLogin(). Error"; #endif setErrorString(reply->errorString()); setStatus(Error); emit finished(this); break; } }
void _q_onDownloadRedirect() { if (!reply) { return; } if (reply->error() == QNetworkReply::NoError) { QUrl redirect = reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toString(); if (redirect.isEmpty()) { redirect = reply->header(QNetworkRequest::LocationHeader).toString(); } if (!redirect.isEmpty()) { redirect.setScheme("http"); QString ext = track.value("original_format").toString(); formats << Format("original", QString("%1 (%2)").arg(StreamsRequest::tr("Original format")).arg(ext.toUpper()), ext, redirect); } } reply->deleteLater(); reply = 0; if (track.value("streamable").toBool()) { getRedirect(track.value("stream_url").toString(), SLOT(_q_onStreamRedirect())); } else { Q_Q(StreamsRequest); setResult(formats); setStatus(Request::Ready); setError(Request::NoError); setErrorString(QString()); emit q->finished(); } }
void _q_onReplyFinished() { if (!reply) { return; } Q_Q(StreamsRequest); if (redirects < MAX_REDIRECTS) { QUrl redirect = reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toString(); if (redirect.isEmpty()) { redirect = reply->header(QNetworkRequest::LocationHeader).toString(); } if (!redirect.isEmpty()) { reply->deleteLater(); reply = 0; followRedirect(redirect); return; } } QString response = QString::fromUtf8(reply->readAll()); QNetworkReply::NetworkError e = reply->error(); QString es = reply->errorString(); reply->deleteLater(); reply = 0; switch (e) { case QNetworkReply::NoError: break; case QNetworkReply::OperationCanceledError: setStatus(Request::Canceled); setError(Request::NoError); setErrorString(QString()); emit q->finished(); return; case QNetworkReply::AuthenticationRequiredError: if (refreshToken.isEmpty()) { setStatus(Request::Failed); setError(Request::Error(e)); setErrorString(es); emit q->finished(); } else { refreshAccessToken(); } return; default: setStatus(Request::Failed); setError(Request::Error(e)); setErrorString(es); emit q->finished(); return; } bool ok = true; track = QtJson::Json::parse(response, ok).toMap(); formats.clear(); if (ok) { if (track.value("downloadable").toBool()) { getRedirect(track.value("download_url").toString(), SLOT(_q_onDownloadRedirect())); return; } if (track.value("streamable").toBool()) { getRedirect(track.value("stream_url").toString(), SLOT(_q_onStreamRedirect())); return; } setResult(formats); setStatus(Request::Ready); setError(Request::NoError); setErrorString(QString()); } else { setStatus(Request::Failed); setError(Request::ParseError); setErrorString(Request::tr("Unable to parse response")); } emit q->finished(); }
/** * Parse Tokens * Description: Takes a TokenList and a Command object and parses the TokenList in order * to generate a command (list of programs in a pipeline); * Returns: true on success; false otherwise */ bool parseTokens( TokenList tokens, Command * command ) { bool success = true; Program *currentProgram = command->program = newProgram(); bool begin = true; for (int i = 0; i < tokens.count; i++) { char * token = tokens.tokens[i]; // Check if we are at the beginning of a program if ( begin ) { if ( strncmp( token, "time", max( strlen( token ), strlen( "time" ) ) ) == 0 ) { currentProgram->name = token; currentProgram->next = newProgram(); currentProgram = currentProgram->next; begin = true; // If we have at least two tokens left and the next one is a pipe // then make a blank timed program // Note: This doesn't do anything since we don't allow // piped time commands but this would help support it // in the future and it currently prevents better // error checking if ( i + 2 < tokens.count && isPipe( tokens.tokens[i+1] ) ) { currentProgram->name = NULL; currentProgram->next = newProgram(); currentProgram = currentProgram->next; i++; } // The beginning of a program cannot be <, >, &, or | } else if ( !isRedirection( token ) && !isPipe( token ) && !isBackground( token ) ) { currentProgram->name = token; currentProgram->argv[currentProgram->argc++] = token; // Don't come back here again until we process a new program begin = false; } else { error("Program may not start with <, >, |, or &"); success = false; break; } } else { // Process redirection if ( isRedirection( token ) ) { // Only one level of redirection allowed if ( currentProgram->redirect == DEFAULT ) { // Need to have at least one token after a redirect if ( i+1 < tokens.count ) { if ( !isRedirection(tokens.tokens[i+1]) && !isPipe(tokens.tokens[i+1]) && !isBackground(tokens.tokens[i+1]) ) { currentProgram->redirectResource = tokens.tokens[i+1]; currentProgram->redirect = getRedirect( token ); // Skip a token i++; } else { error("Expected file after a redirect"); success = false; break; } } // We can have redirections like <file or >file else if ( strlen( token ) > 1 ) { currentProgram->redirectResource = token+1; currentProgram->redirect = getRedirect( token ); } else { error("Expected file after a redirect"); success = false; break; } } else { error("Only one level of redirection allowed"); success = false; break; } // Process pipe } else if ( isPipe( token ) ) { // Check if there's a token after this one if ( i+1 < tokens.count ) { currentProgram->next = newProgram(); currentProgram = currentProgram->next; begin = true; } else { error("Expected program after pipe"); success = false; break; } // Process background } else if ( isBackground( token ) ) { // & must be last token if ( i+1 >= tokens.count ) command->background = true; else { error("& can only be placed at end of command"); success = false; } break; } // Plain old argument else currentProgram->argv[currentProgram->argc++] = token; } } return success; }
void PublishToMePlugin::checkCaptcha() { QNetworkReply *reply = qobject_cast<QNetworkReply*>(sender()); if (!reply) { emit error(tr("Network error")); return; } const QString redirect = getRedirect(reply); if (!redirect.isEmpty()) { if (FILE_REGEXP.indexIn(redirect) == 0) { emit downloadRequest(QNetworkRequest(redirect)); } else if (m_redirects < MAX_REDIRECTS) { followRedirect(redirect, SLOT(checkCaptcha())); } else { emit error(tr("Maximum redirects reached")); } reply->deleteLater(); return; } switch (reply->error()) { case QNetworkReply::NoError: break; case QNetworkReply::OperationCanceledError: reply->deleteLater(); return; default: emit error(reply->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toString()); reply->deleteLater(); return; } const QString response = QString::fromUtf8(reply->readAll()); if (FILE_REGEXP.indexIn(response) != -1) { QString url = FILE_REGEXP.cap(); if (url.startsWith("/")) { url.prepend(reply->url().scheme() + "://" + reply->url().authority()); } emit downloadRequest(QNetworkRequest(url)); } else if (response.contains("verification code is incorrect")) { QString recaptchaKey = response.section("/file/captcha.html?v=", 1, 1).section('"', 0, 0); if (recaptchaKey.isEmpty()) { emit error(tr("No captcha key found")); } else { recaptchaKey.prepend(QString("http://%1/file/captcha.html?v=").arg(reply->url().host())); emit captchaRequest(RECAPTCHA_PLUGIN_ID, CaptchaType::Image, recaptchaKey, "submitCaptchaResponse"); } } else { const int secs = response.section("tik-tak\" >", 1, 1).section('<', 0, 0).toInt(); if (secs > 0) { startWaitTimer(secs * 1000, SLOT(getDownloadLink())); } else { emit error(tr("Unknown error")); } } reply->deleteLater(); }
void PublishToMePlugin::checkWaitTime() { QNetworkReply *reply = qobject_cast<QNetworkReply*>(sender()); if (!reply) { emit error(tr("Network error")); return; } const QString redirect = getRedirect(reply); if (!redirect.isEmpty()) { if (FILE_REGEXP.indexIn(redirect) == 0) { emit downloadRequest(QNetworkRequest(redirect)); } else if (m_redirects < MAX_REDIRECTS) { followRedirect(redirect, SLOT(checkWaitTime())); } else { emit error(tr("Maximum redirects reached")); } reply->deleteLater(); return; } switch (reply->error()) { case QNetworkReply::NoError: break; case QNetworkReply::OperationCanceledError: reply->deleteLater(); return; default: emit error(reply->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toString()); reply->deleteLater(); return; } const QString response = QString::fromUtf8(reply->readAll()); if (FILE_REGEXP.indexIn(response) != -1) { QString url = FILE_REGEXP.cap(); if (url.startsWith("/")) { url.prepend(reply->url().scheme() + "://" + reply->url().authority()); } emit downloadRequest(QNetworkRequest(url)); } else if (response.contains("Downloading is not possible")) { const QTime time = QTime::fromString(response.section("Please wait", 1, 1).section("to download", 0, 0) .trimmed(), "hh:mm:ss"); if (time.isValid()) { emit waitRequest(QTime(0, 0).msecsTo(time), true); } else { emit error(tr("Unknown error")); } } else { QString recaptchaKey = response.section("/file/captcha.html?v=", 1, 1).section('"', 0, 0); if (recaptchaKey.isEmpty()) { emit error(tr("No captcha key found")); } else { recaptchaKey.prepend(QString("http://%1/file/captcha.html?v=").arg(reply->url().host())); emit captchaRequest(RECAPTCHA_PLUGIN_ID, CaptchaType::Image, recaptchaKey, "submitCaptchaResponse"); } } reply->deleteLater(); }
void MybbFeedRequest::checkPage() { QNetworkReply *reply = qobject_cast<QNetworkReply*>(sender()); if (!reply) { setErrorString(tr("Network error")); setStatus(Error); emit finished(this); return; } QString redirect = getRedirect(reply); if (!redirect.isEmpty()) { reply->deleteLater(); if (m_redirects < MAX_REDIRECTS) { followRedirect(redirect, SLOT(checkPage())); } else { setErrorString(tr("Maximum redirects reached")); setStatus(Error); emit finished(this); } return; } switch (reply->error()) { case QNetworkReply::NoError: break; case QNetworkReply::OperationCanceledError: setErrorString(QString()); setStatus(Canceled); emit finished(this); return; default: setErrorString(reply->errorString()); setStatus(Error); emit finished(this); return; } const QUrl url = reply->url(); const QString baseUrl = url.scheme() + "://" + url.authority(); QString page = QString::fromUtf8(reply->readAll()); reply->deleteLater(); fixRelativeUrls(page, baseUrl); const QHtmlDocument document(page); const QHtmlElement html = document.htmlElement(); if (m_results == 0) { QString redirect = getLatestPageUrl(html); if (!redirect.isEmpty()) { if (m_redirects < MAX_REDIRECTS) { followRedirect(redirect, SLOT(checkPage())); } else { setErrorString(tr("Maximum redirects reached")); setStatus(Error); emit finished(this); } return; } #ifdef MYBB_DEBUG qDebug() << "MybbFeedRequest::checkPage(). Writing start of feed"; #endif writeStartFeed(); writeFeedTitle(html); writeFeedUrl(baseUrl); } const QHtmlElementList items = getItems(html); if (items.isEmpty()) { #ifdef MYBB_DEBUG qDebug() << "MybbFeedRequest::checkPage(). No items found. Writing end of feed"; #endif writeEndFeed(); setErrorString(QString()); setStatus(Ready); emit finished(this); return; } const int max = m_settings.value("maxResults", 20).toInt(); int i = items.size() - 1; while ((i >= 0) && (m_results < max)) { const QHtmlElement &item = items.at(i); --i; ++m_results; #ifdef MYBB_DEBUG qDebug() << "MybbFeedRequest::checkPage(). Writing item" << m_results << "of" << max; #endif writeStartItem(); writeItemAuthor(item); writeItemBody(item); writeItemDate(item); writeItemTitle(item); writeItemUrl(item); writeEndItem(); } if (m_results < max) { const QString next = getNextPageUrl(html); if (!next.isEmpty()) { getPage(next); return; } } #ifdef MYBB_DEBUG qDebug() << "MybbFeedRequest::checkPage(). Writing end of feed"; #endif writeEndFeed(); setErrorString(QString()); setStatus(Ready); emit finished(this); }