diff options
Diffstat (limited to 'worker.c')
-rw-r--r-- | worker.c | 233 |
1 files changed, 233 insertions, 0 deletions
diff --git a/worker.c b/worker.c new file mode 100644 index 0000000..09b5752 --- /dev/null +++ b/worker.c @@ -0,0 +1,233 @@ +#include <locale.h> +#include "worker.h" + +using namespace std; + +cTVScraperWorker::cTVScraperWorker(cTVScraperDB *db) : cThread("tvscraper", true) { + startLoop = true; + scanVideoDir = false; + manualScan = false; + this->db = db; + moviedbScraper = NULL; + tvdbScraper = NULL; + initSleep = 2 * 60 * 1000; + loopSleep = 5 * 60 * 1000; + language = ""; +} + +cTVScraperWorker::~cTVScraperWorker() { + if (moviedbScraper) + delete moviedbScraper; + if (tvdbScraper) + delete tvdbScraper; +} + +void cTVScraperWorker::SetLanguage(void) { + string loc = setlocale(LC_NAME, NULL); + size_t index = loc.find_first_of("_"); + string langISO = ""; + if (index > 0) { + langISO = loc.substr(0, index); + } + if (langISO.size() == 2) { + language = langISO.c_str(); + dsyslog("tvscraper: using language %s", language.c_str()); + return; + } + language = "en"; + dsyslog("tvscraper: using fallback language %s", language.c_str()); +} + +void cTVScraperWorker::Stop(void) { + waitCondition.Broadcast(); // wakeup the thread + Cancel(5); // wait up to 5 seconds for thread was stopping + db->BackupToDisc(); +} + +void cTVScraperWorker::InitVideoDirScan(void) { + scanVideoDir = true; + waitCondition.Broadcast(); +} + +void cTVScraperWorker::InitManualScan(void) { + manualScan = true; + waitCondition.Broadcast(); +} + +void cTVScraperWorker::SetDirectories(void) { + plgBaseDir = config.GetBaseDir(); + stringstream strSeriesDir; + strSeriesDir << plgBaseDir << "/series"; + seriesDir = strSeriesDir.str(); + stringstream strMovieDir; + strMovieDir << plgBaseDir << "/movies"; + movieDir = strMovieDir.str(); + bool ok = false; + ok = CreateDirectory(plgBaseDir); + if (ok) + ok = CreateDirectory(seriesDir); + if (ok) + ok = CreateDirectory(movieDir); + if (!ok) { + esyslog("tvscraper: ERROR: check %s for write permissions", plgBaseDir.c_str()); + startLoop = false; + } else { + dsyslog("tvscraper: using base directory %s", plgBaseDir.c_str()); + } +} + +scrapType cTVScraperWorker::GetScrapType(const cEvent *event) { + scrapType type = scrapNone; + int duration = event->Duration() / 60; + if ((duration > 19) && (duration < 65)) { + type = scrapSeries; + } else if (duration > 80) { + type = scrapMovie; + } + return type; +} + +bool cTVScraperWorker::ConnectScrapers(void) { + if (!moviedbScraper) { + moviedbScraper = new cMovieDBScraper(movieDir, db, language); + if (!moviedbScraper->Connect()) { + esyslog("tvscraper: ERROR, connection to TheMovieDB failed"); + return false; + } + } + if (!tvdbScraper) { + tvdbScraper = new cTVDBScraper(seriesDir, db, language); + if (!tvdbScraper->Connect()) { + esyslog("tvscraper: ERROR, connection to TheTVDB failed"); + return false; + } + } + return true; +} + +void cTVScraperWorker::DisconnectScrapers(void) { + if (moviedbScraper) { + delete moviedbScraper; + moviedbScraper = NULL; + } + if (tvdbScraper) { + delete tvdbScraper; + tvdbScraper = NULL; + } +} + +void cTVScraperWorker::ScrapEPG(void) { + vector<string> channels = config.GetChannels(); + int numChannels = channels.size(); + for (int i=0; i<numChannels; i++) { + string channelID = channels[i]; + const cChannel *channel = Channels.GetByChannelID(tChannelID::FromString(channelID.c_str())); + dsyslog("tvscraper: scrapping Channel %s %s", channel->Name(), channelID.c_str()); + cSchedulesLock schedulesLock; + const cSchedules *schedules = cSchedules::Schedules(schedulesLock); + const cSchedule *Schedule = schedules->GetSchedule(channel); + if (Schedule) { + const cEvent *event = NULL; + for (event = Schedule->Events()->First(); event; event = Schedule->Events()->Next(event)) { + if (!Running()) + return; + scrapType type = GetScrapType(event); + if (type != scrapNone) { + if (!db->CheckScrap(event->StartTime(), channelID)) + continue; + if (type == scrapSeries) { + tvdbScraper->Scrap(event); + } else if (type == scrapMovie) { + moviedbScraper->Scrap(event); + } + waitCondition.TimedWait(mutex, 100); + } + } + } + } +} + +void cTVScraperWorker::ScrapRecordings(void) { + db->ClearRecordings(); + for (cRecording *rec = Recordings.First(); rec; rec = Recordings.Next(rec)) { + const cRecordingInfo *recInfo = rec->Info(); + const cEvent *recEvent = recInfo->GetEvent(); + if (recEvent) { + tEventID recEventID = recEvent->EventID(); + string recTitle = recInfo->Title(); + scrapType type = GetScrapType(recEvent); + if (type == scrapSeries) { + int seriesID = db->SearchSeries(recEvent->Title()); + if (seriesID) { + db->InsertRecording((int)recEventID, seriesID, 0); + } else { + tvdbScraper->Scrap(recEvent, (int)recEventID); + } + } else if (type == scrapMovie) { + int movieID = db->SearchMovie(recEvent->Title()); + if (movieID) { + db->InsertRecording((int)recEventID, 0, movieID); + } else { + moviedbScraper->Scrap(recEvent, (int)recEventID); + } + } + } + } +} + +void cTVScraperWorker::CheckRunningTimers(void) { + for (cTimer *timer = Timers.First(); timer; timer = Timers.Next(timer)) { + if (timer->Recording()) { + const cEvent *event = timer->Event(); + scrapType type = GetScrapType(event); + if (type == scrapSeries) { + db->SetRecordingSeries((int)event->EventID()); + } else if (type == scrapMovie) { + db->SetRecordingMovie((int)event->EventID()); + } + } + } +} + +bool cTVScraperWorker::StartScrapping(void) { + if (manualScan) { + manualScan = false; + return true; + } + //wait at least one day from last scrapping to scrap again + int minTime = 24 * 60 * 60; + return db->CheckStartScrapping(minTime); +} + + +void cTVScraperWorker::Action(void) { + if (!startLoop) + return; + mutex.Lock(); + dsyslog("tvscraper: waiting %d minutes to start main loop", initSleep / 1000 / 60); + waitCondition.TimedWait(mutex, initSleep); + + while (Running()) { + if (scanVideoDir) { + scanVideoDir = false; + dsyslog("tvscraper: scanning video dir"); + if (ConnectScrapers()) { + ScrapRecordings(); + } + DisconnectScrapers(); + continue; + } + CheckRunningTimers(); + if (StartScrapping()) { + dsyslog("tvscraper: start scrapping epg"); + db->ClearOutdated(movieDir); + if (ConnectScrapers()) { + ScrapEPG(); + } + DisconnectScrapers(); + db->BackupToDisc(); + dsyslog("tvscraper: epg scrapping done"); + } + waitCondition.TimedWait(mutex, loopSleep); + } +} |