From 95c8c2b60cfa455520798ea4db2a071ed18c2a2c Mon Sep 17 00:00:00 2001 From: Klaus Schmidinger Date: Sun, 13 Oct 2002 12:14:49 +0200 Subject: [PATCH] New configuration file 'reccmds.conf' --- CONTRIBUTORS | 2 + HISTORY | 3 + MANUAL | 36 +++++++---- config.c | 16 +++-- config.h | 5 +- i18n.c | 18 +++++- menu.c | 168 +++++++++++++++++++++++++++++++-------------------- menu.h | 3 +- osd.c | 6 +- vdr.5 | 11 +++- vdr.c | 3 +- 11 files changed, 176 insertions(+), 95 deletions(-) diff --git a/CONTRIBUTORS b/CONTRIBUTORS index 4d3ddeed..33d89d7b 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -432,3 +432,5 @@ Robert Schiele Gerhard Steiner for suggesting that the SVDRP command PUTE shall trigger an immediate write of the 'epg.data' file + for suggesting the new configuration file 'reccmds.conf' to define commands that + shall be executed from the "Recordings" menu diff --git a/HISTORY b/HISTORY index b336f204..b76f091f 100644 --- a/HISTORY +++ b/HISTORY @@ -1607,3 +1607,6 @@ Video Disk Recorder Revision History OSD will now be closed automatically. - The SVDRP command PUTE now triggers an immediate write of the 'epg.data' file (suggested by Gerhard Steiner). +- The new configuration file 'reccmds.conf' can be used to define commands that + shall be executed from the "Recordings" menu; see MANUAL and 'man vdr(5)' for + details (suggested by Gerhard Steiner). diff --git a/MANUAL b/MANUAL index 2dc75a34..79e80d03 100644 --- a/MANUAL +++ b/MANUAL @@ -8,20 +8,20 @@ Video Disk Recorder User's Manual possible, several keys have different meanings in the various modes: - Key Normal VDR Channels Timers Edit/New Recordings Replay + Key Normal VDR Channels Timers Edit/New Recordings Replay - Up Ch up Crsr up Crsr up Crsr up Crsr up Crsr up Play - Down Ch down Crsr down Crsr down Crsr down Crsr down Crsr down Pause - Left Prev group - Page up Page up Decrement Page up Search back - Right Next group - Page down Page down Increment Page down Search forward - Ok Ch display Select Switch Edit Accept Play Progress disp. - Menu Menu on Menu off Menu off Menu off Menu off Menu off Menu on - Back - Menu off VDR menu VDR menu Discard VDR menu Recordings menu - Red - Record Edit Edit ABC/abc Play Jump - Green - Language New New Ins/Ovr Rewind Skip -60s - Yellow - - Delete Delete Delete Delete Skip +60s - Blue - Stop/Resume Mark On/Off(1) - Summary Stop - 0..9 Ch select - - - Numeric inp. - Editing + Up Ch up Crsr up Crsr up Crsr up Crsr up Crsr up Play + Down Ch down Crsr down Crsr down Crsr down Crsr down Crsr down Pause + Left Prev group - Page up Page up Decrement Page up Search back + Right Next group - Page down Page down Increment Page down Search forward + Ok Ch display Select Switch Edit Accept Play Progress disp. + Menu Menu on Menu off Menu off Menu off Menu off Menu off Menu on + Back - Menu off VDR menu VDR menu Discard VDR menu Recordings menu + Red - Record Edit Edit ABC/abc Play/Commands(2) Jump + Green - Language New New Ins/Ovr Rewind Skip -60s + Yellow - - Delete Delete Delete Delete Skip +60s + Blue - Stop/Resume Mark On/Off(1) - Summary Stop + 0..9 Ch select - - - Numeric inp. Exec cmd(2) Editing Power Shutdown Volume+ Volume up @@ -31,6 +31,7 @@ Video Disk Recorder User's Manual (1) The "On/Off" button in the "Timers" menu only works if sorting the timers has been enabled in the "Setup" menu. Otherwise the Blue button is used to "mark" a timer for moving. + (2) See "Processing Recordings" below. * Navigating through the On Screen Menus @@ -187,6 +188,15 @@ Video Disk Recorder User's Manual A previously stopped playback session can be resumed by pressing the "Blue" button in the "VDR" menu. +* Processing Recordings + + The configuration file 'reccmds.conf' can be used to define system commands + that can be applied to the recording that is currently highlighted in the + "Recordings" menu. The "Red" button in the "Recordings" menu opens the "Recording + commands" menu if there are commands defined in the file 'reccmds.conf'. Pressing + one of the keys '1'..'9' in the "Recordings" menu executes the corresponding + command from 'reccmds.conf' (see also "Executing system commands" below). + * Replay Control The following keys have the listed meaning in Replay mode: diff --git a/config.c b/config.c index ad9282be..d9cdb43c 100644 --- a/config.c +++ b/config.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: config.c 1.108 2002/10/13 08:52:25 kls Exp $ + * $Id: config.c 1.109 2002/10/13 10:03:49 kls Exp $ */ #include "config.h" @@ -391,12 +391,16 @@ bool cCommand::Parse(const char *s) return false; } -const char *cCommand::Execute(void) +const char *cCommand::Execute(const char *Parameters) { - dsyslog("executing command '%s'", command); free(result); result = NULL; - FILE *p = popen(command, "r"); + char *cmdbuf = NULL; + if (Parameters) + asprintf(&cmdbuf, "%s %s", command, Parameters); + const char *cmd = cmdbuf ? cmdbuf : command; + dsyslog("executing command '%s'", cmd); + FILE *p = popen(cmd, "r"); if (p) { int l = 0; int c; @@ -410,7 +414,8 @@ const char *cCommand::Execute(void) pclose(p); } else - esyslog("ERROR: can't open pipe for command '%s'", command); + esyslog("ERROR: can't open pipe for command '%s'", cmd); + free(cmdbuf); return result; } @@ -469,6 +474,7 @@ bool cCaDefinition::Parse(const char *s) // -- cCommands -------------------------------------------------------------- cCommands Commands; +cCommands RecordingCommands; // -- cTimers ---------------------------------------------------------------- diff --git a/config.h b/config.h index a24f71a3..1f043c4a 100644 --- a/config.h +++ b/config.h @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: config.h 1.133 2002/10/13 08:35:49 kls Exp $ + * $Id: config.h 1.134 2002/10/13 10:03:09 kls Exp $ */ #ifndef __CONFIG_H @@ -95,7 +95,7 @@ public: bool Parse(const char *s); const char *Title(void) { return title; } bool Confirm(void) { return confirm; } - const char *Execute(void); + const char *Execute(const char *Parameters = NULL); }; typedef uint32_t in_addr_t; //XXX from /usr/include/netinet/in.h (apparently this is not defined on systems with glibc < 2.2) @@ -224,6 +224,7 @@ public: extern cTimers Timers; extern cCommands Commands; +extern cCommands RecordingCommands; extern cSVDRPhosts SVDRPhosts; extern cCaDefinitions CaDefinitions; diff --git a/i18n.c b/i18n.c index d8dc3b7b..311378c5 100644 --- a/i18n.c +++ b/i18n.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: i18n.c 1.95 2002/10/06 11:31:18 kls Exp $ + * $Id: i18n.c 1.96 2002/10/13 11:03:39 kls Exp $ * * Translations provided by: * @@ -199,6 +199,22 @@ const tI18nPhrase Phrases[] = { "Comenzi", "Parancsok", }, + { "Recording commands", + "Befehle für Aufzeichnungen", + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + }, { "Edit channel", "Kanal editieren", "Uredi kanal", diff --git a/menu.c b/menu.c index bdf7dba7..077922a1 100644 --- a/menu.c +++ b/menu.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: menu.c 1.216 2002/10/13 09:15:26 kls Exp $ + * $Id: menu.c 1.217 2002/10/13 12:10:54 kls Exp $ */ #include "menu.h" @@ -1431,6 +1431,77 @@ eOSState cMenuSchedule::ProcessKey(eKeys Key) return state; } +// --- cMenuCommands --------------------------------------------------------- + +class cMenuCommands : public cOsdMenu { +private: + cCommands *commands; + char *parameters; + eOSState Execute(void); +public: + cMenuCommands(const char *Title, cCommands *Commands, const char *Parameters = NULL); + virtual ~cMenuCommands(); + virtual eOSState ProcessKey(eKeys Key); + }; + +cMenuCommands::cMenuCommands(const char *Title, cCommands *Commands, const char *Parameters) +:cOsdMenu(Title) +{ + SetHasHotkeys(); + commands = Commands; + parameters = Parameters ? strdup(Parameters) : NULL; + int i = 0; + cCommand *command; + + while ((command = commands->Get(i)) != NULL) { + Add(new cOsdItem(hk(command->Title()))); + i++; + } +} + +cMenuCommands::~cMenuCommands() +{ + free(parameters); +} + +eOSState cMenuCommands::Execute(void) +{ + cCommand *command = commands->Get(Current()); + if (command) { + char *buffer = NULL; + bool confirmed = true; + if (command->Confirm()) { + asprintf(&buffer, "%s?", command->Title()); + confirmed = Interface->Confirm(buffer); + free(buffer); + } + if (confirmed) { + asprintf(&buffer, "%s...", command->Title()); + Interface->Status(buffer); + Interface->Flush(); + free(buffer); + const char *Result = command->Execute(parameters); + if (Result) + return AddSubMenu(new cMenuText(command->Title(), Result, fontFix)); + return osEnd; + } + } + return osContinue; +} + +eOSState cMenuCommands::ProcessKey(eKeys Key) +{ + eOSState state = cOsdMenu::ProcessKey(Key); + + if (state == osUnknown) { + switch (Key) { + case kOk: return Execute(); + default: break; + } + } + return state; +} + // --- cMenuRecordingItem ---------------------------------------------------- class cMenuRecordingItem : public cOsdItem { @@ -1545,7 +1616,7 @@ void cMenuRecordings::SetHelpKeys(void) case 0: SetHelp(NULL); break; case 1: SetHelp(tr("Open")); break; case 2: - case 3: SetHelp(tr("Play"), tr("Rewind"), tr("Delete"), NewHelpKeys == 3 ? tr("Summary") : NULL); + case 3: SetHelp(RecordingCommands.Count() ? tr("Commands") : tr("Play"), tr("Rewind"), tr("Delete"), NewHelpKeys == 3 ? tr("Summary") : NULL); } helpKeys = NewHelpKeys; } @@ -1595,6 +1666,8 @@ eOSState cMenuRecordings::Play(void) eOSState cMenuRecordings::Rewind(void) { + if (HasSubMenu() || Count() == 0) + return osContinue; cMenuRecordingItem *ri = (cMenuRecordingItem *)Get(Current()); if (ri && !ri->IsDirectory()) { cDevice::PrimaryDevice()->StopReplay(); // must do this first to be able to rewind the currently replayed recording @@ -1607,6 +1680,8 @@ eOSState cMenuRecordings::Rewind(void) eOSState cMenuRecordings::Delete(void) { + if (HasSubMenu() || Count() == 0) + return osContinue; cMenuRecordingItem *ri = (cMenuRecordingItem *)Get(Current()); if (ri && !ri->IsDirectory()) { if (Interface->Confirm(tr("Delete recording?"))) { @@ -1654,6 +1729,27 @@ eOSState cMenuRecordings::Summary(void) return osContinue; } +eOSState cMenuRecordings::Commands(eKeys Key) +{ + if (HasSubMenu() || Count() == 0) + return osContinue; + cMenuRecordingItem *ri = (cMenuRecordingItem *)Get(Current()); + if (ri && !ri->IsDirectory()) { + cRecording *recording = GetRecording(ri); + if (recording) { + char *parameter = NULL; + asprintf(¶meter, "'%s'", recording->FileName()); + cMenuCommands *menu; + eOSState state = AddSubMenu(menu = new cMenuCommands(tr("Recording commands"), &RecordingCommands, parameter)); + free(parameter); + if (Key != kNone) + state = menu->ProcessKey(Key); + return state; + } + } + return osContinue; +} + eOSState cMenuRecordings::ProcessKey(eKeys Key) { bool HadSubMenu = HasSubMenu(); @@ -1661,11 +1757,12 @@ eOSState cMenuRecordings::ProcessKey(eKeys Key) if (state == osUnknown) { switch (Key) { - case kOk: - case kRed: return Play(); + case kOk: return Play(); + case kRed: return (helpKeys > 1 && RecordingCommands.Count()) ? Commands() : Play(); case kGreen: return Rewind(); case kYellow: return Delete(); case kBlue: return Summary(); + case k1...k9: return Commands(Key); default: break; } } @@ -2051,67 +2148,6 @@ eOSState cMenuSetup::ProcessKey(eKeys Key) return state; } -// --- cMenuCommands --------------------------------------------------------- - -class cMenuCommands : public cOsdMenu { -private: - eOSState Execute(void); -public: - cMenuCommands(void); - virtual eOSState ProcessKey(eKeys Key); - }; - -cMenuCommands::cMenuCommands(void) -:cOsdMenu(tr("Commands")) -{ - SetHasHotkeys(); - int i = 0; - cCommand *command; - - while ((command = Commands.Get(i)) != NULL) { - Add(new cOsdItem(hk(command->Title()))); - i++; - } -} - -eOSState cMenuCommands::Execute(void) -{ - cCommand *command = Commands.Get(Current()); - if (command) { - char *buffer = NULL; - bool confirmed = true; - if (command->Confirm()) { - asprintf(&buffer, "%s?", command->Title()); - confirmed = Interface->Confirm(buffer); - free(buffer); - } - if (confirmed) { - asprintf(&buffer, "%s...", command->Title()); - Interface->Status(buffer); - Interface->Flush(); - free(buffer); - const char *Result = command->Execute(); - if (Result) - return AddSubMenu(new cMenuText(command->Title(), Result, fontFix)); - return osEnd; - } - } - return osContinue; -} - -eOSState cMenuCommands::ProcessKey(eKeys Key) -{ - eOSState state = cOsdMenu::ProcessKey(Key); - - if (state == osUnknown) { - switch (Key) { - case kOk: return Execute(); - default: break; - } - } - return state; -} - // --- cMenuPluginItem ------------------------------------------------------- class cMenuPluginItem : public cOsdItem { @@ -2237,7 +2273,7 @@ eOSState cMenuMain::ProcessKey(eKeys Key) case osTimers: return AddSubMenu(new cMenuTimers); case osRecordings: return AddSubMenu(new cMenuRecordings); case osSetup: return AddSubMenu(new cMenuSetup); - case osCommands: return AddSubMenu(new cMenuCommands); + case osCommands: return AddSubMenu(new cMenuCommands(tr("Commands"), &Commands)); case osStopRecord: if (Interface->Confirm(tr("Stop recording?"))) { cOsdItem *item = Get(Current()); if (item) { diff --git a/menu.h b/menu.h index 325a29f3..ba3c3d55 100644 --- a/menu.h +++ b/menu.h @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: menu.h 1.47 2002/10/06 10:35:49 kls Exp $ + * $Id: menu.h 1.48 2002/10/13 10:34:09 kls Exp $ */ #ifndef __MENU_H @@ -70,6 +70,7 @@ private: eOSState Rewind(void); eOSState Delete(void); eOSState Summary(void); + eOSState Commands(eKeys Key = kNone); public: cMenuRecordings(const char *Base = NULL, int Level = 0, bool OpenSubMenus = false); ~cMenuRecordings(); diff --git a/osd.c b/osd.c index a2daf603..acd9aec4 100644 --- a/osd.c +++ b/osd.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: osd.c 1.35 2002/08/25 09:18:31 kls Exp $ + * $Id: osd.c 1.36 2002/10/13 10:31:28 kls Exp $ */ #include "osd.h" @@ -623,9 +623,7 @@ eOSState cOsdMenu::ProcessKey(eKeys Key) return state; } switch (Key) { - case k1...k9: if (hasHotkeys) - return HotKey(Key); - break; + case k1...k9: return hasHotkeys ? HotKey(Key) : osUnknown; case kUp|k_Repeat: case kUp: CursorUp(); break; case kDown|k_Repeat: diff --git a/vdr.5 b/vdr.5 index b36422fa..ccb7b924 100644 --- a/vdr.5 +++ b/vdr.5 @@ -8,7 +8,7 @@ .\" License as specified in the file COPYING that comes with the .\" vdr distribution. .\" -.\" $Id: vdr.5 1.7 2002/10/13 09:03:53 kls Exp $ +.\" $Id: vdr.5 1.8 2002/10/13 12:14:49 kls Exp $ .\" .TH vdr 5 "7 Sep 2002" "1.2.0" "Video Disk Recorder Files" .SH NAME @@ -311,7 +311,6 @@ PC keyboard, RCU for the home-built "Remote Control Unit", or LIRC for the "Linux Infrared Remote Control"), \fBkey\fR is the name of the key that is defined (like Up, Down, Menu etc.), and \fBcode\fR is a character string that this remote control delivers when the given key is pressed. - .SS COMMANDS The file \fIcommands.conf\fR contains the definitions of commands that can be executed from the \fBvdr\fR main menu's "Commands" option. @@ -327,6 +326,8 @@ be a confirmation prompt before actually executing the command. This can be used for commands that might have serious results (like deleting files etc) to make sure they are not executed inadvertently. +Everything following (and including) a '#' character is considered to be comment. + By default the menu entries in the "Commands" menu will be numbered '1'...'9' to make them selectable by pressing the corresponding number key. If you want to use your own numbering scheme (maybe to skip certain numbers), just precede @@ -353,6 +354,12 @@ Don't send emails to the author asking where to find these ;-) .br The '?' at the end of the "Check for new mail?" entry will prompt the user whether this command shall really be executed. +.SS RECORDING COMMANDS +The file \fIreccmds.conf\fR can be used to define commands that can be applied +to the currently highlighted recording in the "Recordings" menu. The syntax is +exactly the same as described for the file \fIcommands.conf\fR. When executing +a command, the directory name of the recording will be appended to the command +string, separated by a blank and enclosed in single quotes. .SS SVDRP HOSTS The file \fIsvdrphosts.conf\fR contains the IP numbers of all hosts that are allowed to access the SVDRP port. diff --git a/vdr.c b/vdr.c index c1e0c11a..beeee889 100644 --- a/vdr.c +++ b/vdr.c @@ -22,7 +22,7 @@ * * The project's page is at http://www.cadsoft.de/people/kls/vdr * - * $Id: vdr.c 1.126 2002/10/12 15:22:29 kls Exp $ + * $Id: vdr.c 1.127 2002/10/13 12:13:19 kls Exp $ */ #include @@ -319,6 +319,7 @@ int main(int argc, char *argv[]) Channels.Load(AddDirectory(ConfigDirectory, "channels.conf")); Timers.Load(AddDirectory(ConfigDirectory, "timers.conf")); Commands.Load(AddDirectory(ConfigDirectory, "commands.conf"), true); + RecordingCommands.Load(AddDirectory(ConfigDirectory, "reccmds.conf"), true); SVDRPhosts.Load(AddDirectory(ConfigDirectory, "svdrphosts.conf"), true); CaDefinitions.Load(AddDirectory(ConfigDirectory, "ca.conf"), true); Keys.Load(AddDirectory(ConfigDirectory, "remote.conf"));