New configuration file 'reccmds.conf'

This commit is contained in:
Klaus Schmidinger 2002-10-13 12:14:49 +02:00
parent 44cb1a79a5
commit 95c8c2b60c
11 changed files with 176 additions and 95 deletions

View File

@ -432,3 +432,5 @@ Robert Schiele <rschiele@uni-mannheim.de>
Gerhard Steiner <steiner@mail.austria.com>
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

View File

@ -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).

36
MANUAL
View File

@ -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:

View File

@ -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 ----------------------------------------------------------------

View File

@ -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;

18
i18n.c
View File

@ -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",

168
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 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(&parameter, "'%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) {

3
menu.h
View File

@ -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();

6
osd.c
View File

@ -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:

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 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.

3
vdr.c
View File

@ -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 <getopt.h>
@ -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"));