| 916 | } |
| 917 | |
| 918 | QByteArray Application::editConfigViaScript() const |
| 919 | { |
| 920 | #if defined(SYNCTHINGCTL_USE_SCRIPT) || defined(SYNCTHINGCTL_USE_JSENGINE) |
| 921 | // get script |
| 922 | auto script = QByteArray(); |
| 923 | auto scriptFileName = QString(); |
| 924 | if (m_args.script.isPresent()) { |
| 925 | // read script file |
| 926 | auto scriptFile = QFile(QString::fromLocal8Bit(m_args.script.firstValue())); |
| 927 | if (scriptFile.open(QFile::ReadOnly)) { |
| 928 | script = scriptFile.readAll(); |
| 929 | scriptFileName = scriptFile.fileName(); |
| 930 | } |
| 931 | if (scriptFile.error() != QFile::NoError) { |
| 932 | cerr << Phrases::Error << "Unable to read specified script file \"" << m_args.script.firstValue() << "\":" << Phrases::End; |
| 933 | cerr << scriptFile.errorString().toStdString() << '\n'; |
| 934 | return QByteArray(); |
| 935 | } |
| 936 | } else if (m_args.jsLines.isPresent()) { |
| 937 | // construct script from CLI arguments |
| 938 | auto requiredSize = QString::size_type(0); |
| 939 | for (const auto *const line : m_args.jsLines.values()) { |
| 940 | requiredSize += static_cast<QString::size_type>(std::strlen(line)) + 1; |
| 941 | } |
| 942 | script.reserve(requiredSize); |
| 943 | for (const auto *const line : m_args.jsLines.values()) { |
| 944 | script += line; |
| 945 | script += '\n'; |
| 946 | } |
| 947 | // remove trailing termination to avoid e.g. "Expected token `)' in line 2" when "… line 1" would make more sense |
| 948 | #if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0) |
| 949 | script.removeLast(); |
| 950 | #else |
| 951 | script.remove(script.size() - 1, 1); |
| 952 | #endif |
| 953 | } |
| 954 | |
| 955 | // define function to print error |
| 956 | const auto printError([](const auto &object) { |
| 957 | cerr << object.toString().toStdString() << " in line " << SYNCTHINGCTL_JS_INT(object.property(QStringLiteral("lineNumber"))) << endl; |
| 958 | }); |
| 959 | |
| 960 | // evaluate config via JSON.parse() |
| 961 | auto engine = SYNCTHINGCTL_JS_ENGINE(); |
| 962 | auto globalObject = engine.globalObject(); |
| 963 | const auto configString = QJsonDocument(m_connection.rawConfig()).toJson(QJsonDocument::Indented); |
| 964 | globalObject.setProperty(QStringLiteral("configStr"), SYNCTHINGCTL_JS_VALUE(QString::fromUtf8(configString)) SYNCTHINGCTL_JS_READONLY); |
| 965 | const auto configObj = engine.evaluate(QStringLiteral("JSON.parse(configStr)")); |
| 966 | if (configObj.isError()) { |
| 967 | cerr << Phrases::Error << "Unable to evaluate the current Syncthing configuration." << Phrases::End; |
| 968 | printError(configObj); |
| 969 | cerr << "Syncthing configuration: " << configString.data() << flush; |
| 970 | return QByteArray(); |
| 971 | } |
| 972 | globalObject.setProperty(QStringLiteral("config"), configObj SYNCTHINGCTL_JS_UNDELETABLE); |
| 973 | |
| 974 | // provide additional values |
| 975 | globalObject.setProperty(QStringLiteral("ownID"), m_connection.myId() SYNCTHINGCTL_JS_UNDELETABLE); |
nothing calls this directly
no test coverage detected