[svn-upgrade] Integrating new upstream version, teleschorsch (0.1.4)
[debian/teleschorsch.git] / main.cpp
index 8d0632fa2555574150f21ba5b66f71919a4d9df8..88292b8e9a11ef24d724620935e808a79f5faf7b 100644 (file)
--- a/main.cpp
+++ b/main.cpp
@@ -25,6 +25,9 @@
 #include <QFile>
 #include <QProcess>
 #include <QMessageBox>
+#include <QDateTime>
+#include <QLocale>
+#include <QTranslator>
 #include "main.h"
 #include "options.h"
 
@@ -101,6 +104,129 @@ QString readChannelVec(const ConfigInfo& configInfo, ChannelVec& channelVec) {
 }
 
 
+/// \brief Finds a value for a specified variable and appends it to a string.
+///
+/// \param[in]  var    variable to substitute. These are the possibilities:
+///                    - d  day of month (01-31)
+///                    - m  month (01-12)
+///                    - y  year (last two digits)
+///                    - Y  year (4 digits)
+///                    - dow_DE  day of week in German (Montag, ...)
+/// \param[in]  date   date that should be used when replacing the date dependend variables
+/// \param[out] result The determined value of the variable is _appended_.
+/// \param[out] error  error message in error cases
+/// \returns true in case of success.
+bool substituteVar(const QString& var, QDate date, QString& result, QString& errorMsg) {
+       if (var == "d") {result += date.toString("dd"); return true;}
+       if (var == "m") {result += date.toString("MM"); return true;}
+       if (var == "y") {result += date.toString("yy"); return true;}
+       if (var == "Y") {result += date.toString("yyyy"); return true;}
+       if (var == "dow_DE") {
+               int dow = date.dayOfWeek() - 1;
+               static const char dow_de[][16] = {"Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag", "Sonntag"};
+               if (dow >= 0 && dow < 7) {result += dow_de[dow]; return true;}
+       }
+       errorMsg = QObject::tr("No match for variable %1").arg(var);
+       return false;
+}
+
+
+/// \brief Finds a string, where variables of the form <code>${var}</code> are substituted in input (normally a staticUrl).
+///
+/// - ${d}  day of month (01-31)
+/// - ${m}  month (01-12)
+/// - ${y}  year (last two digits)
+/// - ${Y}  year (4 digits)
+/// - ${dow_DE}  day of week in German (Montag, ...)
+///
+/// \param[in]  input  string where the substitution should be done.
+/// \param[in]  date   date that should be used when replacing the date dependend variables
+/// \param[out] result The result string with the variables substituted is appended here
+/// \param[out] error  error message in error cases
+/// \returns true in case of success.
+bool substituteVars(const QString& input, QDate date, QString& result, QString& errorMsg) {
+       int pos = 0;
+       int lastPos = 0;
+       while (pos != -1) {
+               pos = input.indexOf("${", lastPos);
+               if (pos == -1) result += input.mid(lastPos);
+               else result += input.mid(lastPos, pos-lastPos);
+               lastPos = pos;
+               
+               // Match?
+               if (pos != -1) {
+                       pos = input.indexOf("}", lastPos);
+                       if (pos == -1) {
+                               errorMsg = QObject::tr("${ not closed with }.");
+                               return false;
+                       }
+                       QString var = input.mid(lastPos+2, pos-lastPos-2);
+                       if (!substituteVar(var, date, result, errorMsg)) return false;
+                       lastPos = pos+1;
+               }
+       }
+       return true;
+}
+
+
+/// \brief Calls the /bin/sh shell with the specified command and appends the result to a string variable.
+///
+/// \param[in]  command command to execute with <code>/bin/sh -c "command"</code>
+/// \param[out] result  The result string where the output is appended at.
+/// \param[out] error   error message in error cases
+/// \returns true in case of success.
+bool executeShellCommand(const QString& command, QString& result, QString& errorMsg) {
+       QProcess evalUrl(0);
+       QString cmd = "/bin/sh -c \"" + command + "\"";
+       evalUrl.start(cmd);
+       if (evalUrl.waitForFinished(3000)) {
+               QByteArray newResult = evalUrl.readAllStandardOutput();
+               if (result != newResult) {result += newResult.trimmed();}
+               return true;
+       } 
+       errorMsg = QObject::tr("Shell command executed when substituting URL (%1) timed out.").arg(command);
+       return false;
+}
+
+
+/// \brief Evaluates the staticUrl
+///
+/// - Variables of the form ${var} are substituted according the the function ::substituteVars
+/// - If the staticUrl is enclosed by backticks it is evaluated by a shell command (after the substitution mentioned above)
+///
+/// \param[in]  staticUrl string where the substitution should be done.
+/// \param[in]  date      date that should be used when replacing the date dependend variables
+/// \param[out] result    The result string is appended here
+/// \param[out] error     error message in error cases
+/// \returns true in case of success.
+bool evaluateStaticUrl(const QString& staticUrl, QDate date, QString& result, QString& errorMsg) {
+       QString subst;
+       bool success = substituteVars(staticUrl, date, subst, errorMsg);
+       if (!success) return false;
+
+       // Evaluate staticUrl - it might be dynamic despite its name :-)
+       QString cmdres;
+       if (subst.left(1) == "`" && subst.right(1) == "`") {
+               success = executeShellCommand(subst.mid(1, subst.size()-2), cmdres, errorMsg);
+               if (!success) return false;
+               result = cmdres;
+       } else result = subst;
+       return true;
+}
+
+
+void appendPlayerOffsetOption(const QString& player, QTime offset, QStringList& arguments) {
+       QTime zero = QTime(0, 0, 0, 0);
+       int offsetSec = zero.secsTo(offset);
+       if (player.indexOf("vlc") != -1) arguments.append("--start-time");
+       if (player.indexOf("gmplayer") != -1) {
+               arguments << "-cache" << "512"; // -cache 512 does not belong to this function but for now...
+               arguments << "-ss"; 
+       }
+       arguments << QString::number(offsetSec);
+}
+
+
 
 // MainDialog
 // ==========
