diff options
Diffstat (limited to 'recording.c')
-rw-r--r-- | recording.c | 206 |
1 files changed, 147 insertions, 59 deletions
diff --git a/recording.c b/recording.c index ed74c46..93b0af8 100644 --- a/recording.c +++ b/recording.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: recording.c 1.98 2005/05/07 15:25:15 kls Exp $ + * $Id: recording.c 1.107 2005/05/29 11:16:57 kls Exp $ */ #include "recording.h" @@ -23,6 +23,8 @@ #include "tools.h" #include "videodir.h" +#define SUMMARYFALLBACK + #define RECEXT ".rec" #define DELEXT ".del" /* This was the original code, which works fine in a Linux only environment. @@ -45,7 +47,10 @@ // end of implementation for brain dead systems #define RESUMEFILESUFFIX "/resume%s%s.vdr" +#ifdef SUMMARYFALLBACK #define SUMMARYFILESUFFIX "/summary.vdr" +#endif +#define INFOFILESUFFIX "/info.vdr" #define MARKSFILESUFFIX "/marks.vdr" #define MINDISKSPACE 1024 // MB @@ -213,6 +218,68 @@ void cResumeFile::Delete(void) } } +// --- cRecordingInfo -------------------------------------------------------- + +cRecordingInfo::cRecordingInfo(const cEvent *Event) +{ + if (Event) { + event = Event; + channelID = event->ChannelID(); + ownEvent = NULL; + } + else + event = ownEvent = new cEvent(0); +} + +cRecordingInfo::~cRecordingInfo() +{ + delete ownEvent; +} + +void cRecordingInfo::SetData(const char *Title, const char *ShortText, const char *Description) +{ + if (!isempty(Title)) + ((cEvent *)event)->SetTitle(Title); + if (!isempty(ShortText)) + ((cEvent *)event)->SetShortText(ShortText); + if (!isempty(Description)) + ((cEvent *)event)->SetDescription(Description); +} + +bool cRecordingInfo::Read(FILE *f) +{ + if (ownEvent) { + cReadLine ReadLine; + char *s; + while ((s = ReadLine.Read(f)) != NULL) { + char *t = skipspace(s + 1); + switch (*s) { + case 'C': { + char *p = strchr(t, ' '); + if (p) + *p = 0; // strips optional channel name + if (*t) + channelID = tChannelID::FromString(t); + } + break; + default: if (!ownEvent->Parse(s)) + return false; + break; + } + } + return true; + } + return false; +} + +bool cRecordingInfo::Write(FILE *f, const char *Prefix) const +{ + if (channelID.Valid()) + fprintf(f, "%sC %s\n", Prefix, *channelID.ToString()); + event->Dump(f, Prefix, true); + return true; +} + // --- cRecording ------------------------------------------------------------ #define RESUME_NOT_INITIALIZED (-2) @@ -308,7 +375,7 @@ static char *ExchangeChars(char *s, bool ToFileSystem) return s; } -cRecording::cRecording(cTimer *Timer, const char *Title, const char *Subtitle, const char *Summary) +cRecording::cRecording(cTimer *Timer, const cEvent *Event) { resume = RESUME_NOT_INITIALIZED; titleBuffer = NULL; @@ -316,7 +383,8 @@ cRecording::cRecording(cTimer *Timer, const char *Title, const char *Subtitle, c fileName = NULL; name = NULL; // set up the actual name: - const char *OriginalSubtitle = Subtitle; + const char *Title = Event ? Event->Title() : NULL; + const char *Subtitle = Event ? Event->ShortText() : NULL; char SubtitleBuffer[MAX_SUBTITLE_LENGTH]; if (isempty(Title)) Title = Timer->Channel()->Name(); @@ -333,6 +401,14 @@ cRecording::cRecording(cTimer *Timer, const char *Title, const char *Subtitle, c name = strdup(Timer->File()); name = strreplace(name, TIMERMACRO_TITLE, Title); name = strreplace(name, TIMERMACRO_EPISODE, Subtitle); + // avoid blanks at the end: + int l = strlen(name); + while (l-- > 2) { + if (name[l] == ' ' && name[l - 1] != '~') + name[l] = 0; + else + break; + } if (Timer->IsSingleEvent()) { Timer->SetFile(name); // this was an instant recording, so let's set the actual data Timers.SetModified(); @@ -347,17 +423,13 @@ cRecording::cRecording(cTimer *Timer, const char *Title, const char *Subtitle, c start = Timer->StartTime(); priority = Timer->Priority(); lifetime = Timer->Lifetime(); - // handle summary: - summary = !isempty(Timer->Summary()) ? strdup(Timer->Summary()) : NULL; - if (!summary) { - Subtitle = OriginalSubtitle; - if (isempty(Subtitle)) - Subtitle = ""; - if (isempty(Summary)) - Summary = ""; - if (*Subtitle || *Summary) - asprintf(&summary, "%s\n\n%s%s%s", Title, Subtitle, (*Subtitle && *Summary) ? "\n\n" : "", Summary); - } + // handle info: + info = new cRecordingInfo(Event); + // this is a somewhat ugly hack to get the 'summary' information from the + // timer into the recording info, but it saves us from having to actually + // copy the entire event data: + if (!isempty(Timer->Summary())) + info->SetData(isempty(info->Title()) ? Timer->File() : NULL, NULL, Timer->Summary()); } cRecording::cRecording(const char *FileName) @@ -370,7 +442,7 @@ cRecording::cRecording(const char *FileName) char *p = strrchr(FileName, '/'); name = NULL; - summary = NULL; + info = new cRecordingInfo; if (p) { time_t now = time(NULL); struct tm tm_r; @@ -386,39 +458,57 @@ cRecording::cRecording(const char *FileName) name[p - FileName] = 0; name = ExchangeChars(name, false); } - // read an optional summary file: - char *SummaryFileName = NULL; - asprintf(&SummaryFileName, "%s%s", fileName, SUMMARYFILESUFFIX); - int f = open(SummaryFileName, O_RDONLY); - if (f >= 0) { - struct stat buf; - if (fstat(f, &buf) == 0) { - int size = buf.st_size; - summary = MALLOC(char, size + 1); // +1 for terminating 0 - if (summary) { - int rbytes = safe_read(f, summary, size); - if (rbytes >= 0) { - summary[rbytes] = 0; - if (rbytes != size) - esyslog("%s: expected %d bytes but read %d", SummaryFileName, size, rbytes); - } - else { - LOG_ERROR_STR(SummaryFileName); - free(summary); - summary = NULL; + // read an optional info file: + char *InfoFileName = NULL; + asprintf(&InfoFileName, "%s%s", fileName, INFOFILESUFFIX); + FILE *f = fopen(InfoFileName, "r"); + if (f) { + info->Read(f); + fclose(f); + } + else if (errno != ENOENT) + LOG_ERROR_STR(InfoFileName); + free(InfoFileName); +#ifdef SUMMARYFALLBACK + // fall back to the old 'summary.vdr' if there was no 'info.vdr': + if (isempty(info->Title())) { + char *SummaryFileName = NULL; + asprintf(&SummaryFileName, "%s%s", fileName, SUMMARYFILESUFFIX); + FILE *f = fopen(SummaryFileName, "r"); + if (f) { + int line = 0; + char *data[3] = { NULL }; + cReadLine ReadLine; + char *s; + while ((s = ReadLine.Read(f)) != NULL && line < 3) { + if (*s) { + if (data[line]) { + int len = strlen(s); + len += strlen(data[line]) + 1; + data[line] = (char *)realloc(data[line], len + 1); + strcat(data[line], "\n"); + strcat(data[line], s); + } + else + data[line] = strdup(s); + } + else + line++; } - + fclose(f); + if (line == 1) { + data[2] = data[1]; + data[1] = NULL; } - else - esyslog("can't allocate %d byte of memory for summary file '%s'", size + 1, SummaryFileName); - close(f); + info->SetData(data[0], data[1], data[2]); + for (int i = 0; i < 3; i ++) + free(data[i]); } - else + else if (errno != ENOENT) LOG_ERROR_STR(SummaryFileName); + free(SummaryFileName); } - else if (errno != ENOENT) - LOG_ERROR_STR(SummaryFileName); - free(SummaryFileName); +#endif } } @@ -428,7 +518,7 @@ cRecording::~cRecording() free(sortBuffer); free(fileName); free(name); - free(summary); + delete info; } char *cRecording::StripEpisodeName(char *s) @@ -513,7 +603,8 @@ const char *cRecording::Title(char Delimiter, bool NewIndicator, int Level) cons Delimiter, s); // let's not display a trailing '~': - stripspace(titleBuffer); + if (!NewIndicator) + stripspace(titleBuffer); s = &titleBuffer[strlen(titleBuffer) - 1]; if (*s == '~') *s = 0; @@ -568,21 +659,18 @@ bool cRecording::IsEdited(void) const return *s == '%'; } -bool cRecording::WriteSummary(void) +bool cRecording::WriteInfo(void) { - if (summary) { - char *SummaryFileName = NULL; - asprintf(&SummaryFileName, "%s%s", fileName, SUMMARYFILESUFFIX); - FILE *f = fopen(SummaryFileName, "w"); - if (f) { - if (fputs(summary, f) < 0) - LOG_ERROR_STR(SummaryFileName); - fclose(f); - } - else - LOG_ERROR_STR(SummaryFileName); - free(SummaryFileName); + char *InfoFileName = NULL; + asprintf(&InfoFileName, "%s%s", fileName, INFOFILESUFFIX); + FILE *f = fopen(InfoFileName, "w"); + if (f) { + info->Write(f); + fclose(f); } + else + LOG_ERROR_STR(InfoFileName); + free(InfoFileName); return true; } @@ -956,7 +1044,7 @@ bool cIndexFile::CatchUp(int Index) LOG_ERROR_STR(fileName); if (Index < last - (i ? 2 * INDEXSAFETYLIMIT : 0) || Index > 10 * INDEXSAFETYLIMIT) // keep off the end in case of "Pause live video" break; - sleep(1); + cCondWait::SleepMs(1000); } } return index != NULL; |