Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • akiraohgaki/ocs-manager
  • dfn2/ocs-manager
  • azubieta/ocs-manager
  • rws77/ocs-manager
4 results
Show changes
Commits on Source (182)
Showing
with 511 additions and 207 deletions
*.pro.user
build_*/
lib/qtlib/
lib/qtil/
lib/AppImageUpdate/
lib/AppImageUpdate-prebuilt/
stages:
- build
appimage:
stage: build
image: ubuntu:14.04
only:
- master
- /^release\-.+/
script:
- ./scripts/package appimage
artifacts:
paths:
- build_*/ocs-manager*.AppImage
expire_in: 2 days
dist: trusty
sudo: required
services:
- docker
branches:
only:
- master
script:
- mntdir='/mnt/ocs-manager'
#- docker run --rm -v $(pwd):${mntdir} ubuntu:16.04 /bin/bash -c "sh ${mntdir}/scripts/build-docker.sh snap"
#- docker run --rm -v $(pwd):${mntdir} ubuntu:16.04 /bin/bash -c "sh ${mntdir}/scripts/build-docker.sh flatpak"
- docker run --rm -v $(pwd):${mntdir} ubuntu:17.10 /bin/bash -c "sh ${mntdir}/scripts/build-docker.sh appimage"
- cat transfer.log
# ocs-manager
[![License: GPL v3](https://img.shields.io/badge/License-GPL%20v3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0)
[![Build Status](https://travis-ci.org/opendesktop/ocs-manager.svg?branch=master)](https://travis-ci.org/opendesktop/ocs-manager)
A tool to handle item installation from OCS provider, file management, and apply themes.
Copyright: 2017, Opendesktop.org
Copyright: 2017-2019, Opendesktop.org
License: GPL-3+
......@@ -12,7 +12,7 @@ HEADERS += \
$${PWD}/src/handlers/systemhandler.h \
$${PWD}/src/handlers/ocsapihandler.h \
$${PWD}/src/handlers/itemhandler.h \
$${PWD}/src/handlers/appimagehandler.h \
$${PWD}/src/handlers/updatehandler.h \
$${PWD}/src/handlers/desktopthemehandler.h
SOURCES += \
......@@ -22,17 +22,18 @@ SOURCES += \
$${PWD}/src/handlers/systemhandler.cpp \
$${PWD}/src/handlers/ocsapihandler.cpp \
$${PWD}/src/handlers/itemhandler.cpp \
$${PWD}/src/handlers/appimagehandler.cpp \
$${PWD}/src/handlers/updatehandler.cpp \
$${PWD}/src/handlers/desktopthemehandler.cpp
RESOURCES += $${PWD}/configs/configs.qrc
INCLUDEPATH += $${PWD}/src
unix:!ios:!android {
contains(DEFINES, APP_DESKTOP) {
QT += dbus
HEADERS += \
$${PWD}/src/updaters/appimageupdater.h \
$${PWD}/src/desktopthemes/kdetheme.h \
$${PWD}/src/desktopthemes/gnometheme.h \
$${PWD}/src/desktopthemes/xfcetheme.h \
......@@ -40,6 +41,7 @@ unix:!ios:!android {
$${PWD}/src/desktopthemes/matetheme.h
SOURCES += \
$${PWD}/src/updaters/appimageupdater.cpp \
$${PWD}/src/desktopthemes/kdetheme.cpp \
$${PWD}/src/desktopthemes/gnometheme.cpp \
$${PWD}/src/desktopthemes/xfcetheme.cpp \
......
{
"id": "ocs-manager",
"name": "ocs-manager",
"version": "0.4.4",
"version": "0.8.1",
"organization": "Opendesktop.org",
"domain": "org.opendesktop.ocs-manager",
"icon": ":/desktop/ocs-manager.svg",
......@@ -9,5 +9,5 @@
"license": "GPL-3+",
"author": "Opendesktop.org",
"contact": "contact@opendesktop.org",
"homepage": "https://github.com/opendesktop/ocs-manager"
"homepage": "https://git.opendesktop.org/akiraohgaki/ocs-manager"
}
{
"bin": {
"name": "Softwares",
"destination": "$HOME/.local/bin",
"name": "Software",
"destination": "",
"xdg_destination": "$HOME/.local/bin",
"generic_destination": "$APP_DATA/bin"
},
"downloads": {
"name": "Downloads",
"destination": "$XDG_DOWNLOAD_DIR",
"destination": "",
"xdg_destination": "$XDG_DOWNLOAD_DIR",
"generic_destination": "$APP_DATA/downloads"
},
"documents": {
"name": "Documents",
"destination": "$XDG_DOCUMENTS_DIR",
"destination": "",
"xdg_destination": "$XDG_DOCUMENTS_DIR",
"generic_destination": "$APP_DATA/documents"
},
"pictures": {
"name": "Pictures",
"destination": "$XDG_PICTURES_DIR",
"destination": "",
"xdg_destination": "$XDG_PICTURES_DIR",
"generic_destination": "$APP_DATA/pictures"
},
"music": {
"name": "Music",
"destination": "$XDG_MUSIC_DIR",
"destination": "",
"xdg_destination": "$XDG_MUSIC_DIR",
"generic_destination": "$APP_DATA/music"
},
"videos": {
"name": "Videos",
"destination": "$XDG_VIDEOS_DIR",
"destination": "",
"xdg_destination": "$XDG_VIDEOS_DIR",
"generic_destination": "$APP_DATA/videos"
},
"wallpapers": {
"name": "Wallpapers",
"destination": "$XDG_DATA_HOME/wallpapers",
"destination": "",
"xdg_destination": "$XDG_DATA_HOME/wallpapers",
"generic_destination": "$APP_DATA/wallpapers"
},
"fonts": {
"name": "Fonts",
"destination": "$HOME/.fonts",
"destination": "",
"xdg_destination": "$HOME/.fonts",
"generic_destination": "$APP_DATA/fonts"
},
"cursors": {
"name": "Cursors",
"destination": "$HOME/.icons",
"destination": "",
"xdg_destination": "$HOME/.icons",
"generic_destination": "$APP_DATA/cursors"
},
"icons": {
"name": "Icons",
"destination": "$XDG_DATA_HOME/icons",
"destination": "",
"xdg_destination": "$XDG_DATA_HOME/icons",
"generic_destination": "$APP_DATA/icons"
},
"emoticons": {
"name": "Emoticons",
"destination": "$XDG_DATA_HOME/emoticons",
"destination": "",
"xdg_destination": "$XDG_DATA_HOME/emoticons",
"generic_destination": "$APP_DATA/emoticons"
},
"themes": {
"name": "Desktop Themes",
"destination": "$HOME/.themes",
"destination": "",
"xdg_destination": "$HOME/.themes",
"generic_destination": "$APP_DATA/themes"
},
"emerald_themes": {
"name": "Emerald Themes",
"destination": "$HOME/.emerald/themes",
"destination": "",
"xdg_destination": "$HOME/.emerald/themes",
"generic_destination": "$APP_DATA/emerald_themes"
},
"enlightenment_themes": {
"name": "Enlightenment Themes",
"destination": "$HOME/.e/e/themes",
"destination": "",
"xdg_destination": "$HOME/.e/e/themes",
"generic_destination": "$APP_DATA/enlightenment_themes"
},
"enlightenment_backgrounds": {
"name": "Enlightenment Backgrounds",
"destination": "$HOME/.e/e/backgrounds",
"destination": "",
"xdg_destination": "$HOME/.e/e/backgrounds",
"generic_destination": "$APP_DATA/enlightenment_backgrounds"
},
"fluxbox_styles": {
"name": "Fluxbox Styles",
"destination": "$HOME/.fluxbox/styles",
"destination": "",
"xdg_destination": "$HOME/.fluxbox/styles",
"generic_destination": "$APP_DATA/fluxbox_styles"
},
"pekwm_themes": {
"name": "PekWM Themes",
"destination": "$HOME/.pekwm/themes",
"destination": "",
"xdg_destination": "$HOME/.pekwm/themes",
"generic_destination": "$APP_DATA/pekwm_themes"
},
"icewm_themes": {
"name": "IceWM Themes",
"destination": "$HOME/.icewm/themes",
"destination": "",
"xdg_destination": "$HOME/.icewm/themes",
"generic_destination": "$APP_DATA/icewm_themes"
},
"plasma_plasmoids": {
"name": "Plasma Plasmoids",
"destination": "$XDG_DATA_HOME/plasma/plasmoids",
"destination": "",
"xdg_destination": "$XDG_DATA_HOME/plasma/plasmoids",
"generic_destination": "$APP_DATA/plasma_plasmoids"
},
"plasma_look_and_feel": {
"name": "Plasma Look and Feel",
"destination": "$XDG_DATA_HOME/plasma/look-and-feel",
"destination": "",
"xdg_destination": "$XDG_DATA_HOME/plasma/look-and-feel",
"generic_destination": "$APP_DATA/plasma_look_and_feel"
},
"plasma_desktopthemes": {
"name": "Plasma Desktop Themes",
"destination": "$XDG_DATA_HOME/plasma/desktoptheme",
"destination": "",
"xdg_destination": "$XDG_DATA_HOME/plasma/desktoptheme",
"generic_destination": "$APP_DATA/plasma_desktopthemes"
},
"kwin_effects": {
"name": "KWin Effects",
"destination": "$XDG_DATA_HOME/kwin/effects",
"destination": "",
"xdg_destination": "$XDG_DATA_HOME/kwin/effects",
"generic_destination": "$APP_DATA/kwin_effects"
},
"kwin_scripts": {
"name": "KWin Scripts",
"destination": "$XDG_DATA_HOME/kwin/scripts",
"destination": "",
"xdg_destination": "$XDG_DATA_HOME/kwin/scripts",
"generic_destination": "$APP_DATA/kwin_scripts"
},
"kwin_tabbox": {
"name": "KWin Window Switcher",
"destination": "$XDG_DATA_HOME/kwin/tabbox",
"destination": "",
"xdg_destination": "$XDG_DATA_HOME/kwin/tabbox",
"generic_destination": "$APP_DATA/kwin_tabbox"
},
"aurorae_themes": {
"name": "Aurorae Themes",
"destination": "$XDG_DATA_HOME/aurorae/themes",
"destination": "",
"xdg_destination": "$XDG_DATA_HOME/aurorae/themes",
"generic_destination": "$APP_DATA/aurorae_themes"
},
"dekorator_themes": {
"name": "deKorator Themes",
"destination": "$XDG_DATA_HOME/deKorator/themes",
"destination": "",
"xdg_destination": "$XDG_DATA_HOME/deKorator/themes",
"generic_destination": "$APP_DATA/dekorator_themes"
},
"qtcurve": {
"name": "QtCurve Themes",
"destination": "$XDG_DATA_HOME/QtCurve",
"destination": "",
"xdg_destination": "$XDG_DATA_HOME/QtCurve",
"generic_destination": "$APP_DATA/qtcurve"
},
"color_schemes": {
"name": "KDE Color Schemes",
"destination": "$XDG_DATA_HOME/color-schemes",
"destination": "",
"xdg_destination": "$XDG_DATA_HOME/color-schemes",
"generic_destination": "$APP_DATA/color_schemes"
},
"gnome_shell_extensions": {
"name": "Gnome Shell Extensions",
"destination": "$XDG_DATA_HOME/gnome-shell/extensions",
"destination": "",
"xdg_destination": "$XDG_DATA_HOME/gnome-shell/extensions",
"generic_destination": "$APP_DATA/gnome_shell_extensions"
},
"cinnamon_applets": {
"name": "Cinnamon Applets",
"destination": "$XDG_DATA_HOME/cinnamon/applets",
"destination": "",
"xdg_destination": "$XDG_DATA_HOME/cinnamon/applets",
"generic_destination": "$APP_DATA/cinnamon_applets"
},
"cinnamon_desklets": {
"name": "Cinnamon Desklets",
"destination": "$XDG_DATA_HOME/cinnamon/desklets",
"destination": "",
"xdg_destination": "$XDG_DATA_HOME/cinnamon/desklets",
"generic_destination": "$APP_DATA/cinnamon_desklets"
},
"cinnamon_extensions": {
"name": "Cinnamon Extensions",
"destination": "$XDG_DATA_HOME/cinnamon/extensions",
"destination": "",
"xdg_destination": "$XDG_DATA_HOME/cinnamon/extensions",
"generic_destination": "$APP_DATA/cinnamon_extensions"
},
"nautilus_scripts": {
"name": "Nautilus Scripts",
"destination": "$XDG_DATA_HOME/nautilus/scripts",
"destination": "",
"xdg_destination": "$XDG_DATA_HOME/nautilus/scripts",
"generic_destination": "$APP_DATA/nautilus_scripts"
},
"amarok_scripts": {
"name": "Amarok Scripts",
"destination": "$KDEHOME/share/apps/amarok/scripts",
"destination": "",
"xdg_destination": "$KDEHOME/share/apps/amarok/scripts",
"generic_destination": "$APP_DATA/amarok_scripts"
},
"yakuake_skins": {
"name": "Yakuake Skins",
"destination": "$KDEHOME/share/apps/yakuake/skins",
"destination": "",
"xdg_destination": "$KDEHOME/share/apps/yakuake/skins",
"generic_destination": "$APP_DATA/yakuake_skins"
},
"cairo_clock_themes": {
"name": "Cairo-Clock Themes",
"destination": "$HOME/.cairo-clock/themes",
"destination": "",
"xdg_destination": "$HOME/.cairo-clock/themes",
"generic_destination": "$APP_DATA/cairo_clock_themes"
},
"books": {
"name": "Books",
"destination": "$APP_DATA/books",
"destination": "",
"xdg_destination": "$APP_DATA/books",
"generic_destination": "$APP_DATA/books"
},
"comics": {
"name": "Comics",
"destination": "$APP_DATA/comics",
"destination": "",
"xdg_destination": "$APP_DATA/comics",
"generic_destination": "$APP_DATA/comics"
}
}
......@@ -59,6 +59,8 @@ bool KdeTheme::applyAsCursor() const
<< "c.writeEntry('cursorTheme', '" + themeName_ + "');";
if (evaluateScript(script)) {
QProcess::startDetached("sh -c \"echo 'Xcursor.theme: " + themeName_ + "' | xrdb -merge\"");
auto setLaunchEnv = QDBusMessage::createMethodCall("org.kde.klauncher5", "/KLauncher", "org.kde.KLauncher", "setLaunchEnv");
setLaunchEnv.setArguments(QVariantList() << QVariant(QString("XCURSOR_THEME")) << QVariant(themeName_));
QDBusConnection::sessionBus().call(setLaunchEnv);
......@@ -67,6 +69,10 @@ bool KdeTheme::applyAsCursor() const
notifyChange.setArguments(QVariantList() << QVariant(qint32(5)) << QVariant(qint32(0)));
QDBusConnection::sessionBus().send(notifyChange);
QProcess::startDetached("kwin --replace");
QProcess::startDetached("kquitapp5 plasmashell");
QProcess::startDetached("sh -c \"XCURSOR_THEME='" + themeName_ + "' kstart5 plasmashell\"");
return true;
}
return false;
......
#include "appimagehandler.h"
#ifdef QTLIB_UNIX
#include "appimage/update.h"
#endif
#include "handlers/confighandler.h"
AppImageHandler::AppImageHandler(ConfigHandler *configHandler, QObject *parent)
: QObject(parent), configHandler_(configHandler)
{}
bool AppImageHandler::isUpdateAvailable(const QString &path) const
{
#ifdef QTLIB_UNIX
appimage::update::Updater appImageUpdater(path.toStdString());
bool updateAvailable;
return appImageUpdater.checkForChanges(updateAvailable);
#endif
return false;
}
#ifdef QTLIB_UNIX
bool AppImageHandler::updateAppImage(const QString &path) const
{
appimage::update::Updater appImageUpdater(path.toStdString(), false);
return appImageUpdater.start();
// TODO: make signals&slots bindings later
}
#endif
#pragma once
#include <QObject>
class ConfigHandler;
class AppImageHandler : public QObject
{
Q_OBJECT
public:
explicit AppImageHandler(ConfigHandler *configHandler, QObject *parent = nullptr);
public slots:
bool isUpdateAvailable(const QString &path) const;
#ifdef QTLIB_UNIX
bool updateAppImage(const QString &path) const;
#endif
private:
ConfigHandler *configHandler_;
};
......@@ -3,15 +3,15 @@
#include <QStringList>
#include <QStandardPaths>
#include "qtlib_dir.h"
#include "qtil_dir.h"
ConfigHandler::ConfigHandler(QObject *parent)
: QObject(parent)
{
appConfig_ = qtlib::Config(":/configs");
appConfig_ = Qtil::Config(":/configs");
importAppConfigApplication();
importAppConfigInstallTypes();
usrConfig_ = qtlib::Config(qtlib::Dir::genericConfigPath() + "/" + getAppConfigApplication()["id"].toString());
usrConfig_ = Qtil::Config(Qtil::Dir::genericConfigPath() + "/" + getAppConfigApplication()["id"].toString());
}
QJsonObject ConfigHandler::getAppConfigApplication() const
......@@ -31,6 +31,11 @@ QJsonObject ConfigHandler::getUsrConfigApplication() const
bool ConfigHandler::setUsrConfigApplication(const QJsonObject &object) const
{
/* object format
{
"update_checked_at": 1483658977219
}
*/
return usrConfig_.set("application", object);
}
......@@ -64,6 +69,16 @@ bool ConfigHandler::setUsrConfigInstalledItems(const QJsonObject &object) const
return usrConfig_.set("installed_items", object);
}
QJsonObject ConfigHandler::getUsrConfigUpdateAvailableItems() const
{
return usrConfig_.get("update_available_items");
}
bool ConfigHandler::setUsrConfigUpdateAvailableItems(const QJsonObject &object) const
{
return usrConfig_.set("update_available_items", object);
}
bool ConfigHandler::setUsrConfigProvidersProvider(const QString &providerKey, const QJsonObject &object) const
{
/* object format
......@@ -162,6 +177,26 @@ bool ConfigHandler::removeUsrConfigInstalledItemsItem(const QString &itemKey) co
return setUsrConfigInstalledItems(installedItems);
}
bool ConfigHandler::setUsrConfigUpdateAvailableItemsItem(const QString &itemKey, const QJsonObject &object) const
{
/* object format
{
"installed_item": "http://example.com/downloads/example.AppImage",
"update_method": "appimageupdate"
}
*/
auto updateAvailableItems = getUsrConfigUpdateAvailableItems();
updateAvailableItems[itemKey] = object;
return setUsrConfigUpdateAvailableItems(updateAvailableItems);
}
bool ConfigHandler::removeUsrConfigUpdateAvailableItemsItem(const QString &itemKey) const
{
auto updateAvailableItems = getUsrConfigUpdateAvailableItems();
updateAvailableItems.remove(itemKey);
return setUsrConfigUpdateAvailableItems(updateAvailableItems);
}
void ConfigHandler::importAppConfigApplication()
{
appConfigApplication_ = appConfig_.get("application");
......@@ -172,8 +207,15 @@ void ConfigHandler::importAppConfigInstallTypes()
auto installTypes = appConfig_.get("install_types");
for (const auto &key : installTypes.keys()) {
auto installtype = installTypes[key].toObject();
installtype["destination"] = convertPathString(installtype["destination"].toString());
installtype["generic_destination"] = convertPathString(installtype["generic_destination"].toString());
auto xdgDestination = convertPathString(installtype["xdg_destination"].toString());
auto genericDestination = convertPathString(installtype["generic_destination"].toString());
installtype["xdg_destination"] = xdgDestination;
installtype["generic_destination"] = genericDestination;
#ifdef APP_DESKTOP
installtype["destination"] = xdgDestination;
#else
installtype["destination"] = genericDestination;
#endif
installTypes[key] = installtype;
}
auto installTypesAlias = appConfig_.get("install_types_alias");
......@@ -194,7 +236,7 @@ QString ConfigHandler::convertPathString(const QString &path) const
{
auto newPath = path;
if (newPath.contains("$HOME")) {
newPath.replace("$HOME", qtlib::Dir::homePath());
newPath.replace("$HOME", Qtil::Dir::homePath());
}
else if (newPath.contains("$XDG_DOCUMENTS_DIR")) {
newPath.replace("$XDG_DOCUMENTS_DIR", QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation));
......@@ -212,13 +254,13 @@ QString ConfigHandler::convertPathString(const QString &path) const
newPath.replace("$XDG_VIDEOS_DIR", QStandardPaths::writableLocation(QStandardPaths::MoviesLocation));
}
else if (newPath.contains("$XDG_DATA_HOME")) {
newPath.replace("$XDG_DATA_HOME", qtlib::Dir::genericDataPath());
newPath.replace("$XDG_DATA_HOME", Qtil::Dir::genericDataPath());
}
else if (newPath.contains("$KDEHOME")) {
newPath.replace("$KDEHOME", qtlib::Dir::kdehomePath());
newPath.replace("$KDEHOME", Qtil::Dir::kdehomePath());
}
else if (newPath.contains("$APP_DATA")) {
newPath.replace("$APP_DATA", qtlib::Dir::genericDataPath() + "/" + getAppConfigApplication()["id"].toString());
newPath.replace("$APP_DATA", Qtil::Dir::genericDataPath() + "/" + getAppConfigApplication()["id"].toString());
}
return newPath;
}
......@@ -3,7 +3,7 @@
#include <QObject>
#include <QJsonObject>
#include "qtlib_config.h"
#include "qtil_config.h"
class ConfigHandler : public QObject
{
......@@ -24,6 +24,8 @@ public slots:
bool setUsrConfigCategories(const QJsonObject &object) const;
QJsonObject getUsrConfigInstalledItems() const;
bool setUsrConfigInstalledItems(const QJsonObject &object) const;
QJsonObject getUsrConfigUpdateAvailableItems() const;
bool setUsrConfigUpdateAvailableItems(const QJsonObject &object) const;
bool setUsrConfigProvidersProvider(const QString &providerKey, const QJsonObject &object) const;
bool removeUsrConfigProvidersProvider(const QString &providerKey) const;
......@@ -32,14 +34,16 @@ public slots:
bool setUsrConfigCategoriesInstallType(const QString &providerKey, const QString &categoryKey, const QString &installType) const;
bool setUsrConfigInstalledItemsItem(const QString &itemKey, const QJsonObject &object) const;
bool removeUsrConfigInstalledItemsItem(const QString &itemKey) const;
bool setUsrConfigUpdateAvailableItemsItem(const QString &itemKey, const QJsonObject &object) const;
bool removeUsrConfigUpdateAvailableItemsItem(const QString &itemKey) const;
private:
void importAppConfigApplication();
void importAppConfigInstallTypes();
QString convertPathString(const QString &path) const;
qtlib::Config appConfig_;
qtlib::Config usrConfig_;
Qtil::Config appConfig_;
Qtil::Config usrConfig_;
QJsonObject appConfigApplication_;
QJsonObject appConfigInstallTypes_;
};
......@@ -2,7 +2,7 @@
#include <QStringList>
#ifdef QTLIB_UNIX
#ifdef APP_DESKTOP
#include <QFileInfo>
#include "desktopthemes/kdetheme.h"
......@@ -96,9 +96,9 @@ bool DesktopThemeHandler::isApplicableType(const QString &installType) const
return applicableTypes.contains(installType);
}
#ifdef QTLIB_UNIX
bool DesktopThemeHandler::applyTheme(const QString &path, const QString &installType) const
{
#ifdef APP_DESKTOP
if (QFileInfo::exists(path) && isApplicableType(installType)) {
auto desktop = desktopEnvironment();
......@@ -196,7 +196,7 @@ bool DesktopThemeHandler::applyTheme(const QString &path, const QString &install
}
}
}
#endif
return false;
}
#endif
......@@ -12,8 +12,5 @@ public:
public slots:
QString desktopEnvironment() const;
bool isApplicableType(const QString &installType) const;
#ifdef QTLIB_UNIX
bool applyTheme(const QString &path, const QString &installType) const;
#endif
};
......@@ -6,14 +6,16 @@
#include <QFileInfo>
#include <QDateTime>
#ifdef QTLIB_UNIX
#include <QProcess>
#ifdef APP_DESKTOP
#include <QStringList>
#include <QDir>
#include <QDirIterator>
#endif
#include "qtlib_dir.h"
#include "qtlib_file.h"
#include "qtlib_networkresource.h"
#include "qtlib_package.h"
#include "qtil_dir.h"
#include "qtil_file.h"
#include "qtil_networkresource.h"
#include "qtil_package.h"
#include "handlers/confighandler.h"
......@@ -67,9 +69,9 @@ void ItemHandler::getItem(const QString &command, const QString &url, const QStr
itemMetadataSet[itemKey] = metadata;
setMetadataSet(itemMetadataSet);
auto *resource = new qtlib::NetworkResource(itemKey, QUrl(url), true, this);
connect(resource, &qtlib::NetworkResource::downloadProgress, this, &ItemHandler::downloadProgress);
connect(resource, &qtlib::NetworkResource::finished, this, &ItemHandler::networkResourceFinished);
auto *resource = new Qtil::NetworkResource(itemKey, QUrl(url), true, this);
connect(resource, &Qtil::NetworkResource::downloadProgress, this, &ItemHandler::downloadProgress);
connect(resource, &Qtil::NetworkResource::finished, this, &ItemHandler::networkResourceFinished);
resource->get();
result["status"] = QString("success_downloadstart");
......@@ -112,8 +114,7 @@ void ItemHandler::getItemByOcsUrl(const QString &ocsUrl, const QString &provider
filename = QUrl(url).fileName();
}
// Still support xdg and xdgs schemes for backward compatibility
if ((scheme == "ocs" || scheme == "ocss" || scheme == "xdg" || scheme == "xdgs")
if ((scheme == "ocs" || scheme == "ocss")
&& (command == "download" || command == "install")
&& QUrl(url).isValid()
&& configHandler_->getAppConfigInstallTypes().contains(type)
......@@ -146,26 +147,18 @@ void ItemHandler::uninstall(const QString &itemKey)
auto installedItem = configHandler_->getUsrConfigInstalledItems()[itemKey].toObject();
auto installType = installedItem["install_type"].toString();
qtlib::Dir destDir;
#ifdef QTLIB_UNIX
destDir.setPath(configHandler_->getAppConfigInstallTypes()[installType].toObject()["destination"].toString());
Qtil::Dir destDir(configHandler_->getAppConfigInstallTypes()[installType].toObject()["destination"].toString());
for (const auto &filename : installedItem["files"].toArray()) {
#ifdef APP_DESKTOP
for (const auto filename : installedItem["files"].toArray()) {
QFileInfo fileInfo(destDir.path() + "/" + filename.toString());
// plasmapkg: Installation process has should be saved plasmapkg into destination directory
// plasmapkg: Installation process will saved plasmapkg into destination directory
qtlib::Package package(fileInfo.filePath());
Qtil::Package package(fileInfo.filePath());
// Uninstall
if (installType == "bin") {
if (fileInfo.filePath().endsWith(".appimage", Qt::CaseInsensitive)) {
QProcess process;
process.start(fileInfo.filePath() + " --remove-appimage-desktop-integration");
process.waitForFinished();
}
}
else if (installType == "plasma_plasmoids" || installType == "plasma4_plasmoids" || installType == "plasma5_plasmoids") {
if (installType == "plasma_plasmoids" || installType == "plasma4_plasmoids" || installType == "plasma5_plasmoids") {
package.uninstallAsPlasmapkg("plasmoid");
}
else if (installType == "plasma_look_and_feel" || installType == "plasma5_look_and_feel") {
......@@ -186,34 +179,33 @@ void ItemHandler::uninstall(const QString &itemKey)
// Remove file
if (fileInfo.isDir()) {
qtlib::Dir(fileInfo.filePath()).remove();
Qtil::Dir(fileInfo.filePath()).remove();
}
else {
qtlib::File(fileInfo.filePath()).remove();
Qtil::File(fileInfo.filePath()).remove();
}
}
#else
destDir.setPath(configHandler_->getAppConfigInstallTypes()[installType].toObject()["generic_destination"].toString());
for (const auto &filename : installedItem["files"].toArray()) {
for (const auto filename : installedItem["files"].toArray()) {
QFileInfo fileInfo(destDir.path() + "/" + filename.toString());
if (fileInfo.isDir()) {
qtlib::Dir(fileInfo.filePath()).remove();
Qtil::Dir(fileInfo.filePath()).remove();
}
else {
qtlib::File(fileInfo.filePath()).remove();
Qtil::File(fileInfo.filePath()).remove();
}
}
#endif
configHandler_->removeUsrConfigInstalledItemsItem(itemKey);
configHandler_->removeUsrConfigUpdateAvailableItemsItem(itemKey);
result["status"] = QString("success_uninstall");
result["message"] = tr("Uninstalled");
emit uninstallFinished(result);
}
void ItemHandler::networkResourceFinished(qtlib::NetworkResource *resource)
void ItemHandler::networkResourceFinished(Qtil::NetworkResource *resource)
{
auto itemKey = resource->id();
......@@ -251,7 +243,7 @@ void ItemHandler::setMetadataSet(const QJsonObject &metadataSet)
emit metadataSetChanged();
}
void ItemHandler::saveDownloadedFile(qtlib::NetworkResource *resource)
void ItemHandler::saveDownloadedFile(Qtil::NetworkResource *resource)
{
auto itemKey = resource->id();
......@@ -270,9 +262,9 @@ void ItemHandler::saveDownloadedFile(qtlib::NetworkResource *resource)
auto filename = metadata["filename"].toString();
auto installType = metadata["install_type"].toString();
qtlib::Dir destDir(configHandler_->getAppConfigInstallTypes()[installType].toObject()["destination"].toString());
Qtil::Dir destDir(configHandler_->getAppConfigInstallTypes()[installType].toObject()["destination"].toString());
destDir.make();
qtlib::File destFile(destDir.path() + "/" + filename);
Qtil::File destFile(destDir.path() + "/" + filename);
if (destFile.exists()) {
auto filenamePrefix = QString::number(QDateTime::currentMSecsSinceEpoch()) + "_";
......@@ -294,7 +286,7 @@ void ItemHandler::saveDownloadedFile(qtlib::NetworkResource *resource)
resource->deleteLater();
}
void ItemHandler::installDownloadedFile(qtlib::NetworkResource *resource)
void ItemHandler::installDownloadedFile(Qtil::NetworkResource *resource)
{
// Installation pre-process
auto itemKey = resource->id();
......@@ -315,13 +307,15 @@ void ItemHandler::installDownloadedFile(qtlib::NetworkResource *resource)
auto installType = metadata["install_type"].toString();
QString tempDirPrefix = "temp_" + filename;
qtlib::Dir tempDir(qtlib::Dir::genericCachePath() + "/"
Qtil::Dir tempDir(Qtil::Dir::genericCachePath() + "/"
+ configHandler_->getAppConfigApplication()["id"].toString() + "/"
+ tempDirPrefix);
tempDir.make();
qtlib::Dir tempDestDir(tempDir.path() + "/dest");
Qtil::Dir tempDestDir(tempDir.path() + "/dest");
tempDestDir.make();
qtlib::Package package(tempDir.path() + "/" + filename);
Qtil::Dir tempSrcDir(tempDir.path() + "/src");
tempSrcDir.make();
Qtil::Package package(tempDir.path() + "/" + filename);
if (!resource->saveData(package.path())) {
result["status"] = QString("error_save");
......@@ -341,11 +335,10 @@ void ItemHandler::installDownloadedFile(qtlib::NetworkResource *resource)
result["message"] = tr("Installing");
emit installStarted(result);
qtlib::Dir destDir;
#ifdef QTLIB_UNIX
destDir.setPath(configHandler_->getAppConfigInstallTypes()[installType].toObject()["destination"].toString());
Qtil::Dir destDir(configHandler_->getAppConfigInstallTypes()[installType].toObject()["destination"].toString());
// plasmapkg: Need to save package to remove installed files later
#ifdef APP_DESKTOP
// plasmapkg: Should save a package to remove installed files in uninstall process
if (installType == "bin"
&& package.installAsProgram(tempDestDir.path() + "/" + filename)) {
......@@ -381,6 +374,32 @@ void ItemHandler::installDownloadedFile(qtlib::NetworkResource *resource)
package.installAsFile(tempDestDir.path() + "/" + filename);
result["message"] = tr("The KWin window switcher has been installed");
}
else if (installType == "cursors"
&& package.installAsArchive(tempSrcDir.path())
&& installThemes("cursors", filename.section(".", 0, 0), tempSrcDir.path(), tempDestDir.path())) {
result["message"] = tr("The cursor theme has been installed");
}
else if (installType == "icons"
&& package.installAsArchive(tempSrcDir.path())
&& installThemes("icons", filename.section(".", 0, 0), tempSrcDir.path(), tempDestDir.path())) {
result["message"] = tr("The icon theme has been installed");
}
else if (installType == "emoticons"
&& package.installAsArchive(tempSrcDir.path())
&& installThemes("emoticons", filename.section(".", 0, 0), tempSrcDir.path(), tempDestDir.path())) {
result["message"] = tr("The emoticon theme has been installed");
}
else if ((installType == "themes"
|| installType == "gnome_shell_themes"
|| installType == "cinnamon_themes"
|| installType == "gtk2_themes"
|| installType == "gtk3_themes"
|| installType == "metacity_themes"
|| installType == "xfwm4_themes")
&& package.installAsArchive(tempSrcDir.path())
&& installThemes("themes", filename.section(".", 0, 0), tempSrcDir.path(), tempDestDir.path())) {
result["message"] = tr("The desktop theme has been installed");
}
else if (package.installAsArchive(tempDestDir.path())) {
result["message"] = tr("The archive file has been extracted");
}
......@@ -396,9 +415,7 @@ void ItemHandler::installDownloadedFile(qtlib::NetworkResource *resource)
return;
}
#else
destDir.setPath(configHandler_->getAppConfigInstallTypes()[installType].toObject()["generic_destination"].toString());
if (qtlib::File(package.path()).copy(tempDestDir.path() + "/" + filename)) {
if (Qtil::File(package.path()).copy(tempDestDir.path() + "/" + filename)) {
result["message"] = tr("The file has been installed");
}
else {
......@@ -423,15 +440,24 @@ void ItemHandler::installDownloadedFile(qtlib::NetworkResource *resource)
}
if (fileInfo.isDir()) {
qtlib::Dir(fileInfo.filePath()).move(destDir.path() + "/" + destFilename);
Qtil::Dir(fileInfo.filePath()).move(destDir.path() + "/" + destFilename);
}
else {
qtlib::File(fileInfo.filePath()).move(destDir.path() + "/" + destFilename);
Qtil::File(fileInfo.filePath()).move(destDir.path() + "/" + destFilename);
}
installedFiles.append(QJsonValue(destFilename));
}
if (installedFiles.isEmpty()) {
result["status"] = QString("error_install");
result["message"] = tr("Failed to installation");
emit installFinished(result);
tempDir.remove();
resource->deleteLater();
return;
}
// Installation post-process
metadata.remove("command");
metadata["files"] = installedFiles;
......@@ -445,3 +471,66 @@ void ItemHandler::installDownloadedFile(qtlib::NetworkResource *resource)
tempDir.remove();
resource->deleteLater();
}
#ifdef APP_DESKTOP
bool ItemHandler::installThemes(const QString &installType, const QString &name, const QString &srcDir, const QString &destDir)
{
QStringList themeDirs;
if (installType == "cursors") {
//QDirIterator iterator(srcDir, QStringList() << "index.theme", QDir::Files, QDirIterator::Subdirectories);
QDirIterator iterator(srcDir, QStringList() << "cursors", QDir::Dirs, QDirIterator::Subdirectories);
while (iterator.hasNext()) {
auto path = iterator.next();
path.truncate(path.lastIndexOf("/"));
themeDirs << path;
}
}
else if (installType == "icons") {
QDirIterator iterator(srcDir, QStringList() << "index.theme", QDir::Files, QDirIterator::Subdirectories);
while (iterator.hasNext()) {
auto path = iterator.next();
path.truncate(path.lastIndexOf("/"));
themeDirs << path;
}
}
else if (installType == "emoticons") {
QDirIterator iterator(srcDir, QStringList() << "emoticons.xml", QDir::Files, QDirIterator::Subdirectories);
while (iterator.hasNext()) {
auto path = iterator.next();
path.truncate(path.lastIndexOf("/"));
themeDirs << path;
}
}
else if (installType == "themes") {
/*QDirIterator iterator(srcDir,
QStringList() << "cinnamon"
<< "gnome-shell"
<< "gtk-2.0"
<< "gtk-3.0"
<< "metacity-1"
<< "plank"
<< "unity"
<< "xfwm4",
QDir::Dirs, QDirIterator::Subdirectories);*/
QDirIterator iterator(srcDir, QStringList() << "index.theme", QDir::Files, QDirIterator::Subdirectories);
while (iterator.hasNext()) {
auto path = iterator.next();
path.truncate(path.lastIndexOf("/"));
themeDirs << path;
}
}
if (!themeDirs.isEmpty()) {
for (const auto &themeDir : themeDirs) {
auto themeName = name;
if (themeDir != srcDir) {
themeName = themeDir.split("/").last();
}
Qtil::Dir(themeDir).move(destDir + "/" + themeName);
}
return true;
}
return false;
}
#endif
......@@ -3,7 +3,7 @@
#include <QObject>
#include <QJsonObject>
namespace qtlib {
namespace Qtil {
class NetworkResource;
}
......@@ -37,13 +37,17 @@ public slots:
void uninstall(const QString &itemKey);
private slots:
void networkResourceFinished(qtlib::NetworkResource *resource);
void networkResourceFinished(Qtil::NetworkResource *resource);
private:
void setMetadataSet(const QJsonObject &metadataSet);
void saveDownloadedFile(qtlib::NetworkResource *resource);
void installDownloadedFile(qtlib::NetworkResource *resource);
void saveDownloadedFile(Qtil::NetworkResource *resource);
void installDownloadedFile(Qtil::NetworkResource *resource);
#ifdef APP_DESKTOP
bool installThemes(const QString &installType, const QString &name, const QString &srcDir, const QString &destDir);
#endif
ConfigHandler *configHandler_;
QJsonObject metadataSet_;
......
......@@ -3,7 +3,7 @@
#include <QStringList>
#include <QJsonValue>
#include "qtlib_ocsapi.h"
#include "qtil_ocsapi.h"
#include "handlers/confighandler.h"
......@@ -13,9 +13,9 @@ OcsApiHandler::OcsApiHandler(ConfigHandler *configHandler, QObject *parent)
bool OcsApiHandler::addProviders(const QString &providerFileUrl) const
{
auto providers = qtlib::OcsApi::getProviderFile(QUrl(providerFileUrl));
auto providers = Qtil::OcsApi::getProviderFile(QUrl(providerFileUrl));
if (!providers.isEmpty()) {
for (const auto &providerValue : providers) {
for (const auto providerValue : providers) {
auto provider = providerValue.toObject();
if (provider.contains("location")) {
// Use location (API base URL) as unique key
......@@ -60,7 +60,7 @@ bool OcsApiHandler::updateCategories(const QString &providerKey, bool force) con
}
auto baseUrl = providers[providerKey].toObject()["location"].toString();
auto response = qtlib::OcsApi(baseUrl, QUrl(baseUrl)).getContentCategories();
auto response = Qtil::OcsApi(baseUrl, QUrl(baseUrl)).getContentCategories();
if (!response.contains("data")) {
return false;
......@@ -69,7 +69,7 @@ bool OcsApiHandler::updateCategories(const QString &providerKey, bool force) con
// Data type variation workaround, convert object to array
QJsonArray responseData;
if (response["data"].isObject()) {
for (const auto &dataValue : response["data"].toObject()) {
for (const auto dataValue : response["data"].toObject()) {
responseData.append(dataValue);
}
}
......@@ -86,7 +86,7 @@ bool OcsApiHandler::updateCategories(const QString &providerKey, bool force) con
}
QJsonObject newProviderCategories;
for (const auto &dataValue : responseData) {
for (const auto dataValue : responseData) {
auto data = dataValue.toObject();
// Data type variation workaround, convert int to string
......@@ -185,7 +185,7 @@ QJsonObject OcsApiHandler::getContents(const QString &providerKeys, const QStrin
query.addQueryItem("sortmode", sortmode);
query.addQueryItem("pagesize", QString::number(pagesize));
query.addQueryItem("page", QString::number(page));
responseSet[providerKey] = qtlib::OcsApi(baseUrl, QUrl(baseUrl)).getContentDataSet(query);
responseSet[providerKey] = Qtil::OcsApi(baseUrl, QUrl(baseUrl)).getContentDataSet(query);
}
}
......@@ -198,7 +198,7 @@ QJsonObject OcsApiHandler::getContent(const QString &providerKey, const QString
auto providers = configHandler_->getUsrConfigProviders();
if (providers.contains(providerKey)) {
auto baseUrl = providers[providerKey].toObject()["location"].toString();
response = qtlib::OcsApi(baseUrl, QUrl(baseUrl)).getContentData(contentId);
response = Qtil::OcsApi(baseUrl, QUrl(baseUrl)).getContentData(contentId);
}
return response;
}
......@@ -3,27 +3,19 @@
#include <QUrl>
#include <QDesktopServices>
#ifdef QTLIB_UNIX
#ifdef APP_DESKTOP
#include <QFileInfo>
#include <QProcess>
#endif
#ifdef Q_OS_ANDROID
#include "qtlib_package.h"
#include "qtil_package.h"
#endif
SystemHandler::SystemHandler(QObject *parent)
: QObject(parent)
{}
bool SystemHandler::isUnix() const
{
#ifdef QTLIB_UNIX
return true;
#endif
return false;
}
bool SystemHandler::isMobileDevice() const
{
#if defined(APP_MOBILE)
......@@ -42,7 +34,7 @@ bool SystemHandler::openUrl(const QString &url) const
path.replace("file://localhost", "", Qt::CaseInsensitive);
path.replace("file://", "", Qt::CaseInsensitive);
#ifdef QTLIB_UNIX
#ifdef APP_DESKTOP
if ((path.endsWith(".appimage", Qt::CaseInsensitive) || path.endsWith(".exe", Qt::CaseInsensitive))
&& QFileInfo(path).isExecutable()) {
return QProcess::startDetached(path);
......@@ -51,7 +43,7 @@ bool SystemHandler::openUrl(const QString &url) const
#ifdef Q_OS_ANDROID
if (path.endsWith(".apk", Qt::CaseInsensitive)) {
return qtlib::Package(path).installAsApk();
return Qtil::Package(path).installAsApk();
}
#endif
......
......@@ -10,7 +10,6 @@ public:
explicit SystemHandler(QObject *parent = nullptr);
public slots:
bool isUnix() const;
bool isMobileDevice() const;
bool openUrl(const QString &url) const;
};
#include "updatehandler.h"
#include <QStringList>
#include <QJsonValue>
#include <QJsonArray>
#include <QDateTime>
#include "qtil_file.h"
#include "handlers/confighandler.h"
#ifdef APP_DESKTOP
#include "updaters/appimageupdater.h"
#endif
UpdateHandler::UpdateHandler(ConfigHandler *configHandler, QObject *parent)
: QObject(parent), configHandler_(configHandler)
{}
void UpdateHandler::checkAll()
{
// Resets data
QJsonObject updateAvailableItems;
configHandler_->setUsrConfigUpdateAvailableItems(updateAvailableItems);
auto installedItems = configHandler_->getUsrConfigInstalledItems();
if (installedItems.isEmpty()) {
emit checkAllStarted(false);
return;
}
emit checkAllStarted(true);
for (const auto &itemKey : installedItems.keys()) {
auto installedItem = installedItems[itemKey].toObject();
auto filename = installedItem["filename"].toString();
auto installType = installedItem["install_type"].toString();
auto filePath = configHandler_->getAppConfigInstallTypes()[installType].toObject()["destination"].toString() + "/" + filename;
QString updateMethod = "";
if (installType == "bin") {
#ifdef APP_DESKTOP
if (filePath.endsWith(".appimage", Qt::CaseInsensitive)) {
if (AppImageUpdater(itemKey, filePath).checkForChanges()) {
updateMethod = "appimageupdate";
}
//else if (OcsFileUpdater(url).checkFile()) {
// updateMethod = "appimageupdate_ocs";
//}
}
#endif
}
if (!updateMethod.isEmpty()) {
QJsonObject updateAvailableItem;
updateAvailableItem["installed_item"] = itemKey;
updateAvailableItem["update_method"] = updateMethod;
// Use installed item's key as unique key to the update available item
configHandler_->setUsrConfigUpdateAvailableItemsItem(itemKey, updateAvailableItem);
}
}
auto application = configHandler_->getUsrConfigApplication();
application["update_checked_at"] = QDateTime::currentMSecsSinceEpoch();
configHandler_->setUsrConfigApplication(application);
emit checkAllFinished(true);
}
void UpdateHandler::update(const QString &itemKey)
{
auto updateAvailableItems = configHandler_->getUsrConfigUpdateAvailableItems();
if (!updateAvailableItems.contains(itemKey)) {
emit updateStarted(itemKey, false);
return;
}
auto updateMethod = updateAvailableItems[itemKey].toObject()["update_method"].toString();
#ifdef APP_DESKTOP
if (updateMethod == "appimageupdate") {
updateAppImage(itemKey);
}
//else if (updateMethod == "appimageupdate_ocs") {
// updateAppImageOcs(itemKey);
//}
#endif
}
#ifdef APP_DESKTOP
void UpdateHandler::appImageUpdaterFinished(AppImageUpdater *updater)
{
auto itemKey = updater->id();
auto metadata = metadataSet_[itemKey].toObject();
metadataSet_.remove(itemKey);
if (!updater->isFinishedWithNoError()) {
emit updateFinished(itemKey, false);
updater->deleteLater();
return;
}
auto installedItemKey = metadata["installed_item_key"].toString();
auto installedItem = metadata["installed_item_obj"].toObject();
auto newFilename = metadata["new_filename"].toString();
auto filename = installedItem["filename"].toString();
installedItem["filename"] = newFilename;
QJsonArray files;
files.append(QJsonValue(newFilename));
installedItem["files"] = files;
installedItem["installed_at"] = QDateTime::currentMSecsSinceEpoch();
configHandler_->setUsrConfigInstalledItemsItem(installedItemKey, installedItem);
if (newFilename != filename) {
Qtil::File(updater->path()).remove();
}
configHandler_->removeUsrConfigUpdateAvailableItemsItem(itemKey);
emit updateFinished(itemKey, true);
updater->deleteLater();
}
#endif
#ifdef APP_DESKTOP
void UpdateHandler::updateAppImage(const QString &itemKey)
{
auto updateAvailableItem = configHandler_->getUsrConfigUpdateAvailableItems()[itemKey].toObject();
auto installedItemKey = updateAvailableItem["installed_item"].toString();
auto installedItems = configHandler_->getUsrConfigInstalledItems();
if (!installedItems.contains(installedItemKey)) {
emit updateStarted(itemKey, false);
return;
}
auto installedItem = installedItems[installedItemKey].toObject();
auto filename = installedItem["filename"].toString();
auto installType = installedItem["install_type"].toString();
auto filePath = configHandler_->getAppConfigInstallTypes()[installType].toObject()["destination"].toString() + "/" + filename;
auto *updater = new AppImageUpdater(itemKey, filePath, this);
connect(updater, &AppImageUpdater::updateProgress, this, &UpdateHandler::updateProgress);
connect(updater, &AppImageUpdater::finished, this, &UpdateHandler::appImageUpdaterFinished);
QJsonObject metadata;
metadata["installed_item_key"] = installedItemKey;
metadata["installed_item_obj"] = installedItem;
metadata["new_filename"] = filename;
QString assembledNewFilename = "";
QString rawNewFilename = "";
auto updateInformation = updater->describeAppImage();
for (const auto &info : updateInformation.split("\n")) {
if (info.endsWith(".zsync", Qt::CaseInsensitive)) {
if (info.startsWith("Assembled ZSync URL:", Qt::CaseInsensitive)) {
assembledNewFilename = info.split("/").last().replace(".zsync", "", Qt::CaseInsensitive);
}
else if (info.startsWith("Raw update information:", Qt::CaseInsensitive)) {
rawNewFilename = info.split("|").last().split("/").last().replace(".zsync", "", Qt::CaseInsensitive);
}
}
}
if (!assembledNewFilename.isEmpty()) {
metadata["new_filename"] = assembledNewFilename;
}
else if (!rawNewFilename.isEmpty() && !rawNewFilename.contains("*")) {
metadata["new_filename"] = rawNewFilename;
}
metadataSet_[itemKey] = metadata;
emit updateStarted(itemKey, true);
updater->start();
}
#endif