/* * This file is part of smolbote. It's copyrighted by the contributors recorded * in the version control history of the file, available from its original * location: https://neueland.iserlohn-fortress.net/smolbote.hg * * SPDX-License-Identifier: GPL-3.0 */ #include "browser.h" #include "version.h" #include #include #include #include #include "plugin.h" #include "session.h" #include #include #ifdef _WIN32 #include #include #endif int main(int argc, char **argv) { // a beautiful hack to be able to write to stdout on Windows #ifdef _WIN32 if (AttachConsole(ATTACH_PARENT_PROCESS)) { freopen("CONOUT$", "w", stdout); freopen("CONOUT$", "w", stderr); } #endif // create and load configuration std::unique_ptr config = std::make_unique(nullptr); #ifdef QT_DEBUG QObject::connect(config.get(), &Configuration::settingChanged, [](const std::string &path, const QString &value) { qDebug("!!! setting changed %s=[%s]", path.c_str(), qUtf8Printable(value)); }); #endif if(!config->parse(argc, argv)) { qWarning("Error parsing command line, check --help for usage."); return -1; } if(!config->parse(config->value("config").value())) { qWarning("Error parsing config file."); } // --version if(config->exists("version")) { std::cout << "smolbote " << SMOLBOTE_VERSION << std::endl; return 0; } // --build if(config->exists("build")) { std::cout << SMOLBOTE_BUILD; return 0; } QVector plugins = loadPlugins(config->value("plugins.path").value()); QMap> pluginCommands; for(const auto &plugin : plugins) { auto *pluginInterface = qobject_cast(plugin.instance); Q_CHECK_PTR(pluginInterface); QHashIterator> i(pluginInterface->commands()); while(i.hasNext()) { i.next(); pluginCommands.insert(i.key(), i.value()); } } if(config->exists("help")) { std::cout << "smolbote " << SMOLBOTE_VERSION << ": yet another no-frills browser" << std::endl; std::cout << "Usage: " << argv[0] << " [options] [command/URL(s)]" << std::endl << std::endl; std::cout << "Command-line Options: " << std::endl << config->commandlineOptions() << std::endl; std::cout << "Commands: " << std::endl; for(auto it = pluginCommands.constBegin(); it != pluginCommands.constEnd(); ++it) { std::cout << it.key().toStdString() << std::endl; } std::cout << std::endl; std::cout << "Configuration Options: " << std::endl << config->configurationOptions() << std::endl; #ifdef Q_OS_LINUX std::cout << std::endl << "For more information refer to the manual page smolbote.7" << std::endl; #endif return 0; } // argc, argv, allowSecondary Browser app(argc, argv); // set this, otherwise the webview becomes black when using a stylesheet app.setAttribute(Qt::AA_DontCreateNativeWidgetSiblings, true); // translator if(config->exists("browser.locale")) { auto *translator = new QTranslator(&app); if(translator->load("qt_" + config->value("browser.locale").value(), QLibraryInfo::location(QLibraryInfo::TranslationsPath))) app.installTranslator(translator); else delete translator; } if(config->exists("browser.translation")) { auto *translator = new QTranslator(&app); if(translator->load(config->value("browser.translation").value())) app.installTranslator(translator); else delete translator; } // command line arguments bool ignoreSecondary = config->exists("no-remote"); auto arguments = config->value>("args"); auto session = config->value("browser.session"); auto profile = config->value("profile.default"); app.setConfiguration(config); app.setup(profile.value()); for(const Plugin &plugin : plugins) { app.registerPlugin(plugin); } QStringList urls; if(arguments) { for(const auto &u : arguments.value()) { if(pluginCommands.contains(QString::fromStdString(u))) { return pluginCommands.value(QString::fromStdString(u))(); } else { urls.append(QString::fromStdString(u)); } } } // if(!ignoreSecondary) { QObject::connect(&app, &Browser::receivedMessage, &app, [&app](quint32 instanceId, QByteArray message) { auto doc = QJsonDocument::fromJson(message); app.createSession(doc.object()); }); } if(app.isPrimary()) { app.createSession(Session::toJsonObject(profile.value(), urls)); } else if(ignoreSecondary) { // app is not primary (= secondary), and --ignore-secondary is set return -1; } else if(session) { QFile sessionJson(session.value()); if(sessionJson.open(QIODevice::ReadOnly | QIODevice::Text)) { app.sendMessage(sessionJson.readAll()); sessionJson.close(); qDebug("session data sent"); return EXIT_SUCCESS; } else { qWarning("Could not open session [%s].", qUtf8Printable(sessionJson.fileName())); } } else { auto message = Session::toJsonObject(profile.value(), urls); qDebug("sending message: %s", app.sendMessage(QJsonDocument(message).toJson()) ? "okay" : "failed"); qDebug("message>>>\n%s", qUtf8Printable(QJsonDocument(message).toJson())); return EXIT_SUCCESS; } return app.exec(); }