diff --git a/src/gui/moviebrowser.cpp b/src/gui/moviebrowser.cpp index 66395b79b..743b22154 100644 --- a/src/gui/moviebrowser.cpp +++ b/src/gui/moviebrowser.cpp @@ -1100,6 +1100,7 @@ int CMovieBrowser::exec(const char* path) } else if ((show_mode == MB_SHOW_YT) && (msg == CRCInput::RC_record) && m_movieSelectionHandler) { + m_movieSelectionHandler->source = (show_mode == MB_SHOW_YT) ? MI_MOVIE_INFO::YT : MI_MOVIE_INFO::NK; if (cYTCache::getInstance()->addToCache(m_movieSelectionHandler)) { const char *format = g_Locale->getText(LOCALE_MOVIEBROWSER_YT_CACHE_ADD); char buf[1024]; @@ -3762,27 +3763,29 @@ neutrino_locale_t CMovieBrowser::getFeedLocale(void) int CYTCacheSelectorTarget::exec(CMenuTarget* /*parent*/, const std::string & actionKey) { + MI_MOVIE_INFO::miSource source = (movieBrowser->show_mode == MB_SHOW_YT) ? MI_MOVIE_INFO::YT : MI_MOVIE_INFO::NK; + int selected = movieBrowser->yt_menue->getSelected(); if (actionKey == "cancel_all") { - cYTCache::getInstance()->cancelAll(); + cYTCache::getInstance()->cancelAll(source); } else if (actionKey == "completed_clear") { - cYTCache::getInstance()->clearCompleted(); + cYTCache::getInstance()->clearCompleted(source); } else if (actionKey == "failed_clear") { - cYTCache::getInstance()->clearFailed(); - } else if (actionKey == "rc_spkr" && selected >= movieBrowser->yt_pending_offset && selected < movieBrowser->yt_completed_offset) { + cYTCache::getInstance()->clearFailed(source); + } else if (actionKey == "rc_spkr" && movieBrowser->yt_pending_offset && selected >= movieBrowser->yt_pending_offset && selected < movieBrowser->yt_pending_end) { cYTCache::getInstance()->cancel(&movieBrowser->yt_pending[selected - movieBrowser->yt_pending_offset]); - } else if (actionKey == "rc_spkr" && selected >= movieBrowser->yt_completed_offset && selected < movieBrowser->yt_failed_offset) { + } else if (actionKey == "rc_spkr" && movieBrowser->yt_completed_offset && selected >= movieBrowser->yt_completed_offset && selected < movieBrowser->yt_completed_end) { cYTCache::getInstance()->remove(&movieBrowser->yt_completed[selected - movieBrowser->yt_completed_offset]); } else if (actionKey == "") { - if (movieBrowser->yt_pending_offset && selected >= movieBrowser->yt_pending_offset && selected < movieBrowser->yt_completed_offset) { + if (movieBrowser->yt_pending_offset && selected >= movieBrowser->yt_pending_offset && selected < movieBrowser->yt_pending_end) { if(ShowMsg (LOCALE_MOVIEBROWSER_YT_CACHE, g_Locale->getText(LOCALE_MOVIEBROWSER_YT_CANCEL_TRANSFER), CMessageBox::mbrNo, CMessageBox::mbYes | CMessageBox::mbNo) == CMessageBox::mbrYes) cYTCache::getInstance()->cancel(&movieBrowser->yt_pending[selected - movieBrowser->yt_pending_offset]); else return menu_return::RETURN_NONE; - } else if (movieBrowser->yt_completed_offset && selected >= movieBrowser->yt_completed_offset && selected < movieBrowser->yt_failed_offset) { + } else if (movieBrowser->yt_completed_offset && selected >= movieBrowser->yt_completed_offset && selected < movieBrowser->yt_completed_end) { // FIXME -- anything sensible to do here? return menu_return::RETURN_NONE; - } else if (movieBrowser->yt_failed_offset && selected >= movieBrowser->yt_failed_offset && selected < movieBrowser->yt_menue->getItemsCount()){ + } else if (movieBrowser->yt_failed_offset && selected >= movieBrowser->yt_failed_offset && selected < movieBrowser->yt_failed_end){ cYTCache::getInstance()->clearFailed(&movieBrowser->yt_failed[selected - movieBrowser->yt_failed_offset]); cYTCache::getInstance()->addToCache(&movieBrowser->yt_failed[selected - movieBrowser->yt_failed_offset]); const char *format = g_Locale->getText(LOCALE_MOVIEBROWSER_YT_CACHE_ADD); @@ -3808,13 +3811,17 @@ void CMovieBrowser::refreshYTMenu() delete m; yt_menue->removeItem(item_id); } - yt_pending = cYTCache::getInstance()->getPending(); - yt_completed = cYTCache::getInstance()->getCompleted(); - yt_failed = cYTCache::getInstance()->getFailed(); + MI_MOVIE_INFO::miSource source = (show_mode == MB_SHOW_YT) ? MI_MOVIE_INFO::YT : MI_MOVIE_INFO::NK; + yt_pending = cYTCache::getInstance()->getPending(source); + yt_completed = cYTCache::getInstance()->getCompleted(source); + yt_failed = cYTCache::getInstance()->getFailed(source); yt_pending_offset = 0; yt_completed_offset = 0; yt_failed_offset = 0; + yt_pending_end = 0; + yt_completed_end = 0; + yt_failed_end = 0; if (!yt_pending.empty()) { yt_menue->addItem(new CMenuSeparator(CMenuSeparator::LINE | CMenuSeparator::STRING, LOCALE_MOVIEBROWSER_YT_PENDING)); @@ -3825,6 +3832,7 @@ void CMovieBrowser::refreshYTMenu() for (std::vector::iterator it = yt_pending.begin(); it != yt_pending.end(); ++it, ++i) { yt_menue->addItem(new CMenuForwarder((*it).file.Name.c_str(), true, NULL, ytcache_selector)); } + yt_pending_end = yt_menue->getItemsCount(); } if (!yt_completed.empty()) { @@ -3836,6 +3844,7 @@ void CMovieBrowser::refreshYTMenu() for (std::vector::iterator it = yt_completed.begin(); it != yt_completed.end(); ++it, ++i) { yt_menue->addItem(new CMenuForwarder((*it).file.Name.c_str(), true, NULL, ytcache_selector)); } + yt_completed_end = yt_menue->getItemsCount(); } if (!yt_failed.empty()) { @@ -3847,6 +3856,7 @@ void CMovieBrowser::refreshYTMenu() for (std::vector::iterator it = yt_failed.begin(); it != yt_failed.end(); ++it, ++i) { yt_menue->addItem(new CMenuForwarder((*it).file.Name.c_str(), true, NULL, ytcache_selector)); } + yt_failed_end = yt_menue->getItemsCount(); } CFrameBuffer::getInstance()->Clear(); // due to possible width change diff --git a/src/gui/moviebrowser.h b/src/gui/moviebrowser.h index 67e6b1a6a..6b77fb958 100644 --- a/src/gui/moviebrowser.h +++ b/src/gui/moviebrowser.h @@ -346,6 +346,9 @@ class CMovieBrowser : public CMenuTarget int yt_pending_offset; int yt_completed_offset; int yt_failed_offset; + int yt_pending_end; + int yt_completed_end; + int yt_failed_end; std::vector yt_pending; std::vector yt_completed; std::vector yt_failed; diff --git a/src/gui/movieinfo.h b/src/gui/movieinfo.h index d7d36dceb..143f83447 100644 --- a/src/gui/movieinfo.h +++ b/src/gui/movieinfo.h @@ -179,6 +179,9 @@ class MI_MOVIE_INFO std::string ytdate; // yt published std::string ytid; // yt published int ytitag; // youtube quality profile + + enum miSource { UNKNOWN = 0, YT, NK }; + miSource source; }; typedef std::vector MI_MOVIE_LIST; diff --git a/src/system/ytcache.cpp b/src/system/ytcache.cpp index 2e1affdc1..f6e0b8093 100644 --- a/src/system/ytcache.cpp +++ b/src/system/ytcache.cpp @@ -30,7 +30,7 @@ #if LIBCURL_VERSION_NUM < 0x071507 #include #endif -#define URL_TIMEOUT 60 +#define URL_TIMEOUT 3600 #include "helpers.h" #include "settings.h" @@ -59,16 +59,19 @@ cYTCache *cYTCache::getInstance(void) std::string cYTCache::getName(MI_MOVIE_INFO *mi, std::string ext) { - char ytitag[10]; - snprintf(ytitag, sizeof(ytitag), "%d", mi->ytitag); - return g_settings.downloadcache_dir + "/" + mi->ytid + "-" + std::string(ytitag) + "." + ext; + switch (mi->source) { + case MI_MOVIE_INFO::YT: + return g_settings.downloadcache_dir + "/" + mi->ytid + "-" + to_string(mi->ytitag) + "." + ext; + case MI_MOVIE_INFO::NK: + return g_settings.downloadcache_dir + "/nk-" + mi->ytid + "." + ext; + default: + return ""; + } } bool cYTCache::getNameIfExists(std::string &fname, const std::string &id, int itag, std::string ext) { - char ytitag[10]; - snprintf(ytitag, sizeof(ytitag), "%d", itag); - std::string f = g_settings.downloadcache_dir + "/" + id + "-" + std::string(ytitag) + "." + ext; + std::string f = g_settings.downloadcache_dir + "/" + id + "-" + to_string(itag) + "." + ext; if (access(f, R_OK)) return false; fname = f; @@ -148,12 +151,15 @@ bool cYTCache::download(MI_MOVIE_INFO *mi) } } + + fprintf (stderr, "downloading %s to %s\n", mi->file.Url.c_str(), file.c_str()); CURLcode res = curl_easy_perform(curl); curl_easy_cleanup(curl); fclose(fp); if (res) { + fprintf (stderr, "downloading %s to %s failed: %s\n", mi->file.Url.c_str(), file.c_str(), cerror); unlink(file.c_str()); return false; } @@ -261,16 +267,21 @@ void cYTCache::remove(MI_MOVIE_INFO *mi) } } -void cYTCache::cancelAll(void) +void cYTCache::cancelAll(MI_MOVIE_INFO::miSource source) { { OpenThreads::ScopedLock m_lock(mutex); if (pending.empty()) return; - if (pending.size() > 1) { - failed.insert(failed.end(), pending.begin() + 1, pending.end()); - pending.erase(pending.begin() + 1, pending.end()); - } + if (pending.size() > 1) + for (std::vector::iterator it = pending.begin() + 1; it != pending.end();) + if ((*it).source == source) { + failed.push_back(*it); + it = pending.erase(it); + } else + ++it; + if (pending.front().source != source) + return; } cancelled = true; @@ -280,28 +291,43 @@ void cYTCache::cancelAll(void) { OpenThreads::ScopedLock m_lock(mutex); cancelled = false; - pending.clear(); + if (pending.size() > 0) { + if (pthread_create(&thread, NULL, downloadThread, this)) { + perror("pthread_create"); + return; + } + pthread_detach(thread); + } } } -std::vector cYTCache::getFailed(void) +std::vector cYTCache::getFailed(MI_MOVIE_INFO::miSource source) { OpenThreads::ScopedLock m_lock(mutex); - std::vector res = failed; + std::vector res; + for (std::vector::iterator it = failed.begin(); it != failed.end(); ++it) + if ((*it).source == source) + res.push_back(*it); return res; } -std::vector cYTCache::getCompleted(void) +std::vector cYTCache::getCompleted(MI_MOVIE_INFO::miSource source) { OpenThreads::ScopedLock m_lock(mutex); - std::vector res = completed; + std::vector res; + for (std::vector::iterator it = completed.begin(); it != completed.end(); ++it) + if ((*it).source == source) + res.push_back(*it); return res; } -std::vector cYTCache::getPending(void) +std::vector cYTCache::getPending(MI_MOVIE_INFO::miSource source) { OpenThreads::ScopedLock m_lock(mutex); - std::vector res = pending; + std::vector res; + for (std::vector::iterator it = pending.begin(); it != pending.end(); ++it) + if ((*it).source == source) + res.push_back(*it); return res; } @@ -331,7 +357,27 @@ void cYTCache::clearCompleted(MI_MOVIE_INFO *mi) completed.clear(); } +void cYTCache::clearFailed(MI_MOVIE_INFO::miSource source) +{ + OpenThreads::ScopedLock m_lock(mutex); + for (std::vector::iterator it = failed.begin(); it != failed.end();) + if ((*it).source == source) + it = failed.erase(it); + else + ++it; +} + +void cYTCache::clearCompleted(MI_MOVIE_INFO::miSource source) +{ + OpenThreads::ScopedLock m_lock(mutex); + for (std::vector::iterator it = completed.begin(); it != completed.end();) + if ((*it).source == source) + it = completed.erase(it); + else + ++it; +} + bool cYTCache::compareMovieInfo(MI_MOVIE_INFO *a, MI_MOVIE_INFO *b) { - return a->ytid == b->ytid && a->ytitag == b->ytitag; + return a->ytid == b->ytid && a->ytitag == b->ytitag && a->source == b->source; } diff --git a/src/system/ytcache.h b/src/system/ytcache.h index 015e7e5e0..e342a745c 100644 --- a/src/system/ytcache.h +++ b/src/system/ytcache.h @@ -54,12 +54,14 @@ class cYTCache bool addToCache(MI_MOVIE_INFO *mi); void cancel(MI_MOVIE_INFO *mi); void remove(MI_MOVIE_INFO *mi); - void cancelAll(void); - std::vector getCompleted(void); - std::vector getFailed(void); - std::vector getPending(void); - void clearCompleted(MI_MOVIE_INFO *mi = NULL); - void clearFailed(MI_MOVIE_INFO *mi = NULL); + void cancelAll(MI_MOVIE_INFO::miSource = MI_MOVIE_INFO::YT); + std::vector getCompleted(MI_MOVIE_INFO::miSource = MI_MOVIE_INFO::YT); + std::vector getFailed(MI_MOVIE_INFO::miSource = MI_MOVIE_INFO::YT); + std::vector getPending(MI_MOVIE_INFO::miSource = MI_MOVIE_INFO::YT); + void clearCompleted(MI_MOVIE_INFO *mi); + void clearFailed(MI_MOVIE_INFO *mi); + void clearCompleted(MI_MOVIE_INFO::miSource source = MI_MOVIE_INFO::YT); + void clearFailed(MI_MOVIE_INFO::miSource source = MI_MOVIE_INFO::YT); bool getNameIfExists(std::string &fname, const std::string &id, int itag, std::string ext = ".jpg"); }; #endif