Commit dc4c5070 authored by akiraohgaki's avatar akiraohgaki Committed by GitHub
Browse files

Merge pull request #24 from xdgurl/development

Development
parents 719d8261 241f7425
*.pro.user
pkg/build/
SHELL = /bin/sh
TARGET = xdgurl
srcdir = ./src
DESTDIR =
prefix = /usr/local
exec_prefix = $(prefix)
bindir = $(exec_prefix)/bin
datadir = $(prefix)/share
INSTALL = install
INSTALL_PROGRAM = $(INSTALL) -D -m 755
INSTALL_DATA = $(INSTALL) -D -m 644
RM = rm -f
.PHONY: all rebuild build clean install uninstall
all: rebuild ;
rebuild: clean build ;
build: $(TARGET) ;
clean:
$(RM) ./$(TARGET)
install: build
$(INSTALL_PROGRAM) ./$(TARGET) $(DESTDIR)$(bindir)/$(TARGET)
$(INSTALL_DATA) $(srcdir)/$(TARGET).desktop $(DESTDIR)$(datadir)/applications/$(TARGET).desktop
uninstall:
$(RM) $(DESTDIR)$(bindir)/$(TARGET)
$(RM) $(DESTDIR)$(datadir)/applications/$(TARGET).desktop
$(TARGET):
# Just copy for now
install -m 755 $(srcdir)/$(TARGET).py ./$(TARGET)
unix:!android {
isEmpty(PREFIX) {
PREFIX = /usr/local
}
SRCDIR = src
BINDIR = $${PREFIX}/bin
DATADIR = $${PREFIX}/share
target.path = $${BINDIR}
desktop.files = $${SRCDIR}/desktop/$${TARGET}.desktop
desktop.path = $${DATADIR}/applications
icon.files = $${SRCDIR}/desktop/$${TARGET}.svg
icon.path = $${DATADIR}/icons/hicolor/scalable/apps
INSTALLS += target desktop icon
}
export(INSTALLS)
# Maintainer: Akira Ohgaki <akiraohgaki@gmail.com>
pkgname=xdgurl
pkgver=1.0.1
pkgver=2.0.0
pkgrel=1
pkgdesc="An install helper program for desktop stuff."
arch=('i686' 'x86_64')
url="https://github.com/xdgurl/xdgurl"
license=('GPL3')
depends=('tk')
depends=('qt5-base>=5.3.0' 'qt5-svg>=5.3.0' 'qt5-declarative>=5.3.0' 'qt5-quickcontrols>=5.3.0')
#source=("https://github.com/xdgurl/xdgurl/archive/release-$pkgver.tar.gz")
source=("$pkgname.tar.gz")
md5sums=() #autofill using updpkgsums
......@@ -15,11 +15,12 @@ md5sums=() #autofill using updpkgsums
build() {
#cd "$pkgname-release-$pkgver"
cd $pkgname
qmake PREFIX="/usr"
make
}
package() {
#cd "$pkgname-release-$pkgver"
cd $pkgname
make DESTDIR="$pkgdir" prefix="/usr" install
make INSTALL_ROOT="$pkgdir" install
}
#!/bin/sh
cd `dirname $0`
TMPDIR=/tmp
PKGDIR=`cd $(dirname $0) && pwd`
BUILDDIR=$PKGDIR/build
PROJDIR=`dirname $PKGDIR`
PROJNAME=`basename $PROJDIR`
PARENTDIR=`dirname $PROJDIR`
build_ubuntu() {
mkdir ./build
cp -r ../src ./build/
cp ../Makefile ./build/
cp -r ./ubuntu/debian ./build/
cd ./build
#sudo apt install build-essential qt5-default libqt5svg5-dev qtdeclarative5-dev devscripts debhelper fakeroot
cd $PARENTDIR
tar -czvf $TMPDIR/$PROJNAME.tar.gz --exclude ".git" $PROJNAME
mkdir $BUILDDIR
mv $TMPDIR/$PROJNAME.tar.gz $BUILDDIR
tar -xzvf $BUILDDIR/$PROJNAME.tar.gz -C $BUILDDIR
cp -r $PKGDIR/ubuntu/debian $BUILDDIR/$PROJNAME
cd $BUILDDIR/$PROJNAME
debuild -uc -us -b
}
build_fedora() {
tar -czvf /tmp/xdgurl.tar.gz ../../xdgurl
mkdir -p ./build/SOURCES
mkdir -p ./build/SPECS
mv /tmp/xdgurl.tar.gz ./build/SOURCES/
cp ./fedora/xdgurl.spec ./build/SPECS/
rpmbuild --define '_topdir '`pwd`'/build' -bb ./build/SPECS/xdgurl.spec
#sudo dnf install make automake gcc gcc-c++ libtool qt5-qtbase-devel qt5-qtsvg-devel qt5-qtdeclarative-devel rpm-build
cd $PARENTDIR
tar -czvf $TMPDIR/$PROJNAME.tar.gz --exclude ".git" $PROJNAME
mkdir $BUILDDIR
mkdir $BUILDDIR/SOURCES
mkdir $BUILDDIR/SPECS
mv $TMPDIR/$PROJNAME.tar.gz $BUILDDIR/SOURCES
cp $PKGDIR/fedora/xdgurl.spec $BUILDDIR/SPECS
rpmbuild --define "_topdir $BUILDDIR" -bb $BUILDDIR/SPECS/xdgurl.spec
}
build_arch() {
tar -czvf /tmp/xdgurl.tar.gz ../../xdgurl
mkdir ./build
mv /tmp/xdgurl.tar.gz ./build/
cp ./arch/PKGBUILD ./build/
cd ./build
#sudo pacman -S base-devel qt5-base qt5-svg qt5-declarative qt5-quickcontrols
cd $PARENTDIR
tar -czvf $TMPDIR/$PROJNAME.tar.gz --exclude ".git" $PROJNAME
mkdir $BUILDDIR
mv $TMPDIR/$PROJNAME.tar.gz $BUILDDIR
cp $PKGDIR/arch/PKGBUILD $BUILDDIR
cd $BUILDDIR
updpkgsums
makepkg -s
}
......
Summary: An install helper program for desktop stuff
Name: xdgurl
Version: 1.0.1
Version: 2.0.0
Release: 1%{?dist}
License: GPLv3+
Group: Applications/Internet
......@@ -9,7 +9,8 @@ URL: https://github.com/xdgurl/xdgurl
#Source0: https://github.com/xdgurl/xdgurl/archive/release-%{version}.tar.gz
Source0: %{name}.tar.gz
Requires: tkinter, python3-tkinter
Requires: qt5-qtbase >= 5.3.0, qt5-qtbase-gui >= 5.3.0, qt5-qtsvg >= 5.3.0, qt5-qtdeclarative >= 5.3.0, qt5-qtquickcontrols >= 5.3.0
BuildRequires: make, automake, gcc, gcc-c++, libtool, qt5-qtbase-devel, qt5-qtsvg-devel, qt5-qtdeclarative-devel, rpm-build
%description
An install helper program for desktop stuff.
......@@ -20,20 +21,27 @@ An install helper program for desktop stuff.
%build
%define debug_package %{nil}
qmake-qt5 PREFIX="/usr"
make
%install
make DESTDIR="%{buildroot}" prefix="/usr" install
make INSTALL_ROOT="%{buildroot}" install
%files
%defattr(-,root,root)
%{_bindir}/%{name}
%{_datadir}/applications/%{name}.desktop
%{_datadir}/icons/hicolor/scalable/apps/%{name}.svg
%clean
rm -rf %{buildroot}
%changelog
* Fri Oct 28 2016 Akira Ohgaki <akiraohgaki@gmail.com> - 2.0.0-1
- Re-implemented xdgurl as Qt program
- Download progress bar
- Add install-type "bin"
* Fri Jul 15 2016 Akira Ohgaki <akiraohgaki@gmail.com> - 1.0.1-1
- Clean successfull message
- Return exit code
......
xdgurl (2.0.0-0ubuntu1) xenial; urgency=low
* Re-implemented xdgurl as Qt program
* Download progress bar
* Add install-type "bin"
-- Akira Ohgaki <akiraohgaki@gmail.com> Fri, 28 Oct 2016 08:53:57 +0000
xdgurl (1.0.1-0ubuntu1) xenial; urgency=low
* Clean successfull message
......
......@@ -2,11 +2,11 @@ Source: xdgurl
Section: web
Priority: optional
Maintainer: Akira Ohgaki <akiraohgaki@gmail.com>
Build-Depends: build-essential (>= 11), devscripts (>= 2.14), debhelper (>= 9), fakeroot (>= 1.20)
Build-Depends: build-essential (>= 11), qt5-default (>= 5.3.0), libqt5svg5-dev (>= 5.3.0), qtdeclarative5-dev (>= 5.3.0), devscripts (>= 2.14), debhelper (>= 9), fakeroot (>= 1.20)
Standards-Version: 3.9.4
Package: xdgurl
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}, python-tk (>= 2.7.0), python3-tk (>= 3.2.0)
Description: xdgurl
Depends: ${shlibs:Depends}, ${misc:Depends}, libqt5svg5 (>= 5.3.0), qtdeclarative5-qtquick2-plugin (>= 5.3.0), qtdeclarative5-window-plugin (>= 5.3.0), qtdeclarative5-controls-plugin (>= 5.3.0), qtdeclarative5-dialogs-plugin (>= 5.3.0)
Description: An install helper program for desktop stuff
An install helper program for desktop stuff.
......@@ -3,8 +3,11 @@
%:
dh $@
override_dh_auto_configure:
qmake PREFIX="/usr"
override_dh_auto_install:
make DESTDIR="$(CURDIR)/debian/tmp" prefix="/usr" install
make INSTALL_ROOT="$(CURDIR)/debian/tmp" install
override_dh_shlibdeps:
# ignore
usr/bin/xdgurl
usr/share/applications/xdgurl.desktop
usr/share/icons/hicolor/scalable/apps/xdgurl.svg
unix:!android {
QMAKE_LFLAGS += -Wl,-rpath=\\\$\$ORIGIN
QMAKE_LFLAGS += -Wl,-rpath=/usr/lib/$${TARGET}
QMAKE_RPATH =
}
{
"id": "xdgurl",
"name": "xdgurl",
"version": "2.0.0",
"organization": "xdgurl",
"domain": "com.xdgurl.xdgurl",
"icon": ":/desktop/xdgurl.svg",
"description": "An install helper program for desktop stuff.",
"license": "GPL-3+",
"author": "Akira Ohgaki",
"contact": "akiraohgaki@gmail.com",
"homepage": "https://github.com/xdgurl/xdgurl"
}
<RCC>
<qresource prefix="/configs">
<file>application.json</file>
<file>destinations.json</file>
<file>destinations_alias.json</file>
</qresource>
</RCC>
{
"bin": "$HOME/.bin",
"downloads": "$HOME/Downloads",
"documents": "$HOME/Documents",
"pictures": "$HOME/Pictures",
"music": "$HOME/Music",
"videos": "$HOME/Videos",
"wallpapers": "$XDG_DATA_HOME/wallpapers",
"fonts": "$HOME/.fonts",
"cursors": "$HOME/.icons",
"icons": "$XDG_DATA_HOME/icons",
"emoticons": "$XDG_DATA_HOME/emoticons",
"themes": "$HOME/.themes",
"emerald_themes": "$HOME/.emerald/themes",
"enlightenment_themes": "$HOME/.e/e/themes",
"enlightenment_backgrounds": "$HOME/.e/e/backgrounds",
"fluxbox_styles": "$HOME/.fluxbox/styles",
"pekwm_themes": "$HOME/.pekwm/themes",
"icewm_themes": "$HOME/.icewm/themes",
"plasma_plasmoids": "$XDG_DATA_HOME/plasma/plasmoids",
"plasma_look_and_feel": "$XDG_DATA_HOME/plasma/look-and-feel",
"plasma_desktopthemes": "$XDG_DATA_HOME/plasma/desktoptheme",
"kwin_effects": "$XDG_DATA_HOME/kwin/effects",
"kwin_scripts": "$XDG_DATA_HOME/kwin/scripts",
"kwin_tabbox": "$XDG_DATA_HOME/kwin/tabbox",
"aurorae_themes": "$XDG_DATA_HOME/aurorae/themes",
"dekorator_themes": "$XDG_DATA_HOME/deKorator/themes",
"qtcurve": "$XDG_DATA_HOME/QtCurve",
"color_schemes": "$XDG_DATA_HOME/color-schemes",
"gnome_shell_extensions": "$XDG_DATA_HOME/gnome-shell/extensions",
"cinnamon_applets": "$XDG_DATA_HOME/cinnamon/applets",
"cinnamon_desklets": "$XDG_DATA_HOME/cinnamon/desklets",
"cinnamon_extensions": "$XDG_DATA_HOME/cinnamon/extensions",
"nautilus_scripts": "$XDG_DATA_HOME/nautilus/scripts",
"amarok_scripts": "$KDEHOME/share/apps/amarok/scripts",
"yakuake_skins": "$KDEHOME/share/apps/yakuake/skins",
"cairo_clock_themes": "$HOME/.cairo-clock/themes"
}
{
"gnome_shell_themes": "themes",
"cinnamon_themes": "themes",
"gtk2_themes": "themes",
"gtk3_themes": "themes",
"metacity_themes": "themes",
"xfwm4_themes": "themes",
"openbox_themes": "themes",
"kvantum_themes": "themes",
"compiz_themes": "emerald_themes",
"beryl_themes": "emerald_themes",
"plasma4_plasmoids": "plasma_plasmoids",
"plasma5_plasmoids": "plasma_plasmoids",
"plasma5_look_and_feel": "plasma_look_and_feel",
"plasma5_desktopthemes": "plasma_desktopthemes",
"plasma_color_schemes": "color_schemes"
}
#include "xdgurl.h"
#include <QUrl>
#include <QUrlQuery>
#include <QTemporaryFile>
#include <QNetworkReply>
#include <QDesktopServices>
#include "../../libs/utils/config.h"
#include "../../libs/utils/network.h"
#include "../../libs/utils/file.h"
#include "../../libs/utils/package.h"
namespace handlers {
XdgUrl::XdgUrl(const QString &xdgUrl, utils::Config *config, utils::Network *network, QObject *parent) :
QObject(parent), xdgUrl_(xdgUrl), config_(config), network_(network)
{
parse();
loadDestinations();
connect(network_, &utils::Network::finished, this, &handlers::XdgUrl::downloaded);
connect(network_, &utils::Network::downloadProgress, this, &handlers::XdgUrl::downloadProgress);
}
void XdgUrl::process()
{
/**
* xdgs scheme is a reserved name, so the process of xdgs
* is the same process of the xdg scheme currently.
*/
if (!isValid()) {
QJsonObject result;
result["status"] = QString("error_validation");
result["message"] = QString("Invalid XDG-URL " + xdgUrl_);
emit error(result);
return;
}
network_->get(QUrl(metadata_["url"].toString()));
emit started();
}
bool XdgUrl::isValid()
{
QString scheme = metadata_["scheme"].toString();
QString command = metadata_["command"].toString();
QString url = metadata_["url"].toString();
QString type = metadata_["type"].toString();
QString filename = metadata_["filename"].toString();
if ((scheme == "xdg" || scheme == "xdgs")
&& (command == "download" || command == "install")
&& QUrl(url).isValid()
&& destinations_.contains(type)
&& !filename.isEmpty()) {
return true;
}
return false;
}
void XdgUrl::openDestination()
{
if (!destination_.isEmpty()) {
QDesktopServices::openUrl(QUrl("file://" + destination_));
}
}
QString XdgUrl::xdgUrl() const
{
return xdgUrl_;
}
QJsonObject XdgUrl::metadata() const
{
return metadata_;
}
void XdgUrl::downloaded(QNetworkReply *reply)
{
if (reply->error() != QNetworkReply::NoError) {
QJsonObject result;
result["status"] = QString("error_network");
result["message"] = reply->errorString();
emit error(result);
return;
}
else if (reply->hasRawHeader("Location")) {
QString redirectUrl = QString(reply->rawHeader("Location"));
if (redirectUrl.startsWith("/")) {
redirectUrl = reply->url().authority() + redirectUrl;
}
network_->get(QUrl(redirectUrl));
return;
}
else if (reply->hasRawHeader("Refresh")) {
QString refreshUrl = QString(reply->rawHeader("Refresh")).split("url=").last();
if (refreshUrl.startsWith("/")) {
refreshUrl = reply->url().authority() + refreshUrl;
}
network_->get(QUrl(refreshUrl));
return;
}
if (metadata_["command"].toString() == "download") {
saveDownloadedFile(reply);
}
else if (metadata_["command"].toString() == "install") {
installDownloadedFile(reply);
}
}
void XdgUrl::parse()
{
QUrl url(xdgUrl_);
QUrlQuery query(url);
metadata_["scheme"] = QString("xdg");
metadata_["command"] = QString("download");
metadata_["url"] = QString("");
metadata_["type"] = QString("downloads");
metadata_["filename"] = QString("");
if (!url.scheme().isEmpty()) {
metadata_["scheme"] = url.scheme();
}
if (!url.host().isEmpty()) {
metadata_["command"] = url.host();
}
if (query.hasQueryItem("url") && !query.queryItemValue("url").isEmpty()) {
metadata_["url"] = query.queryItemValue("url", QUrl::FullyDecoded);
}
if (query.hasQueryItem("type") && !query.queryItemValue("type").isEmpty()) {
metadata_["type"] = query.queryItemValue("type", QUrl::FullyDecoded);
}
if (query.hasQueryItem("filename") && !query.queryItemValue("filename").isEmpty()) {
metadata_["filename"] = QUrl(query.queryItemValue("filename", QUrl::FullyDecoded)).fileName();
}
if (!metadata_["url"].toString().isEmpty() && metadata_["filename"].toString().isEmpty()) {
metadata_["filename"] = QUrl(metadata_["url"].toString()).fileName();
}
}
void XdgUrl::loadDestinations()
{
QJsonObject configDestinations = config_->get("destinations");
QJsonObject configDestinationsAlias = config_->get("destinations_alias");
foreach (const QString key, configDestinations.keys()) {
destinations_[key] = convertPathString(configDestinations[key].toString());
}
foreach (const QString key, configDestinationsAlias.keys()) {
QString value = configDestinationsAlias[key].toString();
if (destinations_.contains(value)) {
destinations_[key] = destinations_.value(value);
}
}
}
QString XdgUrl::convertPathString(const QString &path)
{
QString newPath = path;
if (newPath.contains("$HOME")) {
newPath.replace("$HOME", utils::File::homePath());
}
else if (newPath.contains("$XDG_DATA_HOME")) {
newPath.replace("$XDG_DATA_HOME", utils::File::genericDataPath());
}
else if (newPath.contains("$KDEHOME")) {
newPath.replace("$KDEHOME", utils::File::kdehomePath());
}
return newPath;
}
void XdgUrl::saveDownloadedFile(QNetworkReply *reply)
{
QJsonObject result;
QTemporaryFile temporaryFile;
if (!temporaryFile.open() || temporaryFile.write(reply->readAll()) == -1) {
result["status"] = QString("error_save");
result["message"] = temporaryFile.errorString();
emit error(result);
return;
}
QString type = metadata_["type"].toString();
QString destination = destinations_[type].toString();
QString path = destination + "/" + metadata_["filename"].toString();
utils::File::makeDir(destination);
utils::File::remove(path); // Remove previous downloaded file
if (!temporaryFile.copy(path)) {
result["status"] = QString("error_save");
result["message"] = temporaryFile.errorString();
emit error(result);
return;
}
destination_ = destination;
result["status"] = QString("success_download");
result["message"] = QString("The file has been stored into " + destination);
emit finished(result);
}
void XdgUrl::installDownloadedFile(QNetworkReply *reply)
{
QJsonObject result;
QTemporaryFile temporaryFile;
if (!temporaryFile.open() || temporaryFile.write(reply->readAll()) == -1) {
result["status"] = QString("error_save");
result["message"] = temporaryFile.errorString();
emit error(result);
return;
}
QString type = metadata_["type"].toString();
QString destination = destinations_[type].toString();
QString path = destination + "/" + metadata_["filename"].toString();
utils::File::makeDir(destination);
utils::File::remove(path); // Remove previous downloaded file
if (type == "bin"
&& utils::Package::installProgram(temporaryFile.fileName(), path)) {
result["message"] = QString("The program has been installed into " + destination);
}
else if ((type == "plasma_plasmoids" || type == "plasma4_plasmoids" || type == "plasma5_plasmoids")
&& utils::Package::installPlasmapkg(temporaryFile.fileName(), "plasmoid")) {
result["message"] = QString("The plasmoid has been installed");
}
else if ((type == "plasma_look_and_feel" || type == "plasma5_look_and_feel")
&& utils::Package::installPlasmapkg(temporaryFile.fileName(), "lookandfeel")) {
result["message"] = QString("The plasma look and feel has been installed");
}
else if ((type == "plasma_desktopthemes" || type == "plasma5_desktopthemes")
&& utils::Package::installPlasmapkg(temporaryFile.fileName(), "theme")) {
result["message"] = QString("The plasma desktop theme has been installed");
}
else if (type == "kwin_effects"
&& utils::Package::installPlasmapkg(temporaryFile.fileName(), "kwineffect")) {
result["message"] = QString("The KWin effect has been installed");
}
else if (type == "kwin_scripts"
&& utils::Package::installPlasmapkg(temporaryFile.fileName(), "kwinscript")) {
result["message"] = QString("The KWin script has been installed");
}
else if (type == "kwin_tabbox"
&& utils::Package::installPlasmapkg(temporaryFile.fileName(), "windowswitcher")) {
result["message"] = QString("The KWin window switcher has been installed");
}
else if (utils::Package::uncompressArchive(temporaryFile.fileName(), destination)) {
result["message"] = QString("The archive file has been uncompressed into " + destination);
}
else if (temporaryFile.copy(path)) {