From d661c573f986198fb0e48deb106f11de8e4c7291 Mon Sep 17 00:00:00 2001 From: guinux Date: Sat, 29 Jul 2017 16:35:04 +0200 Subject: [PATCH] v4.9.0 --- .gitignore | 3 +- Makefile | 26 +- data/dbus/org.manjaro.pamac.service | 5 - ...mac.conf => org.manjaro.pamac.system.conf} | 14 +- data/dbus/org.manjaro.pamac.system.service | 5 + data/dbus/org.manjaro.pamac.user.service | 3 + data/networkmanager/99_update_pamac_tray | 12 - data/systemd/pamac-system.service | 7 + data/systemd/pamac.service | 7 - po/files_to_translate | 6 +- po/pamac.pot | 139 +- resources/Makefile | 9 +- resources/manager_window.ui | 58 +- resources/package-upgrade.png | Bin 0 -> 501 bytes resources/pamac.manager.gresource.xml | 2 + resources/pamac.transaction.gresource.xml | 1 - resources/pamac.updater.gresource.xml | 6 - resources/updater_window.ui | 455 ------- src/Makefile | 53 +- src/alpm_config.vala | 25 +- src/common.vala | 4 +- src/history_dialog.vala | 2 +- src/installer.vala | 12 +- src/manager.vala | 26 +- src/manager_window.vala | 445 +++++-- src/mirrors_config.vala | 23 - src/package.vala | 3 + src/preferences_dialog.vala | 4 +- src/refresh.vala | 100 -- src/{daemon.vala => system_daemon.vala} | 1114 +++-------------- src/transaction.vala | 390 +++--- src/tray.vala | 90 +- src/updater.vala | 105 -- src/updater_window.vala | 384 ------ src/user_daemon.vala | 967 ++++++++++++++ vapi/libalpm.vapi | 1 + 36 files changed, 1979 insertions(+), 2527 deletions(-) delete mode 100644 data/dbus/org.manjaro.pamac.service rename data/dbus/{org.manjaro.pamac.conf => org.manjaro.pamac.system.conf} (57%) create mode 100644 data/dbus/org.manjaro.pamac.system.service create mode 100644 data/dbus/org.manjaro.pamac.user.service delete mode 100755 data/networkmanager/99_update_pamac_tray create mode 100644 data/systemd/pamac-system.service delete mode 100644 data/systemd/pamac.service create mode 100644 resources/package-upgrade.png delete mode 100644 resources/pamac.updater.gresource.xml delete mode 100644 resources/updater_window.ui delete mode 100644 src/refresh.vala rename src/{daemon.vala => system_daemon.vala} (65%) delete mode 100644 src/updater.vala delete mode 100644 src/updater_window.vala create mode 100644 src/user_daemon.vala diff --git a/.gitignore b/.gitignore index 7adf1ff..28d5e38 100644 --- a/.gitignore +++ b/.gitignore @@ -5,7 +5,8 @@ src/*.c src/pamac.h src/pamac.vapi src/libpamac.so -src/pamac-daemon +src/pamac-user-daemon +src/pamac-system-daemon src/pamac-tray src/pamac-tray-appindicator src/pamac-manager diff --git a/Makefile b/Makefile index 7b51c7f..2b0e16d 100644 --- a/Makefile +++ b/Makefile @@ -28,20 +28,21 @@ install: install_pamac-tray-appindicator install -Dm644 src/pamac.h $(includedir)/pamac.h install -Dm644 src/pamac.vapi $(datadir)/vala/vapi/pamac.vapi install -Dm755 src/libpamac.so $(libdir)/libpamac.so - install -Dm744 src/pamac-daemon $(bindir)/pamac-daemon + install -Dm755 src/pamac-user-daemon $(bindir)/pamac-user-daemon + install -Dm744 src/pamac-system-daemon $(bindir)/pamac-system-daemon install -Dm755 src/pamac-tray $(bindir)/pamac-tray install -Dm755 src/pamac-manager $(bindir)/pamac-manager - install -Dm755 src/pamac-updater $(bindir)/pamac-updater + ln -srf $(bindir)/pamac-manager $(bindir)/pamac-updater install -Dm755 src/pamac-install $(bindir)/pamac-install - install -Dm755 src/pamac-refresh $(bindir)/pamac-refresh install -Dm644 data/applications/pamac-tray.desktop $(sysconfdir)/xdg/autostart/pamac-tray.desktop install -Dm644 data/applications/pamac-manager.desktop $(datadir)/applications/pamac-manager.desktop install -Dm644 data/applications/pamac-updater.desktop $(datadir)/applications/pamac-updater.desktop install -Dm644 data/applications/pamac-install.desktop $(datadir)/applications/pamac-install.desktop install -Dm644 data/config/pamac.conf $(sysconfdir)/pamac.conf - install -Dm644 data/dbus/org.manjaro.pamac.conf $(sysconfdir)/dbus-1/system.d/org.manjaro.pamac.conf - install -Dm644 data/dbus/org.manjaro.pamac.service $(datadir)/dbus-1/system-services/org.manjaro.pamac.service - install -Dm644 data/systemd/pamac.service $(libdir)/systemd/system/pamac.service + install -Dm644 data/dbus/org.manjaro.pamac.system.conf $(sysconfdir)/dbus-1/system.d/org.manjaro.pamac.system.conf + install -Dm644 data/dbus/org.manjaro.pamac.user.service $(datadir)/dbus-1/services/org.manjaro.pamac.user.service + install -Dm644 data/dbus/org.manjaro.pamac.system.service $(datadir)/dbus-1/system-services/org.manjaro.pamac.system.service + install -Dm644 data/systemd/pamac-system.service $(libdir)/systemd/system/pamac-system.service install -Dm644 data/systemd/pamac-cleancache.service $(libdir)/systemd/system/pamac-cleancache.service install -Dm644 data/systemd/pamac-cleancache.timer $(libdir)/systemd/system/pamac-cleancache.timer install -Dm644 data/systemd/pamac-mirrorlist.service $(libdir)/systemd/system/pamac-mirrorlist.service @@ -49,7 +50,6 @@ install: install_pamac-tray-appindicator mkdir -p $(libdir)/systemd/system/multi-user.target.wants ln -srf $(libdir)/systemd/system/pamac-cleancache.timer $(libdir)/systemd/system/multi-user.target.wants ln -srf $(libdir)/systemd/system/pamac-mirrorlist.timer $(libdir)/systemd/system/multi-user.target.wants - install -Dm744 data/networkmanager/99_update_pamac_tray $(sysconfdir)/NetworkManager/dispatcher.d/99_update_pamac_tray install -Dm644 data/polkit/org.manjaro.pamac.policy $(datadir)/polkit-1/actions/org.manjaro.pamac.policy install -Dm644 data/mime/x-alpm-package.xml $(datadir)/mime/packages/x-alpm-package.xml @@ -66,27 +66,27 @@ uninstall: rm -f $(includedir)/pamac.h rm -f $(datadir)/vala/vapi/pamac.vapi rm -f $(libdir)/libpamac.so - rm -f $(bindir)/pamac-daemon + rm -f $(bindir)/pamac-user-daemon + rm -f $(bindir)/pamac-system-daemon rm -f $(bindir)/pamac-tray rm -f $(bindir)/pamac-tray-appindicator rm -f $(bindir)/pamac-manager rm -f $(bindir)/pamac-updater rm -f $(bindir)/pamac-install - rm -f $(bindir)/pamac-refresh rm -f $(sysconfdir)/xdg/autostart/pamac-tray.desktop rm -f $(sysconfdir)/xdg/autostart/pamac-tray-appindicator.desktop rm -f $(datadir)/applications/pamac-manager.desktop rm -f $(datadir)/applications/pamac-updater.desktop rm -f $(datadir)/applications/pamac-install.desktop rm -f $(sysconfdir)/pamac.conf - rm -f $(sysconfdir)/dbus-1/system.d/org.manjaro.pamac.conf - rm -f $(datadir)/dbus-1/system-services/org.manjaro.pamac.service - rm -f $(libdir)/systemd/system/pamac.service + rm -f $(sysconfdir)/dbus-1/system.d/org.manjaro.pamac.system.conf + rm -f $(datadir)/dbus-1/services/org.manjaro.pamac.user.service + rm -f $(datadir)/dbus-1/system-services/org.manjaro.pamac.system.service + rm -f $(libdir)/systemd/system/pamac-system.service rm -f $(libdir)/systemd/system/pamac-cleancache.service rm -f $(libdir)/systemd/system/pamac-cleancache.timer rm -f $(libdir)/systemd/system/pamac-mirrorlist.service rm -f $(libdir)/systemd/system/pamac-mirrorlist.timer rm -f $(libdir)/systemd/system/multi-user.target.wants/pamac-cleancache.timer - rm -f $(sysconfdir)/NetworkManager/dispatcher.d/99_update_pamac_tray rm -f $(datadir)/polkit-1/actions/org.manjaro.pamac.policy rm -f $(datadir)/mime/packages/x-alpm-package.xml diff --git a/data/dbus/org.manjaro.pamac.service b/data/dbus/org.manjaro.pamac.service deleted file mode 100644 index 1d8b045..0000000 --- a/data/dbus/org.manjaro.pamac.service +++ /dev/null @@ -1,5 +0,0 @@ -[D-BUS Service] -Name=org.manjaro.pamac -Exec=/usr/bin/pamac-daemon -User=root -SystemdService=pamac.service diff --git a/data/dbus/org.manjaro.pamac.conf b/data/dbus/org.manjaro.pamac.system.conf similarity index 57% rename from data/dbus/org.manjaro.pamac.conf rename to data/dbus/org.manjaro.pamac.system.conf index bd374ab..b826875 100644 --- a/data/dbus/org.manjaro.pamac.conf +++ b/data/dbus/org.manjaro.pamac.system.conf @@ -4,19 +4,19 @@ - + - + - - + - diff --git a/data/dbus/org.manjaro.pamac.system.service b/data/dbus/org.manjaro.pamac.system.service new file mode 100644 index 0000000..e1e2929 --- /dev/null +++ b/data/dbus/org.manjaro.pamac.system.service @@ -0,0 +1,5 @@ +[D-BUS Service] +Name=org.manjaro.pamac.system +Exec=/usr/bin/pamac-system-daemon +User=root +SystemdService=pamac-system.service diff --git a/data/dbus/org.manjaro.pamac.user.service b/data/dbus/org.manjaro.pamac.user.service new file mode 100644 index 0000000..29fa0fc --- /dev/null +++ b/data/dbus/org.manjaro.pamac.user.service @@ -0,0 +1,3 @@ +[D-BUS Service] +Name=org.manjaro.pamac.user +Exec=/usr/bin/pamac-user-daemon diff --git a/data/networkmanager/99_update_pamac_tray b/data/networkmanager/99_update_pamac_tray deleted file mode 100755 index 402ccd8..0000000 --- a/data/networkmanager/99_update_pamac_tray +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/sh - -INTERFACE=$1 # The interface which is brought up or down -STATUS=$2 # The new state of the interface - -case "$STATUS" in - 'up') # $INTERFACE is up - [[ -e /usr/bin/mhwd-live ]] && sleep 30 - /usr/bin/pamac-refresh - ;; -esac - diff --git a/data/systemd/pamac-system.service b/data/systemd/pamac-system.service new file mode 100644 index 0000000..c9b1431 --- /dev/null +++ b/data/systemd/pamac-system.service @@ -0,0 +1,7 @@ +[Unit] +Description=Pamac System Session + +[Service] +Type=dbus +BusName=org.manjaro.pamac.system +ExecStart=/usr/bin/pamac-system-daemon diff --git a/data/systemd/pamac.service b/data/systemd/pamac.service deleted file mode 100644 index 536e633..0000000 --- a/data/systemd/pamac.service +++ /dev/null @@ -1,7 +0,0 @@ -[Unit] -Description=Pamac - -[Service] -Type=dbus -BusName=org.manjaro.pamac -ExecStart=/usr/bin/pamac-daemon diff --git a/po/files_to_translate b/po/files_to_translate index f552672..949b67f 100644 --- a/po/files_to_translate +++ b/po/files_to_translate @@ -1,11 +1,10 @@ -../src/daemon.vala +../src/user_daemon.vala +../src/system_daemon.vala ../src/transaction.vala ../src/installer.vala ../src/tray.vala ../src/manager.vala -../src/updater.vala ../src/manager_window.vala -../src/updater_window.vala ../src/preferences_dialog.vala ../src/choose_ignorepkgs_dialog.vala @@ -14,6 +13,5 @@ ../resources/history_dialog.ui ../resources/transaction_sum_dialog.ui ../resources/manager_window.ui -../resources/updater_window.ui ../resources/preferences_dialog.ui ../resources/choose_ignorepkgs_dialog.ui diff --git a/po/pamac.pot b/po/pamac.pot index 92a28a1..554843c 100644 --- a/po/pamac.pot +++ b/po/pamac.pot @@ -21,114 +21,110 @@ msgstr "" msgid "Authentication is required" msgstr "" -#: ../src/daemon.vala -msgid "Failed to initialize alpm library" -msgstr "" - -#: ../src/daemon.vala ../src/transaction.vala -msgid "Authentication failed" -msgstr "" - -#: ../src/daemon.vala -msgid "Failed to synchronize any databases" -msgstr "" - -#: ../src/daemon.vala +#: ../src/user_daemon.vala msgid "Unknown" msgstr "" -#: ../src/daemon.vala +#: ../src/user_daemon.vala ../src/manager_window.vala msgid "Explicitly installed" msgstr "" -#: ../src/daemon.vala ../src/manager_window.vala +#: ../src/user_daemon.vala ../src/manager_window.vala msgid "Installed as a dependency for another package" msgstr "" -#: ../src/daemon.vala +#: ../src/user_daemon.vala msgid "Yes" msgstr "" -#: ../src/daemon.vala +#: ../src/user_daemon.vala msgid "No" msgstr "" -#: ../src/daemon.vala +#: ../src/system_daemon.vala +msgid "Failed to initialize alpm library" +msgstr "" + +#: ../src/system_daemon.vala ../src/transaction.vala +msgid "Authentication failed" +msgstr "" + +#: ../src/system_daemon.vala +msgid "Failed to synchronize any databases" +msgstr "" + +#: ../src/system_daemon.vala msgid "Failed to init transaction" msgstr "" -#: ../src/daemon.vala +#: ../src/system_daemon.vala msgid "Failed to prepare transaction" msgstr "" -#: ../src/daemon.vala +#: ../src/system_daemon.vala #, c-format msgid "target not found: %s" msgstr "" -#: ../src/daemon.vala +#: ../src/system_daemon.vala #, c-format msgid "package %s does not have a valid architecture" msgstr "" -#: ../src/daemon.vala +#: ../src/system_daemon.vala #, c-format -msgid "%s: requires %s" +msgid "unable to satisfy dependency '%s' required by %s" msgstr "" -#: ../src/daemon.vala +#: ../src/system_daemon.vala #, c-format -msgid "%s: installing %s (%s) breaks dependency '%s'" +msgid "installing %s (%s) breaks dependency '%s' required by %s" msgstr "" -#: ../src/daemon.vala +#: ../src/system_daemon.vala #, c-format -msgid "%s: removing %s breaks dependency '%s'" +msgid "removing %s breaks dependency '%s' required by %s" msgstr "" -#: ../src/daemon.vala +#: ../src/system_daemon.vala #, c-format msgid "%s and %s are in conflict" msgstr "" -#: ../src/daemon.vala +#: ../src/system_daemon.vala #, c-format msgid "%s needs to be removed but it is a locked package" msgstr "" -#: ../src/daemon.vala +#: ../src/system_daemon.vala msgid "Failed to commit transaction" msgstr "" -#: ../src/daemon.vala +#: ../src/system_daemon.vala #, c-format msgid "%s exists in both %s and %s" msgstr "" -#: ../src/daemon.vala +#: ../src/system_daemon.vala #, c-format msgid "%s: %s already exists in filesystem" msgstr "" -#: ../src/daemon.vala +#: ../src/system_daemon.vala #, c-format msgid "%s is invalid or corrupted" msgstr "" -#: ../src/daemon.vala +#: ../src/system_daemon.vala #, c-format msgid "%s appears to be truncated: %jd/%jd bytes\n" msgstr "" -#: ../src/daemon.vala +#: ../src/system_daemon.vala #, c-format msgid "failed retrieving file '%s' from %s : %s\n" msgstr "" -#: ../src/transaction.vala -msgid "A Gtk3 frontend for libalpm" -msgstr "" - #: ../src/transaction.vala msgid "Copy" msgstr "" @@ -174,11 +170,7 @@ msgstr "" msgid "To reinstall" msgstr "" -#: ../src/transaction.vala -msgid "To update" -msgstr "" - -#: ../src/transaction.vala ../src/updater_window.vala +#: ../src/transaction.vala ../src/manager_window.vala msgid "Total download size" msgstr "" @@ -191,10 +183,6 @@ msgstr "" msgid "Transaction cancelled" msgstr "" -#: ../src/transaction.vala -msgid "Waiting for another package manager to quit" -msgstr "" - #: ../src/transaction.vala msgid "Checking dependencies" msgstr "" @@ -345,6 +333,7 @@ msgid "Warning" msgstr "" #: ../src/transaction.vala ../resources/progress_dialog.ui +#: ../resources/history_dialog.ui msgid "_Close" msgstr "" @@ -356,18 +345,14 @@ msgstr "" msgid "Transaction successfully finished" msgstr "" -#: ../src/installer.vala ../src/manager.vala ../src/updater.vala +#: ../src/installer.vala ../src/manager.vala msgid "Pamac is already running" msgstr "" -#: ../src/tray.vala ../src/updater_window.vala +#: ../src/tray.vala ../src/manager_window.vala msgid "Your system is up-to-date" msgstr "" -#: ../src/tray.vala ../src/updater_window.vala -msgid "Update Manager" -msgstr "" - #: ../src/tray.vala ../src/manager_window.vala msgid "Package Manager" msgstr "" @@ -376,7 +361,7 @@ msgstr "" msgid "_Quit" msgstr "" -#: ../src/tray.vala ../src/updater_window.vala +#: ../src/tray.vala #, c-format msgid "%u available update" msgid_plural "%u available updates" @@ -384,7 +369,7 @@ msgstr[0] "" msgstr[1] "" #: ../src/tray.vala ../src/manager_window.vala ../resources/progress_dialog.ui -#: ../resources/manager_window.ui ../resources/updater_window.ui +#: ../resources/manager_window.ui msgid "Details" msgstr "" @@ -392,6 +377,10 @@ msgstr "" msgid "Deselect" msgstr "" +#: ../src/manager_window.vala +msgid "Upgrade" +msgstr "" + #: ../src/manager_window.vala ../resources/manager_window.ui msgid "Install" msgstr "" @@ -400,6 +389,10 @@ msgstr "" msgid "Remove" msgstr "" +#: ../src/manager_window.vala +msgid "Waiting for another package manager to quit" +msgstr "" + #: ../src/manager_window.vala #, c-format msgid "%u pending operation" @@ -436,7 +429,6 @@ msgid "Licenses" msgstr "" #: ../src/manager_window.vala ../resources/manager_window.ui -#: ../resources/updater_window.ui msgid "Repository" msgstr "" @@ -525,7 +517,6 @@ msgid "Check Dependencies" msgstr "" #: ../src/manager_window.vala ../resources/manager_window.ui -#: ../resources/updater_window.ui msgid "Name" msgstr "" @@ -534,8 +525,7 @@ msgid "Install Local Packages" msgstr "" #: ../src/manager_window.vala ../resources/transaction_sum_dialog.ui -#: ../resources/manager_window.ui ../resources/updater_window.ui -#: ../resources/choose_ignorepkgs_dialog.ui +#: ../resources/manager_window.ui ../resources/choose_ignorepkgs_dialog.ui msgid "_Cancel" msgstr "" @@ -547,6 +537,10 @@ msgstr "" msgid "Alpm Package" msgstr "" +#: ../src/manager_window.vala +msgid "A Gtk3 frontend for libalpm" +msgstr "" + #: ../src/preferences_dialog.vala ../resources/preferences_dialog.ui msgid "How often to check for updates, value in hours" msgstr "" @@ -592,19 +586,19 @@ msgstr "" msgid "Commit" msgstr "" -#: ../resources/manager_window.ui ../resources/updater_window.ui +#: ../resources/manager_window.ui msgid "Refresh databases" msgstr "" -#: ../resources/manager_window.ui ../resources/updater_window.ui +#: ../resources/manager_window.ui msgid "View History" msgstr "" -#: ../resources/manager_window.ui ../resources/updater_window.ui +#: ../resources/manager_window.ui msgid "Preferences" msgstr "" -#: ../resources/manager_window.ui ../resources/updater_window.ui +#: ../resources/manager_window.ui msgid "About" msgstr "" @@ -612,19 +606,23 @@ msgstr "" msgid "Search" msgstr "" -#: ../resources/manager_window.ui ../resources/updater_window.ui +#: ../resources/manager_window.ui msgid "State" msgstr "" -#: ../resources/manager_window.ui ../resources/updater_window.ui +#: ../resources/manager_window.ui msgid "Repositories" msgstr "" -#: ../resources/manager_window.ui ../resources/updater_window.ui +#: ../resources/manager_window.ui +msgid "Updates" +msgstr "" + +#: ../resources/manager_window.ui msgid "Version" msgstr "" -#: ../resources/manager_window.ui ../resources/updater_window.ui +#: ../resources/manager_window.ui msgid "Size" msgstr "" @@ -632,8 +630,7 @@ msgstr "" msgid "Popularity" msgstr "" -#: ../resources/manager_window.ui ../resources/updater_window.ui -#: ../resources/preferences_dialog.ui +#: ../resources/manager_window.ui ../resources/preferences_dialog.ui msgid "AUR" msgstr "" @@ -653,7 +650,7 @@ msgstr "" msgid "Files" msgstr "" -#: ../resources/manager_window.ui ../resources/updater_window.ui +#: ../resources/manager_window.ui msgid "_Apply" msgstr "" diff --git a/resources/Makefile b/resources/Makefile index b162ec8..9e1f28d 100644 --- a/resources/Makefile +++ b/resources/Makefile @@ -9,8 +9,6 @@ MANAGER_RESOURCES_FILES = manager_window.ui \ package-reinstall.png \ package-remove.png -UPDATER_RESOURCES_FILES = updater_window.ui - INSTALLER_RESOURCES_FILES = progress_dialog.ui TRANSACTION_RESOURCES_FILES = progress_box.ui \ @@ -23,11 +21,9 @@ TRANSACTION_GRESOURCE_FILE = pamac.transaction.gresource.xml MANAGER_GRESOURCE_FILE = pamac.manager.gresource.xml -UPDATER_GRESOURCE_FILE = pamac.updater.gresource.xml - INSTALLER_GRESOURCE_FILE = pamac.installer.gresource.xml -resources: transaction_resources.c manager_resources.c updater_resources.c installer_resources.c +resources: transaction_resources.c manager_resources.c installer_resources.c clean: rm -f *.c @@ -38,8 +34,5 @@ transaction_resources.c: $(TRANSACTION_GRESOURCE_FILE) $(TRANSACTION_RESOURCES_F manager_resources.c: $(MANAGER_GRESOURCE_FILE) $(MANAGER_RESOURCES_FILES) glib-compile-resources $(MANAGER_GRESOURCE_FILE) --target=manager_resources.c --generate-source -updater_resources.c: $(UPDATER_GRESOURCE_FILE) $(UPDATER_RESOURCES_FILES) - glib-compile-resources $(UPDATER_GRESOURCE_FILE) --target=updater_resources.c --generate-source - installer_resources.c: $(INSTALLER_GRESOURCE_FILE) $(INSTALLER_RESOURCES_FILES) glib-compile-resources $(INSTALLER_GRESOURCE_FILE) --target=installer_resources.c --generate-source diff --git a/resources/manager_window.ui b/resources/manager_window.ui index 5cde00f..a3f294a 100644 --- a/resources/manager_window.ui +++ b/resources/manager_window.ui @@ -294,6 +294,21 @@ 3 + + + True + False + vertical + + + + + + updates + Updates + 4 + + False @@ -311,6 +326,7 @@ True False + center packages_stack @@ -394,7 +410,7 @@ - 3 + 3 @@ -512,7 +528,7 @@ - 3 + 3 @@ -543,6 +559,44 @@ 1 + + + True + False + vertical + True + + + True + False + end + object-select-symbolic + 6 + + + False + True + 0 + + + + + True + False + start + + + False + True + 1 + + + + + updated + 2 + + True diff --git a/resources/package-upgrade.png b/resources/package-upgrade.png new file mode 100644 index 0000000000000000000000000000000000000000..bef932bd6840a7946aa9a86494f161469e100eb8 GIT binary patch literal 501 zcmVmV?Q?u1A!y9gt(T3sVeXU@!QT^Q)PTj9BzGynPK{QnrI*GIcb`US%@bC{vN zeE){cnI}weRou*MXPt$WS?19nc)4<=RAgEqE39YqhPN{TY%30}kY${6dWdEm9f zoqhDFiJoYV0YZY2&;bh`HQ=EE!GpOxb*@4gkkBIw6cM7}!Cay=KNi9v0;7Z{D@sE` zfk{%4-#EQNlt$7Yfa8O`!1>X={0*QZ*Q+-#LcK6RgK1yay|-a manager_window.ui + history_dialog.ui package-available.png package-available-locked.png package-install.png @@ -9,5 +10,6 @@ package-installed-updated.png package-reinstall.png package-remove.png + package-upgrade.png diff --git a/resources/pamac.transaction.gresource.xml b/resources/pamac.transaction.gresource.xml index 3a0a65f..90c24d1 100644 --- a/resources/pamac.transaction.gresource.xml +++ b/resources/pamac.transaction.gresource.xml @@ -3,7 +3,6 @@ progress_dialog.ui progress_box.ui - history_dialog.ui choose_provider_dialog.ui transaction_sum_dialog.ui diff --git a/resources/pamac.updater.gresource.xml b/resources/pamac.updater.gresource.xml deleted file mode 100644 index 397f598..0000000 --- a/resources/pamac.updater.gresource.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - updater_window.ui - - diff --git a/resources/updater_window.ui b/resources/updater_window.ui deleted file mode 100644 index f8a1d17..0000000 --- a/resources/updater_window.ui +++ /dev/null @@ -1,455 +0,0 @@ - - - - - - False - - - True - False - 6 - vertical - 6 - - - True - True - True - Refresh databases - - - - False - True - 0 - - - - - True - True - True - View History - - - - False - True - 1 - - - - - True - True - True - Preferences - - - - False - True - 3 - - - - - True - True - True - About - - - - False - True - 4 - - - - - main - 1 - - - - - diff --git a/src/Makefile b/src/Makefile index 726e605..4603838 100644 --- a/src/Makefile +++ b/src/Makefile @@ -21,11 +21,10 @@ PAMAC_LIB_FLAGS = -X -I. \ --pkg=pamac \ COMMON_SOURCES = common.vala \ + package.vala \ pamac_config.vala -TRANSACTION_SOURCES = package.vala \ - transaction.vala \ - history_dialog.vala \ +TRANSACTION_SOURCES = transaction.vala \ choose_provider_dialog.vala \ transaction_sum_dialog.vala \ progress_box.vala @@ -38,22 +37,12 @@ TRANSACTION_GRESOURCE_FILE = ../resources/pamac.transaction.gresource.xml MANAGER_GRESOURCE_FILE = ../resources/pamac.manager.gresource.xml -UPDATER_GRESOURCE_FILE = ../resources/pamac.updater.gresource.xml - INSTALLER_GRESOURCE_FILE = ../resources/pamac.installer.gresource.xml -binaries: pamac-refresh pamac-daemon pamac-tray pamac-updater pamac-manager pamac-install +binaries: pamac-user-daemon pamac-system-daemon pamac-tray pamac-manager pamac-install clean: - rm -f *.c pamac.h pamac.vapi libpamac.so pamac-refresh pamac-daemon pamac-tray pamac-tray-appindicator pamac-updater pamac-manager pamac-install - -pamac-refresh: pamac_config.vala refresh.vala - valac -o pamac-refresh \ - -X -w \ - --pkg=gio-2.0 \ - --pkg=posix \ - pamac_config.vala \ - refresh.vala + rm -f *.c pamac.h pamac.vapi libpamac.so pamac-user-daemon pamac-system-daemon pamac-tray pamac-tray-appindicator pamac-manager pamac-install pamac-tray: $(COMMON_SOURCES) alpm_config.vala tray.vala tray-gtk.vala valac -o pamac-tray \ @@ -74,8 +63,21 @@ pamac-tray-appindicator: $(COMMON_SOURCES) alpm_config.vala tray.vala tray-appin tray-appindicator.vala \ tray.vala -pamac-daemon: ../vapi/libalpm.vapi ../vapi/polkit-gobject-1.vapi ../vapi/libcurl.vapi alpm_config.vala $(COMMON_SOURCES) package.vala aur.vala mirrors_config.vala daemon.vala - valac -o pamac-daemon \ +pamac-user-daemon: ../vapi/libalpm.vapi alpm_config.vala common.vala package.vala aur.vala user_daemon.vala + valac -o pamac-user-daemon \ + $(COMMON_VALA_FLAGS) \ + $(ALPM_VALA_FLAGS) \ + --pkg=json-glib-1.0 \ + --pkg=libsoup-2.4 \ + --thread \ + alpm_config.vala \ + common.vala \ + package.vala \ + aur.vala \ + user_daemon.vala + +pamac-system-daemon: ../vapi/libalpm.vapi ../vapi/polkit-gobject-1.vapi ../vapi/libcurl.vapi alpm_config.vala $(COMMON_SOURCES) aur.vala mirrors_config.vala system_daemon.vala + valac -o pamac-system-daemon \ $(COMMON_VALA_FLAGS) \ $(ALPM_VALA_FLAGS) \ --pkg=polkit-gobject-1 \ @@ -85,10 +87,9 @@ pamac-daemon: ../vapi/libalpm.vapi ../vapi/polkit-gobject-1.vapi ../vapi/libcurl --thread \ alpm_config.vala \ $(COMMON_SOURCES) \ - package.vala \ aur.vala \ mirrors_config.vala \ - daemon.vala + system_daemon.vala libpamac.so: $(COMMON_SOURCES) $(TRANSACTION_SOURCES) $(PREFERENCES_SOURCES) ../resources/transaction_resources.c valac -o libpamac.so \ @@ -105,7 +106,7 @@ libpamac.so: $(COMMON_SOURCES) $(TRANSACTION_SOURCES) $(PREFERENCES_SOURCES) ../ $(TRANSACTION_SOURCES) \ $(PREFERENCES_SOURCES) -pamac-manager: libpamac.so ../resources/manager_resources.c manager_window.vala manager.vala +pamac-manager: libpamac.so ../resources/manager_resources.c history_dialog.vala manager_window.vala manager.vala valac -o pamac-manager \ $(COMMON_VALA_FLAGS) \ $(PAMAC_LIB_FLAGS) \ @@ -113,20 +114,10 @@ pamac-manager: libpamac.so ../resources/manager_resources.c manager_window.vala --pkg=gdk-3.0 \ --gresources=$(MANAGER_GRESOURCE_FILE) \ ../resources/manager_resources.c \ + history_dialog.vala \ manager_window.vala \ manager.vala -pamac-updater: libpamac.so ../resources/updater_resources.c updater_window.vala updater.vala - valac -o pamac-updater \ - $(COMMON_VALA_FLAGS) \ - $(PAMAC_LIB_FLAGS) \ - --pkg=gtk+-3.0 \ - --pkg=gdk-3.0 \ - --gresources=$(UPDATER_GRESOURCE_FILE) \ - ../resources/updater_resources.c \ - updater_window.vala \ - updater.vala - pamac-install: libpamac.so ../resources/installer_resources.c progress_dialog.vala installer.vala valac -o pamac-install \ $(COMMON_VALA_FLAGS) \ diff --git a/src/alpm_config.vala b/src/alpm_config.vala index f236d33..96e11db 100644 --- a/src/alpm_config.vala +++ b/src/alpm_config.vala @@ -51,7 +51,7 @@ class AlpmConfig { string? arch; double deltaratio; int usesyslog; - int checkspace; + public int checkspace; GLib.List cachedirs; GLib.List hookdirs; GLib.List ignoregroups; @@ -134,9 +134,22 @@ class AlpmConfig { } } - public Alpm.Handle? get_handle (bool files_db = false) { - Alpm.Errno error; - Alpm.Handle? handle = new Alpm.Handle (rootdir, dbpath, out error); + public Alpm.Handle? get_handle (bool files_db = false, bool tmp_db = false) { + Alpm.Errno error = 0; + Alpm.Handle? handle = null; + if (tmp_db) { + string tmp_dbpath = "/tmp/pamac-checkdbs-%s".printf (Environment.get_user_name ()); + try { + Process.spawn_command_line_sync ("mkdir -p %s".printf (tmp_dbpath)); + Process.spawn_command_line_sync ("ln -sf %s/local %s".printf (dbpath, tmp_dbpath)); + Process.spawn_command_line_sync ("cp -au %s/sync %s".printf (dbpath, tmp_dbpath)); + handle = new Alpm.Handle (rootdir, tmp_dbpath, out error); + } catch (SpawnError e) { + stderr.printf ("SpawnError: %s\n", e.message); + } + } else { + handle = new Alpm.Handle (rootdir, dbpath, out error); + } if (error == Alpm.Errno.DB_VERSION) { try { Process.spawn_command_line_sync ("pacman-db-upgrade", null, null, null); @@ -153,7 +166,9 @@ class AlpmConfig { if (files_db) { handle.dbext = ".files"; } - handle.logfile = logfile; + if (!tmp_db) { + handle.logfile = logfile; + } handle.gpgdir = gpgdir; handle.arch = arch; handle.deltaratio = deltaratio; diff --git a/src/common.vala b/src/common.vala index dbdb99c..514d40d 100644 --- a/src/common.vala +++ b/src/common.vala @@ -39,8 +39,8 @@ namespace Pamac { public struct Updates { public bool is_syncfirst; - public UpdateInfos[] repos_updates; - public UpdateInfos[] aur_updates; + public AlpmPackage[] repos_updates; + public AURPackage[] aur_updates; } public struct ErrorInfos { diff --git a/src/history_dialog.vala b/src/history_dialog.vala index 3d2a0f3..c7aafb2 100644 --- a/src/history_dialog.vala +++ b/src/history_dialog.vala @@ -19,7 +19,7 @@ namespace Pamac { - [GtkTemplate (ui = "/org/manjaro/pamac/transaction/history_dialog.ui")] + [GtkTemplate (ui = "/org/manjaro/pamac/manager/history_dialog.ui")] class HistoryDialog : Gtk.Dialog { [GtkChild] diff --git a/src/installer.vala b/src/installer.vala index c565ca6..4b51a8f 100644 --- a/src/installer.vala +++ b/src/installer.vala @@ -26,7 +26,7 @@ namespace Pamac { bool important_details; public Installer () { - application_id = "org.manjaro.pamac.install"; + application_id = "org.manjaro.pamac.installer"; flags |= ApplicationFlags.HANDLES_OPEN; } @@ -90,16 +90,6 @@ namespace Pamac { stderr.printf ("%s\n", e.message); } run = app.get_is_remote (); - if (run) { - return run; - } - app = new Application ("org.manjaro.pamac.updater", 0); - try { - app.register (); - } catch (GLib.Error e) { - stderr.printf ("%s\n", e.message); - } - run = app.get_is_remote (); return run; } diff --git a/src/manager.vala b/src/manager.vala index e59fa9f..72878dc 100644 --- a/src/manager.vala +++ b/src/manager.vala @@ -22,10 +22,11 @@ namespace Pamac { class Manager : Gtk.Application { ManagerWindow manager_window; bool pamac_run; + bool started; public Manager () { application_id = "org.manjaro.pamac.manager"; - flags = ApplicationFlags.FLAGS_NONE; + flags = ApplicationFlags.HANDLES_COMMAND_LINE; } public override void startup () { @@ -67,13 +68,22 @@ namespace Pamac { } } - public override void activate () { + public override int command_line (ApplicationCommandLine cmd) { + if (cmd.get_arguments ()[0] == "pamac-updater") { + manager_window.display_package_queue.clear (); + manager_window.main_stack.visible_child_name = "browse"; + manager_window.filters_stack.visible_child_name = "updates"; + } else if (!started) { + manager_window.show_default_pkgs (); + started = true; + } if (!pamac_run) { manager_window.present (); while (Gtk.events_pending ()) { Gtk.main_iteration (); } } + return 0; } public override void shutdown () { @@ -86,17 +96,7 @@ namespace Pamac { bool check_pamac_running () { Application app; bool run = false; - app = new Application ("org.manjaro.pamac.updater", 0); - try { - app.register (); - } catch (GLib.Error e) { - stderr.printf ("%s\n", e.message); - } - run = app.get_is_remote (); - if (run) { - return run; - } - app = new Application ("org.manjaro.pamac.install", 0); + app = new Application ("org.manjaro.pamac.installer", 0); try { app.register (); } catch (GLib.Error e) { diff --git a/src/manager_window.vala b/src/manager_window.vala index 31da6d7..b0b18c0 100644 --- a/src/manager_window.vala +++ b/src/manager_window.vala @@ -17,6 +17,8 @@ * along with this program. If not, see . */ +const string VERSION = "4.9.0"; + namespace Pamac { class ActivableCellRendererPixbuf : Gtk.CellRendererPixbuf { @@ -42,12 +44,13 @@ namespace Pamac { Gdk.Pixbuf? to_install_icon; Gdk.Pixbuf? to_reinstall_icon; Gdk.Pixbuf? to_remove_icon; + Gdk.Pixbuf? to_upgrade_icon; Gdk.Pixbuf? installed_locked_icon; Gdk.Pixbuf? available_locked_icon; // manager objects [GtkChild] - Gtk.Stack main_stack; + public Gtk.Stack main_stack; [GtkChild] Gtk.Button button_back; [GtkChild] @@ -79,6 +82,8 @@ namespace Pamac { [GtkChild] Gtk.StackSwitcher packages_stackswitcher; [GtkChild] + Gtk.Label updated_label; + [GtkChild] Gtk.Stack properties_stack; [GtkChild] Gtk.StackSwitcher properties_stackswitcher; @@ -116,6 +121,7 @@ namespace Pamac { // menu Gtk.Menu right_click_menu; Gtk.MenuItem deselect_item; + Gtk.MenuItem upgrade_item; Gtk.MenuItem install_item; Gtk.MenuItem remove_item; Gtk.MenuItem details_item; @@ -130,15 +136,19 @@ namespace Pamac { Gtk.ListStore packages_list; Gtk.ListStore aur_list; - Queue display_package_queue; + public Queue display_package_queue; string current_package_displayed; public Transaction transaction; + delegate void TransactionAction (); bool refreshing; bool important_details; bool transaction_running; + bool sysupgrade_running; bool generate_mirrors_list; + bool waiting; + bool force_refresh; uint search_entry_timeout_id; @@ -151,13 +161,11 @@ namespace Pamac { refreshing = false; important_details = false; transaction_running = false; + sysupgrade_running = false; generate_mirrors_list = false; this.title = dgettext (null, "Package Manager"); - Timeout.add (100, populate_window); - } - - bool populate_window () { + updated_label.set_markup ("%s".printf (dgettext (null, "Your system is up-to-date"))); this.get_window ().set_cursor (new Gdk.Cursor.for_display (Gdk.Display.get_default (), Gdk.CursorType.WATCH)); while (Gtk.events_pending ()) { Gtk.main_iteration (); @@ -166,6 +174,9 @@ namespace Pamac { deselect_item = new Gtk.MenuItem.with_label (dgettext (null, "Deselect")); deselect_item.activate.connect (on_deselect_item_activate); right_click_menu.append (deselect_item); + upgrade_item = new Gtk.MenuItem.with_label (dgettext (null, "Upgrade")); + upgrade_item.activate.connect (on_upgrade_item_activate); + right_click_menu.append (upgrade_item); install_item = new Gtk.MenuItem.with_label (dgettext (null, "Install")); install_item.activate.connect (on_install_item_activate); right_click_menu.append (install_item); @@ -205,7 +216,7 @@ namespace Pamac { uint origin; string pkgname; treemodel.get (treeiter, 0, out origin, 1, out pkgname); - if (origin == 2 ) { //origin == Alpm.Package.From.LOCALDB) + if (origin == 2) { //origin == Alpm.Package.From.LOCALDB if (unlikely (transaction.transaction_summary.contains (pkgname))) { pixbuf = installed_locked_icon; } else if (unlikely (transaction.should_hold (pkgname))) { @@ -221,6 +232,8 @@ namespace Pamac { pixbuf = available_locked_icon; } else if (unlikely (transaction.to_install.contains (pkgname))) { pixbuf = to_install_icon; + } else if (unlikely (transaction.to_update.contains (pkgname))) { + pixbuf = to_upgrade_icon; } else { pixbuf = uninstalled_icon; } @@ -246,7 +259,13 @@ namespace Pamac { uint origin; string pkgname; treemodel.get (treeiter, 0, out origin, 1, out pkgname); - if ((uint) origin == 2 ) { //origin == Alpm.Package.From.LOCALDB) + if (filters_stack.visible_child_name == "updates") { + if (unlikely (transaction.temporary_ignorepkgs.contains (pkgname))) { + pixbuf = uninstalled_icon; + } else { + pixbuf = to_upgrade_icon; + } + } else if ((uint) origin == 2) { //origin == Alpm.Package.From.LOCALDB if (unlikely (transaction.transaction_summary.contains (pkgname))) { pixbuf = installed_locked_icon; } else if (unlikely (transaction.should_hold (pkgname))) { @@ -273,6 +292,7 @@ namespace Pamac { to_install_icon = new Gdk.Pixbuf.from_resource ("/org/manjaro/pamac/manager/package-install.png"); to_reinstall_icon = new Gdk.Pixbuf.from_resource ("/org/manjaro/pamac/manager/package-reinstall.png"); to_remove_icon = new Gdk.Pixbuf.from_resource ("/org/manjaro/pamac/manager/package-remove.png"); + to_upgrade_icon = new Gdk.Pixbuf.from_resource ("/org/manjaro/pamac/manager/package-upgrade.png"); installed_locked_icon = new Gdk.Pixbuf.from_resource ("/org/manjaro/pamac/manager/package-installed-locked.png"); available_locked_icon = new Gdk.Pixbuf.from_resource ("/org/manjaro/pamac/manager/package-available-locked.png"); } catch (GLib.Error e) { @@ -280,9 +300,6 @@ namespace Pamac { } transaction = new Transaction (this as Gtk.ApplicationWindow); - transaction.mode = Mode.MANAGER; - transaction.start_waiting.connect (on_start_waiting); - transaction.stop_waiting.connect (on_stop_waiting); transaction.start_downloading.connect (on_start_downloading); transaction.stop_downloading.connect (on_stop_downloading); transaction.start_building.connect (on_start_building); @@ -292,6 +309,8 @@ namespace Pamac { transaction.write_pamac_config_finished.connect (on_write_pamac_config_finished); transaction.set_pkgreason_finished.connect (on_set_pkgreason_finished); transaction.generate_mirrors_list.connect (on_generate_mirrors_list); + transaction.run_preferences_dialog_finished.connect (on_run_preferences_dialog_finished); + transaction.get_updates_finished.connect (on_get_updates_finished); // integrate progress box and term widget main_stack.add_named (transaction.term_window, "term"); @@ -301,15 +320,16 @@ namespace Pamac { display_package_queue = new Queue (); - update_lists (); - show_default_pkgs (); - search_entry.grab_focus (); - main_stack.notify["visible-child"].connect (on_main_stack_visible_child_changed); filters_stack.notify["visible-child"].connect (on_filters_stack_visible_child_changed); packages_stack.notify["visible-child"].connect (on_packages_stack_visible_child_changed); properties_stack.notify["visible-child"].connect (on_properties_stack_visible_child_changed); + Timeout.add (100, populate_window); + } + + bool populate_window () { + update_lists (); return false; } @@ -319,6 +339,8 @@ namespace Pamac { } void on_set_pkgreason_finished () { + transaction.unlock (); + transaction.refresh_handle (); refresh_packages_list (); if (main_stack.visible_child_name == "details") { if (transaction.get_installed_pkg (current_package_displayed).name != "" @@ -328,7 +350,7 @@ namespace Pamac { display_aur_properties (current_package_displayed); } } - } + } void support_aur (bool enable_aur) { if (enable_aur) { @@ -340,28 +362,76 @@ namespace Pamac { } } - void set_pendings_operations () { - if (!transaction_running && !generate_mirrors_list) { - uint total_pending = transaction.to_install.length + transaction.to_remove.length + transaction.to_build.length; - if (total_pending == 0) { - transaction.progress_box.action_label.label = ""; - cancel_button.sensitive = false; - apply_button.sensitive = false; - if (important_details) { - transaction_infobox.show_all (); + void try_lock_and_run (TransactionAction action) { + if (transaction.get_lock ()) { + action (); + } else { + waiting = true; + transaction.progress_box.action_label.label = dgettext (null, "Waiting for another package manager to quit") + "..."; + transaction.start_progressbar_pulse (); + cancel_button.sensitive = true; + transaction_infobox.show_all (); + Timeout.add (5000, () => { + bool locked = transaction.get_lock (); + if (locked) { + waiting = false; + transaction.stop_progressbar_pulse (); + action (); } - } else { - string info = dngettext (null, "%u pending operation", "%u pending operations", total_pending).printf (total_pending); - transaction.progress_box.action_label.label = info; - cancel_button.sensitive = true; - apply_button.sensitive = true; + return !locked; + }); + } + } + + void set_pendings_operations () { + if (!transaction_running && !generate_mirrors_list && !refreshing && !sysupgrade_running) { + if (filters_stack.visible_child_name == "updates") { + uint64 total_dsize = 0; + packages_list.foreach ((model, path, iter) => { + string name; + uint64 dsize; + packages_list.get (iter, 1, out name, 5, out dsize); + if (transaction.to_update.contains (name)) { + total_dsize += dsize; + } + return false; + }); + if (total_dsize > 0) { + transaction.progress_box.action_label.set_markup("%s: %s".printf (dgettext (null, "Total download size"), format_size (total_dsize))); + } else { + transaction.progress_box.action_label.label = ""; + } + if (!transaction_running && !generate_mirrors_list && !refreshing && !sysupgrade_running + && (transaction.to_update.length > 0)) { + apply_button.sensitive = true; + } else { + apply_button.sensitive = false; + } + cancel_button.sensitive = false; // fix an possible visibility issue transaction_infobox.show_all (); + } else { + uint total_pending = transaction.to_install.length + transaction.to_remove.length + transaction.to_build.length; + if (total_pending == 0) { + transaction.progress_box.action_label.label = ""; + cancel_button.sensitive = false; + apply_button.sensitive = false; + if (important_details) { + transaction_infobox.show_all (); + } + } else { + string info = dngettext (null, "%u pending operation", "%u pending operations", total_pending).printf (total_pending); + transaction.progress_box.action_label.label = info; + cancel_button.sensitive = true; + apply_button.sensitive = true; + // fix an possible visibility issue + transaction_infobox.show_all (); + } } } } - void show_default_pkgs () { + public void show_default_pkgs () { this.get_window ().set_cursor (new Gdk.Cursor.for_display (Gdk.Display.get_default (), Gdk.CursorType.WATCH)); transaction.get_installed_pkgs.begin ((obj, res) => { populate_packages_list (transaction.get_installed_pkgs.end (res)); @@ -402,7 +472,9 @@ namespace Pamac { } void on_mark_explicit_button_clicked (Gtk.Button button) { - transaction.start_set_pkgreason (current_package_displayed, 0); //Alpm.Package.Reason.EXPLICIT + if (transaction.get_lock ()) { + transaction.start_set_pkgreason (current_package_displayed, 0); //Alpm.Package.Reason.EXPLICIT + } } Gtk.Widget populate_details_grid (string detail_type, string detail, Gtk.Widget? previous_widget) { @@ -411,6 +483,7 @@ namespace Pamac { label.halign = Gtk.Align.START; details_grid.attach_next_to (label, previous_widget, Gtk.PositionType.BOTTOM); if (!transaction_running + && !sysupgrade_running && detail_type == dgettext (null, "Install Reason") && detail == dgettext (null, "Installed as a dependency for another package")) { var box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 12); @@ -816,14 +889,26 @@ namespace Pamac { packages_treeview.freeze_child_notify (); packages_list.clear (); foreach (unowned AlpmPackage pkg in pkgs) { + string version; + uint64 size; + string size_str; + if (filters_stack.visible_child_name == "updates") { + version = "%s\n(%s)".printf (pkg.version, pkg.installed_version); + size = pkg.download_size; + size_str = pkg.download_size == 0 ? "" : GLib.format_size (pkg.download_size); + } else { + version = pkg.version; + size = pkg.size; + size_str = GLib.format_size (pkg.size); + } packages_list.insert_with_values (null, -1, 0, pkg.origin, 1, pkg.name, 2, "%s\n%s".printf (pkg.name, Markup.escape_text (pkg.desc)), - 3, pkg.version, + 3, version, 4, pkg.repo, - 5, pkg.size, - 6, GLib.format_size (pkg.size)); + 5, size, + 6, size_str); } packages_treeview.thaw_child_notify (); packages_treeview.thaw_notify (); @@ -836,24 +921,21 @@ namespace Pamac { aur_treeview.freeze_child_notify (); aur_list.clear (); foreach (unowned AURPackage aur_pkg in pkgs) { - AlpmPackage alpm_pkg = transaction.get_installed_pkg (aur_pkg.name); - if (alpm_pkg.name != "") { - aur_list.insert_with_values (null, -1, - 0, alpm_pkg.origin, - 1, alpm_pkg.name, - 2, "%s\n%s".printf (alpm_pkg.name, Markup.escape_text (alpm_pkg.desc)), - 3, alpm_pkg.version, - 4, aur_pkg.popularity, - 5, "%.2f".printf (aur_pkg.popularity)); + string version; + if (filters_stack.visible_child_name == "updates") { + version = "%s\n(%s)".printf (aur_pkg.version, aur_pkg.installed_version); + } else if (aur_pkg.installed_version == "") { + version = aur_pkg.version; } else { - aur_list.insert_with_values (null, -1, - 0, 0, - 1, aur_pkg.name, - 2, "%s\n%s".printf (aur_pkg.name, Markup.escape_text (aur_pkg.desc)), - 3, aur_pkg.version, - 4, aur_pkg.popularity, - 5, "%.2f".printf (aur_pkg.popularity)); + version = aur_pkg.installed_version; } + aur_list.insert_with_values (null, -1, + 0, aur_pkg.installed_version == "" ? 0 : 2, //Alpm.Package.From.LOCALDB + 1, aur_pkg.name, + 2, "%s\n%s".printf (aur_pkg.name, Markup.escape_text (aur_pkg.desc)), + 3, version, + 4, aur_pkg.popularity, + 5, "%.2f".printf (aur_pkg.popularity)); } aur_treeview.thaw_child_notify (); aur_treeview.thaw_notify (); @@ -863,7 +945,13 @@ namespace Pamac { void refresh_packages_list () { switch (filters_stack.visible_child_name) { case "search": + aur_list.clear (); + filters_stack.visible = true; + set_pendings_operations (); packages_stackswitcher.visible = transaction.enable_aur; + if (packages_stack.visible_child_name == "updated") { + packages_stack.visible_child_name = "repos"; + } Gtk.TreeSelection selection = search_treeview.get_selection (); if (selection.get_selected (null, null)) { on_search_treeview_selection_changed (); @@ -873,20 +961,41 @@ namespace Pamac { } break; case "groups": + filters_stack.visible = true; + set_pendings_operations (); packages_stack.visible_child_name = "repos"; packages_stackswitcher.visible = false; on_groups_treeview_selection_changed (); break; case "states": + filters_stack.visible = true; + set_pendings_operations (); packages_stack.visible_child_name = "repos"; packages_stackswitcher.visible = false; on_states_treeview_selection_changed (); break; case "repos": + filters_stack.visible = true; + set_pendings_operations (); packages_stack.visible_child_name = "repos"; packages_stackswitcher.visible = false; on_repos_treeview_selection_changed (); break; + case "updates": + packages_list.clear (); + aur_list.clear (); + var attention_val = GLib.Value (typeof (bool)); + attention_val.set_boolean (false); + filters_stack.child_set_property (filters_stack.get_child_by_name ("updates"), + "needs-attention", + attention_val); + filters_stack.visible = false; + packages_stack.visible_child_name = "repos"; + packages_stackswitcher.visible = false; + apply_button.visible = false; + this.get_window ().set_cursor (new Gdk.Cursor.for_display (Gdk.Display.get_default (), Gdk.CursorType.WATCH)); + transaction.start_get_updates (); + break; default: break; } @@ -1005,6 +1114,10 @@ namespace Pamac { if (!transaction.should_hold (pkgname)) { transaction.to_remove.add (pkgname); } + } else if (transaction.to_update.remove (pkgname)) { + transaction.temporary_ignorepkgs.add (pkgname); + } else if (transaction.temporary_ignorepkgs.remove (pkgname)) { + transaction.to_update.add (pkgname); } else { transaction.to_install.add (pkgname); } @@ -1037,7 +1150,13 @@ namespace Pamac { uint origin; string pkgname; aur_list.get (iter, 0, out origin, 1, out pkgname); - if (origin == 2) { //Alpm.Package.From.LOCALDB + if (filters_stack.visible_child_name == "updates") { + if (transaction.to_update.remove (pkgname)) { + transaction.temporary_ignorepkgs.add (pkgname); + } else if (transaction.temporary_ignorepkgs.remove (pkgname)) { + transaction.to_update.add (pkgname); + } + } else if (origin == 2) { //Alpm.Package.From.LOCALDB if (!transaction.transaction_summary.contains (pkgname)) { if (transaction.to_remove.remove (pkgname)) { } else if (!transaction.should_hold (pkgname)) { @@ -1119,12 +1238,30 @@ namespace Pamac { void on_deselect_item_activate () { foreach (unowned string pkgname in selected_pkgs) { if (transaction.to_install.remove (pkgname)) { + } else if (transaction.to_update.remove (pkgname)) { + transaction.temporary_ignorepkgs.add (pkgname); } else { transaction.to_remove.remove (pkgname); } } foreach (unowned string pkgname in selected_aur) { - transaction.to_build.remove (pkgname); + if (transaction.to_build.remove (pkgname)) { + } else { + transaction.to_update.remove (pkgname); + transaction.temporary_ignorepkgs.add (pkgname); + } + } + set_pendings_operations (); + } + + void on_upgrade_item_activate () { + foreach (unowned string pkgname in selected_pkgs) { + transaction.temporary_ignorepkgs.remove (pkgname); + transaction.to_update.add (pkgname); + } + foreach (unowned string pkgname in selected_aur) { + transaction.temporary_ignorepkgs.remove (pkgname); + transaction.to_update.add (pkgname); } set_pendings_operations (); } @@ -1188,6 +1325,7 @@ namespace Pamac { selected_pkgs = new GLib.List (); selected_aur = new GLib.List (); deselect_item.sensitive = false; + upgrade_item.sensitive = false; install_item.sensitive = false; remove_item.sensitive = false; if (selected_paths.length () == 1) { @@ -1201,8 +1339,11 @@ namespace Pamac { selected_pkgs.append (pkgname); details_item.sensitive = true; if (transaction.to_install.contains (pkgname) - || transaction.to_remove.contains (pkgname)) { + || transaction.to_remove.contains (pkgname) + || transaction.to_update.contains (pkgname)) { deselect_item.sensitive = true; + } else if (transaction.temporary_ignorepkgs.contains (pkgname)) { + upgrade_item.sensitive = true; } else if (origin == 2) { //Alpm.Package.From.LOCALDB remove_item.sensitive = true; } else if (origin == 3) { //Alpm.Package.From.SYNCDB @@ -1219,12 +1360,17 @@ namespace Pamac { selected_pkgs.append (pkgname); if (!deselect_item.sensitive) { if (transaction.to_install.contains (pkgname) - || transaction.to_remove.contains (pkgname)) { + || transaction.to_remove.contains (pkgname) + || transaction.to_update.contains (pkgname)) { deselect_item.sensitive = true; } } if (origin == 3) { //Alpm.Package.From.SYNCDB - install_item.sensitive = true; + if (transaction.temporary_ignorepkgs.contains (pkgname)) { + upgrade_item.sensitive = true; + } else { + install_item.sensitive = true; + } } if (origin == 2) { //Alpm.Package.From.LOCALDB remove_item.sensitive = true; @@ -1234,7 +1380,7 @@ namespace Pamac { right_click_menu.popup (null, null, null, event.button, event.time); return true; } - } + } return false; } @@ -1268,6 +1414,7 @@ namespace Pamac { selected_pkgs = new GLib.List (); selected_aur = new GLib.List (); deselect_item.sensitive = false; + upgrade_item.sensitive = false; install_item.sensitive = false; remove_item.sensitive = false; if (selected_paths.length () == 1) { @@ -1297,9 +1444,11 @@ namespace Pamac { } } foreach (unowned string pkgname in selected_pkgs) { - if (transaction.to_remove.contains (pkgname)) { + if (transaction.to_remove.contains (pkgname) + || transaction.to_update.contains (pkgname)) { deselect_item.sensitive = true; - break; + } else if (transaction.temporary_ignorepkgs.contains (pkgname)) { + upgrade_item.sensitive = true; } } right_click_menu.popup (null, null, null, event.button, event.time); @@ -1573,12 +1722,44 @@ namespace Pamac { [GtkCallback] void on_menu_button_toggled () { - preferences_button.sensitive = !transaction_running; + preferences_button.sensitive = !(transaction_running || sysupgrade_running); } [GtkCallback] void on_history_button_clicked () { - transaction.run_history_dialog (); + this.get_window ().set_cursor (new Gdk.Cursor.for_display (Gdk.Display.get_default (), Gdk.CursorType.WATCH)); + while (Gtk.events_pending ()) { + Gtk.main_iteration (); + } + var file = GLib.File.new_for_path ("/var/log/pacman.log"); + if (!file.query_exists ()) { + GLib.stderr.printf ("File '%s' doesn't exist.\n", file.get_path ()); + } else { + StringBuilder text = new StringBuilder (); + try { + // Open file for reading and wrap returned FileInputStream into a + // DataInputStream, so we can read line by line + var dis = new DataInputStream (file.read ()); + string line; + // Read lines until end of file (null) is reached + while ((line = dis.read_line ()) != null) { + // construct text in reverse order + text.prepend (line + "\n"); + } + } catch (GLib.Error e) { + GLib.stderr.printf ("%s\n", e.message); + } + var history_dialog = new HistoryDialog (this); + history_dialog.textview.buffer.set_text (text.str, (int) text.len); + this.get_window ().set_cursor (null); + history_dialog.show (); + history_dialog.response.connect (() => { + history_dialog.destroy (); + }); + while (Gtk.events_pending ()) { + Gtk.main_iteration (); + } + } } [GtkCallback] @@ -1589,7 +1770,6 @@ namespace Pamac { dgettext (null, "_Open"),Gtk.ResponseType.ACCEPT); chooser.window_position = Gtk.WindowPosition.CENTER_ON_PARENT; chooser.icon_name = "system-software-install"; - chooser.default_width = 900; chooser.select_multiple = true; chooser.local_only = false; chooser.create_folders = false; @@ -1603,13 +1783,8 @@ namespace Pamac { foreach (unowned string path in packages_paths) { transaction.to_load.add (path); } - this.get_window ().set_cursor (new Gdk.Cursor.for_display (Gdk.Display.get_default (), Gdk.CursorType.WATCH)); chooser.destroy (); - while (Gtk.events_pending ()) { - Gtk.main_iteration (); - } - transaction_running = true; - transaction.run (); + try_lock_and_run (run_transaction); } } else { chooser.destroy (); @@ -1621,18 +1796,43 @@ namespace Pamac { [GtkCallback] void on_preferences_button_clicked () { - transaction.run_preferences_dialog.begin (); + if (transaction.get_lock ()) { + this.get_window ().set_cursor (new Gdk.Cursor.for_display (Gdk.Display.get_default (), Gdk.CursorType.WATCH)); + transaction.run_preferences_dialog (); + } else { + transaction.display_error (dgettext (null, "Waiting for another package manager to quit"), {}); + } + } + + void on_run_preferences_dialog_finished () { + transaction.unlock (); + if (filters_stack.visible_child_name == "updates") { + transaction.start_get_updates (); + } else { + this.get_window ().set_cursor (null); + } } [GtkCallback] void on_about_button_clicked () { - transaction.run_about_dialog (); + string[] authors = {"Guillaume Benoit"}; + Gtk.show_about_dialog ( + this, + "program_name", "Pamac", + "icon_name", "system-software-install", + "logo_icon_name", "system-software-install", + "comments", dgettext (null, "A Gtk3 frontend for libalpm"), + "copyright", "Copyright © 2017 Guillaume Benoit", + "authors", authors, + "version", VERSION, + "license_type", Gtk.License.GPL_3_0, + "website", "http://github.com/manjaro/pamac"); } [GtkCallback] void on_details_button_clicked () { important_details = false; - if (transaction_running) { + if (transaction_running || sysupgrade_running) { main_stack.visible_child_name = "term"; } else { uint total_pending = transaction.to_install.length + transaction.to_remove.length + transaction.to_build.length; @@ -1658,17 +1858,47 @@ namespace Pamac { [GtkCallback] void on_apply_button_clicked () { + if (filters_stack.visible_child_name == "updates") { + force_refresh = false; + refreshing = true; + try_lock_and_run (run_refresh); + } else { + try_lock_and_run (run_transaction); + } + } + + void run_transaction () { transaction_running = true; apply_button.sensitive = false; cancel_button.sensitive = false; transaction.run (); } + void run_sysupgrade () { + sysupgrade_running = true; + apply_button.sensitive = false; + cancel_button.sensitive = false; + transaction.sysupgrade (false); + } + [GtkCallback] void on_cancel_button_clicked () { - if (transaction_running || refreshing) { + if (waiting) { + waiting = false; + transaction.stop_progressbar_pulse (); + transaction.to_load.remove_all (); + transaction.unlock (); + set_pendings_operations (); + } else if (transaction_running) { transaction_running = false; transaction.cancel (); + } else if (refreshing) { + refreshing = false; + transaction.cancel (); + } else if (sysupgrade_running) { + sysupgrade_running = false; + transaction.cancel (); + transaction.to_build.remove_all (); } else { transaction.clear_lists (); set_pendings_operations (); @@ -1689,19 +1919,60 @@ namespace Pamac { [GtkCallback] void on_refresh_button_clicked () { + force_refresh = true; + try_lock_and_run (run_refresh); + } + + void run_refresh () { this.get_window ().set_cursor (new Gdk.Cursor.for_display (Gdk.Display.get_default (), Gdk.CursorType.WATCH)); - refreshing = true; - transaction.start_refresh (true); + transaction.start_refresh (force_refresh); apply_button.sensitive = false; + cancel_button.sensitive = true; transaction_infobox.show_all (); } - void on_start_waiting () { - cancel_button.sensitive = true; - } - - void on_stop_waiting () { - set_pendings_operations (); + void on_get_updates_finished (Updates updates) { + if (filters_stack.visible_child_name == "updates") { + transaction.to_update.remove_all (); + packages_stackswitcher.visible = false; + if ((updates.repos_updates.length + updates.aur_updates.length) == 0) { + filters_stack.visible = false; + if (!refreshing && !transaction_running && !sysupgrade_running) { + transaction_infobox.visible = false; + } + packages_stack.visible_child_name = "updated"; + this.get_window ().set_cursor (null); + } else { + if (updates.repos_updates.length > 0) { + foreach (unowned AlpmPackage pkg in updates.repos_updates) { + if (!transaction.temporary_ignorepkgs.contains (pkg.name)) { + transaction.to_update.add (pkg.name); + } + } + populate_packages_list (updates.repos_updates); + } + if (updates.aur_updates.length > 0) { + packages_stackswitcher.visible = true; + foreach (unowned AURPackage pkg in updates.aur_updates) { + if (!transaction.temporary_ignorepkgs.contains (pkg.name)) { + transaction.to_update.add (pkg.name); + } + } + populate_aur_list (updates.aur_updates); + if (updates.repos_updates.length == 0) { + packages_stack.visible_child_name = "aur"; + } + } + set_pendings_operations (); + } + } else if ((updates.repos_updates.length + updates.aur_updates.length) > 0) { + this.get_window ().set_cursor (null); + var attention_val = GLib.Value (typeof (bool)); + attention_val.set_boolean (true); + filters_stack.child_set_property (filters_stack.get_child_by_name ("updates"), + "needs-attention", + attention_val); + } } void on_start_downloading () { @@ -1737,7 +2008,7 @@ namespace Pamac { } void on_transaction_finished (bool success) { - refresh_packages_list (); + transaction.refresh_handle (); if (main_stack.visible_child_name == "details") { if (transaction.get_installed_pkg (current_package_displayed).name != "" || transaction.get_sync_pkg (current_package_displayed).name != "") { @@ -1750,14 +2021,18 @@ namespace Pamac { } transaction.to_load.remove_all (); if (refreshing) { - if (success) { - transaction_running = true; - transaction.sysupgrade (false); - } refreshing = false; + run_sysupgrade (); + } else if (sysupgrade_running) { + sysupgrade_running = false; + transaction.to_build.remove_all (); + transaction.unlock (); + refresh_packages_list (); } else { transaction_running = false; generate_mirrors_list = false; + transaction.unlock (); + refresh_packages_list (); } set_pendings_operations (); } diff --git a/src/mirrors_config.vala b/src/mirrors_config.vala index b09c9c6..d929fef 100644 --- a/src/mirrors_config.vala +++ b/src/mirrors_config.vala @@ -20,32 +20,9 @@ namespace Pamac { class MirrorsConfig { string conf_path; - GLib.List _countries ; public string choosen_generation_method { get; private set; } public string choosen_country { get; private set; } - public unowned GLib.List countries { - get { - try { - string countries_str; - int status; - Process.spawn_command_line_sync ("pacman-mirrors -l", - out countries_str, - null, - out status); - _countries = new GLib.List (); - if (status == 0) { - foreach (unowned string country in countries_str.split ("\n")) { - _countries.append (country); - } - } - } catch (SpawnError e) { - stdout.printf ("Error: %s\n", e.message); - } - return _countries; - } - } - public MirrorsConfig (string path) { conf_path = path; diff --git a/src/package.vala b/src/package.vala index b9cb72d..bbb6282 100644 --- a/src/package.vala +++ b/src/package.vala @@ -21,9 +21,11 @@ namespace Pamac { public struct AlpmPackage { public string name; public string version; + public string installed_version; public string desc; public string repo; public uint64 size; + public uint64 download_size; public uint origin; } @@ -54,6 +56,7 @@ namespace Pamac { public struct AURPackage { public string name; public string version; + public string installed_version; public string desc; public double popularity; } diff --git a/src/preferences_dialog.vala b/src/preferences_dialog.vala index 8bf338d..85313a1 100644 --- a/src/preferences_dialog.vala +++ b/src/preferences_dialog.vala @@ -62,6 +62,7 @@ namespace Pamac { Gtk.ListStore ignorepkgs_liststore; Transaction transaction; uint64 previous_refresh_period; + string[] countries; public PreferencesDialog (Transaction transaction) { Object (transient_for: transaction.application_window, use_header_bar: 1); @@ -108,8 +109,9 @@ namespace Pamac { var mirrors_config = new MirrorsConfig ("/etc/pacman-mirrors.conf"); mirrors_country_comboboxtext.append_text (dgettext (null, "Worldwide")); mirrors_country_comboboxtext.active = 0; + countries = transaction.get_mirrors_countries (); int index = 1; - foreach (unowned string country in mirrors_config.countries) { + foreach (unowned string country in countries) { mirrors_country_comboboxtext.append_text (country); if (country == mirrors_config.choosen_country) { mirrors_country_comboboxtext.active = index; diff --git a/src/refresh.vala b/src/refresh.vala deleted file mode 100644 index 1e17533..0000000 --- a/src/refresh.vala +++ /dev/null @@ -1,100 +0,0 @@ -/* - * pamac-vala - * - * Copyright (C) 2014-2017 Guillaume Benoit - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a get of the GNU General Public License - * along with this program. If not, see . - */ - -namespace Pamac { - [DBus (name = "org.manjaro.pamac")] - interface Daemon : Object { - public abstract void start_refresh (bool force) throws IOError; - [DBus (no_reply = true)] - public abstract void quit () throws IOError; - public signal void refresh_finished (bool success); - } -} - -Pamac.Daemon pamac_daemon; -MainLoop loop; - -bool check_pamac_running () { - Application app; - bool run = false; - app = new Application ("org.manjaro.pamac.manager", 0); - try { - app.register (); - } catch (GLib.Error e) { - stderr.printf ("%s\n", e.message); - } - run = app.get_is_remote (); - if (run) { - return run; - } - app = new Application ("org.manjaro.pamac.updater", 0); - try { - app.register (); - } catch (GLib.Error e) { - stderr.printf ("%s\n", e.message); - } - run = app.get_is_remote (); - if (run) { - return run; - } - app = new Application ("org.manjaro.pamac.install", 0); - try { - app.register (); - } catch (GLib.Error e) { - stderr.printf ("%s\n", e.message); - } - run = app.get_is_remote (); - return run; -} - -void on_refresh_finished () { - Timeout.add (1000, () => { - if (!check_pamac_running ()) { - try { - pamac_daemon.quit (); - } catch (IOError e) { - stderr.printf ("IOError: %s\n", e.message); - } - } - Timeout.add (100, () => { - loop.quit (); - return false; - }); - return false; - }); -} - -int main () { - var pamac_config = new Pamac.Config ("/etc/pamac.conf"); - // if refresh period is 0, just exit - if (pamac_config.refresh_period != 0) { - if (!check_pamac_running ()) { - try { - pamac_daemon = Bus.get_proxy_sync (BusType.SYSTEM, "org.manjaro.pamac", "/org/manjaro/pamac"); - pamac_daemon.refresh_finished.connect (on_refresh_finished); - pamac_daemon.start_refresh (false); - loop = new MainLoop (); - loop.run (); - } catch (IOError e) { - stderr.printf ("IOError: %s\n", e.message); - } - } - } - return 0; -} diff --git a/src/daemon.vala b/src/system_daemon.vala similarity index 65% rename from src/daemon.vala rename to src/system_daemon.vala index 30bd6ad..d7abf36 100644 --- a/src/daemon.vala +++ b/src/system_daemon.vala @@ -20,7 +20,7 @@ // i18n const string GETTEXT_PACKAGE = "pamac"; -Pamac.Daemon pamac_daemon; +Pamac.SystemDaemon system_daemon; MainLoop loop; public delegate void AlpmActionDelegate (); @@ -36,73 +36,20 @@ public class AlpmAction { } } -private int alpm_pkg_compare_name (Alpm.Package pkg_a, Alpm.Package pkg_b) { - return strcmp (pkg_a.name, pkg_b.name); -} - -private string global_search_string; - -private int alpm_pkg_sort_search_by_relevance (Alpm.Package pkg_a, Alpm.Package pkg_b) { - if (global_search_string != null) { - // display exact match first - if (pkg_a.name == global_search_string) { - return 0; - } - if (pkg_b.name == global_search_string) { - return 1; - } - if (pkg_a.name.has_prefix (global_search_string + "-")) { - if (pkg_b.name.has_prefix (global_search_string + "-")) { - return strcmp (pkg_a.name, pkg_b.name); - } - return 0; - } - if (pkg_b.name.has_prefix (global_search_string + "-")) { - if (pkg_a.name.has_prefix (global_search_string + "-")) { - return strcmp (pkg_a.name, pkg_b.name); - } - return 1; - } - if (pkg_a.name.has_prefix (global_search_string)) { - if (pkg_b.name.has_prefix (global_search_string)) { - return strcmp (pkg_a.name, pkg_b.name); - } - return 0; - } - if (pkg_b.name.has_prefix (global_search_string)) { - if (pkg_a.name.has_prefix (global_search_string)) { - return strcmp (pkg_a.name, pkg_b.name); - } - return 1; - } - if (pkg_a.name.contains (global_search_string)) { - if (pkg_b.name.contains (global_search_string)) { - return strcmp (pkg_a.name, pkg_b.name); - } - return 0; - } - if (pkg_b.name.contains (global_search_string)) { - if (pkg_a.name.contains (global_search_string)) { - return strcmp (pkg_a.name, pkg_b.name); - } - return 1; - } - } - return strcmp (pkg_a.name, pkg_b.name); -} - namespace Pamac { - [DBus (name = "org.manjaro.pamac")] - public class Daemon: Object { + [DBus (name = "org.manjaro.pamac.system")] + public class SystemDaemon: Object { private AlpmConfig alpm_config; private Alpm.Handle? alpm_handle; private Alpm.Handle? files_handle; public Cond provider_cond; public Mutex provider_mutex; public int? choosen_provider; + private bool refreshed; private bool force_refresh; private bool enable_downgrade; private bool check_aur_updates; + private bool aur_updates_checked; private HashTable new_alpm_conf; private Alpm.TransFlag flags; private string[] to_install; @@ -118,11 +65,8 @@ namespace Pamac { private string[] temporary_ignorepkgs; private UpdateInfos[] aur_conflicts_to_remove; private ThreadPool thread_pool; - private Mutex databases_lock_mutex; + private BusName lock_id; private Json.Array aur_updates_results; - private HashTable aur_search_results; - private HashTable aur_infos; - private bool extern_lock; private GLib.File lockfile; public ErrorInfos current_error; public Timer timer; @@ -149,25 +93,23 @@ namespace Pamac { public signal void generate_mirrors_list_data (string line); public signal void generate_mirrors_list_finished (); - public Daemon () { + public SystemDaemon () { alpm_config = new AlpmConfig ("/etc/pacman.conf"); - databases_lock_mutex = Mutex (); aur_pkgbases_to_build = new GLib.List (); aur_desc_list = new GenericSet (str_hash, str_equal); already_checked_aur_dep = new GenericSet (str_hash, str_equal); to_install_as_dep = new HashTable (str_hash, str_equal); aurdb_path = "/tmp/pamac-aur"; aur_updates_results = new Json.Array (); - aur_search_results = new HashTable (str_hash, str_equal); - aur_infos = new HashTable (str_hash, str_equal); timer = new Timer (); - extern_lock = false; + lock_id = new BusName (""); refresh_handle (); Timeout.add (500, check_extern_lock); create_thread_pool (); cancellable = new Cancellable (); curl = new Curl.Easy (); authorized = false; + refreshed = false; } public void set_environment_variables (HashTable variables) { @@ -223,29 +165,27 @@ namespace Pamac { alpm_handle.totaldlcb = (Alpm.TotalDownloadCallBack) cb_totaldownload; alpm_handle.logcb = (Alpm.LogCallBack) cb_log; lockfile = GLib.File.new_for_path (alpm_handle.lockfile); + files_handle = alpm_config.get_handle (true); + files_handle.eventcb = (Alpm.EventCallBack) cb_event; + files_handle.progresscb = (Alpm.ProgressCallBack) cb_progress; + files_handle.questioncb = (Alpm.QuestionCallBack) cb_question; + files_handle.fetchcb = (Alpm.FetchCallBack) cb_fetch; + files_handle.totaldlcb = (Alpm.TotalDownloadCallBack) cb_totaldownload; + files_handle.logcb = (Alpm.LogCallBack) cb_log; } - files_handle = alpm_config.get_handle (true); - files_handle.eventcb = (Alpm.EventCallBack) cb_event; - files_handle.progresscb = (Alpm.ProgressCallBack) cb_progress; - files_handle.questioncb = (Alpm.QuestionCallBack) cb_question; - files_handle.fetchcb = (Alpm.FetchCallBack) cb_fetch; - files_handle.totaldlcb = (Alpm.TotalDownloadCallBack) cb_totaldownload; - files_handle.logcb = (Alpm.LogCallBack) cb_log; } private bool check_extern_lock () { - if (extern_lock) { + if (lock_id == "extern") { if (!lockfile.query_exists ()) { - extern_lock = false; + lock_id = new BusName (""); refresh_handle (); - databases_lock_mutex.unlock (); } } else { if (lockfile.query_exists ()) { - if (databases_lock_mutex.trylock ()) { - extern_lock = true; - // Functions trans_init, build_prepare and refresh threads are blocked until unlock. + if (lock_id == "") { // An extern lock appears, check if it is not a too old lock. + lock_id = new BusName ("extern"); int exit_status; string output; uint64 lockfile_time; @@ -280,8 +220,7 @@ namespace Pamac { } catch (Error e) { stderr.printf ("Error: %s\n", e.message); } - extern_lock = false; - databases_lock_mutex.unlock (); + lock_id = new BusName (""); } } } @@ -300,7 +239,48 @@ namespace Pamac { return true; } + public string[] get_mirrors_countries () { + string[] countries = {}; + try { + string countries_str; + int status; + Process.spawn_command_line_sync ("pacman-mirrors -lq", + out countries_str, + null, + out status); + if (status == 0) { + foreach (unowned string country in countries_str.split ("\n")) { + countries += country; + } + } + } catch (SpawnError e) { + stderr.printf ("Error: %s\n", e.message); + } + return countries; + } + + public bool get_lock (GLib.BusName sender) { + if (lock_id == sender) { + return true; + } else if (lock_id == "") { + lock_id = sender; + return true; + } + return false; + } + + public bool unlock (GLib.BusName sender) { + if (lock_id == sender) { + lock_id = new BusName (""); + return true; + } + return false; + } + private async bool check_authorization (GLib.BusName sender) { + if (lock_id != sender) { + return false; + } if (authorized) { return true; } @@ -359,9 +339,7 @@ namespace Pamac { private void write_alpm_config () { alpm_config.write (new_alpm_conf); alpm_config.reload (); - databases_lock_mutex.lock (); refresh_handle (); - databases_lock_mutex.unlock (); write_alpm_config_finished ((alpm_handle.checkspace == 1)); } @@ -394,10 +372,6 @@ namespace Pamac { } catch (Error e) { stderr.printf ("Error: %s\n", e.message); } - alpm_config.reload (); - databases_lock_mutex.lock (); - refresh_handle (); - databases_lock_mutex.unlock (); generate_mirrors_list_finished (); } @@ -435,8 +409,8 @@ namespace Pamac { } public void start_write_mirrors_config (HashTable new_mirrors_conf, GLib.BusName sender) { - var mirrors_config = new MirrorsConfig ("/etc/pacman-mirrors.conf"); check_authorization.begin (sender, (obj, res) => { + var mirrors_config = new MirrorsConfig ("/etc/pacman-mirrors.conf"); bool authorized = check_authorization.end (res); if (authorized) { mirrors_config.write (new_mirrors_conf); @@ -452,7 +426,11 @@ namespace Pamac { if (authorized) { unowned Alpm.Package? pkg = alpm_handle.localdb.get_pkg (pkgname); if (pkg != null) { - pkg.reason = (Alpm.Package.Reason) reason; + // lock the database + if (alpm_handle.trans_init (0) == 0) { + pkg.reason = (Alpm.Package.Reason) reason; + alpm_handle.trans_release (); + } } } set_pkgreason_finished (); @@ -486,17 +464,6 @@ namespace Pamac { private void refresh () { current_error = ErrorInfos (); - if (!databases_lock_mutex.trylock ()) { - // Wait for pacman to finish - emit_event (0, 0, {}); - databases_lock_mutex.lock (); - } - if (cancellable.is_cancelled ()) { - cancellable.reset (); - refresh_finished (true); - databases_lock_mutex.unlock (); - return; - } write_log_file ("synchronizing package lists"); cancellable.reset (); int force = (force_refresh) ? 1 : 0; @@ -504,7 +471,6 @@ namespace Pamac { bool success = update_dbs (alpm_handle, force); if (cancellable.is_cancelled ()) { refresh_finished (false); - databases_lock_mutex.unlock (); return; } // update ".files", do not need to know if we succeeded @@ -514,16 +480,26 @@ namespace Pamac { } else if (success) { // We should always succeed if at least one DB was upgraded - we may possibly // fail later with unresolved deps, but that should be rare, and would be expected + refreshed = true; refresh_finished (true); } else { current_error.message = _("Failed to synchronize any databases"); refresh_finished (false); } - databases_lock_mutex.unlock (); } - public void start_refresh (bool force) { + public void start_refresh (bool force, GLib.BusName sender) { + if (lock_id != sender) { + return; + } force_refresh = force; + if (force_refresh) { + refreshed = false; + } + if (refreshed) { + refresh_finished (true); + return; + } try { thread_pool.add (new AlpmAction (refresh)); } catch (ThreadError e) { @@ -531,25 +507,6 @@ namespace Pamac { } } - public bool get_checkspace () { - return alpm_handle.checkspace == 1 ? true : false; - } - - public string get_lockfile () { - return alpm_handle.lockfile; - } - - public string[] get_ignorepkgs () { - string[] result = {}; - unowned Alpm.List ignorepkgs = alpm_handle.ignorepkgs; - while (ignorepkgs != null) { - unowned string ignorepkg = ignorepkgs.data; - result += ignorepkg; - ignorepkgs.next (); - } - return result; - } - private void add_ignorepkgs () { foreach (unowned string pkgname in temporary_ignorepkgs) { alpm_handle.add_ignorepkg (pkgname); @@ -563,34 +520,6 @@ namespace Pamac { temporary_ignorepkgs = {}; } - public bool should_hold (string pkgname) { - if (alpm_config.get_holdpkgs ().find_custom (pkgname, strcmp) != null) { - return true; - } - return false; - } - - public uint get_pkg_reason (string pkgname) { - unowned Alpm.Package? pkg = alpm_handle.localdb.get_pkg (pkgname); - if (pkg != null) { - return pkg.reason; - } - return 0; - } - - public uint get_pkg_origin (string pkgname) { - unowned Alpm.Package? pkg = alpm_handle.localdb.get_pkg (pkgname); - if (pkg != null) { - return pkg.origin; - } else { - pkg = get_syncpkg (pkgname); - if (pkg != null) { - return pkg.origin; - } - } - return 0; - } - private AlpmPackage initialise_pkg_struct (Alpm.Package? alpm_pkg) { if (alpm_pkg != null) { string repo_name = ""; @@ -621,85 +550,6 @@ namespace Pamac { } } - public async AlpmPackage[] get_installed_pkgs () { - AlpmPackage[] pkgs = {}; - unowned Alpm.List pkgcache = alpm_handle.localdb.pkgcache; - while (pkgcache != null) { - unowned Alpm.Package alpm_pkg = pkgcache.data; - pkgs += initialise_pkg_struct (alpm_pkg); - pkgcache.next (); - } - return pkgs; - } - - public async AlpmPackage[] get_explicitly_installed_pkgs () { - AlpmPackage[] pkgs = {}; - unowned Alpm.List pkgcache = alpm_handle.localdb.pkgcache; - while (pkgcache != null) { - unowned Alpm.Package alpm_pkg = pkgcache.data; - if (alpm_pkg.reason == Alpm.Package.Reason.EXPLICIT) { - pkgs += initialise_pkg_struct (alpm_pkg); - } - pkgcache.next (); - } - return pkgs; - } - - public async AlpmPackage[] get_foreign_pkgs () { - AlpmPackage[] pkgs = {}; - unowned Alpm.List pkgcache = alpm_handle.localdb.pkgcache; - while (pkgcache != null) { - unowned Alpm.Package alpm_pkg = pkgcache.data; - bool sync_found = false; - unowned Alpm.List syncdbs = alpm_handle.syncdbs; - while (syncdbs != null) { - unowned Alpm.DB db = syncdbs.data; - unowned Alpm.Package? sync_pkg = db.get_pkg (alpm_pkg.name); - if (sync_pkg != null) { - sync_found = true; - break; - } - syncdbs.next (); - } - if (sync_found == false) { - pkgs += initialise_pkg_struct (alpm_pkg); - } - pkgcache.next (); - } - return pkgs; - } - - public async AlpmPackage[] get_orphans () { - AlpmPackage[] pkgs = {}; - unowned Alpm.List pkgcache = alpm_handle.localdb.pkgcache; - while (pkgcache != null) { - unowned Alpm.Package alpm_pkg = pkgcache.data; - if (alpm_pkg.reason == Alpm.Package.Reason.DEPEND) { - Alpm.List requiredby = alpm_pkg.compute_requiredby (); - if (requiredby.length == 0) { - Alpm.List optionalfor = alpm_pkg.compute_optionalfor (); - if (optionalfor.length == 0) { - pkgs += initialise_pkg_struct (alpm_pkg); - } else { - optionalfor.free_inner (GLib.free); - } - } else { - requiredby.free_inner (GLib.free); - } - } - pkgcache.next (); - } - return pkgs; - } - - public AlpmPackage get_installed_pkg (string pkgname) { - return initialise_pkg_struct (alpm_handle.localdb.get_pkg (pkgname)); - } - - public AlpmPackage find_installed_satisfier (string depstring) { - return initialise_pkg_struct (Alpm.find_satisfier (alpm_handle.localdb.pkgcache, depstring)); - } - private unowned Alpm.Package? get_syncpkg (string name) { unowned Alpm.Package? pkg = null; unowned Alpm.List syncdbs = alpm_handle.syncdbs; @@ -714,234 +564,22 @@ namespace Pamac { return pkg; } - public AlpmPackage get_sync_pkg (string pkgname) { - return initialise_pkg_struct (get_syncpkg (pkgname)); - } - - private unowned Alpm.Package? find_dbs_satisfier (string depstring) { - unowned Alpm.Package? pkg = null; - unowned Alpm.List syncdbs = alpm_handle.syncdbs; - while (syncdbs != null) { - unowned Alpm.DB db = syncdbs.data; - pkg = Alpm.find_satisfier (db.pkgcache, depstring); - if (pkg != null) { - break; - } - syncdbs.next (); - } - return pkg; - } - - public AlpmPackage find_sync_satisfier (string depstring) { - return initialise_pkg_struct (find_dbs_satisfier (depstring)); - } - - private Alpm.List search_all_dbs (string search_string) { - Alpm.List needles = null; - string[] splitted = search_string.split (" "); - foreach (unowned string part in splitted) { - needles.add (part); - } - Alpm.List result = alpm_handle.localdb.search (needles); - Alpm.List syncpkgs = null; - unowned Alpm.List syncdbs = alpm_handle.syncdbs; - while (syncdbs != null) { - unowned Alpm.DB db = syncdbs.data; - if (syncpkgs.length == 0) { - syncpkgs = db.search (needles); - } else { - syncpkgs.join (db.search (needles).diff (syncpkgs, (Alpm.List.CompareFunc) alpm_pkg_compare_name)); - } - syncdbs.next (); - } - result.join (syncpkgs.diff (result, (Alpm.List.CompareFunc) alpm_pkg_compare_name)); - // use custom sort function - global_search_string = search_string; - result.sort (result.length, (Alpm.List.CompareFunc) alpm_pkg_sort_search_by_relevance); - return result; - } - - public async AlpmPackage[] search_pkgs (string search_string) { - AlpmPackage[] result = {}; - Alpm.List alpm_pkgs = search_all_dbs (search_string); - unowned Alpm.List list = alpm_pkgs; - while (list != null) { - unowned Alpm.Package alpm_pkg = list.data; - result += initialise_pkg_struct (alpm_pkg); - list.next (); - } - return result; - } - private AURPackage initialise_aur_struct (Json.Object json_object) { + string installed_version = ""; + unowned Alpm.Package? pkg = alpm_handle.localdb.get_pkg (json_object.get_string_member ("Name")); + if (pkg != null) { + installed_version = pkg.version; + } return AURPackage () { name = json_object.get_string_member ("Name"), version = json_object.get_string_member ("Version"), + installed_version = (owned) installed_version, // desc can be null desc = json_object.get_null_member ("Description") ? "" : json_object.get_string_member ("Description"), popularity = json_object.get_double_member ("Popularity") }; } - public async AURPackage[] search_in_aur (string search_string) { - if (!aur_search_results.contains (search_string)) { - Json.Array pkgs = yield AUR.search (search_string.split (" ")); - aur_search_results.insert (search_string, pkgs); - } - AURPackage[] result = {}; - Json.Array aur_pkgs = aur_search_results.get (search_string); - aur_pkgs.foreach_element ((array, index, node) => { - Json.Object aur_pkg = node.get_object (); - // remove results which exist in repos - if (get_syncpkg (aur_pkg.get_string_member ("Name")) == null) { - result += initialise_aur_struct (node.get_object ()); - } - }); - return result; - } - - public async AURPackageDetails get_aur_details (string pkgname) { - string name = ""; - string version = ""; - string desc = ""; - double popularity = 0; - string packagebase = ""; - string url = ""; - string maintainer = ""; - int64 firstsubmitted = 0; - int64 lastmodified = 0; - int64 outofdate = 0; - int64 numvotes = 0; - string[] licenses = {}; - string[] depends = {}; - string[] makedepends = {}; - string[] checkdepends = {}; - string[] optdepends = {}; - string[] provides = {}; - string[] replaces = {}; - string[] conflicts = {}; - var details = AURPackageDetails (); - if (!aur_infos.contains (pkgname)) { - Json.Array results = yield AUR.multiinfo ({pkgname}); - if (results.get_length () > 0) { - aur_infos.insert (pkgname, results.get_object_element (0)); - } - } - unowned Json.Object? json_object = aur_infos.lookup (pkgname); - if (json_object != null) { - // name - name = json_object.get_string_member ("Name"); - // version - version = json_object.get_string_member ("Version"); - // desc can be null - if (!json_object.get_null_member ("Description")) { - desc = json_object.get_string_member ("Description"); - } - popularity = json_object.get_double_member ("Popularity"); - // packagebase - packagebase = json_object.get_string_member ("PackageBase"); - // url can be null - unowned Json.Node? node = json_object.get_member ("URL"); - if (!node.is_null ()) { - url = node.get_string (); - } - // maintainer can be null - node = json_object.get_member ("Maintainer"); - if (!node.is_null ()) { - maintainer = node.get_string (); - } - // firstsubmitted - firstsubmitted = json_object.get_int_member ("FirstSubmitted"); - // lastmodified - lastmodified = json_object.get_int_member ("LastModified"); - // outofdate can be null - node = json_object.get_member ("OutOfDate"); - if (!node.is_null ()) { - outofdate = node.get_int (); - } - //numvotes - numvotes = json_object.get_int_member ("NumVotes"); - // licenses - node = json_object.get_member ("License"); - if (!node.is_null ()) { - node.get_array ().foreach_element ((array, index, _node) => { - licenses += _node.get_string (); - }); - } else { - licenses += _("Unknown"); - } - // depends - node = json_object.get_member ("Depends"); - if (node != null) { - node.get_array ().foreach_element ((array, index, _node) => { - depends += _node.get_string (); - }); - } - // optdepends - node = json_object.get_member ("OptDepends"); - if (node != null) { - node.get_array ().foreach_element ((array, index, _node) => { - optdepends += _node.get_string (); - }); - } - // makedepends - node = json_object.get_member ("MakeDepends"); - if (node != null) { - node.get_array ().foreach_element ((array, index, _node) => { - makedepends += _node.get_string (); - }); - } - // checkdepends - node = json_object.get_member ("CheckDepends"); - if (node != null) { - node.get_array ().foreach_element ((array, index, _node) => { - checkdepends += _node.get_string (); - }); - } - // provides - node = json_object.get_member ("Provides"); - if (node != null) { - node.get_array ().foreach_element ((array, index, _node) => { - provides += _node.get_string (); - }); - } - // replaces - node = json_object.get_member ("Replaces"); - if (node != null) { - node.get_array ().foreach_element ((array, index, _node) => { - replaces += _node.get_string (); - }); - } - // conflicts - node = json_object.get_member ("Conflicts"); - if (node != null) { - node.get_array ().foreach_element ((array, index, _node) => { - conflicts += _node.get_string (); - }); - } - } - details.name = (owned) name; - details.version = (owned) version ; - details.desc = (owned) desc; - details.popularity = popularity; - details.packagebase = (owned) packagebase; - details.url = (owned) url; - details.maintainer = (owned) maintainer ; - details.firstsubmitted = firstsubmitted; - details.lastmodified = lastmodified; - details.outofdate = outofdate; - details.numvotes = numvotes; - details.licenses = (owned) licenses; - details.depends = (owned) depends; - details.optdepends = (owned) optdepends; - details.checkdepends = (owned) checkdepends; - details.makedepends = (owned) makedepends; - details.provides = (owned) provides; - details.replaces = (owned) replaces; - details.conflicts = (owned) conflicts; - return details; - } - private async void compute_aur_build_list (string[] aur_list) { try { Process.spawn_command_line_sync ("mkdir -p %s".printf (aurdb_path)); @@ -953,28 +591,6 @@ namespace Pamac { yield check_aur_dep_list (aur_list); } - private string splitdep (string depstring) { - // split depmod and version from name - string result; - string[] splitted = depstring.split (">", 2); - if (splitted.length > 1) { - result = splitted[0]; - } else { - splitted = depstring.split ("<", 2); - if (splitted.length > 1) { - result = splitted[0]; - } else { - splitted = depstring.split ("=", 2); - if (splitted.length > 1) { - result = splitted[0]; - } else { - result = depstring; - } - } - } - return result; - } - private async void check_aur_dep_list (string[] pkgnames) { string[] dep_types = {"Depends", "MakeDepends", "CheckDepends"}; string[] dep_to_check = {}; @@ -1008,7 +624,7 @@ namespace Pamac { } // check deps unowned string dep_string = node.get_string (); - string dep_name = splitdep (dep_string); + string dep_name = Alpm.Depend.from_string (dep_string).name; unowned Alpm.Package? pkg = null; // search for the name first to avoid provides trouble pkg = alpm_handle.localdb.get_pkg (dep_name); @@ -1109,320 +725,8 @@ namespace Pamac { } } - public string[] get_repos_names () { - string[] repos_names = {}; - unowned Alpm.List syncdbs = alpm_handle.syncdbs; - while (syncdbs != null) { - unowned Alpm.DB db = syncdbs.data; - repos_names += db.name; - syncdbs.next (); - } - return repos_names; - } - - public async AlpmPackage[] get_repo_pkgs (string repo) { - AlpmPackage[] pkgs = {}; - unowned Alpm.List syncdbs = alpm_handle.syncdbs; - while (syncdbs != null) { - unowned Alpm.DB db = syncdbs.data; - if (db.name == repo) { - unowned Alpm.List pkgcache = db.pkgcache; - while (pkgcache != null) { - unowned Alpm.Package sync_pkg = pkgcache.data; - unowned Alpm.Package? local_pkg = alpm_handle.localdb.get_pkg (sync_pkg.name); - if (local_pkg != null) { - pkgs += initialise_pkg_struct (local_pkg); - } else { - pkgs += initialise_pkg_struct (sync_pkg); - } - pkgcache.next (); - } - break; - } - syncdbs.next (); - } - return pkgs; - } - - public string[] get_groups_names () { - string[] groups_names = {}; - unowned Alpm.List groupcache = alpm_handle.localdb.groupcache; - while (groupcache != null) { - unowned Alpm.Group group = groupcache.data; - if (!(group.name in groups_names)) { - groups_names += group.name; - } - groupcache.next (); - } - unowned Alpm.List syncdbs = alpm_handle.syncdbs; - while (syncdbs != null) { - unowned Alpm.DB db = syncdbs.data; - groupcache = db.groupcache; - while (groupcache != null) { - unowned Alpm.Group group = groupcache.data; - if (!(group.name in groups_names)) { - groups_names += group.name; - } - groupcache.next (); - } - syncdbs.next (); - } - return groups_names; - } - - private Alpm.List group_pkgs (string group_name) { - Alpm.List result = null; - unowned Alpm.Group? grp = alpm_handle.localdb.get_group (group_name); - if (grp != null) { - unowned Alpm.List packages = grp.packages; - while (packages != null) { - unowned Alpm.Package pkg = packages.data; - result.add (pkg); - packages.next (); - } - } - unowned Alpm.List syncdbs = alpm_handle.syncdbs; - while (syncdbs != null) { - unowned Alpm.DB db = syncdbs.data; - grp = db.get_group (group_name); - if (grp != null) { - unowned Alpm.List packages = grp.packages; - while (packages != null) { - unowned Alpm.Package pkg = packages.data; - if (result.find (pkg, (Alpm.List.CompareFunc) alpm_pkg_compare_name) == null) { - result.add (pkg); - } - packages.next (); - } - } - syncdbs.next (); - } - return result; - } - - public async AlpmPackage[] get_group_pkgs (string groupname) { - AlpmPackage[] pkgs = {}; - Alpm.List alpm_pkgs = group_pkgs (groupname); - unowned Alpm.List list = alpm_pkgs; - while (list != null) { - unowned Alpm.Package alpm_pkg = list.data; - pkgs += initialise_pkg_struct (alpm_pkg); - list.next (); - } - return pkgs; - } - - public string[] get_pkg_uninstalled_optdeps (string pkgname) { - string[] optdeps = {}; - unowned Alpm.Package? alpm_pkg = alpm_handle.localdb.get_pkg (pkgname); - if (alpm_pkg == null) { - alpm_pkg = get_syncpkg (pkgname); - } - if (alpm_pkg != null) { - unowned Alpm.List optdepends = alpm_pkg.optdepends; - while (optdepends != null) { - unowned Alpm.Depend optdep = optdepends.data; - if (Alpm.find_satisfier (alpm_handle.localdb.pkgcache, optdep.name) == null) { - optdeps += optdep.compute_string (); - } - optdepends.next (); - } - } - return optdeps; - } - - public AlpmPackageDetails get_pkg_details (string pkgname) { - string name = ""; - string version = ""; - string desc = ""; - string url = ""; - string repo = ""; - string has_signature = ""; - string reason = ""; - string packager = ""; - string builddate = ""; - string installdate = ""; - string[] groups = {}; - string[] backups = {}; - string[] licenses = {}; - string[] depends = {}; - string[] optdepends = {}; - string[] requiredby = {}; - string[] optionalfor = {}; - string[] provides = {}; - string[] replaces = {}; - string[] conflicts = {}; - var details = AlpmPackageDetails (); - unowned Alpm.Package? alpm_pkg = alpm_handle.localdb.get_pkg (pkgname); - if (alpm_pkg == null) { - alpm_pkg = get_syncpkg (pkgname); - } - if (alpm_pkg != null) { - // name - name = alpm_pkg.name; - // version - version = alpm_pkg.version; - // desc can be null - if (alpm_pkg.desc != null) { - desc = alpm_pkg.desc; - } - details.origin = (uint) alpm_pkg.origin; - // url can be null - if (alpm_pkg.url != null) { - url = alpm_pkg.url; - } - // packager can be null - packager = alpm_pkg.packager ?? ""; - // groups - unowned Alpm.List list = alpm_pkg.groups; - while (list != null) { - groups += ((Alpm.List) list).data; - list.next (); - } - // licenses - list = alpm_pkg.licenses; - while (list != null) { - licenses += ((Alpm.List) list).data; - list.next (); - } - // build_date - GLib.Time time = GLib.Time.local ((time_t) alpm_pkg.builddate); - builddate = time.format ("%a %d %b %Y %X %Z"); - // local pkg - if (alpm_pkg.origin == Alpm.Package.From.LOCALDB) { - // repo - unowned Alpm.Package? sync_pkg = get_syncpkg (alpm_pkg.name); - if (sync_pkg != null) { - repo = sync_pkg.db.name; - } - // reason - if (alpm_pkg.reason == Alpm.Package.Reason.EXPLICIT) { - reason = _("Explicitly installed"); - } else if (alpm_pkg.reason == Alpm.Package.Reason.DEPEND) { - reason = _("Installed as a dependency for another package"); - } else { - reason = _("Unknown"); - } - // install_date - time = GLib.Time.local ((time_t) alpm_pkg.installdate); - installdate = time.format ("%a %d %b %Y %X %Z"); - // backups - list = alpm_pkg.backups; - while (list != null) { - backups += "/" + ((Alpm.List) list).data.name; - list.next (); - } - // requiredby - Alpm.List pkg_requiredby = alpm_pkg.compute_requiredby (); - list = pkg_requiredby; - while (list != null) { - requiredby += ((Alpm.List) list).data; - list.next (); - } - pkg_requiredby.free_inner (GLib.free); - // optionalfor - Alpm.List pkg_optionalfor = alpm_pkg.compute_optionalfor (); - list = pkg_optionalfor; - while (list != null) { - optionalfor += ((Alpm.List) list).data; - list.next (); - } - pkg_optionalfor.free_inner (GLib.free); - // sync pkg - } else if (alpm_pkg.origin == Alpm.Package.From.SYNCDB) { - // repos - repo = alpm_pkg.db.name; - // signature - has_signature = alpm_pkg.base64_sig != null ? _("Yes") : _("No"); - } - // depends - list = alpm_pkg.depends; - while (list != null) { - depends += ((Alpm.List) list).data.compute_string (); - list.next (); - } - // optdepends - list = alpm_pkg.optdepends; - while (list != null) { - optdepends += ((Alpm.List) list).data.compute_string (); - list.next (); - } - // provides - list = alpm_pkg.provides; - while (list != null) { - provides += ((Alpm.List) list).data.compute_string (); - list.next (); - } - // replaces - list = alpm_pkg.replaces; - while (list != null) { - replaces += ((Alpm.List) list).data.compute_string (); - list.next (); - } - // conflicts - list = alpm_pkg.conflicts; - while (list != null) { - conflicts += ((Alpm.List) list).data.compute_string (); - list.next (); - } - } - details.name = (owned) name; - details.version = (owned) version; - details.desc = (owned) desc; - details.repo = (owned) repo; - details.url = (owned) url; - details.packager = (owned) packager; - details.builddate = (owned) builddate; - details.installdate = (owned) installdate; - details.reason = (owned) reason; - details.has_signature = (owned) has_signature; - details.licenses = (owned) licenses; - details.depends = (owned) depends; - details.optdepends = (owned) optdepends; - details.requiredby = (owned) requiredby; - details.optionalfor = (owned) optionalfor; - details.provides = (owned) provides; - details.replaces = (owned) replaces; - details.conflicts = (owned) conflicts; - details.groups = (owned) groups; - details.backups = (owned) backups; - return details; - } - - public string[] get_pkg_files (string pkgname) { - string[] files = {}; - unowned Alpm.Package? alpm_pkg = alpm_handle.localdb.get_pkg (pkgname); - if (alpm_pkg != null) { - unowned Alpm.FileList filelist = alpm_pkg.files; - Alpm.File* file_ptr = filelist.files; - for (size_t i = 0; i < filelist.count; i++, file_ptr++) { - if (!file_ptr->name.has_suffix ("/")) { - files += "/" + file_ptr->name; - } - } - } else { - unowned Alpm.List syncdbs = files_handle.syncdbs; - while (syncdbs != null) { - unowned Alpm.DB db = syncdbs.data; - unowned Alpm.Package? files_pkg = db.get_pkg (pkgname); - if (files_pkg != null) { - unowned Alpm.FileList filelist = files_pkg.files; - Alpm.File* file_ptr = filelist.files; - for (size_t i = 0; i < filelist.count; i++, file_ptr++) { - if (!file_ptr->name.has_suffix ("/")) { - files += "/" + file_ptr->name; - } - } - break; - } - syncdbs.next (); - } - } - return files; - } - private void get_updates () { - UpdateInfos[] updates_infos = {}; + AlpmPackage[] updates_infos = {}; unowned Alpm.Package? pkg = null; unowned Alpm.Package? candidate = null; foreach (unowned string name in alpm_config.get_syncfirsts ()) { @@ -1430,13 +734,8 @@ namespace Pamac { if (pkg != null) { candidate = pkg.sync_newversion (alpm_handle.syncdbs); if (candidate != null) { - var infos = UpdateInfos () { - name = candidate.name, - old_version = pkg.version, - new_version = candidate.version, - repo = candidate.db.name, - download_size = candidate.download_size - }; + var infos = initialise_pkg_struct (candidate); + infos.installed_version = pkg.version; updates_infos += (owned) infos; } } @@ -1457,16 +756,11 @@ namespace Pamac { if (alpm_handle.should_ignore (installed_pkg) == 0) { candidate = installed_pkg.sync_newversion (alpm_handle.syncdbs); if (candidate != null) { - var infos = UpdateInfos () { - name = candidate.name, - old_version = installed_pkg.version, - new_version = candidate.version, - repo = candidate.db.name, - download_size = candidate.download_size - }; + var infos = initialise_pkg_struct (candidate); + infos.installed_version = installed_pkg.version; updates_infos += (owned) infos; } else { - if (check_aur_updates && (aur_updates_results.get_length () == 0)) { + if (check_aur_updates && (!aur_updates_checked)) { // check if installed_pkg is a local pkg unowned Alpm.List syncdbs = alpm_handle.syncdbs; while (syncdbs != null) { @@ -1487,9 +781,10 @@ namespace Pamac { } if (check_aur_updates) { // get aur updates - if (aur_updates_results.get_length () == 0) { + if (!aur_updates_checked) { AUR.multiinfo.begin (local_pkgs, (obj, res) => { aur_updates_results = AUR.multiinfo.end (res); + aur_updates_checked = true; var updates = Updates () { is_syncfirst = false, repos_updates = (owned) updates_infos, @@ -1516,20 +811,16 @@ namespace Pamac { } } - private UpdateInfos[] get_aur_updates_infos () { - UpdateInfos[] aur_updates_infos = {}; + private AURPackage[] get_aur_updates_infos () { + AURPackage[] aur_updates_infos = {}; aur_updates_results.foreach_element ((array, index, node) => { unowned Json.Object pkg_info = node.get_object (); unowned string name = pkg_info.get_string_member ("Name"); unowned string new_version = pkg_info.get_string_member ("Version"); unowned string old_version = alpm_handle.localdb.get_pkg (name).version; if (Alpm.pkg_vercmp (new_version, old_version) == 1) { - var infos = UpdateInfos () { - name = name, - old_version = old_version, - new_version = new_version, - repo = "" - }; + var infos = initialise_aur_struct (pkg_info); + infos.installed_version = old_version; aur_updates_infos += (owned) infos; } }); @@ -1547,16 +838,6 @@ namespace Pamac { private bool trans_init (Alpm.TransFlag flags) { current_error = ErrorInfos (); - if (!databases_lock_mutex.trylock ()) { - // Wait for pacman to finish - emit_event (0, 0, {}); - databases_lock_mutex.lock (); - } - if (cancellable.is_cancelled ()) { - cancellable.reset (); - databases_lock_mutex.unlock (); - return false; - } cancellable.reset (); if (alpm_handle.trans_init (flags) == -1) { Alpm.Errno errno = alpm_handle.errno (); @@ -1565,7 +846,6 @@ namespace Pamac { if (errno != 0) { current_error.details = { Alpm.strerror (errno) }; } - databases_lock_mutex.unlock (); return false; } return true; @@ -1583,7 +863,7 @@ namespace Pamac { if (errno != 0) { current_error.details = { Alpm.strerror (errno) }; } - trans_release (); + trans_release (lock_id); success = false; } else { success = trans_prepare_real (); @@ -1592,7 +872,10 @@ namespace Pamac { trans_prepare_finished (success); } - public void start_sysupgrade_prepare_ (bool enable_downgrade_, string[] temporary_ignorepkgs_) { + public void start_sysupgrade_prepare (bool enable_downgrade_, string[] temporary_ignorepkgs_, GLib.BusName sender) { + if (lock_id != sender) { + return; + } enable_downgrade = enable_downgrade_; temporary_ignorepkgs = temporary_ignorepkgs_; try { @@ -1765,13 +1048,13 @@ namespace Pamac { string detail; if (miss->causingpkg == null) { /* package being installed/upgraded has unresolved dependency */ - detail = _("%s: requires %s").printf (miss->target, depstring); + detail = _("unable to satisfy dependency '%s' required by %s").printf (depstring, miss->target); } else if ((pkg = Alpm.pkg_find (trans_add, miss->causingpkg)) != null) { /* upgrading a package breaks a local dependency */ - detail = _("%s: installing %s (%s) breaks dependency '%s'").printf (miss->target, miss->causingpkg, pkg.version, depstring); + detail = _("installing %s (%s) breaks dependency '%s' required by %s").printf (miss->causingpkg, pkg.version, depstring, miss->target); } else { /* removing a package breaks a local dependency */ - detail = _("%s: removing %s breaks dependency '%s'").printf (miss->target, miss->causingpkg, depstring); + detail = _("removing %s breaks dependency '%s' required by %s").printf (miss->causingpkg, depstring, miss->target); } if (!(detail in details)) { details += detail; @@ -1800,7 +1083,7 @@ namespace Pamac { break; } current_error.details = (owned) details; - trans_release (); + trans_release (lock_id); success = false; } else { // Search for holdpkg in target list @@ -1818,7 +1101,7 @@ namespace Pamac { if (found_locked_pkg) { current_error.message = _("Failed to prepare transaction"); current_error.details = (owned) details; - trans_release (); + trans_release (lock_id); success = false; } } @@ -1853,23 +1136,13 @@ namespace Pamac { if (success) { success = trans_prepare_real (); } else { - trans_release (); + trans_release (lock_id); } } trans_prepare_finished (success); } private void build_prepare () { - if (!databases_lock_mutex.trylock ()) { - // Wait for pacman to finish - emit_event (0, 0, {}); - databases_lock_mutex.lock (); - } - if (cancellable.is_cancelled ()) { - cancellable.reset (); - databases_lock_mutex.unlock (); - return; - } // create a fake aur db try { var list = new StringBuilder (); @@ -1897,6 +1170,11 @@ namespace Pamac { // add to_build in to_install for the fake trans prpeapre foreach (unowned string name in to_build) { to_install += name; + // check if we need to remove debug package to avoid dep problem + string debug_pkg_name = "%s-debug".printf (name); + if (alpm_handle.localdb.get_pkg (debug_pkg_name) != null) { + to_remove += debug_pkg_name; + } } // check base-devel group needed to build pkgs var backup_to_remove = new GenericSet (str_hash, str_equal); @@ -2019,31 +1297,25 @@ namespace Pamac { } pkgs_to_remove.next (); } - trans_release (); + trans_release (lock_id); try { Process.spawn_command_line_sync ("rm -f %ssync/aur.db".printf (alpm_handle.dbpath)); } catch (SpawnError e) { stderr.printf ("SpawnError: %s\n", e.message); } // get standard handle - databases_lock_mutex.lock (); refresh_handle (); - databases_lock_mutex.unlock (); // launch standard prepare to_install = real_to_install; trans_prepare (); } } else { - trans_release (); + trans_release (lock_id); } - } else { - databases_lock_mutex.unlock (); } if (!success) { // get standard handle - databases_lock_mutex.lock (); refresh_handle (); - databases_lock_mutex.unlock (); trans_prepare_finished (false); } } @@ -2053,7 +1325,11 @@ namespace Pamac { string[] to_install_, string[] to_remove_, string[] to_load_, - string[] to_build_) { + string[] to_build_, + GLib.BusName sender) { + if (lock_id != sender) { + return; + } flags = flags_; to_install = to_install_; to_remove = to_remove_; @@ -2160,7 +1436,7 @@ namespace Pamac { current_error.errno = (uint) errno; // cancel the download return an EXTERNAL_DOWNLOAD error if (errno == Alpm.Errno.EXTERNAL_DOWNLOAD && cancellable.is_cancelled ()) { - trans_release (); + trans_release (lock_id); trans_commit_finished (false); return; } @@ -2215,7 +1491,7 @@ namespace Pamac { } success = false; } - trans_release (); + trans_release (lock_id); to_install_as_dep.foreach_remove ((pkgname, val) => { unowned Alpm.Package? pkg = alpm_handle.localdb.get_pkg (pkgname); if (pkg != null) { @@ -2237,20 +1513,24 @@ namespace Pamac { stderr.printf ("Thread Error %s\n", e.message); } } else { - trans_release (); + trans_release (lock_id); trans_commit_finished (false); } }); } - public void trans_release () { + public void trans_release (GLib.BusName sender) { + if (lock_id != sender) { + return; + } alpm_handle.trans_release (); remove_ignorepkgs (); - databases_lock_mutex.unlock (); } - [DBus (no_reply = true)] - public void trans_cancel () { + public void trans_cancel (GLib.BusName sender) { + if (lock_id != sender) { + return; + } if (alpm_handle.trans_interrupt () == 0) { // a transaction is being interrupted // it will end the normal way @@ -2347,7 +1627,7 @@ private void cb_event (Alpm.Event.Data data) { break; case Alpm.Event.Type.PKGDOWNLOAD_START: // do not emit event when download is cancelled - if (pamac_daemon.cancellable.is_cancelled ()) { + if (system_daemon.cancellable.is_cancelled ()) { return; } details += data.pkgdownload_file; @@ -2368,7 +1648,7 @@ private void cb_event (Alpm.Event.Data data) { default: break; } - pamac_daemon.emit_event ((uint) data.type, secondary_type, details); + system_daemon.emit_event ((uint) data.type, secondary_type, details); } private void cb_question (Alpm.Question.Data data) { @@ -2398,16 +1678,16 @@ private void cb_question (Alpm.Question.Data data) { providers_str += pkg.name; list.next (); } - pamac_daemon.provider_cond = Cond (); - pamac_daemon.provider_mutex = Mutex (); - pamac_daemon.choosen_provider = null; - pamac_daemon.emit_providers (depend_str, providers_str); - pamac_daemon.provider_mutex.lock (); - while (pamac_daemon.choosen_provider == null) { - pamac_daemon.provider_cond.wait (pamac_daemon.provider_mutex); + system_daemon.provider_cond = Cond (); + system_daemon.provider_mutex = Mutex (); + system_daemon.choosen_provider = null; + system_daemon.emit_providers (depend_str, providers_str); + system_daemon.provider_mutex.lock (); + while (system_daemon.choosen_provider == null) { + system_daemon.provider_cond.wait (system_daemon.provider_mutex); } - data.select_provider_use_index = pamac_daemon.choosen_provider; - pamac_daemon.provider_mutex.unlock (); + data.select_provider_use_index = system_daemon.choosen_provider; + system_daemon.provider_mutex.unlock (); break; case Alpm.Question.Type.CORRUPTED_PKG: // Auto-remove corrupted pkgs in cache @@ -2430,16 +1710,16 @@ private void cb_question (Alpm.Question.Data data) { private void cb_progress (Alpm.Progress progress, string pkgname, int percent, uint n_targets, uint current_target) { if (percent == 0) { - pamac_daemon.emit_progress ((uint) progress, pkgname, (uint) percent, n_targets, current_target); - pamac_daemon.timer.start (); + system_daemon.emit_progress ((uint) progress, pkgname, (uint) percent, n_targets, current_target); + system_daemon.timer.start (); } else if (percent == 100) { - pamac_daemon.emit_progress ((uint) progress, pkgname, (uint) percent, n_targets, current_target); - pamac_daemon.timer.stop (); - }else if (pamac_daemon.timer.elapsed () < 0.5) { + system_daemon.emit_progress ((uint) progress, pkgname, (uint) percent, n_targets, current_target); + system_daemon.timer.stop (); + }else if (system_daemon.timer.elapsed () < 0.5) { return; } else { - pamac_daemon.emit_progress ((uint) progress, pkgname, (uint) percent, n_targets, current_target); - pamac_daemon.timer.start (); + system_daemon.emit_progress ((uint) progress, pkgname, (uint) percent, n_targets, current_target); + system_daemon.timer.start (); } } @@ -2447,7 +1727,7 @@ private uint64 prevprogress; private int cb_download (void* data, uint64 dltotal, uint64 dlnow, uint64 ultotal, uint64 ulnow) { - if (unlikely (pamac_daemon.cancellable.is_cancelled ())) { + if (unlikely (system_daemon.cancellable.is_cancelled ())) { return 1; } @@ -2456,17 +1736,17 @@ private int cb_download (void* data, uint64 dltotal, uint64 dlnow, uint64 ultota if (unlikely (dlnow == 0 || dltotal == 0 || prevprogress == dltotal)) { return 0; } else if (unlikely (prevprogress == 0)) { - pamac_daemon.emit_download (filename, 0, dltotal); - pamac_daemon.emit_download (filename, dlnow, dltotal); - pamac_daemon.timer.start (); + system_daemon.emit_download (filename, 0, dltotal); + system_daemon.emit_download (filename, dlnow, dltotal); + system_daemon.timer.start (); } else if (unlikely (dlnow == dltotal)) { - pamac_daemon.emit_download (filename, dlnow, dltotal); - pamac_daemon.timer.stop (); - } else if (likely (pamac_daemon.timer.elapsed () < 0.5)) { + system_daemon.emit_download (filename, dlnow, dltotal); + system_daemon.timer.stop (); + } else if (likely (system_daemon.timer.elapsed () < 0.5)) { return 0; } else { - pamac_daemon.emit_download (filename, dlnow, dltotal); - pamac_daemon.timer.start (); + system_daemon.emit_download (filename, dlnow, dltotal); + system_daemon.timer.start (); } prevprogress = dlnow; @@ -2475,7 +1755,7 @@ private int cb_download (void* data, uint64 dltotal, uint64 dlnow, uint64 ultota } private int cb_fetch (string fileurl, string localpath, int force) { - if (pamac_daemon.cancellable.is_cancelled ()) { + if (system_daemon.cancellable.is_cancelled ()) { return -1; } @@ -2484,20 +1764,20 @@ private int cb_fetch (string fileurl, string localpath, int force) { var destfile = GLib.File.new_for_path (localpath + url.get_basename ()); var tempfile = GLib.File.new_for_path (destfile.get_path () + ".part"); - pamac_daemon.curl.reset (); - pamac_daemon.curl.setopt (Curl.Option.FAILONERROR, 1L); - pamac_daemon.curl.setopt (Curl.Option.CONNECTTIMEOUT, 30L); - pamac_daemon.curl.setopt (Curl.Option.FILETIME, 1L); - pamac_daemon.curl.setopt (Curl.Option.FOLLOWLOCATION, 1L); - pamac_daemon.curl.setopt (Curl.Option.XFERINFOFUNCTION, cb_download); - pamac_daemon.curl.setopt (Curl.Option.LOW_SPEED_LIMIT, 1L); - pamac_daemon.curl.setopt (Curl.Option.LOW_SPEED_TIME, 30L); - pamac_daemon.curl.setopt (Curl.Option.NETRC, Curl.NetRCOption.OPTIONAL); - pamac_daemon.curl.setopt (Curl.Option.HTTPAUTH, Curl.CURLAUTH_ANY); - pamac_daemon.curl.setopt (Curl.Option.URL, fileurl); - pamac_daemon.curl.setopt (Curl.Option.ERRORBUFFER, error_buffer); - pamac_daemon.curl.setopt (Curl.Option.NOPROGRESS, 0L); - pamac_daemon.curl.setopt (Curl.Option.XFERINFODATA, (void*) url.get_basename ()); + system_daemon.curl.reset (); + system_daemon.curl.setopt (Curl.Option.FAILONERROR, 1L); + system_daemon.curl.setopt (Curl.Option.CONNECTTIMEOUT, 30L); + system_daemon.curl.setopt (Curl.Option.FILETIME, 1L); + system_daemon.curl.setopt (Curl.Option.FOLLOWLOCATION, 1L); + system_daemon.curl.setopt (Curl.Option.XFERINFOFUNCTION, cb_download); + system_daemon.curl.setopt (Curl.Option.LOW_SPEED_LIMIT, 1L); + system_daemon.curl.setopt (Curl.Option.LOW_SPEED_TIME, 30L); + system_daemon.curl.setopt (Curl.Option.NETRC, Curl.NetRCOption.OPTIONAL); + system_daemon.curl.setopt (Curl.Option.HTTPAUTH, Curl.CURLAUTH_ANY); + system_daemon.curl.setopt (Curl.Option.URL, fileurl); + system_daemon.curl.setopt (Curl.Option.ERRORBUFFER, error_buffer); + system_daemon.curl.setopt (Curl.Option.NOPROGRESS, 0L); + system_daemon.curl.setopt (Curl.Option.XFERINFODATA, (void*) url.get_basename ()); bool remove_partial_download = true; if (fileurl.contains (".pkg.tar.") && !fileurl.has_suffix (".sig")) { @@ -2511,15 +1791,15 @@ private int cb_fetch (string fileurl, string localpath, int force) { if (force == 0) { if (destfile.query_exists ()) { // start from scratch only download if our local is out of date. - pamac_daemon.curl.setopt (Curl.Option.TIMECONDITION, Curl.TimeCond.IFMODSINCE); + system_daemon.curl.setopt (Curl.Option.TIMECONDITION, Curl.TimeCond.IFMODSINCE); FileInfo info = destfile.query_info ("time::modified", 0); TimeVal time = info.get_modification_time (); - pamac_daemon.curl.setopt (Curl.Option.TIMEVALUE, time.tv_sec); + system_daemon.curl.setopt (Curl.Option.TIMEVALUE, time.tv_sec); } else if (tempfile.query_exists ()) { // a previous partial download exists, resume from end of file. FileInfo info = tempfile.query_info ("standard::size", 0); int64 size = info.get_size (); - pamac_daemon.curl.setopt (Curl.Option.RESUME_FROM_LARGE, size); + system_daemon.curl.setopt (Curl.Option.RESUME_FROM_LARGE, size); open_mode = "ab"; } } else { @@ -2537,17 +1817,17 @@ private int cb_fetch (string fileurl, string localpath, int force) { return -1; } - pamac_daemon.curl.setopt (Curl.Option.WRITEDATA, localf); + system_daemon.curl.setopt (Curl.Option.WRITEDATA, localf); // perform transfer - Curl.Code err = pamac_daemon.curl.perform (); + Curl.Code err = system_daemon.curl.perform (); // disconnect relationships from the curl handle for things that might go out // of scope, but could still be touched on connection teardown. This really // only applies to FTP transfers. - pamac_daemon.curl.setopt (Curl.Option.NOPROGRESS, 1L); - pamac_daemon.curl.setopt (Curl.Option.ERRORBUFFER, null); + system_daemon.curl.setopt (Curl.Option.NOPROGRESS, 1L); + system_daemon.curl.setopt (Curl.Option.ERRORBUFFER, null); int ret; @@ -2559,11 +1839,11 @@ private int cb_fetch (string fileurl, string localpath, int force) { unowned string effective_url; // retrieve info about the state of the transfer - pamac_daemon.curl.getinfo (Curl.Info.FILETIME, out remote_time); - pamac_daemon.curl.getinfo (Curl.Info.CONTENT_LENGTH_DOWNLOAD, out remote_size); - pamac_daemon.curl.getinfo (Curl.Info.SIZE_DOWNLOAD, out bytes_dl); - pamac_daemon.curl.getinfo (Curl.Info.CONDITION_UNMET, out timecond); - pamac_daemon.curl.getinfo (Curl.Info.EFFECTIVE_URL, out effective_url); + system_daemon.curl.getinfo (Curl.Info.FILETIME, out remote_time); + system_daemon.curl.getinfo (Curl.Info.CONTENT_LENGTH_DOWNLOAD, out remote_size); + system_daemon.curl.getinfo (Curl.Info.SIZE_DOWNLOAD, out bytes_dl); + system_daemon.curl.getinfo (Curl.Info.CONDITION_UNMET, out timecond); + system_daemon.curl.getinfo (Curl.Info.EFFECTIVE_URL, out effective_url); if (timecond == 1 && bytes_dl == 0) { // time condition was met and we didn't download anything. we need to @@ -2583,8 +1863,8 @@ private int cb_fetch (string fileurl, string localpath, int force) { else if (remote_size != -1 && bytes_dl != -1 && bytes_dl != remote_size) { string error = _("%s appears to be truncated: %jd/%jd bytes\n").printf ( fileurl, bytes_dl, remote_size); - pamac_daemon.emit_log ((uint) Alpm.LogLevel.ERROR, error); - pamac_daemon.current_error.details = {error}; + system_daemon.emit_log ((uint) Alpm.LogLevel.ERROR, error); + system_daemon.current_error.details = {error}; if (remove_partial_download) { try { if (tempfile.query_exists ()) { @@ -2639,8 +1919,8 @@ private int cb_fetch (string fileurl, string localpath, int force) { string hostname = url.get_uri ().split("/")[2]; string error = _("failed retrieving file '%s' from %s : %s\n").printf ( url.get_basename (), hostname, (string) error_buffer); - pamac_daemon.emit_log ((uint) Alpm.LogLevel.ERROR, error); - pamac_daemon.current_error.details = {error}; + system_daemon.emit_log ((uint) Alpm.LogLevel.ERROR, error); + system_daemon.current_error.details = {error}; } ret = -1; break; @@ -2650,12 +1930,12 @@ private int cb_fetch (string fileurl, string localpath, int force) { } private void cb_totaldownload (uint64 total) { - pamac_daemon.emit_totaldownload (total); + system_daemon.emit_totaldownload (total); } private void cb_log (Alpm.LogLevel level, string fmt, va_list args) { // do not log errors when download is cancelled - if (pamac_daemon.cancellable.is_cancelled ()) { + if (system_daemon.cancellable.is_cancelled ()) { return; } Alpm.LogLevel logmask = Alpm.LogLevel.ERROR | Alpm.LogLevel.WARNING; @@ -2665,14 +1945,14 @@ private void cb_log (Alpm.LogLevel level, string fmt, va_list args) { string? log = null; log = fmt.vprintf (args); if (log != null) { - pamac_daemon.emit_log ((uint) level, log); + system_daemon.emit_log ((uint) level, log); } } void on_bus_acquired (DBusConnection conn) { - pamac_daemon = new Pamac.Daemon (); + system_daemon = new Pamac.SystemDaemon (); try { - conn.register_object ("/org/manjaro/pamac", pamac_daemon); + conn.register_object ("/org/manjaro/pamac/system", system_daemon); } catch (IOError e) { stderr.printf ("Could not register service\n"); @@ -2686,7 +1966,7 @@ void main () { Intl.textdomain (GETTEXT_PACKAGE); Bus.own_name (BusType.SYSTEM, - "org.manjaro.pamac", + "org.manjaro.pamac.system", BusNameOwnerFlags.NONE, on_bus_acquired, null, diff --git a/src/transaction.vala b/src/transaction.vala index 73614d0..59a8111 100644 --- a/src/transaction.vala +++ b/src/transaction.vala @@ -17,22 +17,11 @@ * along with this program. If not, see . */ -const string VERSION = "4.3.7"; - namespace Pamac { - [DBus (name = "org.manjaro.pamac")] - interface Daemon : Object { - public abstract void set_environment_variables (HashTable variables) throws IOError; - public abstract ErrorInfos get_current_error () throws IOError; - public abstract void start_get_authorization () throws IOError; - public abstract void start_write_pamac_config (HashTable new_pamac_conf) throws IOError; - public abstract void start_write_alpm_config (HashTable new_alpm_conf) throws IOError; - public abstract void start_write_mirrors_config (HashTable new_mirrors_conf) throws IOError; - public abstract void start_generate_mirrors_list () throws IOError; - public abstract void clean_cache (uint keep_nb, bool only_uninstalled) throws IOError; - public abstract void start_set_pkgreason (string pkgname, uint reason) throws IOError; + [DBus (name = "org.manjaro.pamac.user")] + interface UserDaemon : Object { + public abstract void refresh_handle () throws IOError; public abstract AlpmPackage get_installed_pkg (string pkgname) throws IOError; - public abstract void start_refresh (bool force) throws IOError; public abstract bool get_checkspace () throws IOError; public abstract string[] get_ignorepkgs () throws IOError; public abstract bool should_hold (string pkgname) throws IOError; @@ -56,16 +45,36 @@ namespace Pamac { public abstract async AURPackageDetails get_aur_details (string pkgname) throws IOError; public abstract string[] get_pkg_uninstalled_optdeps (string pkgname) throws IOError; public abstract void start_get_updates (bool check_aur_updates) throws IOError; + [DBus (no_reply = true)] + public abstract void quit () throws IOError; + public signal void get_updates_finished (Updates updates); + } + [DBus (name = "org.manjaro.pamac.system")] + interface SystemDaemon : Object { + public abstract void set_environment_variables (HashTable variables) throws IOError; + public abstract string[] get_mirrors_countries () throws IOError; + public abstract ErrorInfos get_current_error () throws IOError; + public abstract bool get_lock () throws IOError; + public abstract bool unlock () throws IOError; + public abstract void start_get_authorization () throws IOError; + public abstract void start_write_pamac_config (HashTable new_pamac_conf) throws IOError; + public abstract void start_write_alpm_config (HashTable new_alpm_conf) throws IOError; + public abstract void start_write_mirrors_config (HashTable new_mirrors_conf) throws IOError; + public abstract void start_generate_mirrors_list () throws IOError; + public abstract void clean_cache (uint keep_nb, bool only_uninstalled) throws IOError; + public abstract void start_set_pkgreason (string pkgname, uint reason) throws IOError; + public abstract void start_refresh (bool force) throws IOError; public abstract void start_sysupgrade_prepare (bool enable_downgrade, string[] temporary_ignorepkgs) throws IOError; public abstract void start_trans_prepare (int transflags, string[] to_install, string[] to_remove, string[] to_load, string[] to_build) throws IOError; public abstract void choose_provider (int provider) throws IOError; public abstract TransactionSummary get_transaction_summary () throws IOError; public abstract void start_trans_commit () throws IOError; public abstract void trans_release () throws IOError; - [DBus (no_reply = true)] public abstract void trans_cancel () throws IOError; + public abstract void start_get_updates (bool check_aur_updates) throws IOError; [DBus (no_reply = true)] public abstract void quit () throws IOError; + public signal void get_updates_finished (Updates updates); public signal void emit_event (uint primary_event, uint secondary_event, string[] details); public signal void emit_providers (string depend, string[] providers); public signal void emit_progress (uint progress, string pkgname, uint percent, uint n_targets, uint current_target); @@ -74,7 +83,6 @@ namespace Pamac { public signal void emit_log (uint level, string msg); public signal void set_pkgreason_finished (); public signal void refresh_finished (bool success); - public signal void get_updates_finished (Updates updates); public signal void trans_prepare_finished (bool success); public signal void trans_commit_finished (bool success); public signal void get_authorization_finished (bool authorized); @@ -86,11 +94,6 @@ namespace Pamac { public signal void generate_mirrors_list_finished (); } - public enum Mode { - MANAGER, - UPDATER - } - public class Transaction: Object { enum Type { @@ -99,7 +102,8 @@ namespace Pamac { BUILD = (1 << 2) } - Daemon daemon; + UserDaemon user_daemon; + SystemDaemon system_daemon; Pamac.Config pamac_config; public bool check_aur_updates { get { return pamac_config.check_aur_updates; } } @@ -117,6 +121,7 @@ namespace Pamac { public GenericSet to_remove; public GenericSet to_load; public GenericSet to_build; + public GenericSet to_update; Queue to_build_queue; string[] aur_pkgs_to_install; GenericSet previous_to_install; @@ -124,8 +129,6 @@ namespace Pamac { public GenericSet transaction_summary; public GenericSet temporary_ignorepkgs; - public Mode mode { get; set; } - uint64 total_download; uint64 already_downloaded; string previous_textbar; @@ -154,22 +157,20 @@ namespace Pamac { //parent window public Gtk.ApplicationWindow? application_window { get; private set; } - public signal void start_waiting (); - public signal void stop_waiting (); public signal void start_downloading (); public signal void stop_downloading (); public signal void start_building (); public signal void stop_building (); public signal void important_details_outpout (bool must_show); - public signal void alpm_handle_refreshed (); public signal void finished (bool success); public signal void set_pkgreason_finished (); - public signal void get_updates_finished (Updates updates); public signal void write_pamac_config_finished (bool recurse, uint64 refresh_period, bool no_update_hide_icon, bool enable_aur, bool search_aur, bool check_aur_updates); public signal void write_alpm_config_finished (bool checkspace); public signal void write_mirrors_config_finished (string choosen_country, string choosen_generation_method); public signal void generate_mirrors_list (); + public signal void run_preferences_dialog_finished (); + public signal void get_updates_finished (Updates updates); public Transaction (Gtk.ApplicationWindow? application_window) { pamac_config = new Pamac.Config ("/etc/pamac.conf"); @@ -177,17 +178,17 @@ namespace Pamac { if (pamac_config.recurse) { flags |= (1 << 5); //Alpm.TransFlag.RECURSE } - to_install = new GenericSet (str_hash, str_equal); to_remove = new GenericSet (str_hash, str_equal); to_load = new GenericSet (str_hash, str_equal); to_build = new GenericSet (str_hash, str_equal); + to_update = new GenericSet (str_hash, str_equal); to_build_queue = new Queue (); previous_to_install = new GenericSet (str_hash, str_equal); previous_to_remove = new GenericSet (str_hash, str_equal); transaction_summary = new GenericSet (str_hash, str_equal); temporary_ignorepkgs = new GenericSet (str_hash, str_equal); - connecting_dbus_signals (); + connecting_user_daemon (); //creating dialogs this.application_window = application_window; transaction_sum_dialog = new TransactionSumDialog (application_window); @@ -230,39 +231,7 @@ namespace Pamac { warning_textbuffer = new StringBuilder (); } - public void run_history_dialog () { - var file = GLib.File.new_for_path ("/var/log/pacman.log"); - if (!file.query_exists ()) { - GLib.stderr.printf ("File '%s' doesn't exist.\n", file.get_path ()); - } else { - StringBuilder text = new StringBuilder (); - try { - // Open file for reading and wrap returned FileInputStream into a - // DataInputStream, so we can read line by line - var dis = new DataInputStream (file.read ()); - string line; - // Read lines until end of file (null) is reached - while ((line = dis.read_line ()) != null) { - // construct text in reverse order - text.prepend (line + "\n"); - } - } catch (GLib.Error e) { - GLib.stderr.printf ("%s\n", e.message); - } - var history_dialog = new HistoryDialog (application_window); - history_dialog.textview.buffer.set_text (text.str, (int) text.len); - history_dialog.show (); - history_dialog.response.connect (() => { - history_dialog.destroy (); - }); - while (Gtk.events_pending ()) { - Gtk.main_iteration (); - } - } - } - - public async void run_preferences_dialog () { - SourceFunc callback = run_preferences_dialog.callback; + public void run_preferences_dialog () { check_authorization.begin ((obj, res) => { bool authorized = check_authorization.end (res); if (authorized) { @@ -273,73 +242,95 @@ namespace Pamac { Gtk.main_iteration (); } } - Idle.add ((owned) callback); + run_preferences_dialog_finished (); }); - yield; - } - - public void run_about_dialog () { - string[] authors = {"Guillaume Benoit"}; - Gtk.show_about_dialog ( - application_window, - "program_name", "Pamac", - "icon_name", "system-software-install", - "logo_icon_name", "system-software-install", - "comments", dgettext (null, "A Gtk3 frontend for libalpm"), - "copyright", "Copyright © 2017 Guillaume Benoit", - "authors", authors, - "version", VERSION, - "license_type", Gtk.License.GPL_3_0, - "website", "http://github.com/manjaro/pamac"); } public ErrorInfos get_current_error () { try { - return daemon.get_current_error (); + return system_daemon.get_current_error (); } catch (IOError e) { stderr.printf ("IOError: %s\n", e.message); return ErrorInfos (); } } + public string[] get_mirrors_countries () { + string[] countries = {}; + connecting_system_daemon (); + try { + countries = system_daemon.get_mirrors_countries (); + } catch (IOError e) { + stderr.printf ("IOError: %s\n", e.message); + } + return countries; + } + + public bool get_lock () { + bool locked = false; + connecting_system_daemon (); + try { + locked = system_daemon.get_lock (); + } catch (IOError e) { + stderr.printf ("IOError: %s\n", e.message); + } + return locked; + } + + public bool unlock () { + bool unlocked = false; + try { + unlocked = system_daemon.unlock (); + } catch (IOError e) { + stderr.printf ("IOError: %s\n", e.message); + } + return unlocked; + } + async bool check_authorization () { SourceFunc callback = check_authorization.callback; bool authorized = false; - ulong handler_id = daemon.get_authorization_finished.connect ((authorized_) => { + ulong handler_id = system_daemon.get_authorization_finished.connect ((authorized_) => { authorized = authorized_; Idle.add ((owned) callback); }); try { - daemon.start_get_authorization (); + system_daemon.start_get_authorization (); } catch (IOError e) { stderr.printf ("IOError: %s\n", e.message); } yield; - daemon.disconnect (handler_id); + system_daemon.disconnect (handler_id); return authorized; } public void start_write_pamac_config (HashTable new_pamac_conf) { try { - daemon.start_write_pamac_config (new_pamac_conf); + system_daemon.write_pamac_config_finished.connect (on_write_pamac_config_finished); + system_daemon.start_write_pamac_config (new_pamac_conf); } catch (IOError e) { stderr.printf ("IOError: %s\n", e.message); + system_daemon.write_pamac_config_finished.disconnect (on_write_pamac_config_finished); } } public void start_write_alpm_config (HashTable new_alpm_conf) { try { - daemon.start_write_alpm_config (new_alpm_conf); + system_daemon.write_alpm_config_finished.connect (on_write_alpm_config_finished); + system_daemon.start_write_alpm_config (new_alpm_conf); } catch (IOError e) { stderr.printf ("IOError: %s\n", e.message); + system_daemon.write_alpm_config_finished.disconnect (on_write_alpm_config_finished); } } public void start_write_mirrors_config (HashTable new_mirrors_conf) { try { - daemon.start_write_mirrors_config (new_mirrors_conf); + system_daemon.write_mirrors_config_finished.connect (on_write_mirrors_config_finished); + system_daemon.start_write_mirrors_config (new_mirrors_conf); } catch (IOError e) { stderr.printf ("IOError: %s\n", e.message); + system_daemon.write_mirrors_config_finished.disconnect (on_write_mirrors_config_finished); } } @@ -415,12 +406,12 @@ namespace Pamac { progress_box.progressbar.text = ""; } - void start_progressbar_pulse () { + public void start_progressbar_pulse () { stop_progressbar_pulse (); pulse_timeout_id = Timeout.add (500, (GLib.SourceFunc) progress_box.progressbar.pulse); } - void stop_progressbar_pulse () { + public void stop_progressbar_pulse () { if (pulse_timeout_id != 0) { Source.remove (pulse_timeout_id); pulse_timeout_id = 0; @@ -435,16 +426,20 @@ namespace Pamac { important_details_outpout (false); generate_mirrors_list (); try { - daemon.start_generate_mirrors_list (); + system_daemon.generate_mirrors_list_data.connect (on_generate_mirrors_list_data); + system_daemon.generate_mirrors_list_finished.connect (on_generate_mirrors_list_finished); + system_daemon.start_generate_mirrors_list (); } catch (IOError e) { stderr.printf ("IOError: %s\n", e.message); stop_progressbar_pulse (); + system_daemon.generate_mirrors_list_data.disconnect (on_generate_mirrors_list_data); + system_daemon.generate_mirrors_list_finished.disconnect (on_generate_mirrors_list_finished); } } public void clean_cache (uint keep_nb, bool only_uninstalled) { try { - daemon.clean_cache (keep_nb, only_uninstalled); + system_daemon.clean_cache (keep_nb, only_uninstalled); } catch (IOError e) { stderr.printf ("IOError: %s\n", e.message); } @@ -452,30 +447,42 @@ namespace Pamac { public void start_set_pkgreason (string pkgname, uint reason) { try { - daemon.start_set_pkgreason (pkgname, reason); + system_daemon.set_pkgreason_finished.connect (on_set_pkgreason_finished); + system_daemon.start_set_pkgreason (pkgname, reason); } catch (IOError e) { stderr.printf ("IOError: %s\n", e.message); + system_daemon.set_pkgreason_finished.disconnect (on_set_pkgreason_finished); } } public void start_refresh (bool force) { string action = dgettext (null, "Synchronizing package databases") + "..."; reset_progress_box (action); + connecting_system_daemon (); + connecting_dbus_signals (); try { - daemon.refresh_finished.connect (on_refresh_finished); - daemon.start_refresh (force); + system_daemon.refresh_finished.connect (on_refresh_finished); + system_daemon.start_refresh (force); } catch (IOError e) { stderr.printf ("IOError: %s\n", e.message); - daemon.refresh_finished.disconnect (on_refresh_finished); + system_daemon.refresh_finished.disconnect (on_refresh_finished); success = false; finish_transaction (); } } + public void refresh_handle () { + try { + user_daemon.refresh_handle (); + } catch (IOError e) { + stderr.printf ("IOError: %s\n", e.message); + } + } + public bool get_checkspace () { bool checkspace = false; try { - checkspace = daemon.get_checkspace (); + checkspace = user_daemon.get_checkspace (); } catch (IOError e) { stderr.printf ("IOError: %s\n", e.message); } @@ -485,7 +492,7 @@ namespace Pamac { public string[] get_ignorepkgs () { string[] ignorepkgs = {}; try { - ignorepkgs = daemon.get_ignorepkgs (); + ignorepkgs = user_daemon.get_ignorepkgs (); } catch (IOError e) { stderr.printf ("IOError: %s\n", e.message); } @@ -494,7 +501,7 @@ namespace Pamac { public AlpmPackage get_installed_pkg (string pkgname) { try { - return daemon.get_installed_pkg (pkgname); + return user_daemon.get_installed_pkg (pkgname); } catch (IOError e) { stderr.printf ("IOError: %s\n", e.message); return AlpmPackage () { @@ -508,7 +515,7 @@ namespace Pamac { public AlpmPackage find_installed_satisfier (string depstring) { try { - return daemon.find_installed_satisfier (depstring); + return user_daemon.find_installed_satisfier (depstring); } catch (IOError e) { stderr.printf ("IOError: %s\n", e.message); return AlpmPackage () { @@ -523,7 +530,7 @@ namespace Pamac { public bool should_hold (string pkgname) { bool should_hold = false; try { - should_hold = daemon.should_hold (pkgname); + should_hold = user_daemon.should_hold (pkgname); } catch (IOError e) { stderr.printf ("IOError: %s\n", e.message); } @@ -533,7 +540,7 @@ namespace Pamac { public uint get_pkg_reason (string pkgname) { uint reason = 0; try { - reason = daemon.get_pkg_reason (pkgname); + reason = user_daemon.get_pkg_reason (pkgname); } catch (IOError e) { stderr.printf ("IOError: %s\n", e.message); } @@ -543,7 +550,7 @@ namespace Pamac { public uint get_pkg_origin (string pkgname) { uint origin = 0; try { - origin = daemon.get_pkg_origin (pkgname); + origin = user_daemon.get_pkg_origin (pkgname); } catch (IOError e) { stderr.printf ("IOError: %s\n", e.message); } @@ -553,7 +560,7 @@ namespace Pamac { public async AlpmPackage[] get_installed_pkgs () { AlpmPackage[] pkgs = {}; try { - pkgs = yield daemon.get_installed_pkgs (); + pkgs = yield user_daemon.get_installed_pkgs (); } catch (IOError e) { stderr.printf ("IOError: %s\n", e.message); } @@ -563,7 +570,7 @@ namespace Pamac { public async AlpmPackage[] get_explicitly_installed_pkgs () { AlpmPackage[] pkgs = {}; try { - pkgs = yield daemon.get_explicitly_installed_pkgs (); + pkgs = yield user_daemon.get_explicitly_installed_pkgs (); } catch (IOError e) { stderr.printf ("IOError: %s\n", e.message); } @@ -573,7 +580,7 @@ namespace Pamac { public async AlpmPackage[] get_foreign_pkgs () { AlpmPackage[] pkgs = {}; try { - pkgs = yield daemon.get_foreign_pkgs (); + pkgs = yield user_daemon.get_foreign_pkgs (); } catch (IOError e) { stderr.printf ("IOError: %s\n", e.message); } @@ -583,7 +590,7 @@ namespace Pamac { public async AlpmPackage[] get_orphans () { AlpmPackage[] pkgs = {}; try { - pkgs = yield daemon.get_orphans (); + pkgs = yield user_daemon.get_orphans (); } catch (IOError e) { stderr.printf ("IOError: %s\n", e.message); } @@ -592,7 +599,7 @@ namespace Pamac { public AlpmPackage get_sync_pkg (string pkgname) { try { - return daemon.get_sync_pkg (pkgname); + return user_daemon.get_sync_pkg (pkgname); } catch (IOError e) { stderr.printf ("IOError: %s\n", e.message); return AlpmPackage () { @@ -606,7 +613,7 @@ namespace Pamac { public AlpmPackage find_sync_satisfier (string depstring) { try { - return daemon.find_sync_satisfier (depstring); + return user_daemon.find_sync_satisfier (depstring); } catch (IOError e) { stderr.printf ("IOError: %s\n", e.message); return AlpmPackage () { @@ -621,7 +628,7 @@ namespace Pamac { public async AlpmPackage[] search_pkgs (string search_string) { AlpmPackage[] pkgs = {}; try { - pkgs = yield daemon.search_pkgs (search_string); + pkgs = yield user_daemon.search_pkgs (search_string); } catch (IOError e) { stderr.printf ("IOError: %s\n", e.message); } @@ -631,7 +638,7 @@ namespace Pamac { public async AURPackage[] search_in_aur (string search_string) { AURPackage[] pkgs = {}; try { - pkgs = yield daemon.search_in_aur (search_string); + pkgs = yield user_daemon.search_in_aur (search_string); } catch (IOError e) { stderr.printf ("IOError: %s\n", e.message); } @@ -641,7 +648,7 @@ namespace Pamac { public string[] get_repos_names () { string[] repos_names = {}; try { - repos_names = daemon.get_repos_names (); + repos_names = user_daemon.get_repos_names (); } catch (IOError e) { stderr.printf ("IOError: %s\n", e.message); } @@ -651,7 +658,7 @@ namespace Pamac { public async AlpmPackage[] get_repo_pkgs (string repo) { AlpmPackage[] pkgs = {}; try { - pkgs = yield daemon.get_repo_pkgs (repo); + pkgs = yield user_daemon.get_repo_pkgs (repo); } catch (IOError e) { stderr.printf ("IOError: %s\n", e.message); } @@ -661,7 +668,7 @@ namespace Pamac { public string[] get_groups_names () { string[] groups_names = {}; try { - groups_names = daemon.get_groups_names (); + groups_names = user_daemon.get_groups_names (); } catch (IOError e) { stderr.printf ("IOError: %s\n", e.message); } @@ -671,7 +678,7 @@ namespace Pamac { public async AlpmPackage[] get_group_pkgs (string group_name) { AlpmPackage[] pkgs = {}; try { - pkgs = yield daemon.get_group_pkgs (group_name); + pkgs = yield user_daemon.get_group_pkgs (group_name); } catch (IOError e) { stderr.printf ("IOError: %s\n", e.message); } @@ -681,7 +688,7 @@ namespace Pamac { public string[] get_pkg_uninstalled_optdeps (string pkgname) { string[] optdeps = {}; try { - optdeps = daemon.get_pkg_uninstalled_optdeps (pkgname); + optdeps = user_daemon.get_pkg_uninstalled_optdeps (pkgname); } catch (IOError e) { stderr.printf ("IOError: %s\n", e.message); } @@ -690,7 +697,7 @@ namespace Pamac { public AlpmPackageDetails get_pkg_details (string pkgname) { try { - return daemon.get_pkg_details (pkgname); + return user_daemon.get_pkg_details (pkgname); } catch (IOError e) { stderr.printf ("IOError: %s\n", e.message); return AlpmPackageDetails () { @@ -710,7 +717,7 @@ namespace Pamac { public string[] get_pkg_files (string pkgname) { try { - return daemon.get_pkg_files (pkgname); + return user_daemon.get_pkg_files (pkgname); } catch (IOError e) { stderr.printf ("IOError: %s\n", e.message); return {}; @@ -727,7 +734,7 @@ namespace Pamac { maintainer = "" }; try { - pkg = yield daemon.get_aur_details (pkgname); + pkg = yield user_daemon.get_aur_details (pkgname); } catch (IOError e) { stderr.printf ("IOError: %s\n", e.message); } @@ -735,9 +742,9 @@ namespace Pamac { } public void start_get_updates () { - daemon.get_updates_finished.connect (on_get_updates_finished); + user_daemon.get_updates_finished.connect (on_get_updates_finished); try { - daemon.start_get_updates (pamac_config.enable_aur && pamac_config.check_aur_updates); + user_daemon.start_get_updates (pamac_config.enable_aur && pamac_config.check_aur_updates); } catch (IOError e) { stderr.printf ("IOError: %s\n", e.message); success = false; @@ -746,9 +753,9 @@ namespace Pamac { } void start_get_updates_for_sysupgrade () { - daemon.get_updates_finished.connect (on_get_updates_for_sysupgrade_finished); + system_daemon.get_updates_finished.connect (on_get_updates_for_sysupgrade_finished); try { - daemon.start_get_updates (pamac_config.enable_aur && pamac_config.check_aur_updates); + system_daemon.start_get_updates (pamac_config.enable_aur && pamac_config.check_aur_updates); } catch (IOError e) { stderr.printf ("IOError: %s\n", e.message); success = false; @@ -762,9 +769,11 @@ namespace Pamac { foreach (unowned string pkgname in temporary_ignorepkgs) { temporary_ignorepkgs_ += pkgname; } + connecting_system_daemon (); + connecting_dbus_signals (); try { // this will respond with trans_prepare_finished signal - daemon.start_sysupgrade_prepare (enable_downgrade, temporary_ignorepkgs_); + system_daemon.start_sysupgrade_prepare (enable_downgrade, temporary_ignorepkgs_); } catch (IOError e) { stderr.printf ("IOError: %s\n", e.message); success = false; @@ -780,19 +789,18 @@ namespace Pamac { } void on_get_updates_finished (Updates updates) { - daemon.get_updates_finished.disconnect (on_get_updates_finished); + user_daemon.get_updates_finished.disconnect (on_get_updates_finished); get_updates_finished (updates); } void on_get_updates_for_sysupgrade_finished (Updates updates) { - daemon.get_updates_finished.disconnect (on_get_updates_for_sysupgrade_finished); + system_daemon.get_updates_finished.disconnect (on_get_updates_for_sysupgrade_finished); // get syncfirst updates if (updates.is_syncfirst) { clear_lists (); - if (mode == Mode.MANAGER) { - sysupgrade_after_trans = true; - } - foreach (unowned UpdateInfos infos in updates.repos_updates) { + sysupgrade_after_trans = true; + no_confirm_commit = true; + foreach (unowned AlpmPackage infos in updates.repos_updates) { to_install.add (infos.name); } // run as a standard transaction @@ -800,7 +808,7 @@ namespace Pamac { } else { if (updates.aur_updates.length != 0) { clear_lists (); - foreach (unowned UpdateInfos infos in updates.aur_updates) { + foreach (unowned AURPackage infos in updates.aur_updates) { if (!(infos.name in temporary_ignorepkgs)) { to_build.add (infos.name); } @@ -838,7 +846,7 @@ namespace Pamac { void start_trans_prepare (int transflags, string[] to_install, string[] to_remove, string[] to_load, string[] to_build) { try { - daemon.start_trans_prepare (transflags, to_install, to_remove, to_load, to_build); + system_daemon.start_trans_prepare (transflags, to_install, to_remove, to_load, to_build); } catch (IOError e) { stderr.printf ("IOError: %s\n", e.message); stop_progressbar_pulse (); @@ -867,6 +875,8 @@ namespace Pamac { foreach (unowned string name in to_build) { to_build_ += name; } + connecting_system_daemon (); + connecting_dbus_signals (); start_trans_prepare (flags, to_install_, to_remove_, to_load_, to_build_); } @@ -896,7 +906,7 @@ namespace Pamac { foreach (var radiobutton in list) { if (radiobutton.active) { try { - daemon.choose_provider (index); + system_daemon.choose_provider (index); } catch (IOError e) { stderr.printf ("IOError: %s\n", e.message); } @@ -917,7 +927,7 @@ namespace Pamac { var summary = TransactionSummary (); transaction_sum_dialog.sum_list.clear (); try { - summary = daemon.get_transaction_summary (); + summary = system_daemon.get_transaction_summary (); } catch (IOError e) { stderr.printf ("IOError: %s\n", e.message); } @@ -1012,20 +1022,6 @@ namespace Pamac { } if (summary.to_upgrade.length > 0) { type |= Type.UPDATE; - if (mode != Mode.UPDATER) { - foreach (unowned UpdateInfos infos in summary.to_upgrade) { - dsize += infos.download_size; - transaction_summary.add (infos.name); - transaction_sum_dialog.sum_list.insert_with_values (out iter, -1, - 1, infos.name, - 2, infos.new_version, - 3, "(%s)".printf (infos.old_version)); - } - Gtk.TreePath path = transaction_sum_dialog.sum_list.get_path (iter); - int pos = (path.get_indices ()[0]) - (summary.to_upgrade.length - 1); - transaction_sum_dialog.sum_list.get_iter (out iter, new Gtk.TreePath.from_indices (pos)); - transaction_sum_dialog.sum_list.set (iter, 0, "%s".printf (dgettext (null, "To update") + ":")); - } } if (dsize == 0) { transaction_sum_dialog.top_label.visible = false; @@ -1038,7 +1034,7 @@ namespace Pamac { void start_commit () { try { - daemon.start_trans_commit (); + system_daemon.start_trans_commit (); } catch (IOError e) { stderr.printf ("IOError: %s\n", e.message); success = false; @@ -1120,21 +1116,19 @@ namespace Pamac { build_cancellable.cancel (); } else { try { - daemon.trans_cancel (); + system_daemon.trans_cancel (); } catch (IOError e) { stderr.printf ("IOError: %s\n", e.message); } } show_in_term ("\n" + dgettext (null, "Transaction cancelled") + ".\n"); progress_box.action_label.label = ""; - stop_progressbar_pulse (); - stop_waiting (); warning_textbuffer = new StringBuilder (); } public void release () { try { - daemon.trans_release (); + system_daemon.trans_release (); } catch (IOError e) { stderr.printf ("IOError: %s\n", e.message); } @@ -1143,7 +1137,10 @@ namespace Pamac { public void stop_daemon () { try { - daemon.quit (); + user_daemon.quit (); + if (system_daemon != null) { + system_daemon.quit (); + } } catch (IOError e) { stderr.printf ("IOError: %s\n", e.message); } @@ -1153,11 +1150,6 @@ namespace Pamac { string? action = null; string? detailed_action = null; switch (primary_event) { - case 0: //special case: wait for database lock - action = dgettext (null, "Waiting for another package manager to quit") + "..."; - start_progressbar_pulse (); - start_waiting (); - break; case 1: //Alpm.Event.Type.CHECKDEPS_START action = dgettext (null, "Checking dependencies") + "..."; break; @@ -1399,11 +1391,8 @@ namespace Pamac { rates_nb = 0; fraction = 0; timer.start (); - if (filename.has_suffix (".db")) { - string action = dgettext (null, "Refreshing %s").printf (filename.replace (".db", "")) + "..."; - reset_progress_box (action); - } else if (filename.has_suffix (".files")) { - string action = dgettext (null, "Refreshing %s").printf (filename.replace (".files", "")) + "..."; + if (filename.has_suffix (".db") || filename.has_suffix (".files")) { + string action = dgettext (null, "Refreshing %s").printf (filename) + "..."; reset_progress_box (action); } } else if (xfered == total) { @@ -1526,7 +1515,7 @@ namespace Pamac { } } - void display_error (string message, string[] details) { + public void display_error (string message, string[] details) { var flags = Gtk.DialogFlags.MODAL; int use_header_bar; Gtk.Settings.get_default ().get ("gtk-dialogs-use-header", out use_header_bar); @@ -1579,6 +1568,7 @@ namespace Pamac { } void finish_transaction () { + disconnecting_dbus_signals (); transaction_summary.remove_all (); reset_progress_box (""); finished (success); @@ -1588,7 +1578,6 @@ namespace Pamac { void on_refresh_finished (bool success) { stop_progressbar_pulse (); this.success = success; - clear_lists (); if (success) { finished (success); reset_progress_box (""); @@ -1597,7 +1586,8 @@ namespace Pamac { handle_error (get_current_error ()); } previous_filename = ""; - daemon.refresh_finished.disconnect (on_refresh_finished); + disconnecting_dbus_signals (); + system_daemon.refresh_finished.disconnect (on_refresh_finished); } void on_trans_prepare_finished (bool success) { @@ -1606,8 +1596,9 @@ namespace Pamac { if (success) { show_warnings (); Type type = set_transaction_sum (); - if (no_confirm_commit || (type == Type.UPDATE && mode == Mode.UPDATER)) { + if (no_confirm_commit || type == Type.UPDATE) { // no_confirm_commit or only updates + to_install.remove_all (); start_commit (); } else if (type != 0) { if (transaction_sum_dialog.run () == Gtk.ResponseType.OK) { @@ -1689,6 +1680,7 @@ namespace Pamac { sysupgrade (false); } else if (build_after_sysupgrade) { build_after_sysupgrade = false; + disconnecting_dbus_signals (); // build aur updates in to_build run (); } else { @@ -1724,13 +1716,16 @@ namespace Pamac { } void on_set_pkgreason_finished () { + system_daemon.set_pkgreason_finished.disconnect (on_set_pkgreason_finished); set_pkgreason_finished (); } void on_write_pamac_config_finished (bool recurse, uint64 refresh_period, bool no_update_hide_icon, bool enable_aur, bool search_aur, bool check_aur_updates) { + system_daemon.write_pamac_config_finished.disconnect (on_write_pamac_config_finished); pamac_config.reload (); - if (recurse) { + flags = (1 << 4); //Alpm.TransFlag.CASCADE + if (pamac_config.recurse) { flags |= (1 << 5); //Alpm.TransFlag.RECURSE } write_pamac_config_finished (recurse, refresh_period, no_update_hide_icon, @@ -1738,10 +1733,12 @@ namespace Pamac { } void on_write_alpm_config_finished (bool checkspace) { + system_daemon.write_alpm_config_finished.disconnect (on_write_alpm_config_finished); write_alpm_config_finished (checkspace); } void on_write_mirrors_config_finished (string choosen_country, string choosen_generation_method) { + system_daemon.write_mirrors_config_finished.disconnect (on_write_mirrors_config_finished); write_mirrors_config_finished (choosen_country, choosen_generation_method); } @@ -1750,35 +1747,50 @@ namespace Pamac { } void on_generate_mirrors_list_finished () { + system_daemon.generate_mirrors_list_data.disconnect (on_generate_mirrors_list_data); + system_daemon.generate_mirrors_list_finished.disconnect (on_generate_mirrors_list_finished); stop_progressbar_pulse (); show_in_term (""); - // force a dbs refresh - start_refresh (true); } - void connecting_dbus_signals () { + void connecting_user_daemon () { try { - daemon = Bus.get_proxy_sync (BusType.SYSTEM, "org.manjaro.pamac", "/org/manjaro/pamac"); - // Set environment variables - daemon.set_environment_variables (pamac_config.environment_variables); - // Connecting to signals - daemon.emit_event.connect (on_emit_event); - daemon.emit_providers.connect (on_emit_providers); - daemon.emit_progress.connect (on_emit_progress); - daemon.emit_download.connect (on_emit_download); - daemon.emit_totaldownload.connect (on_emit_totaldownload); - daemon.emit_log.connect (on_emit_log); - daemon.trans_prepare_finished.connect (on_trans_prepare_finished); - daemon.trans_commit_finished.connect (on_trans_commit_finished); - daemon.set_pkgreason_finished.connect (on_set_pkgreason_finished); - daemon.write_mirrors_config_finished.connect (on_write_mirrors_config_finished); - daemon.write_alpm_config_finished.connect (on_write_alpm_config_finished); - daemon.write_pamac_config_finished.connect (on_write_pamac_config_finished); - daemon.generate_mirrors_list_data.connect (on_generate_mirrors_list_data); - daemon.generate_mirrors_list_finished.connect (on_generate_mirrors_list_finished); + user_daemon = Bus.get_proxy_sync (BusType.SESSION, "org.manjaro.pamac.user", "/org/manjaro/pamac/user"); } catch (IOError e) { stderr.printf ("IOError: %s\n", e.message); } } + + void connecting_system_daemon () { + try { + system_daemon = Bus.get_proxy_sync (BusType.SYSTEM, "org.manjaro.pamac.system", "/org/manjaro/pamac/system"); + // Set environment variables + system_daemon.set_environment_variables (pamac_config.environment_variables); + } catch (IOError e) { + stderr.printf ("IOError: %s\n", e.message); + } + } + + void connecting_dbus_signals () { + system_daemon.emit_event.connect (on_emit_event); + system_daemon.emit_providers.connect (on_emit_providers); + system_daemon.emit_progress.connect (on_emit_progress); + system_daemon.emit_download.connect (on_emit_download); + system_daemon.emit_totaldownload.connect (on_emit_totaldownload); + system_daemon.emit_log.connect (on_emit_log); + system_daemon.trans_prepare_finished.connect (on_trans_prepare_finished); + system_daemon.trans_commit_finished.connect (on_trans_commit_finished); + } + + void disconnecting_dbus_signals () { + system_daemon.emit_event.disconnect (on_emit_event); + system_daemon.emit_providers.disconnect (on_emit_providers); + system_daemon.emit_progress.disconnect (on_emit_progress); + system_daemon.emit_download.disconnect (on_emit_download); + system_daemon.emit_totaldownload.disconnect (on_emit_totaldownload); + system_daemon.emit_log.disconnect (on_emit_log); + system_daemon.trans_prepare_finished.disconnect (on_trans_prepare_finished); + system_daemon.trans_commit_finished.disconnect (on_trans_commit_finished); + } } } diff --git a/src/tray.vala b/src/tray.vala index 4b8c073..4e43154 100644 --- a/src/tray.vala +++ b/src/tray.vala @@ -25,23 +25,19 @@ const string noupdate_icon_name = "pamac-tray-no-update"; const string noupdate_info = _("Your system is up-to-date"); namespace Pamac { - [DBus (name = "org.manjaro.pamac")] - interface Daemon : Object { + [DBus (name = "org.manjaro.pamac.user")] + interface UserDaemon : Object { + public abstract void refresh_handle () throws IOError; public abstract string get_lockfile () throws IOError; - public abstract void start_refresh (bool force) throws IOError; public abstract void start_get_updates (bool check_aur_updates) throws IOError; [DBus (no_reply = true)] public abstract void quit () throws IOError; public signal void get_updates_finished (Updates updates); - public signal void write_pamac_config_finished (bool recurse, uint64 refresh_period, bool no_update_hide_icon, - bool enable_aur, bool search_aur, bool check_aur_updates, - bool no_confirm_build); - public signal void write_alpm_config_finished (bool checkspace); } public abstract class TrayIcon: Gtk.Application { Notify.Notification notification; - Daemon daemon; + UserDaemon daemon; bool extern_lock; uint refresh_timeout_id; public Gtk.Menu menu; @@ -56,11 +52,8 @@ namespace Pamac { void start_daemon () { try { - daemon = Bus.get_proxy_sync (BusType.SYSTEM, "org.manjaro.pamac", "/org/manjaro/pamac"); - // Connecting to signals + daemon = Bus.get_proxy_sync (BusType.SESSION, "org.manjaro.pamac.user", "/org/manjaro/pamac/user"); daemon.get_updates_finished.connect (on_get_updates_finished); - daemon.write_pamac_config_finished.connect (on_write_pamac_config_finished); - daemon.write_alpm_config_finished.connect (on_write_alpm_config_finished); } catch (IOError e) { stderr.printf ("IOError: %s\n", e.message); } @@ -79,10 +72,7 @@ namespace Pamac { // Create menu for right button void create_menu () { menu = new Gtk.Menu (); - var item = new Gtk.MenuItem.with_label (_("Update Manager")); - item.activate.connect (execute_updater); - menu.append (item); - item = new Gtk.MenuItem.with_label (_("Package Manager")); + var item = new Gtk.MenuItem.with_label (_("Package Manager")); item.activate.connect (execute_manager); menu.append (item); item = new Gtk.MenuItem.with_mnemonic (_("_Quit")); @@ -123,13 +113,11 @@ namespace Pamac { public abstract void set_icon_visible (bool visible); - bool start_refresh () { - // if pamac is not running start refresh else just check updates - if (check_pamac_running ()) { - check_updates (); - } else { + bool check_updates () { + var pamac_config = new Pamac.Config ("/etc/pamac.conf"); + if (pamac_config.refresh_period != 0) { try { - daemon.start_refresh (false); + daemon.start_get_updates (pamac_config.enable_aur && pamac_config.check_aur_updates); } catch (IOError e) { stderr.printf ("IOError: %s\n", e.message); } @@ -137,19 +125,6 @@ namespace Pamac { return true; } - void on_write_pamac_config_finished (bool recurse, uint64 refresh_period) { - launch_refresh_timeout (refresh_period); - if (refresh_period == 0) { - set_icon_visible (false); - } else { - check_updates (); - } - } - - void on_write_alpm_config_finished (bool checkspace) { - check_updates (); - } - void on_get_updates_finished (Updates updates) { uint updates_nb = updates.repos_updates.length + updates.aur_updates.length; if (updates_nb == 0) { @@ -172,22 +147,10 @@ namespace Pamac { stop_daemon (); } - void check_updates () { - var pamac_config = new Pamac.Config ("/etc/pamac.conf"); - if (pamac_config.refresh_period == 0) { - return; - } - try { - daemon.start_get_updates (pamac_config.enable_aur && pamac_config.check_aur_updates); - } catch (IOError e) { - stderr.printf ("IOError: %s\n", e.message); - } - } - void show_notification (string info) { try { close_notification(); - notification = new Notify.Notification (_("Update Manager"), info, "system-software-update"); + notification = new Notify.Notification (_("Package Manager"), info, "system-software-update"); notification.add_action ("default", _("Details"), execute_updater); notification.show (); } catch (Error e) { @@ -199,7 +162,7 @@ namespace Pamac { try { if (notification != null) { if (notification.get_closed_reason() == -1 && notification.body != info) { - notification.update (_("Update Manager"), info, "system-software-update"); + notification.update (_("Package Manager"), info, "system-software-update"); notification.show (); } } else { @@ -234,17 +197,7 @@ namespace Pamac { if (run) { return run; } - app = new Application ("org.manjaro.pamac.updater", 0); - try { - app.register (); - } catch (GLib.Error e) { - stderr.printf ("%s\n", e.message); - } - run = app.get_is_remote (); - if (run) { - return run; - } - app = new Application ("org.manjaro.pamac.install", 0); + app = new Application ("org.manjaro.pamac.installer", 0); try { app.register (); } catch (GLib.Error e) { @@ -258,11 +211,12 @@ namespace Pamac { if (extern_lock) { if (!lockfile.query_exists ()) { extern_lock = false; - // let the time to the daemon to update packages - Timeout.add (1000, () => { - check_updates (); - return false; - }); + try { + daemon.refresh_handle (); + } catch (IOError e) { + stderr.printf ("IOError: %s\n", e.message); + } + check_updates (); } } else { if (lockfile.query_exists ()) { @@ -278,7 +232,7 @@ namespace Pamac { refresh_timeout_id = 0; } if (refresh_period_in_hours != 0) { - refresh_timeout_id = Timeout.add_seconds ((uint) refresh_period_in_hours*3600, start_refresh); + refresh_timeout_id = Timeout.add_seconds ((uint) refresh_period_in_hours*3600, check_updates); } } @@ -304,7 +258,7 @@ namespace Pamac { set_tooltip (noupdate_info); set_icon_visible (!pamac_config.no_update_hide_icon); - Notify.init (_("Update Manager")); + Notify.init (_("Package Manager")); start_daemon (); try { @@ -315,7 +269,7 @@ namespace Pamac { lockfile = GLib.File.new_for_path ("var/lib/pacman/db.lck"); } Timeout.add (200, check_extern_lock); - start_refresh (); + check_updates (); launch_refresh_timeout (pamac_config.refresh_period); this.hold (); diff --git a/src/updater.vala b/src/updater.vala deleted file mode 100644 index 6384ae6..0000000 --- a/src/updater.vala +++ /dev/null @@ -1,105 +0,0 @@ -/* - * pamac-vala - * - * Copyright (C) 2014-2017 Guillaume Benoit - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a get of the GNU General Public License - * along with this program. If not, see . - */ - -namespace Pamac { - - class Updater : Gtk.Application { - UpdaterWindow updater_window; - bool pamac_run; - - public Updater () { - application_id = "org.manjaro.pamac.updater"; - flags = ApplicationFlags.FLAGS_NONE; - } - - public override void startup () { - // i18n - Intl.textdomain ("pamac"); - Intl.setlocale (LocaleCategory.ALL, ""); - - base.startup (); - - pamac_run = check_pamac_running (); - if (pamac_run) { - var msg = new Gtk.MessageDialog (null, - Gtk.DialogFlags.MODAL, - Gtk.MessageType.ERROR, - Gtk.ButtonsType.OK, - dgettext (null, "Pamac is already running")); - msg.run (); - msg.destroy (); - } else { - updater_window = new UpdaterWindow (this); - // quit accel - var action = new SimpleAction ("quit", null); - action.activate.connect (() => {this.quit ();}); - this.add_action (action); - string[] accels = {"Q", "W"}; - this.set_accels_for_action ("app.quit", accels); - // back accel - action = new SimpleAction ("back", null); - action.activate.connect (() => {updater_window.on_button_back_clicked ();}); - this.add_action (action); - accels = {"Left"}; - this.set_accels_for_action ("app.back", accels); - } - } - - public override void activate () { - if (!pamac_run) { - updater_window.present (); - } - } - - public override void shutdown () { - base.shutdown (); - if (!pamac_run) { - updater_window.transaction.stop_daemon (); - } - } - - bool check_pamac_running () { - Application app; - bool run = false; - app = new Application ("org.manjaro.pamac.manager", 0); - try { - app.register (); - } catch (GLib.Error e) { - stderr.printf ("%s\n", e.message); - } - run = app.get_is_remote (); - if (run) { - return run; - } - app = new Application ("org.manjaro.pamac.install", 0); - try { - app.register (); - } catch (GLib.Error e) { - stderr.printf ("%s\n", e.message); - } - run = app.get_is_remote (); - return run; - } - } - - static int main (string[] args) { - var updater = new Updater (); - return updater.run (args); - } -} diff --git a/src/updater_window.vala b/src/updater_window.vala deleted file mode 100644 index dda9d6c..0000000 --- a/src/updater_window.vala +++ /dev/null @@ -1,384 +0,0 @@ -/* - * pamac-vala - * - * Copyright (C) 2014-2017 Guillaume Benoit - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a get of the GNU General Public License - * along with this program. If not, see . - */ - -namespace Pamac { - - [GtkTemplate (ui = "/org/manjaro/pamac/updater/updater_window.ui")] - class UpdaterWindow : Gtk.ApplicationWindow { - - [GtkChild] - Gtk.HeaderBar headerbar; - [GtkChild] - Gtk.Button button_back; - [GtkChild] - Gtk.ModelButton preferences_button; - [GtkChild] - Gtk.Stack stack; - [GtkChild] - Gtk.StackSwitcher stackswitcher; - [GtkChild] - Gtk.ScrolledWindow repos_scrolledwindow; - [GtkChild] - Gtk.ScrolledWindow aur_scrolledwindow; - [GtkChild] - Gtk.TreeView repos_updates_treeview; - [GtkChild] - Gtk.CellRendererToggle repos_select_update; - [GtkChild] - Gtk.TreeView aur_updates_treeview; - [GtkChild] - Gtk.CellRendererToggle aur_select_update; - [GtkChild] - Gtk.Box transaction_infobox; - [GtkChild] - Gtk.Button details_button; - [GtkChild] - Gtk.Button apply_button; - [GtkChild] - Gtk.Button cancel_button; - - Gtk.ListStore repos_updates_list; - Gtk.ListStore aur_updates_list; - - public Pamac.Transaction transaction; - - bool transaction_running; - bool generate_mirrors_list; - bool important_details; - string previous_visible_child_name; - - public UpdaterWindow (Gtk.Application application) { - Object (application: application); - - button_back.visible = false; - apply_button.get_style_context ().add_class (Gtk.STYLE_CLASS_SUGGESTED_ACTION); - apply_button.sensitive = false; - stackswitcher.visible = false; - aur_scrolledwindow.visible = false; - transaction_running = false; - important_details = false; - generate_mirrors_list = false; - - headerbar.title = dgettext (null, "Update Manager"); - Timeout.add (100, populate_window); - } - - bool populate_window () { - this.get_window ().set_cursor (new Gdk.Cursor.for_display (Gdk.Display.get_default (), Gdk.CursorType.WATCH)); - while (Gtk.events_pending ()) { - Gtk.main_iteration (); - } - repos_updates_list = new Gtk.ListStore (7, typeof (bool), typeof (string), typeof (string), typeof (string),typeof (string), typeof (string), typeof (uint64)); - repos_updates_treeview.set_model (repos_updates_list); - aur_updates_list = new Gtk.ListStore (4, typeof (bool), typeof (string), typeof (string), typeof (string)); - aur_updates_treeview.set_model (aur_updates_list); - - transaction = new Transaction (this as Gtk.ApplicationWindow); - transaction.mode = Mode.UPDATER; - transaction.start_waiting.connect (on_start_waiting); - transaction.stop_waiting.connect (on_stop_waiting); - transaction.start_downloading.connect (on_start_downloading); - transaction.stop_downloading.connect (on_stop_downloading); - transaction.start_building.connect (on_start_building); - transaction.stop_building.connect (on_stop_building); - transaction.important_details_outpout.connect (on_important_details_output); - transaction.finished.connect (populate_updates_list); - transaction.get_updates_finished.connect (on_get_updates_finished); - transaction.generate_mirrors_list.connect (on_generate_mirrors_list); - - // integrate progress box and term widget - stack.add_named (transaction.term_window, "term"); - transaction_infobox.pack_start (transaction.progress_box); - - // A timeout is needed to let the time to the daemon to deal - // with potential other package manager process running. - Timeout.add (500, () => { - this.get_window ().set_cursor (new Gdk.Cursor.for_display (Gdk.Display.get_default (), Gdk.CursorType.WATCH)); - transaction_infobox.show_all (); - details_button.sensitive = true; - cancel_button.sensitive = true; - transaction.start_refresh (false); - return false; - }); - - stack.notify["visible-child"].connect (on_stack_visible_child_changed); - - return false; - } - - void set_transaction_infobox_visible () { - if (important_details) { - transaction_infobox.show_all (); - return; - } - if (!generate_mirrors_list) { - bool visible = false; - uint64 total_dsize = 0; - repos_updates_list.foreach ((model, path, iter) => { - bool selected; - uint64 dsize; - repos_updates_list.get (iter, 0, out selected, 6, out dsize); - visible |= selected; - if (selected) { - total_dsize += dsize; - } - return false; - }); - if (!visible) { - aur_updates_list.foreach ((model, path, iter) => { - bool selected; - aur_updates_list.get (iter, 0, out selected); - visible |= selected; - return visible; - }); - } - if (visible) { - if (total_dsize != 0) { - transaction.progress_box.action_label.set_markup("%s: %s".printf (dgettext (null, "Total download size"), format_size (total_dsize))); - } else { - transaction.progress_box.action_label.label = ""; - } - // fix an possible visibility issue - transaction_infobox.show_all (); - } else { - transaction_infobox.visible = false; - } - } - } - - [GtkCallback] - void on_repos_select_update_toggled (string path) { - if (!transaction_running) { - Gtk.TreePath treepath = new Gtk.TreePath.from_string (path); - Gtk.TreeIter iter; - string pkgname; - repos_updates_list.get_iter (out iter, treepath); - repos_updates_list.get (iter, 1, out pkgname); - if (repos_select_update.active) { - repos_updates_list.set (iter, 0, false); - transaction.temporary_ignorepkgs.add (pkgname); - } else { - repos_updates_list.set (iter, 0, true); - transaction.temporary_ignorepkgs.remove (pkgname); - } - set_transaction_infobox_visible (); - } - } - - [GtkCallback] - void on_aur_select_update_toggled (string path) { - if (!transaction_running) { - Gtk.TreePath treepath = new Gtk.TreePath.from_string (path); - Gtk.TreeIter iter; - string pkgname; - aur_updates_list.get_iter (out iter, treepath); - aur_updates_list.get (iter, 1, out pkgname); - if (aur_select_update.active) { - aur_updates_list.set (iter, 0, false); - transaction.temporary_ignorepkgs.add (pkgname); - } else { - aur_updates_list.set (iter, 0, true); - transaction.temporary_ignorepkgs.remove (pkgname); - } - set_transaction_infobox_visible (); - } - } - - [GtkCallback] - public void on_button_back_clicked () { - if (aur_scrolledwindow.visible) { - stackswitcher.visible = true; - stack.visible_child_name = previous_visible_child_name; - } else { - stack.visible_child_name = "repos"; - } - } - - void on_stack_visible_child_changed () { - if (stack.visible_child_name == "term") { - button_back.visible = true; - } - } - - [GtkCallback] - void on_menu_button_toggled () { - preferences_button.sensitive = !transaction_running; - } - - [GtkCallback] - void on_preferences_button_clicked () { - transaction.run_preferences_dialog.begin (() => { - if (!generate_mirrors_list) { - populate_updates_list (); - } - }); - } - - [GtkCallback] - void on_apply_button_clicked () { - transaction_running = true; - transaction.sysupgrade (false); - apply_button.sensitive = false; - details_button.sensitive = true; - cancel_button.sensitive = true; - } - - [GtkCallback] - void on_refresh_button_clicked () { - this.get_window ().set_cursor (new Gdk.Cursor.for_display (Gdk.Display.get_default (), Gdk.CursorType.WATCH)); - transaction_infobox.show_all (); - apply_button.sensitive = false; - details_button.sensitive = true; - cancel_button.sensitive = true; - transaction.start_refresh (true); - } - - [GtkCallback] - void on_history_button_clicked () { - transaction.run_history_dialog (); - } - - [GtkCallback] - void on_about_button_clicked () { - transaction.run_about_dialog (); - } - - [GtkCallback] - void on_details_button_clicked () { - details_button.get_style_context ().remove_class (Gtk.STYLE_CLASS_SUGGESTED_ACTION); - important_details = false; - previous_visible_child_name = stack.visible_child_name; - stack.visible_child_name = "term"; - } - - [GtkCallback] - void on_cancel_button_clicked () { - transaction.cancel (); - } - - void on_start_waiting () { - cancel_button.sensitive = true; - } - - void on_stop_waiting () { - populate_updates_list (); - } - - void on_start_downloading () { - cancel_button.sensitive = true; - } - - void on_stop_downloading () { - cancel_button.sensitive = false; - } - - void on_start_building () { - cancel_button.sensitive = true; - } - - void on_stop_building () { - cancel_button.sensitive = false; - } - - void on_important_details_output (bool must_show) { - if (must_show) { - stackswitcher.visible = false; - previous_visible_child_name = stack.visible_child_name; - stack.visible_child_name = "term"; - button_back.visible = false; - } else if (stack.visible_child_name != "term") { - important_details = true; - details_button.sensitive = true; - details_button.get_style_context ().add_class (Gtk.STYLE_CLASS_SUGGESTED_ACTION); - } - } - - void on_generate_mirrors_list () { - generate_mirrors_list = true; - apply_button.sensitive = false; - transaction_infobox.show_all (); - } - - void populate_updates_list () { - transaction_running = false; - generate_mirrors_list = false; - apply_button.grab_default (); - if (!important_details) { - details_button.sensitive = false; - } - cancel_button.sensitive = false; - if (stack.visible_child_name == "term") { - button_back.visible = true; - } - this.get_window ().set_cursor (new Gdk.Cursor.for_display (Gdk.Display.get_default (), Gdk.CursorType.WATCH)); - transaction.progress_box.action_label.label = ""; - transaction.start_get_updates (); - } - - void on_get_updates_finished (Updates updates) { - headerbar.title = dgettext (null, "Update Manager"); - repos_updates_list.clear (); - stackswitcher.visible = false; - repos_scrolledwindow.visible = true; - aur_updates_list.clear (); - aur_scrolledwindow.visible = false; - uint repos_updates_nb = 0; - uint aur_updates_nb = 0; - foreach (unowned UpdateInfos infos in updates.repos_updates) { - string size = infos.download_size != 0 ? format_size (infos.download_size) : ""; - repos_updates_nb++; - repos_updates_list.insert_with_values (null, -1, - 0, !transaction.temporary_ignorepkgs.contains (infos.name), - 1, infos.name, - 2, infos.new_version, - 3, "(%s)".printf (infos.old_version), - 4, infos.repo, - 5, size, - 6, infos.download_size); - } - foreach (unowned UpdateInfos infos in updates.aur_updates) { - aur_updates_nb++; - aur_updates_list.insert_with_values (null, -1, - 0, !transaction.temporary_ignorepkgs.contains (infos.name), - 1, infos.name, - 2, infos.new_version, - 3, "(%s)".printf (infos.old_version)); - } - uint updates_nb = repos_updates_nb + aur_updates_nb; - if (updates_nb == 0) { - headerbar.title = dgettext (null, "Your system is up-to-date"); - apply_button.sensitive = false; - } else { - headerbar.title = dngettext (null, "%u available update", "%u available updates", updates_nb).printf (updates_nb); - apply_button.sensitive = true; - } - set_transaction_infobox_visible (); - if (aur_updates_nb != 0) { - aur_scrolledwindow.visible = true; - if (repos_updates_nb == 0) { - repos_scrolledwindow.visible = false; - } - if (stack.visible_child_name != "term") { - stackswitcher.visible = true; - } - } - this.get_window ().set_cursor (null); - } - } -} diff --git a/src/user_daemon.vala b/src/user_daemon.vala new file mode 100644 index 0000000..557e1b9 --- /dev/null +++ b/src/user_daemon.vala @@ -0,0 +1,967 @@ +/* + * pamac-vala + * + * Copyright (C) 2014-2017 Guillaume Benoit + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a get of the GNU General Public License + * along with this program. If not, see . + */ + +// i18n +const string GETTEXT_PACKAGE = "pamac"; + +Pamac.UserDaemon user_daemon; +MainLoop loop; + +private int alpm_pkg_compare_name (Alpm.Package pkg_a, Alpm.Package pkg_b) { + return strcmp (pkg_a.name, pkg_b.name); +} + +private string global_search_string; + +private int alpm_pkg_sort_search_by_relevance (Alpm.Package pkg_a, Alpm.Package pkg_b) { + if (global_search_string != null) { + // display exact match first + if (pkg_a.name == global_search_string) { + return 0; + } + if (pkg_b.name == global_search_string) { + return 1; + } + if (pkg_a.name.has_prefix (global_search_string + "-")) { + if (pkg_b.name.has_prefix (global_search_string + "-")) { + return strcmp (pkg_a.name, pkg_b.name); + } + return 0; + } + if (pkg_b.name.has_prefix (global_search_string + "-")) { + if (pkg_a.name.has_prefix (global_search_string + "-")) { + return strcmp (pkg_a.name, pkg_b.name); + } + return 1; + } + if (pkg_a.name.has_prefix (global_search_string)) { + if (pkg_b.name.has_prefix (global_search_string)) { + return strcmp (pkg_a.name, pkg_b.name); + } + return 0; + } + if (pkg_b.name.has_prefix (global_search_string)) { + if (pkg_a.name.has_prefix (global_search_string)) { + return strcmp (pkg_a.name, pkg_b.name); + } + return 1; + } + if (pkg_a.name.contains (global_search_string)) { + if (pkg_b.name.contains (global_search_string)) { + return strcmp (pkg_a.name, pkg_b.name); + } + return 0; + } + if (pkg_b.name.contains (global_search_string)) { + if (pkg_a.name.contains (global_search_string)) { + return strcmp (pkg_a.name, pkg_b.name); + } + return 1; + } + } + return strcmp (pkg_a.name, pkg_b.name); +} + +namespace Pamac { + [DBus (name = "org.manjaro.pamac.user")] + public class UserDaemon: Object { + private AlpmConfig alpm_config; + private Alpm.Handle? alpm_handle; + private Alpm.Handle? files_handle; + private bool check_aur_updates; + private bool aur_updates_checked; + private Json.Array aur_updates_results; + private HashTable aur_search_results; + private HashTable aur_infos; + + public signal void get_updates_finished (Updates updates); + + public UserDaemon () { + alpm_config = new AlpmConfig ("/etc/pacman.conf"); + aur_updates_results = new Json.Array (); + aur_search_results = new HashTable (str_hash, str_equal); + aur_infos = new HashTable (str_hash, str_equal); + refresh_handle (); + } + + public void refresh_handle () { + alpm_handle = alpm_config.get_handle (); + if (alpm_handle == null) { + return; + } else { + files_handle = alpm_config.get_handle (true); + } + } + + public bool get_checkspace () { + return alpm_handle.checkspace == 1 ? true : false; + } + + public string get_lockfile () { + return alpm_handle.lockfile; + } + + public string[] get_ignorepkgs () { + string[] result = {}; + unowned Alpm.List ignorepkgs = alpm_handle.ignorepkgs; + while (ignorepkgs != null) { + unowned string ignorepkg = ignorepkgs.data; + result += ignorepkg; + ignorepkgs.next (); + } + return result; + } + + public bool should_hold (string pkgname) { + if (alpm_config.get_holdpkgs ().find_custom (pkgname, strcmp) != null) { + return true; + } + return false; + } + + public uint get_pkg_reason (string pkgname) { + unowned Alpm.Package? pkg = alpm_handle.localdb.get_pkg (pkgname); + if (pkg != null) { + return pkg.reason; + } + return 0; + } + + public uint get_pkg_origin (string pkgname) { + unowned Alpm.Package? pkg = alpm_handle.localdb.get_pkg (pkgname); + if (pkg != null) { + return pkg.origin; + } else { + pkg = get_syncpkg (pkgname); + if (pkg != null) { + return pkg.origin; + } + } + return 0; + } + + private AlpmPackage initialise_pkg_struct (Alpm.Package? alpm_pkg) { + if (alpm_pkg != null) { + string installed_version = ""; + string repo_name = ""; + if (alpm_pkg.origin == Alpm.Package.From.LOCALDB) { + installed_version = alpm_pkg.version; + unowned Alpm.Package? sync_pkg = get_syncpkg (alpm_pkg.name); + if (sync_pkg != null) { + repo_name = sync_pkg.db.name; + } + } else if (alpm_pkg.origin == Alpm.Package.From.SYNCDB) { + unowned Alpm.Package? local_pkg = alpm_handle.localdb.get_pkg (alpm_pkg.name); + if (local_pkg != null) { + installed_version = local_pkg.version; + } + repo_name = alpm_pkg.db.name; + } + return AlpmPackage () { + name = alpm_pkg.name, + version = alpm_pkg.version, + installed_version = (owned) installed_version, + // desc can be null + desc = alpm_pkg.desc ?? "", + repo = (owned) repo_name, + size = alpm_pkg.isize, + download_size = alpm_pkg.download_size, + origin = (uint) alpm_pkg.origin + }; + } else { + return AlpmPackage () { + name = "", + version = "", + installed_version = "", + desc = "", + repo = "" + }; + } + } + + public async AlpmPackage[] get_installed_pkgs () { + AlpmPackage[] pkgs = {}; + unowned Alpm.List pkgcache = alpm_handle.localdb.pkgcache; + while (pkgcache != null) { + unowned Alpm.Package alpm_pkg = pkgcache.data; + pkgs += initialise_pkg_struct (alpm_pkg); + pkgcache.next (); + } + return pkgs; + } + + public async AlpmPackage[] get_explicitly_installed_pkgs () { + AlpmPackage[] pkgs = {}; + unowned Alpm.List pkgcache = alpm_handle.localdb.pkgcache; + while (pkgcache != null) { + unowned Alpm.Package alpm_pkg = pkgcache.data; + if (alpm_pkg.reason == Alpm.Package.Reason.EXPLICIT) { + pkgs += initialise_pkg_struct (alpm_pkg); + } + pkgcache.next (); + } + return pkgs; + } + + public async AlpmPackage[] get_foreign_pkgs () { + AlpmPackage[] pkgs = {}; + unowned Alpm.List pkgcache = alpm_handle.localdb.pkgcache; + while (pkgcache != null) { + unowned Alpm.Package alpm_pkg = pkgcache.data; + bool sync_found = false; + unowned Alpm.List syncdbs = alpm_handle.syncdbs; + while (syncdbs != null) { + unowned Alpm.DB db = syncdbs.data; + unowned Alpm.Package? sync_pkg = db.get_pkg (alpm_pkg.name); + if (sync_pkg != null) { + sync_found = true; + break; + } + syncdbs.next (); + } + if (sync_found == false) { + pkgs += initialise_pkg_struct (alpm_pkg); + } + pkgcache.next (); + } + return pkgs; + } + + public async AlpmPackage[] get_orphans () { + AlpmPackage[] pkgs = {}; + unowned Alpm.List pkgcache = alpm_handle.localdb.pkgcache; + while (pkgcache != null) { + unowned Alpm.Package alpm_pkg = pkgcache.data; + if (alpm_pkg.reason == Alpm.Package.Reason.DEPEND) { + Alpm.List requiredby = alpm_pkg.compute_requiredby (); + if (requiredby.length == 0) { + Alpm.List optionalfor = alpm_pkg.compute_optionalfor (); + if (optionalfor.length == 0) { + pkgs += initialise_pkg_struct (alpm_pkg); + } else { + optionalfor.free_inner (GLib.free); + } + } else { + requiredby.free_inner (GLib.free); + } + } + pkgcache.next (); + } + return pkgs; + } + + public AlpmPackage get_installed_pkg (string pkgname) { + return initialise_pkg_struct (alpm_handle.localdb.get_pkg (pkgname)); + } + + public AlpmPackage find_installed_satisfier (string depstring) { + return initialise_pkg_struct (Alpm.find_satisfier (alpm_handle.localdb.pkgcache, depstring)); + } + + private unowned Alpm.Package? get_syncpkg (string name) { + unowned Alpm.Package? pkg = null; + unowned Alpm.List syncdbs = alpm_handle.syncdbs; + while (syncdbs != null) { + unowned Alpm.DB db = syncdbs.data; + pkg = db.get_pkg (name); + if (pkg != null) { + break; + } + syncdbs.next (); + } + return pkg; + } + + public AlpmPackage get_sync_pkg (string pkgname) { + return initialise_pkg_struct (get_syncpkg (pkgname)); + } + + private unowned Alpm.Package? find_dbs_satisfier (string depstring) { + unowned Alpm.Package? pkg = null; + unowned Alpm.List syncdbs = alpm_handle.syncdbs; + while (syncdbs != null) { + unowned Alpm.DB db = syncdbs.data; + pkg = Alpm.find_satisfier (db.pkgcache, depstring); + if (pkg != null) { + break; + } + syncdbs.next (); + } + return pkg; + } + + public AlpmPackage find_sync_satisfier (string depstring) { + return initialise_pkg_struct (find_dbs_satisfier (depstring)); + } + + private Alpm.List search_all_dbs (string search_string) { + Alpm.List needles = null; + string[] splitted = search_string.split (" "); + foreach (unowned string part in splitted) { + needles.add (part); + } + Alpm.List result = alpm_handle.localdb.search (needles); + Alpm.List syncpkgs = null; + unowned Alpm.List syncdbs = alpm_handle.syncdbs; + while (syncdbs != null) { + unowned Alpm.DB db = syncdbs.data; + if (syncpkgs.length == 0) { + syncpkgs = db.search (needles); + } else { + syncpkgs.join (db.search (needles).diff (syncpkgs, (Alpm.List.CompareFunc) alpm_pkg_compare_name)); + } + syncdbs.next (); + } + result.join (syncpkgs.diff (result, (Alpm.List.CompareFunc) alpm_pkg_compare_name)); + // use custom sort function + global_search_string = search_string; + result.sort (result.length, (Alpm.List.CompareFunc) alpm_pkg_sort_search_by_relevance); + return result; + } + + public async AlpmPackage[] search_pkgs (string search_string) { + AlpmPackage[] result = {}; + Alpm.List alpm_pkgs = search_all_dbs (search_string); + unowned Alpm.List list = alpm_pkgs; + while (list != null) { + unowned Alpm.Package alpm_pkg = list.data; + result += initialise_pkg_struct (alpm_pkg); + list.next (); + } + return result; + } + + private AURPackage initialise_aur_struct (Json.Object json_object) { + string installed_version = ""; + unowned Alpm.Package? pkg = alpm_handle.localdb.get_pkg (json_object.get_string_member ("Name")); + if (pkg != null) { + installed_version = pkg.version; + } + return AURPackage () { + name = json_object.get_string_member ("Name"), + version = json_object.get_string_member ("Version"), + installed_version = (owned) installed_version, + // desc can be null + desc = json_object.get_null_member ("Description") ? "" : json_object.get_string_member ("Description"), + popularity = json_object.get_double_member ("Popularity") + }; + } + + public async AURPackage[] search_in_aur (string search_string) { + if (!aur_search_results.contains (search_string)) { + Json.Array pkgs = yield AUR.search (search_string.split (" ")); + aur_search_results.insert (search_string, pkgs); + } + AURPackage[] result = {}; + Json.Array aur_pkgs = aur_search_results.get (search_string); + aur_pkgs.foreach_element ((array, index, node) => { + Json.Object aur_pkg = node.get_object (); + // remove results which exist in repos + if (get_syncpkg (aur_pkg.get_string_member ("Name")) == null) { + result += initialise_aur_struct (node.get_object ()); + } + }); + return result; + } + + public async AURPackageDetails get_aur_details (string pkgname) { + string name = ""; + string version = ""; + string desc = ""; + double popularity = 0; + string packagebase = ""; + string url = ""; + string maintainer = ""; + int64 firstsubmitted = 0; + int64 lastmodified = 0; + int64 outofdate = 0; + int64 numvotes = 0; + string[] licenses = {}; + string[] depends = {}; + string[] makedepends = {}; + string[] checkdepends = {}; + string[] optdepends = {}; + string[] provides = {}; + string[] replaces = {}; + string[] conflicts = {}; + var details = AURPackageDetails (); + if (!aur_infos.contains (pkgname)) { + Json.Array results = yield AUR.multiinfo ({pkgname}); + if (results.get_length () > 0) { + aur_infos.insert (pkgname, results.get_object_element (0)); + } + } + unowned Json.Object? json_object = aur_infos.lookup (pkgname); + if (json_object != null) { + // name + name = json_object.get_string_member ("Name"); + // version + version = json_object.get_string_member ("Version"); + // desc can be null + if (!json_object.get_null_member ("Description")) { + desc = json_object.get_string_member ("Description"); + } + popularity = json_object.get_double_member ("Popularity"); + // packagebase + packagebase = json_object.get_string_member ("PackageBase"); + // url can be null + unowned Json.Node? node = json_object.get_member ("URL"); + if (!node.is_null ()) { + url = node.get_string (); + } + // maintainer can be null + node = json_object.get_member ("Maintainer"); + if (!node.is_null ()) { + maintainer = node.get_string (); + } + // firstsubmitted + firstsubmitted = json_object.get_int_member ("FirstSubmitted"); + // lastmodified + lastmodified = json_object.get_int_member ("LastModified"); + // outofdate can be null + node = json_object.get_member ("OutOfDate"); + if (!node.is_null ()) { + outofdate = node.get_int (); + } + //numvotes + numvotes = json_object.get_int_member ("NumVotes"); + // licenses + node = json_object.get_member ("License"); + if (!node.is_null ()) { + node.get_array ().foreach_element ((array, index, _node) => { + licenses += _node.get_string (); + }); + } else { + licenses += _("Unknown"); + } + // depends + node = json_object.get_member ("Depends"); + if (node != null) { + node.get_array ().foreach_element ((array, index, _node) => { + depends += _node.get_string (); + }); + } + // optdepends + node = json_object.get_member ("OptDepends"); + if (node != null) { + node.get_array ().foreach_element ((array, index, _node) => { + optdepends += _node.get_string (); + }); + } + // makedepends + node = json_object.get_member ("MakeDepends"); + if (node != null) { + node.get_array ().foreach_element ((array, index, _node) => { + makedepends += _node.get_string (); + }); + } + // checkdepends + node = json_object.get_member ("CheckDepends"); + if (node != null) { + node.get_array ().foreach_element ((array, index, _node) => { + checkdepends += _node.get_string (); + }); + } + // provides + node = json_object.get_member ("Provides"); + if (node != null) { + node.get_array ().foreach_element ((array, index, _node) => { + provides += _node.get_string (); + }); + } + // replaces + node = json_object.get_member ("Replaces"); + if (node != null) { + node.get_array ().foreach_element ((array, index, _node) => { + replaces += _node.get_string (); + }); + } + // conflicts + node = json_object.get_member ("Conflicts"); + if (node != null) { + node.get_array ().foreach_element ((array, index, _node) => { + conflicts += _node.get_string (); + }); + } + } + details.name = (owned) name; + details.version = (owned) version ; + details.desc = (owned) desc; + details.popularity = popularity; + details.packagebase = (owned) packagebase; + details.url = (owned) url; + details.maintainer = (owned) maintainer ; + details.firstsubmitted = firstsubmitted; + details.lastmodified = lastmodified; + details.outofdate = outofdate; + details.numvotes = numvotes; + details.licenses = (owned) licenses; + details.depends = (owned) depends; + details.optdepends = (owned) optdepends; + details.checkdepends = (owned) checkdepends; + details.makedepends = (owned) makedepends; + details.provides = (owned) provides; + details.replaces = (owned) replaces; + details.conflicts = (owned) conflicts; + return details; + } + + public string[] get_repos_names () { + string[] repos_names = {}; + unowned Alpm.List syncdbs = alpm_handle.syncdbs; + while (syncdbs != null) { + unowned Alpm.DB db = syncdbs.data; + repos_names += db.name; + syncdbs.next (); + } + return repos_names; + } + + public async AlpmPackage[] get_repo_pkgs (string repo) { + AlpmPackage[] pkgs = {}; + unowned Alpm.List syncdbs = alpm_handle.syncdbs; + while (syncdbs != null) { + unowned Alpm.DB db = syncdbs.data; + if (db.name == repo) { + unowned Alpm.List pkgcache = db.pkgcache; + while (pkgcache != null) { + unowned Alpm.Package sync_pkg = pkgcache.data; + unowned Alpm.Package? local_pkg = alpm_handle.localdb.get_pkg (sync_pkg.name); + if (local_pkg != null) { + pkgs += initialise_pkg_struct (local_pkg); + } else { + pkgs += initialise_pkg_struct (sync_pkg); + } + pkgcache.next (); + } + break; + } + syncdbs.next (); + } + return pkgs; + } + + public string[] get_groups_names () { + string[] groups_names = {}; + unowned Alpm.List groupcache = alpm_handle.localdb.groupcache; + while (groupcache != null) { + unowned Alpm.Group group = groupcache.data; + if (!(group.name in groups_names)) { + groups_names += group.name; + } + groupcache.next (); + } + unowned Alpm.List syncdbs = alpm_handle.syncdbs; + while (syncdbs != null) { + unowned Alpm.DB db = syncdbs.data; + groupcache = db.groupcache; + while (groupcache != null) { + unowned Alpm.Group group = groupcache.data; + if (!(group.name in groups_names)) { + groups_names += group.name; + } + groupcache.next (); + } + syncdbs.next (); + } + return groups_names; + } + + private Alpm.List group_pkgs (string group_name) { + Alpm.List result = null; + unowned Alpm.Group? grp = alpm_handle.localdb.get_group (group_name); + if (grp != null) { + unowned Alpm.List packages = grp.packages; + while (packages != null) { + unowned Alpm.Package pkg = packages.data; + result.add (pkg); + packages.next (); + } + } + unowned Alpm.List syncdbs = alpm_handle.syncdbs; + while (syncdbs != null) { + unowned Alpm.DB db = syncdbs.data; + grp = db.get_group (group_name); + if (grp != null) { + unowned Alpm.List packages = grp.packages; + while (packages != null) { + unowned Alpm.Package pkg = packages.data; + if (result.find (pkg, (Alpm.List.CompareFunc) alpm_pkg_compare_name) == null) { + result.add (pkg); + } + packages.next (); + } + } + syncdbs.next (); + } + return result; + } + + public async AlpmPackage[] get_group_pkgs (string groupname) { + AlpmPackage[] pkgs = {}; + Alpm.List alpm_pkgs = group_pkgs (groupname); + unowned Alpm.List list = alpm_pkgs; + while (list != null) { + unowned Alpm.Package alpm_pkg = list.data; + pkgs += initialise_pkg_struct (alpm_pkg); + list.next (); + } + return pkgs; + } + + public string[] get_pkg_uninstalled_optdeps (string pkgname) { + string[] optdeps = {}; + unowned Alpm.Package? alpm_pkg = alpm_handle.localdb.get_pkg (pkgname); + if (alpm_pkg == null) { + alpm_pkg = get_syncpkg (pkgname); + } + if (alpm_pkg != null) { + unowned Alpm.List optdepends = alpm_pkg.optdepends; + while (optdepends != null) { + unowned Alpm.Depend optdep = optdepends.data; + if (Alpm.find_satisfier (alpm_handle.localdb.pkgcache, optdep.name) == null) { + optdeps += optdep.compute_string (); + } + optdepends.next (); + } + } + return optdeps; + } + + public AlpmPackageDetails get_pkg_details (string pkgname) { + string name = ""; + string version = ""; + string desc = ""; + string url = ""; + string repo = ""; + string has_signature = ""; + string reason = ""; + string packager = ""; + string builddate = ""; + string installdate = ""; + string[] groups = {}; + string[] backups = {}; + string[] licenses = {}; + string[] depends = {}; + string[] optdepends = {}; + string[] requiredby = {}; + string[] optionalfor = {}; + string[] provides = {}; + string[] replaces = {}; + string[] conflicts = {}; + var details = AlpmPackageDetails (); + unowned Alpm.Package? alpm_pkg = alpm_handle.localdb.get_pkg (pkgname); + if (alpm_pkg == null) { + alpm_pkg = get_syncpkg (pkgname); + } + if (alpm_pkg != null) { + // name + name = alpm_pkg.name; + // version + version = alpm_pkg.version; + // desc can be null + if (alpm_pkg.desc != null) { + desc = alpm_pkg.desc; + } + details.origin = (uint) alpm_pkg.origin; + // url can be null + if (alpm_pkg.url != null) { + url = alpm_pkg.url; + } + // packager can be null + packager = alpm_pkg.packager ?? ""; + // groups + unowned Alpm.List list = alpm_pkg.groups; + while (list != null) { + groups += ((Alpm.List) list).data; + list.next (); + } + // licenses + list = alpm_pkg.licenses; + while (list != null) { + licenses += ((Alpm.List) list).data; + list.next (); + } + // build_date + GLib.Time time = GLib.Time.local ((time_t) alpm_pkg.builddate); + builddate = time.format ("%a %d %b %Y %X %Z"); + // local pkg + if (alpm_pkg.origin == Alpm.Package.From.LOCALDB) { + // repo + unowned Alpm.Package? sync_pkg = get_syncpkg (alpm_pkg.name); + if (sync_pkg != null) { + repo = sync_pkg.db.name; + } + // reason + if (alpm_pkg.reason == Alpm.Package.Reason.EXPLICIT) { + reason = _("Explicitly installed"); + } else if (alpm_pkg.reason == Alpm.Package.Reason.DEPEND) { + reason = _("Installed as a dependency for another package"); + } else { + reason = _("Unknown"); + } + // install_date + time = GLib.Time.local ((time_t) alpm_pkg.installdate); + installdate = time.format ("%a %d %b %Y %X %Z"); + // backups + list = alpm_pkg.backups; + while (list != null) { + backups += "/" + ((Alpm.List) list).data.name; + list.next (); + } + // requiredby + Alpm.List pkg_requiredby = alpm_pkg.compute_requiredby (); + list = pkg_requiredby; + while (list != null) { + requiredby += ((Alpm.List) list).data; + list.next (); + } + pkg_requiredby.free_inner (GLib.free); + // optionalfor + Alpm.List pkg_optionalfor = alpm_pkg.compute_optionalfor (); + list = pkg_optionalfor; + while (list != null) { + optionalfor += ((Alpm.List) list).data; + list.next (); + } + pkg_optionalfor.free_inner (GLib.free); + // sync pkg + } else if (alpm_pkg.origin == Alpm.Package.From.SYNCDB) { + // repos + repo = alpm_pkg.db.name; + // signature + has_signature = alpm_pkg.base64_sig != null ? _("Yes") : _("No"); + } + // depends + list = alpm_pkg.depends; + while (list != null) { + depends += ((Alpm.List) list).data.compute_string (); + list.next (); + } + // optdepends + list = alpm_pkg.optdepends; + while (list != null) { + optdepends += ((Alpm.List) list).data.compute_string (); + list.next (); + } + // provides + list = alpm_pkg.provides; + while (list != null) { + provides += ((Alpm.List) list).data.compute_string (); + list.next (); + } + // replaces + list = alpm_pkg.replaces; + while (list != null) { + replaces += ((Alpm.List) list).data.compute_string (); + list.next (); + } + // conflicts + list = alpm_pkg.conflicts; + while (list != null) { + conflicts += ((Alpm.List) list).data.compute_string (); + list.next (); + } + } + details.name = (owned) name; + details.version = (owned) version; + details.desc = (owned) desc; + details.repo = (owned) repo; + details.url = (owned) url; + details.packager = (owned) packager; + details.builddate = (owned) builddate; + details.installdate = (owned) installdate; + details.reason = (owned) reason; + details.has_signature = (owned) has_signature; + details.licenses = (owned) licenses; + details.depends = (owned) depends; + details.optdepends = (owned) optdepends; + details.requiredby = (owned) requiredby; + details.optionalfor = (owned) optionalfor; + details.provides = (owned) provides; + details.replaces = (owned) replaces; + details.conflicts = (owned) conflicts; + details.groups = (owned) groups; + details.backups = (owned) backups; + return details; + } + + public string[] get_pkg_files (string pkgname) { + string[] files = {}; + unowned Alpm.Package? alpm_pkg = alpm_handle.localdb.get_pkg (pkgname); + if (alpm_pkg != null) { + unowned Alpm.FileList filelist = alpm_pkg.files; + Alpm.File* file_ptr = filelist.files; + for (size_t i = 0; i < filelist.count; i++, file_ptr++) { + if (!file_ptr->name.has_suffix ("/")) { + files += "/" + file_ptr->name; + } + } + } else { + unowned Alpm.List syncdbs = files_handle.syncdbs; + while (syncdbs != null) { + unowned Alpm.DB db = syncdbs.data; + unowned Alpm.Package? files_pkg = db.get_pkg (pkgname); + if (files_pkg != null) { + unowned Alpm.FileList filelist = files_pkg.files; + Alpm.File* file_ptr = filelist.files; + for (size_t i = 0; i < filelist.count; i++, file_ptr++) { + if (!file_ptr->name.has_suffix ("/")) { + files += "/" + file_ptr->name; + } + } + break; + } + syncdbs.next (); + } + } + return files; + } + + private int get_updates () { + AlpmPackage[] updates_infos = {}; + unowned Alpm.Package? pkg = null; + unowned Alpm.Package? candidate = null; + // use a tmp handle + var tmp_handle = alpm_config.get_handle (false, true); + // refresh tmp dbs + unowned Alpm.List syncdbs = tmp_handle.syncdbs; + while (syncdbs != null) { + unowned Alpm.DB db = syncdbs.data; + db.update (0); + syncdbs.next (); + } + string[] local_pkgs = {}; + unowned Alpm.List pkgcache = tmp_handle.localdb.pkgcache; + while (pkgcache != null) { + unowned Alpm.Package installed_pkg = pkgcache.data; + // check if installed_pkg is in IgnorePkg or IgnoreGroup + if (tmp_handle.should_ignore (installed_pkg) == 0) { + candidate = installed_pkg.sync_newversion (tmp_handle.syncdbs); + if (candidate != null) { + var infos = initialise_pkg_struct (candidate); + infos.installed_version = installed_pkg.version; + updates_infos += (owned) infos; + } else { + if (check_aur_updates && (!aur_updates_checked)) { + // check if installed_pkg is a local pkg + syncdbs = tmp_handle.syncdbs; + while (syncdbs != null) { + unowned Alpm.DB db = syncdbs.data; + pkg = Alpm.find_satisfier (db.pkgcache, installed_pkg.name); + if (pkg != null) { + break; + } + syncdbs.next (); + } + if (pkg == null) { + local_pkgs += installed_pkg.name; + } + } + } + } + pkgcache.next (); + } + if (check_aur_updates) { + // get aur updates + if (!aur_updates_checked) { + AUR.multiinfo.begin (local_pkgs, (obj, res) => { + aur_updates_results = AUR.multiinfo.end (res); + aur_updates_checked = true; + var updates = Updates () { + repos_updates = (owned) updates_infos, + aur_updates = get_aur_updates_infos () + }; + get_updates_finished (updates); + }); + } else { + var updates = Updates () { + repos_updates = (owned) updates_infos, + aur_updates = get_aur_updates_infos () + }; + get_updates_finished (updates); + } + } else { + var updates = Updates () { + repos_updates = (owned) updates_infos, + aur_updates = {} + }; + get_updates_finished (updates); + } + return 0; + } + + private AURPackage[] get_aur_updates_infos () { + AURPackage[] aur_updates_infos = {}; + aur_updates_results.foreach_element ((array, index, node) => { + unowned Json.Object pkg_info = node.get_object (); + unowned string name = pkg_info.get_string_member ("Name"); + unowned string new_version = pkg_info.get_string_member ("Version"); + unowned string old_version = alpm_handle.localdb.get_pkg (name).version; + if (Alpm.pkg_vercmp (new_version, old_version) == 1) { + var infos = initialise_aur_struct (pkg_info); + infos.installed_version = old_version; + aur_updates_infos += (owned) infos; + } + }); + return aur_updates_infos; + } + + public void start_get_updates (bool check_aur_updates_) { + check_aur_updates = check_aur_updates_; + new Thread ("get updates thread", get_updates); + } + + [DBus (no_reply = true)] + public void quit () { + loop.quit (); + } + // End of Daemon Object + } +} + +void on_bus_acquired (DBusConnection conn) { + user_daemon = new Pamac.UserDaemon (); + try { + conn.register_object ("/org/manjaro/pamac/user", user_daemon); + } + catch (IOError e) { + stderr.printf ("Could not register service\n"); + loop.quit (); + } +} + +void main () { + // i18n + Intl.setlocale (LocaleCategory.ALL, ""); + Intl.textdomain (GETTEXT_PACKAGE); + + Bus.own_name (BusType.SESSION, + "org.manjaro.pamac.user", + BusNameOwnerFlags.NONE, + on_bus_acquired, + null, + () => { + stderr.printf ("Could not acquire name\n"); + loop.quit (); + }); + + loop = new MainLoop (); + loop.run (); +} diff --git a/vapi/libalpm.vapi b/vapi/libalpm.vapi index 83e82c6..3476284 100644 --- a/vapi/libalpm.vapi +++ b/vapi/libalpm.vapi @@ -550,6 +550,7 @@ namespace Alpm { public ulong name_hash; public Mode mod; + [CCode (cname = "alpm_dep_from_string")] public static Depend from_string(string depstring); [CCode (cname = "alpm_dep_compute_string")]