[svn-inject] Installing original source of teleschorsch upstream/0.0.3
authorgregor herrmann <gregoa@debian.org>
Tue, 27 Feb 2007 22:09:39 +0000 (22:09 -0000)
committergregor herrmann <gregoa@debian.org>
Tue, 27 Feb 2007 22:09:39 +0000 (22:09 -0000)
main.cpp [new file with mode: 0644]
main.h [new file with mode: 0644]
maindialog.ui [new file with mode: 0644]
options.cpp [new file with mode: 0644]
options.h [new file with mode: 0644]
options.ui [new file with mode: 0644]
qteleschorsch.pro [new file with mode: 0644]
teleschorsch.pl [new file with mode: 0755]
teleschorsch.sh [new file with mode: 0755]
teleschorschrc [new file with mode: 0644]

diff --git a/main.cpp b/main.cpp
new file mode 100644 (file)
index 0000000..8d0632f
--- /dev/null
+++ b/main.cpp
@@ -0,0 +1,172 @@
+/*
+# Copyright and License:
+#
+# Copyright (C) 2007 
+# gregor herrmann <gregor+debian@comodo.priv.at>,
+# Philipp Spitzer <philipp@spitzer.priv.at>
+#
+# This program is free software; you can redistribute it and/or modify it   
+# under the terms of the GNU General Public License version 2 as published
+# by the Free Software Foundation.
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA, or point
+# your browser to http://www.gnu.org/licenses/gpl.html
+*/
+
+#include <QtGlobal>
+#include <QtDebug>
+#include <QApplication>
+#include <QVector>
+#include <QFile>
+#include <QProcess>
+#include <QMessageBox>
+#include "main.h"
+#include "options.h"
+
+
+// Functions
+// =========
+
+void initConfigInfo(ConfigInfo& configInfo) {
+       QStringList environment = QProcess::systemEnvironment().filter(QRegExp("^HOME=")); // ("HOME=/home/gregoa")
+       if (environment.size() == 1) {
+               configInfo.home = environment.at(0).mid(5);
+               configInfo.userConfigFile = configInfo.home + + "/.teleschorschrc";
+       }
+       configInfo.systemConfigFile = "/etc/teleschorschrc";
+
+       // User config file
+       if (!configInfo.userConfigFile.isEmpty()) {
+               QFile configFileUser(configInfo.userConfigFile);
+               if (configFileUser.exists()) {configInfo.usedConfigFile  = configInfo.userConfigFile;}
+       }
+
+       // System config file
+       if (configInfo.usedConfigFile.isEmpty()) {
+               QFile configFileSystem(configInfo.systemConfigFile);
+               if (configFileSystem.exists()) configInfo.usedConfigFile = configInfo.systemConfigFile;
+       }
+}
+
+
+bool addConfig(const QString& fileName, ChannelVec& cv, QString& error) {
+       QFile file(fileName);
+       if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {error = QObject::tr("Could not open file %1").arg(fileName); return false;}
+       Channel channel; // current channel
+       bool sectionOccured = false;
+       while (!file.atEnd()) {
+               QString line = QString(file.readLine()).trimmed();
+               if (line.startsWith("#") || line.startsWith(";") || line.isEmpty()) continue; // strip comments
+               
+               // Is the line a [section]?
+               bool section = line.startsWith("[") && line.endsWith("]") && line.size() >= 3;
+               if (section) {
+                       if (sectionOccured) cv.push_back(channel);
+                       sectionOccured = true;
+                       channel = Channel();
+                       channel.name = line.mid(1, line.size()-2);
+               }
+
+               // Read properties
+               int eqPos = line.indexOf("=");
+               bool property = !section && eqPos >= 1;
+               if (property) {
+                       QString propKey = line.left(eqPos);
+                       QString propVal = line.right(line.size()-eqPos-1);
+                       if (!sectionOccured) {error = QObject::tr("Property %1 is only allowed in a [section].").arg(propKey); return false;}
+
+                       if (propKey == "FULLNAME") channel.fullName = propVal;
+                       else if (propKey == "STATICURL") channel.staticUrl = propVal;
+                       else if (propKey == "PLAYER") channel.player = propVal;
+                       else {error = QObject::tr("Unknown key in ini file: %1").arg(propKey); return false;}
+               }
+
+               if (!section && !property) {error = QObject::tr("Line %1 is not valid.").arg(line); return false;}
+       }
+       if (sectionOccured) cv.push_back(channel);
+       return true;
+}
+
+
+QString readChannelVec(const ConfigInfo& configInfo, ChannelVec& channelVec) {
+       if (configInfo.usedConfigFile.isEmpty()) return QObject::tr("Neither %1 nor %2 found.").arg(configInfo.systemConfigFile).arg(configInfo.userConfigFile);
+       QString error;
+       if (!addConfig(configInfo.usedConfigFile, channelVec, error));
+       return error;
+}
+
+
+
+// MainDialog
+// ==========
+
+MainDialog::MainDialog(QWidget *parent): QDialog(parent) {
+       // User interface
+       setupUi(this);
+       QObject::connect(btnOptions, SIGNAL(clicked()), this, SLOT(editOptions()));
+       QObject::connect(btnStart, SIGNAL(clicked()), this, SLOT(startAction()));
+
+       // Init configInfo
+       initConfigInfo(configInfo);
+
+       // Read config
+       QString error = readChannelVec(configInfo, channelVec);
+       if (!error.isEmpty()) QMessageBox::warning(this, tr("Problem when reading the configuration file"), error);
+
+       // Fill in channels
+       updateLwChannels();
+}
+
+
+void MainDialog::editOptions() {
+       OptionsDialog *od = new OptionsDialog();
+       if (od->exec(configInfo.userConfigFile)) {
+               channelVec.clear();
+               QString error = readChannelVec(configInfo, channelVec);
+               if (!error.isEmpty()) QMessageBox::warning(this, tr("Problem when reading the configuration file"), error);
+               updateLwChannels();
+       }
+       delete od;
+}
+
+
+void MainDialog::updateLwChannels() {
+       lwChannels->clear();
+       for (int i = 0; i != channelVec.size(); ++i) lwChannels->addItem(channelVec[i].fullName);
+}
+
+
+bool MainDialog::startAction() {
+       int row = lwChannels->currentRow();
+       if (row > 0) {
+               Channel channel = channelVec[row];
+               qDebug() << "User would like to see " << channel.staticUrl;
+
+               QString program = "/usr/bin/vlc";
+               QStringList arguments;
+               // arguments << "-style" << "motif";
+               // @args=("$player $url " . ${playeroptions}{$player} . " $offsetseconds");
+               QProcess player(0);
+               player.start(program, arguments);
+               player.waitForFinished();
+               return true;
+       }
+       return false;
+}
+
+
+
+// Main function
+// =============
+
+int main(int argc, char *argv[]) {
+       QApplication app(argc, argv);
+       MainDialog *mainDialog = new MainDialog();
+       mainDialog->show();
+       return app.exec();
+} 
diff --git a/main.h b/main.h
new file mode 100644 (file)
index 0000000..e9d01c5
--- /dev/null
+++ b/main.h
@@ -0,0 +1,64 @@
+#ifndef MAIN_H
+#define MAIN_H
+#include "ui_maindialog.h"
+
+// Types
+// =====
+
+struct Channel {
+       QString name;
+       QString fullName;
+       QString staticUrl;
+       QString player;
+};
+
+
+typedef QVector<Channel> ChannelVec;
+
+
+struct ConfigInfo {
+       QString home;               ///< environment variable $HOME (e.g. /home/gregoa) or empty if $HOME does not exist
+       QString systemConfigFile;   ///< system configuration file name (/etc/teleschorschrc)
+       QString userConfigFile;     ///< user configuration file name (e.g. /home/gregoa/.teleschorschrc)
+       QString usedConfigFile;     ///< currently used config file (e.g. /home/gregoa/.teleschorschrc)
+};
+
+
+
+// Functions
+// =========
+
+/// Determine ConfigInfo file names
+void initConfigInfo(ConfigInfo& configInfo);
+
+
+/// Adds the content of the specified config file to the channel vector
+bool addConfig(const QString& fileName, ChannelVec& cv, QString& error);
+
+
+/// \brief Read channel vector
+///
+/// In an error case, the error message is returned.
+QString readChannelVec(const ConfigInfo& configInfo, ChannelVec& channelVec);
+
+
+// MainDialog
+// ==========
+
+class MainDialog: public QDialog, private Ui::MainDialog {
+Q_OBJECT
+
+private:
+       ChannelVec channelVec;
+       ConfigInfo configInfo;
+
+public:
+       MainDialog(QWidget *parent = 0);
+
+public slots:
+       void editOptions();
+       void updateLwChannels();
+       bool startAction();
+};
+
+#endif
diff --git a/maindialog.ui b/maindialog.ui
new file mode 100644 (file)
index 0000000..18618f4
--- /dev/null
@@ -0,0 +1,169 @@
+<ui version="4.0" >
+ <class>MainDialog</class>
+ <widget class="QDialog" name="MainDialog" >
+  <property name="geometry" >
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>400</width>
+    <height>339</height>
+   </rect>
+  </property>
+  <property name="windowTitle" >
+   <string>TeleSchorsch</string>
+  </property>
+  <layout class="QVBoxLayout" >
+   <property name="margin" >
+    <number>9</number>
+   </property>
+   <property name="spacing" >
+    <number>6</number>
+   </property>
+   <item>
+    <layout class="QHBoxLayout" >
+     <property name="margin" >
+      <number>0</number>
+     </property>
+     <property name="spacing" >
+      <number>6</number>
+     </property>
+     <item>
+      <layout class="QVBoxLayout" >
+       <property name="margin" >
+        <number>0</number>
+       </property>
+       <property name="spacing" >
+        <number>6</number>
+       </property>
+       <item>
+        <widget class="QLabel" name="labChannels" >
+         <property name="text" >
+          <string>Channel</string>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <widget class="QListWidget" name="lwChannels" />
+       </item>
+      </layout>
+     </item>
+     <item>
+      <layout class="QVBoxLayout" >
+       <property name="margin" >
+        <number>0</number>
+       </property>
+       <property name="spacing" >
+        <number>6</number>
+       </property>
+       <item>
+        <widget class="QLabel" name="labDate" >
+         <property name="text" >
+          <string>Date</string>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <widget class="QCalendarWidget" name="calDate" >
+         <property name="firstDayOfWeek" >
+          <enum>Qt::Monday</enum>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <widget class="QLabel" name="labOffset" >
+         <property name="text" >
+          <string>Offset</string>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <widget class="QTimeEdit" name="teOffset" >
+         <property name="calendarPopup" >
+          <bool>false</bool>
+         </property>
+        </widget>
+       </item>
+      </layout>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <layout class="QHBoxLayout" >
+     <property name="margin" >
+      <number>0</number>
+     </property>
+     <property name="spacing" >
+      <number>6</number>
+     </property>
+     <item>
+      <widget class="QPushButton" name="btnOptions" >
+       <property name="text" >
+        <string>Options</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <spacer>
+       <property name="orientation" >
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeHint" >
+        <size>
+         <width>40</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+     <item>
+      <widget class="QPushButton" name="btnStart" >
+       <property name="text" >
+        <string>Start</string>
+       </property>
+       <property name="default" >
+        <bool>true</bool>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QPushButton" name="btnQuit" >
+       <property name="text" >
+        <string>Quit</string>
+       </property>
+       <property name="shortcut" >
+        <string/>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+  </layout>
+ </widget>
+ <tabstops>
+  <tabstop>lwChannels</tabstop>
+  <tabstop>calDate</tabstop>
+  <tabstop>teOffset</tabstop>
+  <tabstop>btnStart</tabstop>
+  <tabstop>btnQuit</tabstop>
+  <tabstop>btnOptions</tabstop>
+ </tabstops>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>btnQuit</sender>
+   <signal>clicked()</signal>
+   <receiver>MainDialog</receiver>
+   <slot>accept()</slot>
+   <hints>
+    <hint type="sourcelabel" >
+     <x>352</x>
+     <y>308</y>
+    </hint>
+    <hint type="destinationlabel" >
+     <x>199</x>
+     <y>169</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>
diff --git a/options.cpp b/options.cpp
new file mode 100644 (file)
index 0000000..10cc550
--- /dev/null
@@ -0,0 +1,42 @@
+#include <QMessageBox>
+#include <QFile>
+#include <QTextStream>
+#include "options.h"
+
+OptionsDialog::OptionsDialog(QWidget *parent): QDialog(parent) {
+       setupUi(this);
+}
+
+
+bool OptionsDialog::exec(const QString& configFile) {
+       if (configFile.isEmpty()) {
+               QMessageBox::warning(this, tr("No user config file location"), tr("The location of the user config file could not be determined."));
+               return false;
+       }
+       QFile configFileUser(configFile);
+       if (!configFileUser.exists()) {
+               QMessageBox::StandardButton answer = QMessageBox::question(this, tr("Create user config file?"), tr("The user config file %1 does not exist. Do you want to create it?").arg(configFile), QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel, QMessageBox::Yes);
+               if (answer != QMessageBox::Yes) return false;
+               teIni->clear();
+       } else {
+               if (!configFileUser.open(QIODevice::ReadOnly | QIODevice::Text)) {
+                       QMessageBox::warning(this, tr("File not readable"), tr("The user config file %1 is not readable.").arg(configFile));
+                       return false;
+               }
+               QTextStream in(&configFileUser);
+               while (!in.atEnd()) teIni->append(in.readLine());
+       }
+       configFileUser.close();
+       if (QDialog::exec() == QDialog::Accepted) {
+               // Save
+               if (!configFileUser.open(QIODevice::WriteOnly | QIODevice::Text)) {
+                       QMessageBox::warning(this, tr("File not writeable"), tr("The config file %1 is not writeable.").arg(configFile));
+                       return false;
+               }
+               QTextStream out(&configFileUser);
+               out << teIni->toPlainText();
+               return true;
+       }
+       return false;
+}
+
diff --git a/options.h b/options.h
new file mode 100644 (file)
index 0000000..924a74e
--- /dev/null
+++ b/options.h
@@ -0,0 +1,18 @@
+#include "ui_options.h"
+#include "main.h"
+
+class OptionsDialog: public QDialog, public Ui::OptionsDialog {
+Q_OBJECT
+
+public:
+       OptionsDialog(QWidget *parent = 0);
+
+       /// \brief Shows a dialog where the user can edit the specified configuration file.
+       ///
+       /// If the file was modified and successfully saved, true is returned, otherwise false.
+       /// The dialog shows error to the user itself.
+       /// \todo First try to save and afterwards save. This would give the user the chance to copy & paste his/her changes.
+       /// \param configFile file name with full path to the configuration file to edit.
+       bool exec(const QString& configFile);
+};
+
diff --git a/options.ui b/options.ui
new file mode 100644 (file)
index 0000000..c6245f4
--- /dev/null
@@ -0,0 +1,127 @@
+<ui version="4.0" >
+ <class>OptionsDialog</class>
+ <widget class="QDialog" name="OptionsDialog" >
+  <property name="geometry" >
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>400</width>
+    <height>300</height>
+   </rect>
+  </property>
+  <property name="windowTitle" >
+   <string>TeleSchorsch channel configuration</string>
+  </property>
+  <layout class="QVBoxLayout" >
+   <property name="margin" >
+    <number>9</number>
+   </property>
+   <property name="spacing" >
+    <number>6</number>
+   </property>
+   <item>
+    <widget class="QTextEdit" name="teIni" >
+     <property name="lineWrapMode" >
+      <enum>QTextEdit::NoWrap</enum>
+     </property>
+     <property name="acceptRichText" >
+      <bool>false</bool>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <widget class="QLabel" name="labHelp" >
+     <property name="text" >
+      <string>You may use the following special characters:
+
+&lt;ul>
+&lt;li>${d}: day of month (01-31)
+&lt;li>${m}: month (01-12)
+&lt;li>${y]: year (last two digits)
+&lt;li>${Y}: year (4 digits}
+&lt;li>${dow_DE}: day of week in German (Montag, ...)
+&lt;/ul></string>
+     </property>
+     <property name="textFormat" >
+      <enum>Qt::RichText</enum>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <layout class="QHBoxLayout" >
+     <property name="margin" >
+      <number>0</number>
+     </property>
+     <property name="spacing" >
+      <number>6</number>
+     </property>
+     <item>
+      <spacer>
+       <property name="orientation" >
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeHint" >
+        <size>
+         <width>40</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+     <item>
+      <widget class="QPushButton" name="btnSave" >
+       <property name="text" >
+        <string>Save</string>
+       </property>
+       <property name="default" >
+        <bool>true</bool>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QPushButton" name="btnCancel" >
+       <property name="text" >
+        <string>Cancel</string>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>btnCancel</sender>
+   <signal>clicked()</signal>
+   <receiver>OptionsDialog</receiver>
+   <slot>reject()</slot>
+   <hints>
+    <hint type="sourcelabel" >
+     <x>352</x>
+     <y>269</y>
+    </hint>
+    <hint type="destinationlabel" >
+     <x>199</x>
+     <y>149</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>btnSave</sender>
+   <signal>clicked()</signal>
+   <receiver>OptionsDialog</receiver>
+   <slot>accept()</slot>
+   <hints>
+    <hint type="sourcelabel" >
+     <x>271</x>
+     <y>275</y>
+    </hint>
+    <hint type="destinationlabel" >
+     <x>199</x>
+     <y>149</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>
diff --git a/qteleschorsch.pro b/qteleschorsch.pro
new file mode 100644 (file)
index 0000000..aec77a0
--- /dev/null
@@ -0,0 +1,10 @@
+TEMPLATE = app
+TARGET = 
+DEPENDPATH += .
+INCLUDEPATH += .
+
+# Input
+FORMS += maindialog.ui options.ui
+HEADERS += main.h options.h
+SOURCES += main.cpp options.cpp
+
diff --git a/teleschorsch.pl b/teleschorsch.pl
new file mode 100755 (executable)
index 0000000..0501d7a
--- /dev/null
@@ -0,0 +1,94 @@
+#!/usr/bin/perl -w
+#
+# Copyright and License:
+#
+# Copyright (C) 2007 
+# gregor herrmann <gregor+debian@comodo.priv.at>,
+# Philipp Spitzer <philipp@spitzer.priv.at>
+#
+# This program is free software; you can redistribute it and/or modify it   
+# under the terms of the GNU General Public License version 2 as published
+# by the Free Software Foundation.
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA, or point
+# your browser to http://www.gnu.org/licenses/gpl.html
+
+use strict;
+use Config::IniFiles;
+use DateTime;
+
+sub error {
+       my $msg = shift(@_);
+       print "$msg\n";
+       exit(1);
+}
+
+# variables
+my $configfile;
+if (-r "$ENV{HOME}/.teleschorschrc") {
+       $configfile = "$ENV{HOME}/.teleschorschrc";
+} elsif (-r "/etc/teleschorschrc") {
+       $configfile = "/etc/teleschorschrc";
+} else {
+       error "Neiter /etc/teleschorschrc nor $ENV{HOME}/.teleschorschrc found";
+}
+
+my $defaultdate;
+if (DateTime->now->hour < 12) {
+       $defaultdate = DateTime->now->subtract(days => 1)->dmy(' ');
+} else {
+       $defaultdate = DateTime->now->dmy(' ');
+}
+
+my %playeroptions = ("vlc" => "--start-time", "gmplayer" => "-cache 512 -ss");
+
+# read config
+my %cfg;
+tie %cfg, 'Config::IniFiles', ( -file => $configfile, -allowcontinue => 1) 
+       or error "Can't read $configfile: $!";
+my @channels = sort keys %cfg;
+
+sub create_list {      
+       my $result;
+       foreach my $c (@channels) {
+               $result .= "$c '$cfg{$c}{'FULLNAME'}' off ";
+       }
+       return $result;
+}
+
+# call xdialog
+my $channellist = &create_list;
+my @args=("Xdialog --stdout --title 'TeleSchorsch' --no-tags --radiolist 'Choose your preferred stream:' 0 0 0 $channellist --calendar 'Date' 0 0 $defaultdate --timebox 'Offset\n(Start at beginning of stream: 0:0:0, start at position 3 minutes: 0:3:0, ...)' 0 0 0 0 0");
+my $selection = qx/@args/ or error "@args: $? // $!\n\n";
+my ($stream, $date, $offset) = split (/\n/, $selection);
+
+# manipulate results
+my ($hours, $minutes, $seconds) = split(/:/, $offset);
+my $offsetseconds = $hours * 3600 + $minutes * 60 + $seconds;
+
+my ($day, $month, $year) = split(/\//, $date);
+my $dt = DateTime->new(year => $year, month => $month, day => $day);
+my $y =  $dt->strftime("%y");
+my $Y =  $dt->strftime("%Y");
+my $m =  $dt->strftime("%m");
+my $d =  $dt->strftime("%d");
+my $dt_DE = DateTime->from_object(object => $dt, locale => qx(locale -a | grep ^de_ | head -n 1));
+my $dow_DE = $dt_DE->strftime("%A");
+
+# get missing parameters
+my $player = $cfg{$stream}{'PLAYER'};
+
+my $url = $cfg{$stream}{'STATICURL'};
+no warnings;
+$url =~ s/(\${\w+?})/$1/eeg;
+use warnings;
+
+@args=("$player $url " . ${playeroptions}{$player} . " $offsetseconds");
+print "Calling @args ...\n";
+system (@args) == 0 
+       or error "@args: $? // $!";
diff --git a/teleschorsch.sh b/teleschorsch.sh
new file mode 100755 (executable)
index 0000000..7e36b29
--- /dev/null
@@ -0,0 +1,186 @@
+#!/bin/bash
+
+# Copyright and License:
+#
+# Copyright (C) 2007 
+# gregor herrmann <gregor+debian@comodo.priv.at>,
+# Philipp Spitzer <philipp@spitzer.priv.at>
+#
+# This program is free software; you can redistribute it and/or modify it   
+# under the terms of the GNU General Public License version 2 as published
+# by the Free Software Foundation.
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA, or point
+# your browser to http://www.gnu.org/licenses/gpl.html
+
+# Changes:
+#
+# 0.1.1
+#      add command line options "-xdialog" (default) and "-dialog"
+#
+# 0.1.0
+#      use the new configuration file
+#
+# 0.0.6
+#      move mplayer start options down
+#
+# 0.0.5
+#      implement some more error checks
+#
+# 0.0.4
+#      set default date to yesterday if current time < noon
+#
+# 0.0.3:
+#              clarify description of "start time", i.e. "offset"
+#
+# 0.0.2:
+#      check for required binaries
+#
+# 0.0.1:
+#      first release
+
+# functions
+
+error() {
+       echo "$(basename $0) aborting with error:"
+       echo $1
+       exit 1
+}
+
+# parameters
+
+UI="xdialog"
+if [ -n "$1" ] ; then
+       case "$1" in
+               "-xdialog")
+                       UI="xdialog"
+                       ;;
+               "-dialog")
+                       UI="dialog"
+                       ;;
+       esac
+fi
+
+# checks
+
+case "$UI" in
+       "xdialog")
+               which Xdialog > /dev/null || error "Please install Xdialog or try -dialog."
+               ;;
+       "dialog")
+               which dialog > /dev/null || error "Please install dialog or try -xdialog."
+               ;;
+esac           
+
+which vlc > /dev/null || error "Please install vlc."
+which gmplayer > /dev/null || error "Please install (g)mplayer."
+
+# some variables
+
+if [ -r $HOME/.teleschorschrc ] ; then
+       CONFIG=$HOME/.teleschorschrc
+elif [ -r /etc/teleschorschrc ] ; then
+       CONFIG=/etc/teleschorschrc
+else
+       error "Neiter /etc/teleschorschrc nor $HOME/.teleschorschrc found"
+fi
+
+if [ $(date +"%H") -lt 12 ] ; then
+       DEFAULT_DATE=$(date --date "yesterday" +"%d %m %Y")
+else
+       DEFAULT_DATE=$(date +"%d %m %Y")
+fi
+
+OUTFILE="/tmp/$(basename $0).tmp.$$"
+
+# start the fun
+
+# read config
+
+while read LINE ; do
+       if [ -z "$LINE" ] ; then continue; fi
+       if echo $LINE | egrep "^[#;]" > /dev/null ; then continue; fi
+       if echo $LINE | egrep "^\[" > /dev/null; then
+               if [ -n "$C" ] ; then CHANNELS+=("$C") ; fi
+               C="$LINE"
+       else
+               C+="~$LINE"
+       fi
+done < $CONFIG
+CHANNELS+=("$C")
+
+COUNT="${#CHANNELS[*]}"
+
+# create channel list for (x)dialog
+
+for ((i=0; i < COUNT; i++)) ; do # bashism
+       LIST+=$(echo ${CHANNELS[$i]} | sed -e "s/\[\(.\+\)\]/$i/" -e 's/FULLNAME=//' -e 's/ /\xa0/g' | awk -F '~' '{printf "%s\t%s\toff ", $1, $2}')
+done
+
+# call (x)dialog
+case "$UI" in
+       "xdialog")
+               Xdialog --title "TeleSchorsch" \
+                       --no-tags \
+                       --radiolist "Choose your preferred stream:" 0 0 0 \
+                       $LIST \
+                       --calendar "Date" 0 0 $DEFAULT_DATE \
+                       --timebox "Offset\n(Start at beginning of stream: 0:0:0, start at position 3 minutes: 0:3:0, ...)" 0 0 0 0 0 \
+                       2>$OUTFILE
+               ;;
+       "dialog")
+               dialog --title "TeleSchorsch" \
+                --radiolist "Choose your preferred stream" 0 0 0 \
+                       $LIST \
+                       --calendar "Date" 0 0 $DEFAULT_DATE \
+                       --timebox "Offset\n(Start at beginning of stream: 0:0:0, start at position 3 minutes: 0:3:0, ...)" 0 0 0 0 0 \
+                       2>$OUTFILE
+               ;;
+esac
+
+RETVAL=$?
+
+case $RETVAL in
+       0)
+               ;;
+       *)
+               echo "$(basename $0) exiting (user abort, error, whatnot) with return value: $RETVAL"
+               exit $RETVAL
+               ;;
+esac
+
+[ -e "$OUTFILE" ] && perl -pi -e 's;\n; ;' $OUTFILE \
+       || error "$OUTFILE not found"
+read STREAM DATE OFFSET < $OUTFILE
+[ -n "$STREAM" ] && [ -n "$DATE" ] && [ -n "$OFFSET" ] && rm -f $OUTFILE \
+       || error "Problem with variables, check contents of $OUTFILE"
+
+DATE=$(echo $DATE | perl -p -e 's;(.+)/(.+)/(.+);$3-$2-$1;')
+SECONDS=$(echo $OFFSET | perl -n -e '($h,$m,$s) = split(/:/); print $h*3600 + $m*60 + $s;')
+y=$(date --date "$DATE" +"%y")
+Y=$(date --date "$DATE" +"%Y")
+m=$(date --date "$DATE" +"%m")
+d=$(date --date "$DATE" +"%d")
+dow_DE=$(LANG=$(locale -a | grep ^de_ | head -n 1) date --date "$DATE" +"%A")
+
+URL=$(echo "${CHANNELS[$STREAM]}" | perl -pe 's/^.*STATICURL=(.+?)(~.*|$)/$1/')
+PLAYER=$(echo "${CHANNELS[$STREAM]}" | perl -pe 's/^.*PLAYER=(.+?)(~.*|$)/$1/')
+
+case $PLAYER in
+       gmplayer)
+               STARTOPTION="-cache 512 -ss"
+               ;;
+       vlc)
+               STARTOPTION="--start-time"
+               ;;
+       *)
+               error "Unknown PLAYER: $PLAYER"
+               ;;
+esac
+
+$PLAYER $(eval echo $URL) $STARTOPTION $SECONDS
diff --git a/teleschorschrc b/teleschorschrc
new file mode 100644 (file)
index 0000000..e577304
--- /dev/null
@@ -0,0 +1,74 @@
+[ORFZIB1]
+FULLNAME=ORF - Zeit im Bild 1
+STATICURL=rtsp://81.189.213.1:554/orf2/zb/zib${y}${m}${d}l.rm?URL=/ramgen/orf2/zb/zib${y}${m}${d}l.rm&cloakport=8088,554,7070
+PLAYER=gmplayer
+
+[ORFZIB2]
+FULLNAME=ORF - Zeit im Bild 2
+STATICURL=mms://stream4.orf.at/zib2/zib2_${dow_DE}.wmv
+PLAYER=vlc
+
+[F208h]
+FULLNAME=France 2 - 8 heures
+STATICURL=mms://sdmc.contents.edgestreams.net/horsgv/regions/siege/infos/f2/8h/HD_8h_${Y}${m}${d}.wmv?WMCache=0
+PLAYER=vlc
+
+[F213h]
+FULLNAME=France 2 - 13 heures
+STATICURL=mms://sdmc.contents.edgestreams.net/horsgv/regions/siege/infos/f2/13h/HD_13h_${Y}${m}${d}.wmv?WMCache=0
+PLAYER=vlc
+
+[F220h]
+FULLNAME=France 2 - 20 heures
+STATICURL=mms://sdmc.contents.edgestreams.net/horsgv/regions/siege/infos/f2/20h/HD_20h_${Y}${m}${d}.wmv?WMCache=0
+PLAYER=vlc
+
+[F31213]
+FULLNAME=France 3 - JT 12/13h national
+STATICURL=mms://sdmc.contents.edgestreams.net/horsgv/regions/siege/infos/f3/1214/HD_1214_${Y}${m}${d}.wmv?WMCache=0
+PLAYER=vlc
+
+[F31920]
+FULLNAME=France 3 - JT 19/20h national
+STATICURL=mms://sdmc.contents.edgestreams.net/horsgv/regions/siege/infos/f3/1920/HD_1920_${Y}${m}${d}.wmv?WMCache=0
+PLAYER=vlc
+
+[F3lesoir]
+FULLNAME=France 3 - JT le soir national
+STATICURL=mms://sdmc.contents.edgestreams.net/horsgv/regions/siege/infos/f3/soir3/HD_soir3_${Y}${m}${d}.wmv?WMCache=0
+PLAYER=vlc
+
+[M61250]
+FULLNAME=M6 - le 12 50
+STATICURL=mms://stream1.m6.fr.ipercast.net/m6.fr/6minutes/d/92/d${y}${m}${d}211150SARAV9200000.wmv
+PLAYER=vlc
+
+[M6six]
+FULLNAME=M6 - six
+STATICURL=mms://stream1.m6.fr.ipercast.net/m6.fr/6minutes/d/92/d${y}${m}${d}190000SARAV9200000.wmv
+PLAYER=vlc
+
+[TF1jt13]
+FULLNAME=TF1 - JT 13h
+STATICURL=http://213.205.97.105/tf1jt/jt13d${d}${m}${Y}.asf
+PLAYER=vlc
+
+[TF1jt20]
+FULLNAME=TF1 - JT 20h
+STATICURL=http://213.205.97.105/tf1jt/jt20d${d}${m}${Y}.asf
+PLAYER=vlc
+
+[ORFoe107]
+FULLNAME=ORF - Ö1 Morgenjournal (only current broadcast)
+STATICURL=`wget -q -O- "http://oe1.orf.at/konsole/journal?type=frueh" | grep -Eo "mms://stream2\.orf\.at/oe1/demand/frueh/.+\.WMA"`
+PLAYER=vlc
+
+[ORFoe112]
+FULLNAME=ORF - Ö1 Mittagsjournal (only current broadcast)
+STATICURL=`wget -q -O- "http://oe1.orf.at/konsole/journal?type=mittag" | grep -Eo "mms://stream2\.orf\.at/oe1/demand/mittag/.+\.WMA"`
+PLAYER=vlc
+
+[ORFoe118]
+FULLNAME=ORF - Ö1 Abendjournal (only current broadcast)
+STATICURL=`wget -q -O- "http://oe1.orf.at/konsole/journal?type=abend" | grep -Eo "mms://stream2\.orf\.at/oe1/demand/abend/.+\.WMA"`
+PLAYER=vlc
\ No newline at end of file