From a8ca6f19da6c0c3834729416a0c9eacc004ef200 Mon Sep 17 00:00:00 2001 From: kamel5 Date: Fri, 22 Mar 2019 13:17:22 +0100 Subject: [PATCH] Set ff=unix for some files --- setup.h | 2 +- timerconflict.c | 374 +++++++++---------- timerconflict.h | 76 ++-- tools.c | 964 ++++++++++++++++++++++++------------------------ tools.h | 142 +++---- 5 files changed, 779 insertions(+), 779 deletions(-) diff --git a/setup.h b/setup.h index f7f8b2c..a859024 100644 --- a/setup.h +++ b/setup.h @@ -82,4 +82,4 @@ class cMenuSetupImageCache : public cMenuSetupSubMenu { cMenuSetupImageCache(cTvguideConfig *data); }; -#endif //__TVGUIDE_SETUP_H \ No newline at end of file +#endif //__TVGUIDE_SETUP_H diff --git a/timerconflict.c b/timerconflict.c index cd0eb14..6f34842 100644 --- a/timerconflict.c +++ b/timerconflict.c @@ -1,187 +1,187 @@ -#include -#include -#include -#include "tools.h" -#include "timer.h" -#include "timerconflict.h" - -cTVGuideTimerConflict::cTVGuideTimerConflict(void) { - time = 0; - timeStart = 0; - timeStop = 0; - overlapStart = 0; - overlapStop = 0; - percentPossible = 0; - timerID = 0; -} - -cTVGuideTimerConflict::~cTVGuideTimerConflict(void) { - -} - -bool cTVGuideTimerConflict::timerInvolved(int involvedID) { - int numConflicts = timerIDs.size(); - for (int i=0; i::const_iterator it = conflicts.begin(); it != conflicts.end(); it++) { - cTVGuideTimerConflict *conf = *it; - delete conf; - } - conflicts.clear(); -} - -void cTVGuideTimerConflicts::AddConflict(std::string epgSearchConflictLine) { - /* TIMERCONFLICT FORMAT: - The result list looks like this for example when we have 2 timer conflicts at one time: - 1190232780:152|30|50#152#45:45|10|50#152#45 - '1190232780' is the time of the conflict in seconds since 1970-01-01. - It's followed by list of timers that have a conflict at this time: - '152|30|50#1 int editTimer(cTimer *timer, bool active, int prio, int start, int stop); - 52#45' is the description of the first conflicting timer. Here: - '152' is VDR's timer id of this timer as returned from VDR's LSTT command - '30' is the percentage of recording that would be done (0...100) - '50#152#45' is the list of concurrent timers at this conflict - '45|10|50#152#45' describes the next conflict - */ - cTVGuideTimerConflict *conflict = new cTVGuideTimerConflict(); - splitstring s(epgSearchConflictLine.c_str()); - std::vector flds = s.split(':'); - if (flds.size() < 2) - return; - conflict->time = atoi(flds[0].c_str()); - splitstring s2(flds[1].c_str()); - std::vector flds2 = s2.split('|'); - if (flds2.size() < 3) - return; - conflict->timerID = atoi(flds2[0].c_str()); - conflict->percentPossible = atoi(flds2[1].c_str()); - splitstring s3(flds2[2].c_str()); - std::vector flds3 = s3.split('#'); - std::vector timerIDs; - for (int k = 0; k < flds3.size(); k++) { - timerIDs.push_back(atoi(flds3[k].c_str()) - 1); - } - conflict->timerIDs = timerIDs; - conflicts.push_back(conflict); -} - -void cTVGuideTimerConflicts::CalculateConflicts(void) { - numConflicts = conflicts.size(); -// time_t startTime = 0; -// time_t endTime = 0; - for (int i=0; i < numConflicts; i++) { - cTimeInterval *unionSet = NULL; - int numTimers = conflicts[i]->timerIDs.size(); - for (int j=0; j < numTimers; j++) { -#if VDRVERSNUM >= 20301 - LOCK_TIMERS_READ; - const cTimer *timer = Timers->Get(conflicts[i]->timerIDs[j]); -#else - const cTimer *timer = Timers.Get(conflicts[i]->timerIDs[j]); -#endif - if (timer) { - if (!unionSet) { - unionSet = new cTimeInterval(timer->StartTime(), timer->StopTime()); - } else { - cTimeInterval *timerInterval = new cTimeInterval(timer->StartTime(), timer->StopTime()); - cTimeInterval *newUnion = unionSet->Union(timerInterval); - delete unionSet; - delete timerInterval; - unionSet = newUnion; - } - } - } - conflicts[i]->timeStart = unionSet->Start(); - conflicts[i]->timeStop = unionSet->Stop(); - delete unionSet; - - cTimeInterval *intersect = NULL; - for (int j=0; j < numTimers; j++) { -#if VDRVERSNUM >= 20301 - LOCK_TIMERS_READ; - const cTimer *timer = Timers->Get(conflicts[i]->timerIDs[j]); -#else - const cTimer *timer = Timers.Get(conflicts[i]->timerIDs[j]); -#endif - if (timer) { - if (!intersect) { - intersect = new cTimeInterval(timer->StartTime(), timer->StopTime()); - } else { - cTimeInterval *timerInterval = new cTimeInterval(timer->StartTime(), timer->StopTime()); - cTimeInterval *newIntersect = intersect->Intersect(timerInterval); - if (newIntersect) { - delete intersect; - intersect = newIntersect; - } - delete timerInterval; - } - } - } - conflicts[i]->overlapStart = intersect->Start(); - conflicts[i]->overlapStop = intersect->Stop(); - delete intersect; - } -} - -cTVGuideTimerConflict *cTVGuideTimerConflicts::GetCurrentConflict(void) { - if (currentConflict < 0) - return NULL; - if (currentConflict > (numConflicts-1)) - return NULL; - return conflicts[currentConflict]; -} - -int cTVGuideTimerConflicts::GetCurrentConflictTimerID(int timerIndex) { - if (currentConflict < 0) - return -1; - if (currentConflict > (numConflicts-1)) - return -1; - int numTimersInConflict = conflicts[currentConflict]->timerIDs.size(); - if (timerIndex > (numTimersInConflict - 1)) - return -1; - return conflicts[currentConflict]->timerIDs[timerIndex]; -} - -int cTVGuideTimerConflicts::GetCorrespondingConflict(int timerID) { - int conflictIndex = -1; - if (numConflicts > 0) { - for (int i=0; itimerInvolved(timerID)) { - conflictIndex = i; - break; - } - } - } - return conflictIndex; -} - -cTVGuideTimerConflict *cTVGuideTimerConflicts::GetConflict(int conflictIndex) { - if (conflictIndex < 0) - return NULL; - if (conflictIndex > (numConflicts-1)) - return NULL; - return conflicts[conflictIndex]; -} - -std::vector cTVGuideTimerConflicts::GetConflictsBetween(time_t start, time_t stop) { - std::vector conflictsFound; - for (int i=0; i < numConflicts; i++) { - if ((conflicts[i]->timeStart > start) && (conflicts[i]->timeStart < stop)|| - (conflicts[i]->timeStop > start) && (conflicts[i]->timeStop < stop)) - conflictsFound.push_back(conflicts[i]); - } - return conflictsFound; -} +#include +#include +#include +#include "tools.h" +#include "timer.h" +#include "timerconflict.h" + +cTVGuideTimerConflict::cTVGuideTimerConflict(void) { + time = 0; + timeStart = 0; + timeStop = 0; + overlapStart = 0; + overlapStop = 0; + percentPossible = 0; + timerID = 0; +} + +cTVGuideTimerConflict::~cTVGuideTimerConflict(void) { + +} + +bool cTVGuideTimerConflict::timerInvolved(int involvedID) { + int numConflicts = timerIDs.size(); + for (int i=0; i::const_iterator it = conflicts.begin(); it != conflicts.end(); it++) { + cTVGuideTimerConflict *conf = *it; + delete conf; + } + conflicts.clear(); +} + +void cTVGuideTimerConflicts::AddConflict(std::string epgSearchConflictLine) { + /* TIMERCONFLICT FORMAT: + The result list looks like this for example when we have 2 timer conflicts at one time: + 1190232780:152|30|50#152#45:45|10|50#152#45 + '1190232780' is the time of the conflict in seconds since 1970-01-01. + It's followed by list of timers that have a conflict at this time: + '152|30|50#1 int editTimer(cTimer *timer, bool active, int prio, int start, int stop); + 52#45' is the description of the first conflicting timer. Here: + '152' is VDR's timer id of this timer as returned from VDR's LSTT command + '30' is the percentage of recording that would be done (0...100) + '50#152#45' is the list of concurrent timers at this conflict + '45|10|50#152#45' describes the next conflict + */ + cTVGuideTimerConflict *conflict = new cTVGuideTimerConflict(); + splitstring s(epgSearchConflictLine.c_str()); + std::vector flds = s.split(':'); + if (flds.size() < 2) + return; + conflict->time = atoi(flds[0].c_str()); + splitstring s2(flds[1].c_str()); + std::vector flds2 = s2.split('|'); + if (flds2.size() < 3) + return; + conflict->timerID = atoi(flds2[0].c_str()); + conflict->percentPossible = atoi(flds2[1].c_str()); + splitstring s3(flds2[2].c_str()); + std::vector flds3 = s3.split('#'); + std::vector timerIDs; + for (int k = 0; k < flds3.size(); k++) { + timerIDs.push_back(atoi(flds3[k].c_str()) - 1); + } + conflict->timerIDs = timerIDs; + conflicts.push_back(conflict); +} + +void cTVGuideTimerConflicts::CalculateConflicts(void) { + numConflicts = conflicts.size(); +// time_t startTime = 0; +// time_t endTime = 0; + for (int i=0; i < numConflicts; i++) { + cTimeInterval *unionSet = NULL; + int numTimers = conflicts[i]->timerIDs.size(); + for (int j=0; j < numTimers; j++) { +#if VDRVERSNUM >= 20301 + LOCK_TIMERS_READ; + const cTimer *timer = Timers->Get(conflicts[i]->timerIDs[j]); +#else + const cTimer *timer = Timers.Get(conflicts[i]->timerIDs[j]); +#endif + if (timer) { + if (!unionSet) { + unionSet = new cTimeInterval(timer->StartTime(), timer->StopTime()); + } else { + cTimeInterval *timerInterval = new cTimeInterval(timer->StartTime(), timer->StopTime()); + cTimeInterval *newUnion = unionSet->Union(timerInterval); + delete unionSet; + delete timerInterval; + unionSet = newUnion; + } + } + } + conflicts[i]->timeStart = unionSet->Start(); + conflicts[i]->timeStop = unionSet->Stop(); + delete unionSet; + + cTimeInterval *intersect = NULL; + for (int j=0; j < numTimers; j++) { +#if VDRVERSNUM >= 20301 + LOCK_TIMERS_READ; + const cTimer *timer = Timers->Get(conflicts[i]->timerIDs[j]); +#else + const cTimer *timer = Timers.Get(conflicts[i]->timerIDs[j]); +#endif + if (timer) { + if (!intersect) { + intersect = new cTimeInterval(timer->StartTime(), timer->StopTime()); + } else { + cTimeInterval *timerInterval = new cTimeInterval(timer->StartTime(), timer->StopTime()); + cTimeInterval *newIntersect = intersect->Intersect(timerInterval); + if (newIntersect) { + delete intersect; + intersect = newIntersect; + } + delete timerInterval; + } + } + } + conflicts[i]->overlapStart = intersect->Start(); + conflicts[i]->overlapStop = intersect->Stop(); + delete intersect; + } +} + +cTVGuideTimerConflict *cTVGuideTimerConflicts::GetCurrentConflict(void) { + if (currentConflict < 0) + return NULL; + if (currentConflict > (numConflicts-1)) + return NULL; + return conflicts[currentConflict]; +} + +int cTVGuideTimerConflicts::GetCurrentConflictTimerID(int timerIndex) { + if (currentConflict < 0) + return -1; + if (currentConflict > (numConflicts-1)) + return -1; + int numTimersInConflict = conflicts[currentConflict]->timerIDs.size(); + if (timerIndex > (numTimersInConflict - 1)) + return -1; + return conflicts[currentConflict]->timerIDs[timerIndex]; +} + +int cTVGuideTimerConflicts::GetCorrespondingConflict(int timerID) { + int conflictIndex = -1; + if (numConflicts > 0) { + for (int i=0; itimerInvolved(timerID)) { + conflictIndex = i; + break; + } + } + } + return conflictIndex; +} + +cTVGuideTimerConflict *cTVGuideTimerConflicts::GetConflict(int conflictIndex) { + if (conflictIndex < 0) + return NULL; + if (conflictIndex > (numConflicts-1)) + return NULL; + return conflicts[conflictIndex]; +} + +std::vector cTVGuideTimerConflicts::GetConflictsBetween(time_t start, time_t stop) { + std::vector conflictsFound; + for (int i=0; i < numConflicts; i++) { + if ((conflicts[i]->timeStart > start) && (conflicts[i]->timeStart < stop)|| + (conflicts[i]->timeStop > start) && (conflicts[i]->timeStop < stop)) + conflictsFound.push_back(conflicts[i]); + } + return conflictsFound; +} diff --git a/timerconflict.h b/timerconflict.h index d3def89..0a04dcf 100644 --- a/timerconflict.h +++ b/timerconflict.h @@ -1,38 +1,38 @@ -#ifndef __TVGUIDE_TIMERCONFLICT_H -#define __TVGUIDE_TIMERCONFLICT_H - -class cTVGuideTimerConflict { -public: - cTVGuideTimerConflict(void); - virtual ~cTVGuideTimerConflict(void); - time_t time; - time_t timeStart; - time_t timeStop; - time_t overlapStart; - time_t overlapStop; - int percentPossible; - int timerID; - std::vector timerIDs; - bool timerInvolved(int involvedID); -}; - -class cTVGuideTimerConflicts { -private: - std::vector conflicts; - int numConflicts; - int currentConflict; -public: - cTVGuideTimerConflicts(void); - virtual ~cTVGuideTimerConflicts(void); - void AddConflict(std::string epgSearchConflictLine); - void CalculateConflicts(void); - int NumConflicts(void) {return numConflicts; }; - void SetCurrentConflict(int current) { currentConflict = current; }; - cTVGuideTimerConflict *GetCurrentConflict(void); - int GetCurrentConflictTimerID(int timerIndex); - int GetCorrespondingConflict(int timerID); - cTVGuideTimerConflict *GetConflict(int conflictIndex); - std::vector GetConflictsBetween(time_t start, time_t stop); -}; - -#endif //__TVGUIDE_RECMMANAGER_H \ No newline at end of file +#ifndef __TVGUIDE_TIMERCONFLICT_H +#define __TVGUIDE_TIMERCONFLICT_H + +class cTVGuideTimerConflict { +public: + cTVGuideTimerConflict(void); + virtual ~cTVGuideTimerConflict(void); + time_t time; + time_t timeStart; + time_t timeStop; + time_t overlapStart; + time_t overlapStop; + int percentPossible; + int timerID; + std::vector timerIDs; + bool timerInvolved(int involvedID); +}; + +class cTVGuideTimerConflicts { +private: + std::vector conflicts; + int numConflicts; + int currentConflict; +public: + cTVGuideTimerConflicts(void); + virtual ~cTVGuideTimerConflicts(void); + void AddConflict(std::string epgSearchConflictLine); + void CalculateConflicts(void); + int NumConflicts(void) {return numConflicts; }; + void SetCurrentConflict(int current) { currentConflict = current; }; + cTVGuideTimerConflict *GetCurrentConflict(void); + int GetCurrentConflictTimerID(int timerIndex); + int GetCorrespondingConflict(int timerID); + cTVGuideTimerConflict *GetConflict(int conflictIndex); + std::vector GetConflictsBetween(time_t start, time_t stop); +}; + +#endif //__TVGUIDE_RECMMANAGER_H diff --git a/tools.c b/tools.c index 6caaf1c..b069bd0 100644 --- a/tools.c +++ b/tools.c @@ -1,482 +1,482 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "services/epgsearch.h" - -#include "tools.h" - -cPlugin *GetScraperPlugin(void) { - static cPlugin *pScraper = cPluginManager::GetPlugin("scraper2vdr"); - if( !pScraper ) // if it doesn't exit, try tvscraper - pScraper = cPluginManager::GetPlugin("tvscraper"); - return pScraper; -} - -/**************************************************************************************** -* CUTTEXT -****************************************************************************************/ -std::string CutText(std::string text, int width, const cFont *font) { - if (width <= font->Size()) - return text.c_str(); - if (font->Width(text.c_str()) < width) - return text.c_str(); - cTextWrapper twText; - twText.Set(text.c_str(), font, width); - std::string cuttedTextNative = twText.GetLine(0); - std::stringstream sstrText; - sstrText << cuttedTextNative << "..."; - std::string cuttedText = sstrText.str(); - int actWidth = font->Width(cuttedText.c_str()); - if (actWidth > width) { - int overlap = actWidth - width; - int charWidth = font->Width("."); - if (charWidth == 0) - charWidth = 1; - int cutChars = overlap / charWidth; - if (cutChars > 0) { - cuttedTextNative = cuttedTextNative.substr(0, cuttedTextNative.length() - cutChars); - std::stringstream sstrText2; - sstrText2 << cuttedTextNative << "..."; - cuttedText = sstrText2.str(); - } - } - return cuttedText; -} - -/**************************************************************************************** -* StrToLowerCase -****************************************************************************************/ -std::string StrToLowerCase(std::string str) { - std::string lowerCase = str; - const int length = lowerCase.length(); - for(int i=0; i < length; ++i) { - lowerCase[i] = std::tolower(lowerCase[i]); - } - return lowerCase; -} - -/**************************************************************************************** -* GetDirectoryFromTimer -****************************************************************************************/ -std::string GetDirectoryFromTimer(std::string file) { - std::string dir = ""; - size_t found = file.find_last_of('~'); - if (found != std::string::npos) { - dir = file.substr(0, found); - } - return dir; -} - -/**************************************************************************************** -* GetDirectoryFromTimer -****************************************************************************************/ -void ReadRecordingDirectories(std::vector *folders, cList *rootFolders, cString path) { - cPlugin *epgSearchPlugin = NULL; - epgSearchPlugin = cPluginManager::GetPlugin("epgsearch"); - if (epgSearchPlugin) { - Epgsearch_services_v1_0 *epgSearch = new Epgsearch_services_v1_0; - if (epgSearchPlugin->Service("Epgsearch-services-v1.0", epgSearch)) { - std::set epgSearchDirs = epgSearch->handler->DirectoryList(); - std::set::iterator it; - for (it = epgSearchDirs.begin(); it != epgSearchDirs.end(); it++) { - std::string newFolder = *it; - std::replace(newFolder.begin(), newFolder.end(), '/', '~'); - folders->push_back(newFolder); - } - } - } else { - cList *foldersLevel = NULL; - if (rootFolders) { - foldersLevel = rootFolders; - } else { - foldersLevel = &Folders; - } - for (cNestedItem *folder = foldersLevel->First(); folder; folder = foldersLevel->Next(folder)) { - std::string strFolder = *cString::sprintf("%s%s", *path, folder->Text()); - std::replace(strFolder.begin(), strFolder.end(), '/', '~'); - folders->push_back(strFolder); - cList *subItems = folder->SubItems(); - if (subItems) { - std::string strFolder2 = *cString::sprintf("%s%s", *path, folder->Text()); - std::replace(strFolder2.begin(), strFolder2.end(), '/', '~'); - ReadRecordingDirectories(folders, subItems, strFolder2.c_str()); - } - } - } -} - - -/**************************************************************************************** -* DrawRoundedCorners -****************************************************************************************/ -void DrawRoundedCorners(cPixmap *p, int posX, int posY, int width, int height, int radius, int borderWidth, tColor borderColor) { - if( height > 2*radius) { - p->DrawEllipse(cRect(posX, posY, radius, radius), borderColor, -2); - p->DrawEllipse(cRect(posX - borderWidth, posY - borderWidth, radius, radius), clrTransparent, -2); - - p->DrawEllipse(cRect(posX+width - radius, posY, radius, radius), borderColor, -1); - p->DrawEllipse(cRect(posX+width - radius + borderWidth, posY - borderWidth, radius, radius), clrTransparent, -1); - - p->DrawEllipse(cRect(posX, posY + height - radius, radius, radius), borderColor, -3); - p->DrawEllipse(cRect(posX - borderWidth, posY + height - radius + borderWidth, radius, radius), clrTransparent, -3); - - p->DrawEllipse(cRect(posX + width - radius, posY + height - radius, radius, radius), borderColor, -4); - p->DrawEllipse(cRect(posX + width - radius + borderWidth, posY + height - radius + borderWidth, radius, radius), clrTransparent, -4); - } -} - - -/**************************************************************************************** -* SPLTSTRING -****************************************************************************************/ -// split: receives a char delimiter; returns a vector of strings -// By default ignores repeated delimiters, unless argument rep == 1. -std::vector& splitstring::split(char delim, int rep) { - if (!flds.empty()) flds.clear(); // empty vector if necessary - std::string work = data(); - std::string buf = ""; - int i = 0; - while (i < work.length()) { - if (work[i] != delim) - buf += work[i]; - else if (rep == 1) { - flds.push_back(buf); - buf = ""; - } else if (buf.length() > 0) { - flds.push_back(buf); - buf = ""; - } - i++; - } - if (!buf.empty()) - flds.push_back(buf); - return flds; -} - -/**************************************************************************************** -* FINDIGNORECASE -****************************************************************************************/ -int FindIgnoreCase(const std::string& expr, const std::string& query) -{ - const char *p = expr.c_str(); - const char *r = strcasestr(p, query.c_str()); - - if (!r) - return -1; - return r - p; -} - - -/**************************************************************************************** -* GetAuxValue -****************************************************************************************/ -char* GetAuxValue(const char* aux, const char* name) { - if (isempty(aux)) - return NULL; - - char* descr = strdup(aux); - char* beginaux = strstr(descr, ""); - char* endaux = strstr(descr, ""); - if (!beginaux || !endaux) { - free(descr); - return NULL; - } - - beginaux += 11; // strlen(""); - endaux[0] = 0; - memmove(descr, beginaux, endaux - beginaux + 1); - - if (strcmp(name, "epgsearch") == 0) - return descr; // full aux - - int namelen = strlen(name); - char catname[100] = ""; - catname[0] = '<'; - memcpy(catname + 1, name, namelen); - catname[1 + namelen] = '>'; - catname[2 + namelen] = 0; - - char* cat = strcasestr(descr, catname); - if (!cat) { - free(descr); - return NULL; - } - - cat += namelen + 2; - char* end = strstr(cat, "Info()) - return NULL; - return GetAuxValue(recording->Info()->Aux(), name); -} - -char* GetAuxValue(const cTimer *timer, const char* name) { - if (!timer || !timer->Aux()) - return NULL; - return GetAuxValue(timer->Aux(), name); -} - -/**************************************************************************************** -* FUZZYSEARCH -****************************************************************************************/ - -/****************************************************************************** -FUNCTION afuzzy_init() - Initialization of the fuzzy search routine. This applies to the consequent - calls of the afuzzy_CheckRTR (whole string matching) and afuzzy_CheckSUB - (substring match) routines. afuzzy_init() should be called for each - new pattern or error length. The search is case sensitive - -ARGUMENTS: - p Pattern - kerr Number of possible errors. Shouldn't exceed pattern length - UseFilter Use agrep filter algorithm that speeds up search. - fuzzy pointer to the structure that will be later passes to Check* - (the first 6 elements should be NULLs for the first call) - -RETURN VALUE: - none - -ALGORITHM - see. the article on agrep algorithms. - The only change is accounting transpositions as one edit operation . -******************************************************************************/ -void afuzzy_init(const char *p, int kerr, int UseFilter, AFUZZY *fuzzy) -{ - int cnt, p_len, i, j, l, d, m, dd; - char PatFilter[sizeof(Uint)*8 + 1]; - - fuzzy->k = kerr; - m = strlen(p); - fuzzy->FilterSet = 0; - memset(fuzzy->Map, 0 , sizeof(fuzzy->Map) ); - - if (fuzzy->S) - free(fuzzy->S); - if (fuzzy->R) - free(fuzzy->R); - if (fuzzy->R1) - free(fuzzy->R1); - if (fuzzy->RP) - free(fuzzy->RP); - if (fuzzy->RI) - free(fuzzy->RI); - if (fuzzy->FilterS) - free(fuzzy->FilterS); - - fuzzy->FilterS = NULL; - fuzzy->S = (Uint *)calloc(m + 1, sizeof(Uint)); - fuzzy->R = (Uint *)calloc(fuzzy->k + 1, sizeof(Uint)); - fuzzy->R1 = (Uint *)calloc(fuzzy->k + 1, sizeof(Uint)); - fuzzy->RI = (Uint *)calloc(fuzzy->k + 1, sizeof(Uint)); - fuzzy->RP = (Uint *)calloc(fuzzy->k + 1, sizeof(Uint)); - - for (i = 0, cnt = 0; i < m; i++) - { - l = fuzzy->Map[(unsigned char)p[i]]; - if (!l) - { - l = fuzzy->Map[(unsigned char)p[i]] = ++cnt; - fuzzy->S[l] = 0; - } - fuzzy->S[l] |= 1 << i; - } - - - for (d = 0; d <= fuzzy->k; d++) - fuzzy->RI[d] = (1 << d) - 1; - - fuzzy->mask_ok = (1 << (m - 1)); - fuzzy->r_size = sizeof(Uint) * (fuzzy->k + 1); - p_len = m; - - if (p_len > (int) sizeof(Uint)*8) - p_len = (int) sizeof(Uint)*8; - - /* If k is zero then no filter is needed! */ - if (fuzzy->k && (p_len >= 2*(fuzzy->k + 1)) ) - { - if (UseFilter) - { - fuzzy->FilterSet = 1; - memset(fuzzy->FilterMap, 0 , sizeof(fuzzy->FilterMap) ); - fuzzy->FilterS = (Uint *)calloc(m + 1, sizeof(Uint)); - - /* Not let's fill the interleaved pattern */ - dd = p_len / (fuzzy->k + 1); - p_len = dd * (fuzzy->k + 1); - - for (i = 0, cnt = 0; i < dd; i++) - for (j = 0; j < fuzzy->k + 1; j++, cnt++) - PatFilter[cnt] = (unsigned char)p[j*dd + i]; - PatFilter[p_len] = 0; - - for (i = 0, cnt = 0; i < p_len; i++) - { - l = fuzzy->FilterMap[(unsigned char)PatFilter[i]]; - if (!l) - { - l = fuzzy->FilterMap[(unsigned char)PatFilter[i]] = ++cnt; - fuzzy->FilterS[l] = 0; - } - fuzzy->FilterS[l] |= 1 << i; - } - fuzzy->filter_ok = 0; - for (i = p_len - fuzzy->k - 1; i <= p_len - 1; i++) /* k+1 times */ - fuzzy->filter_ok |= 1 << i; - - /* k+1 first bits set to 1 */ - fuzzy->filter_shift = (1 << (fuzzy->k + 2)) - 1; - } - } -} - -/****************************************************************************** -FUNCTION afuzzy_free() - Cleaning up after previous afuzzy_init() call. - -ARGUMENTS: - fuzzy pointer to the afuzzy parameters structure - -RETURN VALUE: - none -******************************************************************************/ -void afuzzy_free(AFUZZY *fuzzy) -{ - if (fuzzy->S) - { - free(fuzzy->S); - fuzzy->S = NULL; - } - if (fuzzy->R) - { - free(fuzzy->R); - fuzzy->R = NULL; - } - if (fuzzy->R1) - { - free(fuzzy->R1); - fuzzy->R1 = NULL; - } - if (fuzzy->RP) - { - free(fuzzy->RP); - fuzzy->RP = NULL; - } - if (fuzzy->RI) - { - free(fuzzy->RI); - fuzzy->RI = NULL; - } - if (fuzzy->FilterS) - { - free(fuzzy->FilterS); - fuzzy->FilterS = NULL; - } -} - - -/****************************************************************************** -FUNCTION afuzzy_CheckSUB() - Perform a fuzzy pattern substring matching. afuzzy_init() should be - called previously to initialize the pattern and error length. - Positive result means that some part of the string given matches the - pattern with no more than afuzzy->k errors (1 error = 1 letter - replacement or transposition) - -ARGUMENTS: - t the string to test - fuzzy pointer to the afuzzy parameters structure - -RETURN VALUE: - 0 - no match - > 0 - strings match - -ALGORITHM - ???????????????? -******************************************************************************/ -int afuzzy_checkSUB(const char *t, AFUZZY *fuzzy) -{ - register char c; - register int j, d; - - /* For eficciency this case should be little bit optimized */ - if (!fuzzy->k) - { - Uint R = 0, R1; - - for (j = 0; (c = t[j]) != '\0'; j++) - { - R1 = ( ((R<<1) | 1) & fuzzy->S[fuzzy->Map[(unsigned char)c]]); - R = R1; - - if (R1 & fuzzy->mask_ok) - return 1; - } /* end for (register int j = 0 ... */ - return 0; - } - - if (fuzzy->FilterSet && !afuzzy_checkFLT(t, fuzzy)) - return 0; - - memcpy(fuzzy->R, fuzzy->RI, fuzzy->r_size); /* R = RI */ - - for (j = 0; (c = t[j]); j++) - { - for (d = 0; d <= fuzzy->k; d++) - { - fuzzy->R1[d] = (((fuzzy->R[d]<<1) | 1) & - fuzzy->S[fuzzy->Map[(unsigned char)c]]); - if (d > 0) - fuzzy->R1[d] |= ((fuzzy->R[d-1] | fuzzy->R1[d-1])<<1) | 1 | - fuzzy->R[d-1]; - } - if (fuzzy->R1[fuzzy->k] & fuzzy->mask_ok) - return j; - - memcpy(fuzzy->R, fuzzy->R1, fuzzy->r_size); - - } /* end for (register int j = 0 ... */ - - return 0; -} - -int afuzzy_checkFLT(const char *t, AFUZZY *fuzzy) -{ - register Uint FilterR = 0; - register Uint FilterR1; - register int j; - - for (j = 0; t[j] != '\0'; j++) - { - FilterR1 = ( ((FilterR<<(fuzzy->k+1)) | fuzzy->filter_shift) & - fuzzy->FilterS[fuzzy->FilterMap[(unsigned char)t[j]]]); - if (FilterR1 & fuzzy->filter_ok) - return 1; - FilterR = FilterR1; - } /* end for (register int j = 0 ... */ - - return 0; -} +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "services/epgsearch.h" + +#include "tools.h" + +cPlugin *GetScraperPlugin(void) { + static cPlugin *pScraper = cPluginManager::GetPlugin("scraper2vdr"); + if( !pScraper ) // if it doesn't exit, try tvscraper + pScraper = cPluginManager::GetPlugin("tvscraper"); + return pScraper; +} + +/**************************************************************************************** +* CUTTEXT +****************************************************************************************/ +std::string CutText(std::string text, int width, const cFont *font) { + if (width <= font->Size()) + return text.c_str(); + if (font->Width(text.c_str()) < width) + return text.c_str(); + cTextWrapper twText; + twText.Set(text.c_str(), font, width); + std::string cuttedTextNative = twText.GetLine(0); + std::stringstream sstrText; + sstrText << cuttedTextNative << "..."; + std::string cuttedText = sstrText.str(); + int actWidth = font->Width(cuttedText.c_str()); + if (actWidth > width) { + int overlap = actWidth - width; + int charWidth = font->Width("."); + if (charWidth == 0) + charWidth = 1; + int cutChars = overlap / charWidth; + if (cutChars > 0) { + cuttedTextNative = cuttedTextNative.substr(0, cuttedTextNative.length() - cutChars); + std::stringstream sstrText2; + sstrText2 << cuttedTextNative << "..."; + cuttedText = sstrText2.str(); + } + } + return cuttedText; +} + +/**************************************************************************************** +* StrToLowerCase +****************************************************************************************/ +std::string StrToLowerCase(std::string str) { + std::string lowerCase = str; + const int length = lowerCase.length(); + for(int i=0; i < length; ++i) { + lowerCase[i] = std::tolower(lowerCase[i]); + } + return lowerCase; +} + +/**************************************************************************************** +* GetDirectoryFromTimer +****************************************************************************************/ +std::string GetDirectoryFromTimer(std::string file) { + std::string dir = ""; + size_t found = file.find_last_of('~'); + if (found != std::string::npos) { + dir = file.substr(0, found); + } + return dir; +} + +/**************************************************************************************** +* GetDirectoryFromTimer +****************************************************************************************/ +void ReadRecordingDirectories(std::vector *folders, cList *rootFolders, cString path) { + cPlugin *epgSearchPlugin = NULL; + epgSearchPlugin = cPluginManager::GetPlugin("epgsearch"); + if (epgSearchPlugin) { + Epgsearch_services_v1_0 *epgSearch = new Epgsearch_services_v1_0; + if (epgSearchPlugin->Service("Epgsearch-services-v1.0", epgSearch)) { + std::set epgSearchDirs = epgSearch->handler->DirectoryList(); + std::set::iterator it; + for (it = epgSearchDirs.begin(); it != epgSearchDirs.end(); it++) { + std::string newFolder = *it; + std::replace(newFolder.begin(), newFolder.end(), '/', '~'); + folders->push_back(newFolder); + } + } + } else { + cList *foldersLevel = NULL; + if (rootFolders) { + foldersLevel = rootFolders; + } else { + foldersLevel = &Folders; + } + for (cNestedItem *folder = foldersLevel->First(); folder; folder = foldersLevel->Next(folder)) { + std::string strFolder = *cString::sprintf("%s%s", *path, folder->Text()); + std::replace(strFolder.begin(), strFolder.end(), '/', '~'); + folders->push_back(strFolder); + cList *subItems = folder->SubItems(); + if (subItems) { + std::string strFolder2 = *cString::sprintf("%s%s", *path, folder->Text()); + std::replace(strFolder2.begin(), strFolder2.end(), '/', '~'); + ReadRecordingDirectories(folders, subItems, strFolder2.c_str()); + } + } + } +} + + +/**************************************************************************************** +* DrawRoundedCorners +****************************************************************************************/ +void DrawRoundedCorners(cPixmap *p, int posX, int posY, int width, int height, int radius, int borderWidth, tColor borderColor) { + if( height > 2*radius) { + p->DrawEllipse(cRect(posX, posY, radius, radius), borderColor, -2); + p->DrawEllipse(cRect(posX - borderWidth, posY - borderWidth, radius, radius), clrTransparent, -2); + + p->DrawEllipse(cRect(posX+width - radius, posY, radius, radius), borderColor, -1); + p->DrawEllipse(cRect(posX+width - radius + borderWidth, posY - borderWidth, radius, radius), clrTransparent, -1); + + p->DrawEllipse(cRect(posX, posY + height - radius, radius, radius), borderColor, -3); + p->DrawEllipse(cRect(posX - borderWidth, posY + height - radius + borderWidth, radius, radius), clrTransparent, -3); + + p->DrawEllipse(cRect(posX + width - radius, posY + height - radius, radius, radius), borderColor, -4); + p->DrawEllipse(cRect(posX + width - radius + borderWidth, posY + height - radius + borderWidth, radius, radius), clrTransparent, -4); + } +} + + +/**************************************************************************************** +* SPLTSTRING +****************************************************************************************/ +// split: receives a char delimiter; returns a vector of strings +// By default ignores repeated delimiters, unless argument rep == 1. +std::vector& splitstring::split(char delim, int rep) { + if (!flds.empty()) flds.clear(); // empty vector if necessary + std::string work = data(); + std::string buf = ""; + int i = 0; + while (i < work.length()) { + if (work[i] != delim) + buf += work[i]; + else if (rep == 1) { + flds.push_back(buf); + buf = ""; + } else if (buf.length() > 0) { + flds.push_back(buf); + buf = ""; + } + i++; + } + if (!buf.empty()) + flds.push_back(buf); + return flds; +} + +/**************************************************************************************** +* FINDIGNORECASE +****************************************************************************************/ +int FindIgnoreCase(const std::string& expr, const std::string& query) +{ + const char *p = expr.c_str(); + const char *r = strcasestr(p, query.c_str()); + + if (!r) + return -1; + return r - p; +} + + +/**************************************************************************************** +* GetAuxValue +****************************************************************************************/ +char* GetAuxValue(const char* aux, const char* name) { + if (isempty(aux)) + return NULL; + + char* descr = strdup(aux); + char* beginaux = strstr(descr, ""); + char* endaux = strstr(descr, ""); + if (!beginaux || !endaux) { + free(descr); + return NULL; + } + + beginaux += 11; // strlen(""); + endaux[0] = 0; + memmove(descr, beginaux, endaux - beginaux + 1); + + if (strcmp(name, "epgsearch") == 0) + return descr; // full aux + + int namelen = strlen(name); + char catname[100] = ""; + catname[0] = '<'; + memcpy(catname + 1, name, namelen); + catname[1 + namelen] = '>'; + catname[2 + namelen] = 0; + + char* cat = strcasestr(descr, catname); + if (!cat) { + free(descr); + return NULL; + } + + cat += namelen + 2; + char* end = strstr(cat, "Info()) + return NULL; + return GetAuxValue(recording->Info()->Aux(), name); +} + +char* GetAuxValue(const cTimer *timer, const char* name) { + if (!timer || !timer->Aux()) + return NULL; + return GetAuxValue(timer->Aux(), name); +} + +/**************************************************************************************** +* FUZZYSEARCH +****************************************************************************************/ + +/****************************************************************************** +FUNCTION afuzzy_init() + Initialization of the fuzzy search routine. This applies to the consequent + calls of the afuzzy_CheckRTR (whole string matching) and afuzzy_CheckSUB + (substring match) routines. afuzzy_init() should be called for each + new pattern or error length. The search is case sensitive + +ARGUMENTS: + p Pattern + kerr Number of possible errors. Shouldn't exceed pattern length + UseFilter Use agrep filter algorithm that speeds up search. + fuzzy pointer to the structure that will be later passes to Check* + (the first 6 elements should be NULLs for the first call) + +RETURN VALUE: + none + +ALGORITHM + see. the article on agrep algorithms. + The only change is accounting transpositions as one edit operation . +******************************************************************************/ +void afuzzy_init(const char *p, int kerr, int UseFilter, AFUZZY *fuzzy) +{ + int cnt, p_len, i, j, l, d, m, dd; + char PatFilter[sizeof(Uint)*8 + 1]; + + fuzzy->k = kerr; + m = strlen(p); + fuzzy->FilterSet = 0; + memset(fuzzy->Map, 0 , sizeof(fuzzy->Map) ); + + if (fuzzy->S) + free(fuzzy->S); + if (fuzzy->R) + free(fuzzy->R); + if (fuzzy->R1) + free(fuzzy->R1); + if (fuzzy->RP) + free(fuzzy->RP); + if (fuzzy->RI) + free(fuzzy->RI); + if (fuzzy->FilterS) + free(fuzzy->FilterS); + + fuzzy->FilterS = NULL; + fuzzy->S = (Uint *)calloc(m + 1, sizeof(Uint)); + fuzzy->R = (Uint *)calloc(fuzzy->k + 1, sizeof(Uint)); + fuzzy->R1 = (Uint *)calloc(fuzzy->k + 1, sizeof(Uint)); + fuzzy->RI = (Uint *)calloc(fuzzy->k + 1, sizeof(Uint)); + fuzzy->RP = (Uint *)calloc(fuzzy->k + 1, sizeof(Uint)); + + for (i = 0, cnt = 0; i < m; i++) + { + l = fuzzy->Map[(unsigned char)p[i]]; + if (!l) + { + l = fuzzy->Map[(unsigned char)p[i]] = ++cnt; + fuzzy->S[l] = 0; + } + fuzzy->S[l] |= 1 << i; + } + + + for (d = 0; d <= fuzzy->k; d++) + fuzzy->RI[d] = (1 << d) - 1; + + fuzzy->mask_ok = (1 << (m - 1)); + fuzzy->r_size = sizeof(Uint) * (fuzzy->k + 1); + p_len = m; + + if (p_len > (int) sizeof(Uint)*8) + p_len = (int) sizeof(Uint)*8; + + /* If k is zero then no filter is needed! */ + if (fuzzy->k && (p_len >= 2*(fuzzy->k + 1)) ) + { + if (UseFilter) + { + fuzzy->FilterSet = 1; + memset(fuzzy->FilterMap, 0 , sizeof(fuzzy->FilterMap) ); + fuzzy->FilterS = (Uint *)calloc(m + 1, sizeof(Uint)); + + /* Not let's fill the interleaved pattern */ + dd = p_len / (fuzzy->k + 1); + p_len = dd * (fuzzy->k + 1); + + for (i = 0, cnt = 0; i < dd; i++) + for (j = 0; j < fuzzy->k + 1; j++, cnt++) + PatFilter[cnt] = (unsigned char)p[j*dd + i]; + PatFilter[p_len] = 0; + + for (i = 0, cnt = 0; i < p_len; i++) + { + l = fuzzy->FilterMap[(unsigned char)PatFilter[i]]; + if (!l) + { + l = fuzzy->FilterMap[(unsigned char)PatFilter[i]] = ++cnt; + fuzzy->FilterS[l] = 0; + } + fuzzy->FilterS[l] |= 1 << i; + } + fuzzy->filter_ok = 0; + for (i = p_len - fuzzy->k - 1; i <= p_len - 1; i++) /* k+1 times */ + fuzzy->filter_ok |= 1 << i; + + /* k+1 first bits set to 1 */ + fuzzy->filter_shift = (1 << (fuzzy->k + 2)) - 1; + } + } +} + +/****************************************************************************** +FUNCTION afuzzy_free() + Cleaning up after previous afuzzy_init() call. + +ARGUMENTS: + fuzzy pointer to the afuzzy parameters structure + +RETURN VALUE: + none +******************************************************************************/ +void afuzzy_free(AFUZZY *fuzzy) +{ + if (fuzzy->S) + { + free(fuzzy->S); + fuzzy->S = NULL; + } + if (fuzzy->R) + { + free(fuzzy->R); + fuzzy->R = NULL; + } + if (fuzzy->R1) + { + free(fuzzy->R1); + fuzzy->R1 = NULL; + } + if (fuzzy->RP) + { + free(fuzzy->RP); + fuzzy->RP = NULL; + } + if (fuzzy->RI) + { + free(fuzzy->RI); + fuzzy->RI = NULL; + } + if (fuzzy->FilterS) + { + free(fuzzy->FilterS); + fuzzy->FilterS = NULL; + } +} + + +/****************************************************************************** +FUNCTION afuzzy_CheckSUB() + Perform a fuzzy pattern substring matching. afuzzy_init() should be + called previously to initialize the pattern and error length. + Positive result means that some part of the string given matches the + pattern with no more than afuzzy->k errors (1 error = 1 letter + replacement or transposition) + +ARGUMENTS: + t the string to test + fuzzy pointer to the afuzzy parameters structure + +RETURN VALUE: + 0 - no match + > 0 - strings match + +ALGORITHM + ???????????????? +******************************************************************************/ +int afuzzy_checkSUB(const char *t, AFUZZY *fuzzy) +{ + register char c; + register int j, d; + + /* For eficciency this case should be little bit optimized */ + if (!fuzzy->k) + { + Uint R = 0, R1; + + for (j = 0; (c = t[j]) != '\0'; j++) + { + R1 = ( ((R<<1) | 1) & fuzzy->S[fuzzy->Map[(unsigned char)c]]); + R = R1; + + if (R1 & fuzzy->mask_ok) + return 1; + } /* end for (register int j = 0 ... */ + return 0; + } + + if (fuzzy->FilterSet && !afuzzy_checkFLT(t, fuzzy)) + return 0; + + memcpy(fuzzy->R, fuzzy->RI, fuzzy->r_size); /* R = RI */ + + for (j = 0; (c = t[j]); j++) + { + for (d = 0; d <= fuzzy->k; d++) + { + fuzzy->R1[d] = (((fuzzy->R[d]<<1) | 1) & + fuzzy->S[fuzzy->Map[(unsigned char)c]]); + if (d > 0) + fuzzy->R1[d] |= ((fuzzy->R[d-1] | fuzzy->R1[d-1])<<1) | 1 | + fuzzy->R[d-1]; + } + if (fuzzy->R1[fuzzy->k] & fuzzy->mask_ok) + return j; + + memcpy(fuzzy->R, fuzzy->R1, fuzzy->r_size); + + } /* end for (register int j = 0 ... */ + + return 0; +} + +int afuzzy_checkFLT(const char *t, AFUZZY *fuzzy) +{ + register Uint FilterR = 0; + register Uint FilterR1; + register int j; + + for (j = 0; t[j] != '\0'; j++) + { + FilterR1 = ( ((FilterR<<(fuzzy->k+1)) | fuzzy->filter_shift) & + fuzzy->FilterS[fuzzy->FilterMap[(unsigned char)t[j]]]); + if (FilterR1 & fuzzy->filter_ok) + return 1; + FilterR = FilterR1; + } /* end for (register int j = 0 ... */ + + return 0; +} diff --git a/tools.h b/tools.h index 3d2e84f..26212fe 100644 --- a/tools.h +++ b/tools.h @@ -1,71 +1,71 @@ -#ifndef __TVGUIDETOOLS_H -#define __TVGUIDETOOLS_H - -#include -#include -#include -#include -#include - -cPlugin *GetScraperPlugin(void); - -std::string CutText(std::string text, int width, const cFont *font); -std::string StrToLowerCase(std::string str); -std::string GetDirectoryFromTimer(std::string file); -void ReadRecordingDirectories(std::vector *folders, cList *rootFolders, cString path); -void DrawRoundedCorners(cPixmap *p, int posX, int posY, int width, int height, int radius, int borderWidth, tColor borderColor); - -class splitstring : public std::string { - std::vector flds; -public: - splitstring(const char *s) : std::string(s) { }; - std::vector& split(char delim, int rep=0); -}; - -int FindIgnoreCase(const std::string& expr, const std::string& query); - -char* GetAuxValue(const char* aux, const char* name); -char* GetAuxValue(const cRecording *recording, const char* name); -char* GetAuxValue(const cTimer* timer, const char* name); - -#ifndef _AFUZZY_H -#define _AFUZZY_H - -// source from: -/* - Leonid Boitsov 2002. (itman@narod.ru) - C version of Stas Namin. - This code is a GPL software and is distributed under GNU - public licence without any warranty. -*/ - -typedef unsigned int Uint; - -#define MaxPatSize (sizeof(Uint) * 8) - -typedef struct -{ - Uint *R, - *R1, - *RP, - *S, - *RI; - Uint *FilterS; - - int Map[256]; - int FilterMap[256]; - int k; - Uint mask_ok; - Uint filter_ok; - Uint filter_shift; - int r_size; - int FilterSet; -} AFUZZY; - -void afuzzy_init(const char *p, int kerr, int UseFilter, AFUZZY *fuzzy); -void afuzzy_free(AFUZZY *fuzzy); -int afuzzy_checkSUB(const char *t, AFUZZY *fuzzy); -int afuzzy_checkFLT(const char *t, AFUZZY *fuzzy); -#endif - -#endif // __TVGUIDETOOLS_H +#ifndef __TVGUIDETOOLS_H +#define __TVGUIDETOOLS_H + +#include +#include +#include +#include +#include + +cPlugin *GetScraperPlugin(void); + +std::string CutText(std::string text, int width, const cFont *font); +std::string StrToLowerCase(std::string str); +std::string GetDirectoryFromTimer(std::string file); +void ReadRecordingDirectories(std::vector *folders, cList *rootFolders, cString path); +void DrawRoundedCorners(cPixmap *p, int posX, int posY, int width, int height, int radius, int borderWidth, tColor borderColor); + +class splitstring : public std::string { + std::vector flds; +public: + splitstring(const char *s) : std::string(s) { }; + std::vector& split(char delim, int rep=0); +}; + +int FindIgnoreCase(const std::string& expr, const std::string& query); + +char* GetAuxValue(const char* aux, const char* name); +char* GetAuxValue(const cRecording *recording, const char* name); +char* GetAuxValue(const cTimer* timer, const char* name); + +#ifndef _AFUZZY_H +#define _AFUZZY_H + +// source from: +/* + Leonid Boitsov 2002. (itman@narod.ru) + C version of Stas Namin. + This code is a GPL software and is distributed under GNU + public licence without any warranty. +*/ + +typedef unsigned int Uint; + +#define MaxPatSize (sizeof(Uint) * 8) + +typedef struct +{ + Uint *R, + *R1, + *RP, + *S, + *RI; + Uint *FilterS; + + int Map[256]; + int FilterMap[256]; + int k; + Uint mask_ok; + Uint filter_ok; + Uint filter_shift; + int r_size; + int FilterSet; +} AFUZZY; + +void afuzzy_init(const char *p, int kerr, int UseFilter, AFUZZY *fuzzy); +void afuzzy_free(AFUZZY *fuzzy); +int afuzzy_checkSUB(const char *t, AFUZZY *fuzzy); +int afuzzy_checkFLT(const char *t, AFUZZY *fuzzy); +#endif + +#endif // __TVGUIDETOOLS_H