@@ -120,6 +246,11 @@ MainDialog::MainDialog(QWidget *parent): QDialog(parent) {
 
        // Fill in channels
        updateLwChannels();
+
+       // Default date
+       QDateTime dateTime = QDateTime::currentDateTime(); // set the default date to today if it is past midday
+       if (dateTime.time().hour() < 12) dateTime = dateTime.addDays(-1);
+       calDate->setSelectedDate(dateTime.date());
 }
 
 
@@ -142,18 +273,24 @@ void MainDialog::updateLwChannels() {
 
 
 bool MainDialog::startAction() {
-       int row = lwChannels->currentRow();
-       if (row > 0) {
+       QListWidgetItem* selectedChannel = lwChannels->selectedItems().at(0);
+       int row = lwChannels->row(selectedChannel);
+       if (row > -1) {
                Channel channel = channelVec[row];
-               qDebug() << "User would like to see " << channel.staticUrl;
-
-               QString program = "/usr/bin/vlc";
+               QDate date = calDate->selectedDate();
+               QString substUrl;
+               QString errorMsg;
+               if (!evaluateStaticUrl(channel.staticUrl, date, substUrl, errorMsg)) {
+                       QMessageBox::warning(this, tr("Problem when substituting URL"), errorMsg);
+                       return false;
+               }
                QStringList arguments;
-               // arguments << "-style" << "motif";
-               // @args=("$player $url " . ${playeroptions}{$player} . " $offsetseconds");
-               QProcess player(0);
-               player.start(program, arguments);
-               player.waitForFinished();
+               arguments.append(substUrl);
+               appendPlayerOffsetOption(channel.player, teOffset->time(), arguments);
+               QProcess player(this);
+               qDebug() << channel.player << arguments;
+               player.start(channel.player, arguments);
+               player.waitForFinished(-1);
                return true;
        }
        return false;
@@ -166,6 +303,10 @@ bool MainDialog::startAction() {
 
 int main(int argc, char *argv[]) {
        QApplication app(argc, argv);
+       QString locale = QLocale::system().name();
+       QTranslator translator;
+       translator.load(QString(":/qteleschorsch_") + locale);
+       app.installTranslator(&translator);
        MainDialog *mainDialog = new MainDialog();
        mainDialog->show();
        return app.exec();