void HttpRequesterCURL::FinalizeRequests() { long httpResponseStatus = 0; int queuedMessages = 0; CURLMsg* msg = NULL; while((msg = curl_multi_info_read(mHandle, &queuedMessages))) { for(size_t i = 0; i < mHandles.size(); ++i) { if(mHandles[i].handle == msg->easy_handle) { CurlRequest request = mHandles[i]; CURLcode curlCode = curl_easy_getinfo(request.handle, CURLINFO_RESPONSE_CODE, &httpResponseStatus); // TODO: utilize the curlCode if(request.callback != NULL) { request.callback((int)httpResponseStatus, request.request, request.callbackData); } CleanupRequest(request); mHandles.erase(mHandles.begin() + i); break; } } } }
int CurlWrapper::proccess(void* userdata, double dltotal, double dlnow, double ultotal, double ulnow) { if (userdata) { CurlRequest* request = static_cast<CurlRequest*>(userdata); return request->proccess(dltotal, dlnow, ultotal, ulnow); } return -1; }
int CurlWrapper::headerWrite(char* ptr, size_t size, size_t nmemb, void* userdata) { if (userdata) { CurlRequest* request = static_cast<CurlRequest*>(userdata); size_t sizeStr = size * nmemb; return request->headerWrite(ptr, sizeStr); } return 0; }
int CurlWrapper::dataWrite(char* ptr, size_t size, size_t nmemb, void* userdata) { if (userdata) { CurlRequest* request = static_cast<CurlRequest*>(userdata); size_t sizeStr = size * nmemb; if (!request->_canceled) { return request->dataWrite(ptr, sizeStr); } } return 0; }
wxUint32 KissMangaCom::GetMangaListPageCount() { unsigned long result = 500; CurlRequest cr; cr.SetUrl(baseURL + wxT("/MangaList")); cr.SetAgent(agent); cr.SetCookies(cookies); cr.SetCompression(wxT("gzip")); wxString content; wxStringOutputStream sos(&content); cr.SetOutputStream(&sos); cr.ExecuteRequest(); int indexStart = content.find(wxT("class=\"pager\"")) + 13; indexStart = content.find(wxT("</ul>"), indexStart); indexStart = content.rfind(wxT("page="), indexStart) + 6; int indexEnd = content.find(wxT("\""), indexStart); if(indexStart > 5 && indexEnd > -1) { content = content.Mid(indexStart, indexEnd-indexStart); if(content.IsNumber() && content.ToULong(&result)){ return (wxUint32)result; } } Logger::Log(wxT("ERROR +++ KissMangaCom::GetMangaListPageCount() -> Cannot find last page of manga list")); return (wxUint32)result; }
wxArrayString KissMangaCom::GetPageLinks(wxString ChapterLink) { wxArrayString pageLinks; CurlRequest cr; cr.SetUrl(ChapterLink); cr.SetAgent(agent); cr.SetCookies(cookies); cr.SetCompression(wxT("gzip")); wxString content; wxStringOutputStream sos(&content); cr.SetOutputStream(&sos); cr.ExecuteRequest(); int indexStart = content.find(wxT("var lstImages")) + 13; int indexEnd = content.find(wxT("var lstImagesLoaded"), indexStart); if(indexStart > 12 && indexEnd > -1) { content = content.Mid(indexStart, indexEnd-indexStart); indexEnd = 0; // Example Entry: lstImages.push("http://2.bp.blogspot.com/-m2wUve_VBR8/VsFJRUDLJiI/AAAAAAAFMGc/7HfBG-sFqVA/s16000-Ic42/000.png"); while((indexStart = content.find(wxT("lstImages.push(\""), indexEnd)) > -1) { indexStart += 16; indexEnd = content.find(wxT("\""), indexStart); // "\"" pageLinks.Add(content.Mid(indexStart, indexEnd-indexStart)); //wxYield(); } } return pageLinks; }
void LicenseSystem::HandleDeactivate(StringHash eventType, VariantMap& eventData) { Editor* editor = GetSubsystem<Editor>(); CurlRequest* request = (CurlRequest*) (eventData[CurlComplete::P_CURLREQUEST].GetPtr()); if (deactivate_.NotNull()) { assert(request == deactivate_); if (deactivate_->GetError().Length()) { String msg; msg.AppendWithFormat("Unable to deactivate with server: %s", deactivate_->GetError().CString()); editor->PostModalError("Deactivation Error", msg); LOGERROR(msg); } else { String response = request->GetResponse(); if (response.StartsWith("AC_FAILED")) { String msg; msg.AppendWithFormat("Unable to deactivate with server: %s", response.CString()); editor->PostModalError("Deactivation Error", msg); LOGERROR(msg); } else if (response.StartsWith("AC_NOTACTIVATED") || response.StartsWith("AC_SUCCESS")) { ResetLicense(); RemoveLicense(); UIModalOps* ops = GetSubsystem<UIModalOps>(); ops->Hide(); ops->ShowActivation(); } } UnsubscribeFromEvents(deactivate_); deactivate_ = 0; } }
void LicenseSystem::HandleDeactivate(StringHash eventType, VariantMap& eventData) { CurlRequest* request = (CurlRequest*) (eventData[CurlComplete::P_CURLREQUEST].GetPtr()); VariantMap eventDataOut; if (deactivate_.NotNull()) { assert(request == deactivate_); if (deactivate_->GetError().Length()) { String msg = "Deactivation Error:\n"; msg.AppendWithFormat("Unable to deactivate with server: %s", deactivate_->GetError().CString()); eventDataOut[LicenseDeactivationError::P_MESSAGE] = msg; SendEvent(E_LICENSE_DEACTIVATIONERROR, eventDataOut); } else { String response = request->GetResponse(); if (response.StartsWith("AC_FAILED")) { String msg = "Deactivation Error:\n"; msg.AppendWithFormat("Unable to deactivate with server: %s", response.CString()); eventDataOut[LicenseDeactivationError::P_MESSAGE] = msg; SendEvent(E_LICENSE_DEACTIVATIONERROR, eventDataOut); } else if (response.StartsWith("AC_NOTACTIVATED") || response.StartsWith("AC_SUCCESS")) { ResetLicense(); RemoveLicense(); SendEvent(E_LICENSE_DEACTIVATIONSUCCESS); } } UnsubscribeFromEvents(deactivate_); deactivate_ = 0; } }
wxArrayMCEntry KissMangaCom::GetChapterList(MCEntry* MangaEntry) { wxArrayMCEntry chapterList; wxString volumePrefix; wxString chNumber; wxString chEntry; wxString chTitle; wxString chLink; CurlRequest cr; cr.SetUrl(MangaEntry->Link); cr.SetAgent(agent); cr.SetCookies(cookies); cr.SetCompression(wxT("gzip")); wxString content; wxStringOutputStream sos(&content); cr.SetOutputStream(&sos); cr.ExecuteRequest(); int indexStart = content.find(wxT("class=\"listing\"")) + 15; int indexEnd = content.find(wxT("</table>"), indexStart); if(indexStart > 14 && indexEnd > -1) { content = content.Mid(indexStart, indexEnd-indexStart); indexEnd = 0; //Example Entry: /* <a href="/Manga/–-and-–/Vol-003-Ch-014-Read-Online?id=209953" title="Read & – and – Vol.003 Ch.014 Read Online online">& – and – Vol.003 Ch.014 Read Online</a> <a href="/Manga/One-Piece/823---A-World-Abuzz?id=270460" title="Read One Piece 823 - A World Abuzz online">One Piece 823 - A World Abuzz</a> */ while((indexStart = content.find(wxT("<a href=\""), indexEnd)) > -1) { indexStart += 9; indexEnd = content.find(wxT("\""), indexStart); // "\">" chLink = baseURL + content.Mid(indexStart, indexEnd-indexStart); indexStart = indexEnd; indexStart = content.find(wxT(">"), indexStart) + 1; // ">" indexEnd = content.find(wxT("<"), indexStart); // "<" chEntry = content.Mid(indexStart, indexEnd-indexStart); // parse chEntry for: volumePrefix, chNumber, chTitle is impossible, // because KissManga naming is inconsistent // volumePrefix = ... // chNumber = ... // chTitle = ... chapterList.Add(new MCEntry(HtmlUnescapeString(chEntry), chLink)); } } return chapterList; }
void CurlManager::HandleUpdate(StringHash eventType, VariantMap& eventData) { Vector<CurlRequest*> remove; for (unsigned i = 0; i < requests_.Size(); i++) { CurlRequest* request = requests_[i]; if (!request->shouldRun_) { remove.Push(request); VariantMap eventData; eventData[CurlComplete::P_CURLREQUEST] = request; request->SendEvent(E_CURLCOMPLETE, eventData); } } for (unsigned i = 0; i < remove.Size(); i++) { requests_.Remove(SharedPtr<CurlRequest>(remove[i])); } }
void KissMangaCom::Activate(wxString Link) { wxString tmp = Link + wxT("0xb"); // TODO: get offset from online source in case it changes periodically wxString hash = wxEmptyString; unsigned char sum[32]; SHA256((const unsigned char*)tmp.ToAscii().data(), tmp.Len(), sum); // Scripts/google.js (= CryptoJS) for(int i = 0; i < 32; i++) { hash.Append(wxString::Format(wxT("%02x"), sum[i])); } CurlRequest cr; cr.SetUrl(baseURL + wxT("/0xba93?key=") + hash); cr.SetReferer(Link); cr.SetPostData(wxT("key=") + hash); wxString response; wxStringOutputStream sos(&response); cr.SetOutputStream(&sos); cr.ExecuteRequest(); }
void KissMangaCom::UpdateMangaList() { wxTextFile f; /* if(!mangaListFile.IsDirWritable()) { wxMessageBox(wxT("Access denied!\nConfiguration directory: ") + mangaListFile.GetPath()); return; } */ mangaListFile.Mkdir(0755, wxPATH_MKDIR_FULL); // create file, or open if already exists if(!f.Create(mangaListFile.GetFullPath())) { f.Open(mangaListFile.GetFullPath()); f.Clear(); } wxString mangaLink; wxString mangaLabel; CurlRequest cr; cr.SetAgent(agent); cr.SetCookies(cookies); cr.SetCompression(wxT("gzip")); wxString content; wxStringOutputStream sos(&content); cr.SetOutputStream(&sos); wxUint32 pageMax = GetMangaListPageCount() + 1; for(wxUint32 i=1; i<pageMax; i++) { cr.SetUrl(wxString::Format(baseURL + wxT("/MangaList?page=%u"), i)); content = wxEmptyString; if(cr.ExecuteRequest() && !content.IsEmpty()) { int indexStart = content.find(wxT("class=\"listing\"")) + 15; int indexEnd = indexStart;//content.rfind(wxT("</table>")); if(indexStart > 14 && indexEnd > 14) { // Example Entry: <a class="bigChar" href="/Manga/–-and-–">& – and –</a> while((indexStart = content.find(wxT("class=\"bigChar\""), indexEnd)) > -1) { indexStart += 15; indexStart = content.find(wxT("=\""), indexStart) + 2; // "<a href='" indexEnd = content.find(wxT("\""), indexStart); // "\">" mangaLink = baseURL + content.Mid(indexStart, indexEnd-indexStart); indexStart = indexEnd + 2; indexEnd = content.find(wxT("<"), indexStart); // "</a>" mangaLabel = content.Mid(indexStart, indexEnd-indexStart); if(!mangaLabel.IsEmpty()) { f.AddLine(HtmlUnescapeString(mangaLabel) + wxT("\t") + mangaLink); } //wxYield(); } } } sos.Close(); } f.Write(); f.Close(); LoadLocalMangaList(); }