Implemented storing timer id in .timer

This commit is contained in:
Klaus Schmidinger 2018-02-13 09:33:41 +01:00
parent 78831a72d5
commit 3090d8146f
6 changed files with 116 additions and 23 deletions

View File

@ -9162,7 +9162,7 @@ Video Disk Recorder Revision History
a subdirectory.
- SVDRP peering can now be limited to the default SVDRP host (see MANUAL for details).
2018-02-12: Version 2.3.9
2018-02-13: Version 2.3.9
- Updated the Italian OSD texts (thanks to Diego Pierotto).
- Updated the Finnish OSD texts (thanks to Rolf Ahrenberg).
@ -9271,3 +9271,7 @@ Video Disk Recorder Revision History
jumping to the proper offset.
- Fixed getting the info of a newly edited recording (reported by Matthias Senzel).
- Improved calculating signal strength and quality (thanks to Helmut Binder).
- While a timer is recording, the file '.timer' in the recording directory now contains
the full id of the timer that is currently recording into this directory. This is used
to determine whether a timer is still recording on a remote VDR when deleting a recording
from the Recordings menu.

71
menu.c
View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: menu.c 4.60 2018/02/10 12:45:36 kls Exp $
* $Id: menu.c 4.61 2018/02/13 09:25:43 kls Exp $
*/
#include "menu.h"
@ -3111,6 +3111,56 @@ eOSState cMenuRecordings::Rewind(void)
return osContinue;
}
static bool TimerStillRecording(const char *FileName)
{
if (cRecordControl *rc = cRecordControls::GetRecordControl(FileName)) {
// local timer
if (Interface->Confirm(tr("Timer still recording - really delete?"))) {
LOCK_TIMERS_WRITE;
if (cTimer *Timer = rc->Timer()) {
Timer->Skip();
cRecordControls::Process(Timers, time(NULL));
if (Timer->IsSingleEvent()) {
Timers->Del(Timer);
isyslog("deleted timer %s", *Timer->ToDescr());
}
}
}
else
return true; // user didn't confirm deletion
}
else {
// remote timer
cString TimerId = GetRecordingTimerId(FileName);
if (*TimerId) {
int Id;
char *RemoteBuf = NULL;
cString Remote;
if (2 == sscanf(TimerId, "%d@%m[^ \n]", &Id, &RemoteBuf)) {
Remote = RemoteBuf;
free(RemoteBuf);
if (Interface->Confirm(tr("Timer still recording - really delete?"))) {
LOCK_TIMERS_WRITE;
if (cTimer *Timer = Timers->GetById(Id, Remote)) {
Timer->Skip();
if (Timer->IsSingleEvent()) {
if (HandleRemoteModifications(NULL, Timer))
Timers->Del(Timer);
else
return true; // error while deleting remote timer
}
else if (!HandleRemoteModifications(Timer))
return true; // error while modifying remote timer
}
}
else
return true; // user didn't confirm deletion
}
}
}
return false;
}
eOSState cMenuRecordings::Delete(void)
{
if (HasSubMenu() || Count() == 0)
@ -3118,21 +3168,8 @@ eOSState cMenuRecordings::Delete(void)
cMenuRecordingItem *ri = (cMenuRecordingItem *)Get(Current());
if (ri && !ri->IsDirectory()) {
if (Interface->Confirm(tr("Delete recording?"))) {
if (cRecordControl *rc = cRecordControls::GetRecordControl(ri->Recording()->FileName())) {
if (Interface->Confirm(tr("Timer still recording - really delete?"))) {
if (cTimer *Timer = rc->Timer()) {
LOCK_TIMERS_WRITE;
Timer->Skip();
cRecordControls::Process(Timers, time(NULL));
if (Timer->IsSingleEvent()) {
Timers->Del(Timer);
isyslog("deleted timer %s", *Timer->ToDescr());
}
}
}
else
return osContinue;
}
if (TimerStillRecording(ri->Recording()->FileName()))
return osContinue;
cString FileName;
{
LOCK_RECORDINGS_READ;
@ -5198,6 +5235,7 @@ cRecordControl::cRecordControl(cDevice *Device, cTimers *Timers, cTimer *Timer,
SchedulesStateKey.Remove();
LOCK_RECORDINGS_WRITE;
Recordings->AddByName(fileName);
SetRecordingTimerId(fileName, cString::sprintf("%d@%s", Timer->Id(), Setup.SVDRPHostName));
return;
}
else
@ -5250,6 +5288,7 @@ void cRecordControl::Stop(bool ExecuteUserCommand)
DELETENULL(recorder);
timer->SetRecording(false);
timer = NULL;
SetRecordingTimerId(fileName, NULL);
cStatus::MsgRecording(device, NULL, fileName, false);
if (ExecuteUserCommand)
cRecordingUserCommand::InvokeCommand(RUC_AFTERRECORDING, fileName);

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: recording.c 4.19 2018/02/10 13:24:04 kls Exp $
* $Id: recording.c 4.20 2018/02/13 08:44:19 kls Exp $
*/
#include "recording.h"
@ -57,6 +57,7 @@
#define MARKSFILESUFFIX "/marks"
#define SORTMODEFILE ".sort"
#define TIMERRECFILE ".timer"
#define MINDISKSPACE 1024 // MB
@ -117,7 +118,7 @@ void cRemoveDeletedRecordingsThread::Action(void)
r = DeletedRecordings->Next(r);
}
if (deleted) {
const char *IgnoreFiles[] = { SORTMODEFILE, NULL };
const char *IgnoreFiles[] = { SORTMODEFILE, TIMERRECFILE, NULL };
cVideoDirectory::RemoveEmptyVideoDirectories(IgnoreFiles);
}
}
@ -3122,3 +3123,38 @@ void IncRecordingsSortMode(const char *Directory)
RecordingsSortMode = eRecordingsSortMode(0);
SetRecordingsSortMode(Directory, RecordingsSortMode);
}
// --- Recording Timer Indicator ---------------------------------------------
void SetRecordingTimerId(const char *Directory, const char *TimerId)
{
cString FileName = AddDirectory(Directory, TIMERRECFILE);
if (TimerId) {
dsyslog("writing timer id '%s' to %s", TimerId, *FileName);
if (FILE *f = fopen(FileName, "w")) {
fprintf(f, "%s\n", TimerId);
fclose(f);
}
else
LOG_ERROR_STR(*FileName);
}
else {
dsyslog("removing %s", *FileName);
unlink(FileName);
}
}
cString GetRecordingTimerId(const char *Directory)
{
cString FileName = AddDirectory(Directory, TIMERRECFILE);
const char *Id = NULL;
if (FILE *f = fopen(FileName, "r")) {
char buf[HOST_NAME_MAX + 10]; // +10 for numeric timer id and '@'
if (fgets(buf, sizeof(buf), f)) {
stripspace(buf);
Id = buf;
}
fclose(f);
}
return Id;
}

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: recording.h 4.7 2017/12/11 12:56:57 kls Exp $
* $Id: recording.h 4.8 2018/02/13 08:44:19 kls Exp $
*/
#ifndef __RECORDING_H
@ -535,4 +535,7 @@ void GetRecordingsSortMode(const char *Directory);
void SetRecordingsSortMode(const char *Directory, eRecordingsSortMode SortMode);
void IncRecordingsSortMode(const char *Directory);
void SetRecordingTimerId(const char *Directory, const char *TimerId);
cString GetRecordingTimerId(const char *Directory);
#endif //__RECORDING_H

View File

@ -10,7 +10,7 @@
* and interact with the Video Disk Recorder - or write a full featured
* graphical interface that sits on top of an SVDRP connection.
*
* $Id: svdrp.c 4.24 2018/02/05 14:52:27 kls Exp $
* $Id: svdrp.c 4.25 2018/02/13 09:23:11 kls Exp $
*/
#include "svdrp.h"
@ -1334,8 +1334,10 @@ void cSVDRPServer::CmdDELT(const char *Option)
LOCK_TIMERS_WRITE;
Timers->SetExplicitModify();
if (cTimer *Timer = Timers->GetById(strtol(Option, NULL, 10))) {
if (Timer->Recording())
if (Timer->Recording()) {
Timer->Skip();
cRecordControls::Process(Timers, time(NULL));
}
Timers->Del(Timer);
Timers->SetModified();
isyslog("SVDRP < %s deleted timer %s", *connection, *Timer->ToDescr());

11
vdr.5
View File

@ -8,7 +8,7 @@
.\" License as specified in the file COPYING that comes with the
.\" vdr distribution.
.\"
.\" $Id: vdr.5 4.5 2018/02/03 13:56:27 kls Exp $
.\" $Id: vdr.5 4.6 2018/02/13 09:33:41 kls Exp $
.\"
.TH vdr 5 "19 Feb 2015" "2.2" "Video Disk Recorder Files"
.SH NAME
@ -821,6 +821,15 @@ closer).
\fBCURRENT RESTRICTIONS:\fR
-\ the comment is currently not used by VDR
.SS RECORDING TIMER
The file \fI.timer\fR (if present in a recording directory) contains
the full id of the timer that is currently recording into this directory.
Timer ids are of the form
\fBid@hostname\fR
where \fBid\fR is the timer's numerical id on the VDR with the name \fBhostname\fR.
This file is created when the timer starts recording, and is deleted when it ends.
.SS EPG DATA
The file \fIepg.data\fR contains the EPG data in an easily parsable format.
The first character of each line defines what kind of data this line contains.