}
-QString substitudeVar(const QString& var, QDate date) {
- if (var == "d") return date.toString("dd");
- if (var == "m") return date.toString("MM");
- if (var == "y") return date.toString("yy");
- if (var == "Y") return date.toString("yyyy");
+/// \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[][20] = {"Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag", "Sonntag"};
- if (dow >= 0 && dow < 7) return dow_de[dow];
+ static const char dow_de[][16] = {"Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag", "Sonntag"};
+ if (dow >= 0 && dow < 7) {result += dow_de[dow]; return true;}
}
- return "{no match}"; // maybe do some error handling here...
+ errorMsg = QObject::tr("No match for variable %1").arg(var);
+ return false;
}
-QString substitudeStaticUrl(const QString& staticUrl, QDate date) {
- QString result;
+/// \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 = staticUrl.indexOf("${", lastPos);
- if (pos == -1) result += staticUrl.mid(lastPos);
- else result += staticUrl.mid(lastPos, pos-lastPos);
+ 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 = staticUrl.indexOf("}", lastPos);
- if (pos == -1) return ""; // ${ not closed with }. Some day we should report the error somehow...
- QString var = staticUrl.mid(lastPos+2, pos-lastPos-2);
- result += substitudeVar(var, date);
+ 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 :-)
- if (result.left(1) == "`" && result.right(1) == "`") {
- QProcess evalUrl(0);
- QString command = "/bin/sh -c \"echo " + result + "\"";
- evalUrl.start(command);
- if (evalUrl.waitForFinished()) {
- QByteArray newResult = evalUrl.readAllStandardOutput();
- if (result != newResult) {result = newResult.trimmed();}
- }
- }
- return result;
+ 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;
}
if (row > 0) {
Channel channel = channelVec[row];
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.append(substitudeStaticUrl(channel.staticUrl, date));
+ arguments.append(substUrl);
appendPlayerOffsetOption(channel.player, teOffset->time(), arguments);
QProcess player(this);
qDebug() << channel.player << arguments;
player.start(channel.player, arguments);
- player.waitForFinished();
+ player.waitForFinished(-1);
return true;
}
return false;