void WriteRegistryInstance::startExecution() { #ifdef Q_OS_WIN bool ok = true; ActionTools::Registry::Key key = evaluateListElement<ActionTools::Registry::Key>(ok, ReadRegistryInstance::keys, "key"); QString subKey = evaluateString(ok, "subKey"); QString value = evaluateString(ok, "value"); QScriptValue data = evaluateValue(ok, "data"); if(!ok) return; switch(ActionTools::Registry::write(data.toVariant(), key, subKey, value)) { case ActionTools::Registry::WriteCannotFindSubKey: setCurrentParameter("subKey"); emit executionException(CannotFindSubKeyException, tr("Cannot find subKey \"%1\"").arg(subKey)); return; case ActionTools::Registry::WriteCannotWriteValue: setCurrentParameter("value"); emit executionException(CannotWriteValueException, tr("Cannot write value \"%1\"").arg(value)); return; default: break; } #endif emit executionEnded(); }
QPoint ActionInstance::evaluatePoint(bool &ok, const QString ¶meterName, const QString &subParameterName) { if(!ok) return QPoint(); const SubParameter &subParameter = retreiveSubParameter(parameterName, subParameterName); const SubParameter &unitSubParameter = retreiveSubParameter(parameterName, "unit"); QString result; if(subParameter.isCode()) { QScriptValue evaluationResult = evaluateCode(ok, subParameter); if(Code::Point *codePoint = qobject_cast<Code::Point*>(evaluationResult.toQObject())) { QPointF point = QPointF(codePoint->point().x(), codePoint->point().y()); computePercentPosition(point, unitSubParameter); return QPoint(point.x(), point.y()); } result = evaluationResult.toString(); } else result = evaluateText(ok, subParameter); if(!ok) return QPoint(); if(result.isEmpty() || result == ":") return QPoint(); QStringList positionStringList = result.split(":"); if(positionStringList.count() != 2) { ok = false; emit executionException(ActionException::InvalidParameterException, tr("\"%1\" is not a valid position.").arg(result)); return QPoint(); } QPointF point(positionStringList.at(0).toFloat(&ok), positionStringList.at(1).toFloat(&ok)); if(!ok) { emit executionException(ActionException::InvalidParameterException, tr("\"%1\" is not a valid position.").arg(result)); return QPoint(); } computePercentPosition(point, unitSubParameter); return QPoint(point.x(), point.y()); }
void Executer::startNextAction() { mExecutionEnded = false; QScriptValue script = mScriptEngine->globalObject().property("Script"); QString nextLineString = script.property("nextLine").toString(); int previousLine = mCurrentActionIndex; bool ok; int nextLine = nextLineString.toInt(&ok); if(!ok) { nextLine = mScript->labelLine(nextLineString); if(nextLine == -1) { executionException(ActionTools::ActionException::CodeErrorException, tr("Unable to find the label named \"%1\"").arg(nextLineString)); return; } } else --nextLine;//Make the nextLine value 0-based instead of 1-based if(nextLine < 0 || nextLine == mScript->actionCount())//End of the script mCurrentActionIndex = nextLine; else { switch(canExecuteAction(nextLine)) { case IncorrectLine: executionException(ActionTools::ActionException::CodeErrorException, tr("Incorrect Script.nextLine value: %1").arg(nextLineString)); return; case InvalidAction: executionException(ActionTools::ActionException::CodeErrorException, tr("The action at line %1 is invalid").arg(nextLineString)); return; case DisabledAction: case UnselectedAction: case CanExecute: mCurrentActionIndex = nextLine; break; } } if(mCurrentActionIndex >= 0) { for(int actionIndex = mCurrentActionIndex; actionIndex < previousLine; ++actionIndex) mScript->actionAt(actionIndex)->reset(); } executeCurrentAction(); }
void WriteTextFileInstance::startExecution() { bool ok = true; QString filepath = evaluateString(ok, "file"); QString text = evaluateString(ok, "text"); Mode mode = evaluateListElement<Mode>(ok, modes, "mode"); if(!ok) return; QFile file(filepath); if(!file.open(QIODevice::WriteOnly | QIODevice::Text | (mode == Truncate ? QIODevice::Truncate : QIODevice::Append))) { setCurrentParameter("file"); emit executionException(CannotWriteFileException, tr("Cannot open file")); return; } QTextStream textStream(&file); textStream << text; file.close(); emit executionEnded(); }
void WebDownloadInstance::finished() { mFile.close(); switch(mReply->error()) { case QNetworkReply::NoError: if(mDestination == Variable) setVariable(mVariable, QString::fromUtf8(mReply->readAll())); emit executionEnded(); break; case QNetworkReply::OperationCanceledError: if(mDestination == File) mFile.remove(); emit executionEnded(); break; default: { if(mDestination == File) mFile.remove(); setCurrentParameter("url"); emit executionException(DownloadException, tr("Download error: %1").arg(mReply->errorString())); } break; } mProgressDialog->close(); mReply->deleteLater(); mReply = 0; }
void TextInstance::startExecution() { bool ok = true; mText = evaluateString(ok, "text"); int pause = evaluateInteger(ok, "pause"); if(pause < 0) pause = 0; mTimer->setInterval(pause); mCurrentCharacter = 0; if(!ok) return; if(pause == 0) { if(!mKeyboardDevice.writeText(mText)) { emit executionException(FailedToSendInputException, tr("Unable to write the text")); return; } QTimer::singleShot(1, this, SIGNAL(executionEnded())); } else { pressNextKey(); mTimer->start(); } }
void WebDownloadInstance::startExecution() { bool ok = true; QString urlString = evaluateString(ok, "url"); mDestination = evaluateListElement<Destination>(ok, destinations, "destination"); mVariable = evaluateVariable(ok, "variable"); QString file = evaluateString(ok, "file"); if(!ok) return; QUrl url(urlString); if(url.scheme() == QString()) url = QUrl("http://" + urlString, QUrl::TolerantMode); if(!url.isValid()) { setCurrentParameter("url"); emit executionException(ActionTools::ActionException::BadParameterException, tr("Invalid URL")); return; } if(mDestination == File) { mFile.setFileName(file); if(!mFile.open(QIODevice::WriteOnly)) { setCurrentParameter("file"); emit executionException(CannotOpenFileException, tr("Cannot write to file")); return; } } mReply = mNetworkAccessManager->get(QNetworkRequest(url)); connect(mReply, SIGNAL(finished()), this, SLOT(finished())); connect(mReply, SIGNAL(downloadProgress(qint64,qint64)), this, SLOT(downloadProgress(qint64,qint64))); connect(mReply, SIGNAL(readyRead()), this, SLOT(readyRead())); mProgressDialog->setModal(false); mProgressDialog->setWindowTitle(tr("Downloading")); mProgressDialog->setLabelText(tr("Downloading...")); mProgressDialog->setMaximum(100); mProgressDialog->show(); }
QColor ActionInstance::evaluateColor(bool &ok, const QString ¶meterName, const QString &subParameterName) { if(!ok) return {}; const SubParameter &subParameter = retreiveSubParameter(parameterName, subParameterName); QString result; if(subParameter.isCode()) { QScriptValue evaluationResult = evaluateCode(ok, subParameter); if(auto codeColor = qobject_cast<Code::Color*>(evaluationResult.toQObject())) return codeColor->color(); result = evaluationResult.toString(); } else result = evaluateText(ok, subParameter); if(!ok) return QColor(); if(result.isEmpty() || result == QLatin1String("::")) return QColor(); QStringList colorStringList = result.split(QStringLiteral(":")); if(colorStringList.count() != 3) { ok = false; emit executionException(ActionException::InvalidParameterException, tr("\"%1\" is not a valid color.").arg(result)); return QColor(); } QColor color = QColor(colorStringList.at(0).toInt(&ok), colorStringList.at(1).toInt(&ok), colorStringList.at(2).toInt(&ok)); if(!ok) { emit executionException(ActionException::InvalidParameterException, tr("\"%1\" is not a valid color.").arg(result)); return QColor(); } return color; }
void SendMailInstance::recipientRejected(int mailID, const QString &address, const QByteArray &msg) { Q_UNUSED(mailID) cleanup(); emit executionException(ErrorWhileSendingEMailException, tr("Recipient %1 has been rejected: %2").arg(address).arg(QString::fromUtf8(msg))); }
void PlaySoundInstance::startExecution() { bool ok = true; QString file = evaluateString(ok, "file"); int volume = evaluateInteger(ok, "volume"); mBlocking = evaluateBoolean(ok, "blocking"); bool looping = evaluateBoolean(ok, "looping"); bool isUrl = evaluateBoolean(ok, "url"); int playbackRate = evaluateInteger(ok, "playbackRate"); if(!ok) return; mMediaPlaylist->clear(); QUrl url; if(isUrl) url = QUrl(file); else url = QUrl::fromLocalFile(file); if(!mMediaPlaylist->addMedia(url)) { emit executionException(ActionTools::ActionException::InvalidParameterException, tr("Unable to load file %1: %2").arg(file).arg(mMediaPlayer->errorString())); return; } mMediaPlaylist->setPlaybackMode(looping ? QMediaPlaylist::Loop : QMediaPlaylist::CurrentItemOnce); mMediaPlayer->setPlaybackRate(playbackRate / 100.0f); mMediaPlayer->setVolume(volume); mMediaPlayer->play(); if(mMediaPlayer->error() != QMediaPlayer::NoError) { emit executionException(ActionTools::ActionException::InvalidParameterException, tr("Unable to play file %1: %2").arg(file).arg(mMediaPlayer->errorString())); return; } if(!mBlocking) emit executionEnded(); }
QImage ActionInstance::evaluateImage(bool &ok, const QString ¶meterName, const QString &subParameterName) { if(!ok) return QImage(); const SubParameter &subParameter = retreiveSubParameter(parameterName, subParameterName); QString filename; if(subParameter.isCode()) { QScriptValue evaluationResult = evaluateCode(ok, subParameter); if(auto codeImage = qobject_cast<Code::Image*>(evaluationResult.toQObject())) return codeImage->image(); if(!evaluationResult.isString()) { ok = false; emit executionException(ActionException::InvalidParameterException, tr("Invalid image.")); return QImage(); } filename = evaluationResult.toString(); } else filename = evaluateText(ok, subParameter); if(!ok || filename.isEmpty()) return QImage(); QImage image(filename); if(!image.isNull()) return image; ok = false; emit executionException(ActionException::InvalidParameterException, tr("Unable to load image: %1").arg(filename)); return QImage(); }
void ActionInstance::validateParameterRange(bool &ok, int parameter, const QString ¶meterName, const QString ¶meterTranslatedName, int minimum, int maximum) { if(ok && (parameter < minimum || parameter > maximum)) { ok = false; setCurrentParameter(parameterName); emit executionException(ActionTools::ActionException::InvalidParameterException, tr("Invalid %1 value : %2").arg(parameterTranslatedName).arg(parameter)); return; } }
void SendMailInstance::mailFailed(int mailID, int errorCode, const QByteArray &msg) { Q_UNUSED(mailID) cleanup(); QString errorString; switch(errorCode) { case QxtSmtp::NoRecipients: errorString = tr("No recipients"); break; case QxtSmtp::CommandUnrecognized: errorString = tr("Command unrecognized"); break; case QxtSmtp::SyntaxError: errorString = tr("Syntax error"); break; case QxtSmtp::CommandNotImplemented: errorString = tr("Command not implemented"); break; case QxtSmtp::BadSequence: errorString = tr("Bad sequence"); break; case QxtSmtp::ParameterNotImplemented: errorString = tr("Parameter not implemented"); break; case QxtSmtp::MailboxUnavailable: errorString = tr("Mailbox unavailable"); break; case QxtSmtp::UserNotLocal: errorString = tr("User not local"); break; case QxtSmtp::MessageTooLarge: errorString = tr("Message is too large"); break; case QxtSmtp::InvalidMailboxName: errorString = tr("Invalid mailbox name"); break; case QxtSmtp::TransactionFailed: errorString = tr("Transaction failed"); break; default: errorString = tr("Unknown error"); break; } emit executionException(ErrorWhileSendingEMailException, tr("Failed sending e-mail: %1 (%2)").arg(errorString).arg(QString::fromUtf8(msg))); }
void TextInstance::pressNextKey() { if(!mKeyboardDevice.writeText(QString(mText.at(mCurrentCharacter)))) { mTimer->stop(); emit executionException(FailedToSendInputException, tr("Unable to write the text")); return; } ++mCurrentCharacter; if(mCurrentCharacter >= mText.size()) { mTimer->stop(); QTimer::singleShot(1, this, SIGNAL(executionEnded())); return; } }
QString ActionInstance::evaluateVariable(bool &ok, const QString ¶meterName, const QString &subParameterName) { QString result = evaluateString(ok, parameterName, subParameterName); if(!ok) return QString(); if(!result.isEmpty() && !NameRegExp.exactMatch(result)) { ok = false; emit executionException(ActionException::InvalidParameterException, tr("A variable name can only contain alphanumeric characters and cannot start with a digit.")); return QString(); } return result; }
void Executer::updateTimerProgress() { if(mExecutionPaused) return; ActionTools::ActionInstance *actionInstance = currentActionInstance(); switch(mExecutionStatus) { case PrePause: if(mExecutionTime.elapsed() >= actionInstance->pauseBefore() + mPauseBefore) { mExecutionTimer.stop(); startActionExecution(); } mExecutionWindow->setProgressValue(mExecutionTime.elapsed()); break; case Executing://Timeout if(mExecutionTime.elapsed() >= actionInstance->timeout()) { mExecutionTimer.stop(); actionInstance->disconnect(); actionInstance->stopExecution(); executionException(ActionTools::ActionException::TimeoutException, QString()); } mExecutionWindow->setProgressValue(mExecutionTime.elapsed()); break; case PostPause: if(mExecutionTime.elapsed() >= actionInstance->pauseAfter() + mPauseAfter) { mExecutionTimer.stop(); startNextAction(); } mExecutionWindow->setProgressValue(mExecutionTime.elapsed()); break; default: Q_ASSERT(false && "updateTimerProgress() called, but execution is stopped"); break; } }
double ActionInstance::evaluateDouble(bool &ok, const QString ¶meterName, const QString &subParameterName) { QString result = evaluateString(ok, parameterName, subParameterName); if(!ok || result.isEmpty()) return 0.0; double doubleResult = result.toDouble(&ok); if(!ok) { ok = false; emit executionException(ActionException::InvalidParameterException, tr("Decimal value expected.")); return 0.0; } return doubleResult; }
QScriptValue ActionInstance::evaluateCode(bool &ok, const QString &toEvaluate) { ok = true; QScriptValue result = d->scriptEngine->evaluate(toEvaluate); if(result.isError()) { ok = false; emit executionException(ActionException::CodeErrorException, result.toString()); return QScriptValue(); } if(!result.isValid()) { ok = false; return QScriptValue(); } return result; }
int ActionInstance::evaluateInteger(bool &ok, const QString ¶meterName, const QString &subParameterName) { QString result = evaluateString(ok, parameterName, subParameterName); if(!ok || result.isEmpty()) return 0; int intResult = result.toInt(&ok); if(!ok) { ok = false; emit executionException(ActionException::InvalidParameterException, tr("Integer value expected.")); return 0; } return intResult; }
void FindImageInstance::startExecution() { bool ok = true; mSource = evaluateListElement<Source>(ok, sources, QStringLiteral("source")); mImageToFind = evaluateImage(ok, QStringLiteral("imageToFind")); mIfFound = evaluateIfAction(ok, QStringLiteral("ifFound")); mIfNotFound = evaluateIfAction(ok, QStringLiteral("ifNotFound")); mPositionVariableName = evaluateVariable(ok, QStringLiteral("position")); mMethod = evaluateListElement<Method>(ok, methods, QStringLiteral("method")); mWindowRelativePosition = evaluateBoolean(ok, QStringLiteral("windowRelativePosition")); mConfidenceMinimum = evaluateInteger(ok, QStringLiteral("confidenceMinimum")); mMaximumMatches = evaluateInteger(ok, QStringLiteral("maximumMatches")); mDownPyramidCount = evaluateInteger(ok, QStringLiteral("downPyramidCount")); mSearchExpansion = evaluateInteger(ok, QStringLiteral("searchExpansion")); mConfidenceVariableName = evaluateVariable(ok, QStringLiteral("confidence")); mSearchDelay = evaluateInteger(ok, QStringLiteral("searchDelay")); if(!ok) return; validateParameterRange(ok, mConfidenceMinimum, QStringLiteral("confidenceMinimum"), tr("minimum confidence"), 0, 100); validateParameterRange(ok, mMaximumMatches, QStringLiteral("maximumMatches"), tr("maximum matches"), 1); validateParameterRange(ok, mDownPyramidCount, QStringLiteral("downPyramidCount"), tr("downsampling"), 1); validateParameterRange(ok, mSearchExpansion, QStringLiteral("searchExpansion"), tr("search expansion"), 1); if(!ok) return; if(mImageToFind.isNull()) { emit executionException(ActionTools::ActionException::InvalidParameterException, tr("Invalid image to find")); return; } startSearching(); }
QString ActionInstance::evaluateEditableListElement(bool &ok, const Tools::StringListPair &listElements, const QString ¶meterName, const QString &subParameterName) { if(!ok) return QString(); const SubParameter &subParameter = retreiveSubParameter(parameterName, subParameterName); QString result; if(subParameter.isCode()) result = evaluateCode(ok, subParameter).toString(); else result = evaluateText(ok, subParameter); if(!ok) return QString(); //Search in the translated items for(int i=0;i<listElements.second.size();++i) { if(listElements.second.at(i) == result) return listElements.first.at(i); } if(result.isEmpty()) { ok = false; setCurrentParameter(parameterName, subParameterName); emit executionException(ActionException::InvalidParameterException, tr("Please choose a value for this field.")); return QString(); } return result; }
void SystemInstance::startExecution() { bool ok = true; auto operation = evaluateListElement<Operation>(ok, operations, QStringLiteral("operation")); bool force = evaluateBoolean(ok, QStringLiteral("force")); if(!ok) return; SystemSession systemSession; switch(operation) { case Logout: if(!systemSession.logout(force)) { emit executionException(NotAvailable, tr("Logout is not available")); return; } break; case Restart: if(!systemSession.restart(force)) { emit executionException(NotAvailable, tr("Restart is not available")); return; } break; case Shutdown: if(!systemSession.shutdown(force)) { emit executionException(NotAvailable, tr("Shutdown is not available")); return; } break; case Suspend: if(!systemSession.suspend(force)) { emit executionException(NotAvailable, tr("Suspend is not available")); return; } break; case Hibernate: if(!systemSession.hibernate(force)) { emit executionException(NotAvailable, tr("Hibernate is not available")); return; } break; case LockScreen: if(!systemSession.lockScreen()) { emit executionException(NotAvailable, tr("Lock is not available")); return; } break; case StartScreenSaver: if(!systemSession.startScreenSaver()) { emit executionException(NotAvailable, tr("Start screen saver is not available")); return; } break; } executionEnded(); }
void SendMailInstance::authenticationFailed(const QByteArray &msg) { cleanup(); emit executionException(ConnectionErrorException, tr("Authentication failed: %1").arg(QString::fromUtf8(msg))); }
void FindImageInstance::startSearching() { mOpenCVAlgorithms->cancelSearch(); mImagesToSearchIn.clear(); switch(mSource) { case ScreenshotSource: mImagesToSearchIn = ActionTools::ScreenShooter::captureScreens(); break; case WindowSource: { bool ok = true; QString windowName = evaluateString(ok, QStringLiteral("windowName")); if(!ok) return; mWindows = ActionTools::WindowHandle::findWindows(QRegExp(windowName, Qt::CaseSensitive, QRegExp::WildcardUnix)); if(mWindows.isEmpty()) { emit executionException(ActionTools::ActionException::InvalidParameterException, tr("Unable to find any window named %1").arg(windowName)); return; } mImagesToSearchIn = ActionTools::ScreenShooter::captureWindows(mWindows); } break; case ImageSource: { bool ok = true; QImage imageToSearchIn = evaluateImage(ok, QStringLiteral("imageToSearchIn")); if(!ok) return; if(imageToSearchIn.isNull()) { emit executionException(ActionTools::ActionException::InvalidParameterException, tr("Invalid image to search in")); return; } mImagesToSearchIn.append(std::make_pair(QPixmap::fromImage(imageToSearchIn), imageToSearchIn.rect())); } break; } QList<QImage> sourceImages; sourceImages.reserve(mImagesToSearchIn.size()); for(const auto &imageToSearchIn: mImagesToSearchIn) sourceImages.append(imageToSearchIn.first.toImage()); if(!mOpenCVAlgorithms->findSubImageAsync(sourceImages, mImageToFind, mConfidenceMinimum, mMaximumMatches, mDownPyramidCount, mSearchExpansion, static_cast<ActionTools::OpenCVAlgorithms::AlgorithmMethod>(mMethod))) { emit executionException(ErrorWhileSearchingException, tr("Error while searching: %1").arg(mOpenCVAlgorithms->errorString())); return; } }
QString ActionInstance::evaluateTextString(bool &ok, const QString &toEvaluate, int &position) { ok = true; int startIndex = position; QString result; while(position < toEvaluate.length()) { if(toEvaluate[position] == QLatin1Char('$')) { //find a variable name if(VariableRegExp.indexIn(toEvaluate, position) != -1) { QString foundVariableName = VariableRegExp.cap(1); QScriptValue foundVariable = d->scriptEngine->globalObject().property(foundVariableName); position += foundVariableName.length(); if(!foundVariable.isValid()) { ok = false; emit executionException(ActionException::InvalidParameterException, tr("Undefined variable \"%1\"").arg(foundVariableName)); return QString(); } QString stringEvaluationResult; if(foundVariable.isNull()) stringEvaluationResult = QStringLiteral("[Null]"); else if(foundVariable.isUndefined()) stringEvaluationResult = QStringLiteral("[Undefined]"); else if(foundVariable.isArray()) { while((position + 1 < toEvaluate.length()) && toEvaluate[position + 1] == QLatin1Char('[')) { position += 2; QString indexArray = evaluateTextString(ok, toEvaluate, position); if((position < toEvaluate.length()) && toEvaluate[position] == QLatin1Char(']')) { QScriptString internalIndexArray = d->scriptEngine->toStringHandle(indexArray); bool flag = true; int numIndex = internalIndexArray.toArrayIndex(&flag); if(flag) //numIndex is valid foundVariable = foundVariable.property(numIndex); else //use internalIndexArray foundVariable = foundVariable.property(internalIndexArray); } else { //syntax error ok = false; emit executionException(ActionException::InvalidParameterException, tr("Invalid parameter. Unable to evaluate string")); return QString(); } //COMPATIBILITY: we break the while loop if foundVariable is no more of Array type if(!foundVariable.isArray()) break; } //end of while, no more '[' if(foundVariable.isArray()) stringEvaluationResult = evaluateVariableArray(ok, foundVariable); else stringEvaluationResult = foundVariable.toString(); } else if(foundVariable.isVariant()) { QVariant variantEvaluationResult = foundVariable.toVariant(); switch(variantEvaluationResult.type()) { case QVariant::StringList: stringEvaluationResult = variantEvaluationResult.toStringList().join(QStringLiteral("\n")); break; case QVariant::ByteArray: stringEvaluationResult = QStringLiteral("[Raw data]"); break; default: stringEvaluationResult = foundVariable.toString(); break; } } else stringEvaluationResult = foundVariable.toString(); result.append(stringEvaluationResult); } } else if (toEvaluate[position] == QLatin1Char(']')) { if(startIndex == 0) //in top level evaluation isolated character ']' is accepted (for compatibility reason), now prefer "\]" //i.e without matching '[' result.append(toEvaluate[position]); else //on other levels, the parsing is stopped at this point return result; } else if(toEvaluate[position] == QLatin1Char('\\')) { if(startIndex == 0) { //for ascendant compatibility reason //in top level evaluation '\' is not only an escape character, //but can also be a standard character in some cases if((position + 1) < toEvaluate.length()) { position++; if(toEvaluate[position] == QLatin1Char('$') || toEvaluate[position] == QLatin1Char('[') || toEvaluate[position] == QLatin1Char(']') || toEvaluate[position] == QLatin1Char('\\')) result.append(toEvaluate[position]); else { position--; result.append(toEvaluate[position]); } } else result.append(toEvaluate[position]); } else { position++; if( position < toEvaluate.length() ) result.append(toEvaluate[position]); } } else result.append(toEvaluate[position]); position++; } return result; }