2013-04-07 09:16:23 -03:00
#! /usr/bin/python3
2013-03-31 14:31:33 -03:00
# -*- coding:utf-8 -*-
2013-01-06 15:10:13 -03:00
2013-11-26 05:24:54 -03:00
# pamac - A Python implementation of alpm
2014-02-01 11:39:58 -03:00
# Copyright (C) 2013-2014 Guillaume Benoit <guillaume@manjaro.org>
2013-11-26 05:24:54 -03:00
#
# 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 2 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 copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2013-01-06 15:10:13 -03:00
import pyalpm
2013-11-08 11:21:38 -03:00
from gi . repository import Gtk , GObject
2013-11-17 11:05:58 -03:00
from time import sleep
2013-11-08 11:21:38 -03:00
import subprocess
import os
import fnmatch
#import requests
#from ftplib import FTP
#from urllib.parse import urlparse
2013-10-16 10:34:09 -03:00
import dbus
from dbus . mainloop . glib import DBusGMainLoop
2013-11-27 12:11:47 -03:00
import signal
2014-03-05 11:16:51 -03:00
import re
2013-01-06 15:10:13 -03:00
2013-11-08 11:21:38 -03:00
from pamac import config , common , aur
2013-01-20 13:38:33 -03:00
2013-10-16 10:34:09 -03:00
to_remove = set ( )
to_add = set ( )
2013-11-15 11:44:52 -03:00
to_mark_as_dep = set ( )
2013-10-16 10:34:09 -03:00
to_update = set ( )
to_load = set ( )
2013-11-15 10:37:12 -03:00
available_updates = ( False , [ ] )
2013-11-08 11:21:38 -03:00
to_build = [ ]
cancel_download = False
build_proc = None
make_depends = set ( )
base_devel = ( ' autoconf ' , ' automake ' , ' binutils ' , ' bison ' , ' fakeroot ' ,
' file ' , ' findutils ' , ' flex ' , ' gawk ' , ' gcc ' , ' gettext ' ,
' grep ' , ' groff ' , ' gzip ' , ' libtool ' , ' m4 ' , ' make ' , ' patch ' ,
' pkg-config ' , ' sed ' , ' sudo ' , ' texinfo ' , ' util-linux ' , ' which ' )
build_depends = set ( )
2013-10-16 10:34:09 -03:00
handle = None
2013-11-08 11:21:38 -03:00
syncdbs = None
2013-10-16 10:34:09 -03:00
localdb = None
2014-03-05 11:16:51 -03:00
colors_regexp = re . compile ( ' \\ 033 \ [( \ d;)? \ d*m ' )
2013-10-16 10:34:09 -03:00
2013-09-26 13:02:07 -03:00
# i18n
import gettext
import locale
locale . bindtextdomain ( ' pamac ' , ' /usr/share/locale ' )
gettext . bindtextdomain ( ' pamac ' , ' /usr/share/locale ' )
gettext . textdomain ( ' pamac ' )
_ = gettext . gettext
interface = Gtk . Builder ( )
interface . set_translation_domain ( ' pamac ' )
interface . add_from_file ( ' /usr/share/pamac/gui/dialogs.ui ' )
ErrorDialog = interface . get_object ( ' ErrorDialog ' )
WarningDialog = interface . get_object ( ' WarningDialog ' )
2013-10-16 10:34:09 -03:00
#InfoDialog = interface.get_object('InfoDialog')
2014-01-29 11:44:19 -03:00
QuestionDialog = interface . get_object ( ' QuestionDialog ' )
2013-09-26 13:02:07 -03:00
ConfDialog = interface . get_object ( ' ConfDialog ' )
transaction_sum = interface . get_object ( ' transaction_sum ' )
sum_top_label = interface . get_object ( ' sum_top_label ' )
sum_bottom_label = interface . get_object ( ' sum_bottom_label ' )
ChooseDialog = interface . get_object ( ' ChooseDialog ' )
choose_list = interface . get_object ( ' choose_list ' )
choose_label = interface . get_object ( ' choose_label ' )
choose_renderertoggle = interface . get_object ( ' choose_renderertoggle ' )
ProgressWindow = interface . get_object ( ' ProgressWindow ' )
progress_bar = interface . get_object ( ' progressbar2 ' )
progress_label = interface . get_object ( ' progresslabel2 ' )
action_icon = interface . get_object ( ' action_icon ' )
ProgressCancelButton = interface . get_object ( ' ProgressCancelButton ' )
ProgressCloseButton = interface . get_object ( ' ProgressCloseButton ' )
progress_expander = interface . get_object ( ' progress_expander ' )
2013-11-08 11:21:38 -03:00
progress_textview = interface . get_object ( ' progress_textview ' )
2014-01-29 11:44:19 -03:00
PreferencesWindow = interface . get_object ( ' PreferencesWindow ' )
EnableAURButton = interface . get_object ( ' EnableAURButton ' )
RemoveUnrequiredDepsButton = interface . get_object ( ' RemoveUnrequiredDepsButton ' )
RefreshPeriodSpinButton = interface . get_object ( ' RefreshPeriodSpinButton ' )
2014-02-01 11:39:58 -03:00
RefreshPeriodLabel = interface . get_object ( ' RefreshPeriodLabel ' )
# Do it for transalation ease
RefreshPeriodLabel . set_markup ( _ ( ' How often to check for updates, value in hours ' ) + ' : ' )
2013-09-26 13:02:07 -03:00
progress_buffer = progress_textview . get_buffer ( )
2013-10-16 10:34:09 -03:00
DBusGMainLoop ( set_as_default = True )
bus = dbus . SystemBus ( )
def get_dbus_methods ( ) :
proxy = bus . get_object ( ' org.manjaro.pamac ' , ' /org/manjaro/pamac ' , introspect = False )
global Refresh
2013-11-15 10:37:12 -03:00
global CheckUpdates
2013-10-16 10:34:09 -03:00
global Init
global Sysupgrade
global Remove
global Add
global Load
global Prepare
global To_Remove
global To_Add
global Commit
global Interrupt
global Release
global StopDaemon
2013-11-15 10:37:12 -03:00
global SetPkgReason
2014-01-29 11:44:19 -03:00
global WriteConfig
2013-11-15 10:37:12 -03:00
SetPkgReason = proxy . get_dbus_method ( ' SetPkgReason ' , ' org.manjaro.pamac ' )
2013-10-16 10:34:09 -03:00
Refresh = proxy . get_dbus_method ( ' Refresh ' , ' org.manjaro.pamac ' )
2013-11-15 10:37:12 -03:00
CheckUpdates = proxy . get_dbus_method ( ' CheckUpdates ' , ' org.manjaro.pamac ' )
2013-10-16 10:34:09 -03:00
Init = proxy . get_dbus_method ( ' Init ' , ' org.manjaro.pamac ' )
Sysupgrade = proxy . get_dbus_method ( ' Sysupgrade ' , ' org.manjaro.pamac ' )
Remove = proxy . get_dbus_method ( ' Remove ' , ' org.manjaro.pamac ' )
Add = proxy . get_dbus_method ( ' Add ' , ' org.manjaro.pamac ' )
Load = proxy . get_dbus_method ( ' Load ' , ' org.manjaro.pamac ' )
Prepare = proxy . get_dbus_method ( ' Prepare ' , ' org.manjaro.pamac ' )
To_Remove = proxy . get_dbus_method ( ' To_Remove ' , ' org.manjaro.pamac ' )
To_Add = proxy . get_dbus_method ( ' To_Add ' , ' org.manjaro.pamac ' )
Commit = proxy . get_dbus_method ( ' Commit ' , ' org.manjaro.pamac ' )
Interrupt = proxy . get_dbus_method ( ' Interrupt ' , ' org.manjaro.pamac ' )
Release = proxy . get_dbus_method ( ' Release ' , ' org.manjaro.pamac ' )
StopDaemon = proxy . get_dbus_method ( ' StopDaemon ' , ' org.manjaro.pamac ' )
2014-01-29 11:44:19 -03:00
WriteConfig = proxy . get_dbus_method ( ' WriteConfig ' , ' org.manjaro.pamac ' )
2013-10-16 10:34:09 -03:00
def config_dbus_signals ( ) :
bus . add_signal_receiver ( action_handler , dbus_interface = " org.manjaro.pamac " , signal_name = " EmitAction " )
bus . add_signal_receiver ( action_long_handler , dbus_interface = " org.manjaro.pamac " , signal_name = " EmitActionLong " )
bus . add_signal_receiver ( icon_handler , dbus_interface = " org.manjaro.pamac " , signal_name = " EmitIcon " )
bus . add_signal_receiver ( target_handler , dbus_interface = " org.manjaro.pamac " , signal_name = " EmitTarget " )
bus . add_signal_receiver ( percent_handler , dbus_interface = " org.manjaro.pamac " , signal_name = " EmitPercent " )
bus . add_signal_receiver ( need_details_handler , dbus_interface = " org.manjaro.pamac " , signal_name = " EmitNeedDetails " )
bus . add_signal_receiver ( transaction_start_handler , dbus_interface = " org.manjaro.pamac " , signal_name = " EmitTransactionStart " )
bus . add_signal_receiver ( log_error , dbus_interface = " org.manjaro.pamac " , signal_name = " EmitLogError " )
bus . add_signal_receiver ( log_warning , dbus_interface = " org.manjaro.pamac " , signal_name = " EmitLogWarning " )
def action_handler ( action ) :
progress_label . set_text ( action )
def action_long_handler ( action_long ) :
global progress_buffer
end_iter = progress_buffer . get_end_iter ( )
progress_buffer . insert ( end_iter , action_long )
def need_details_handler ( need ) :
progress_expander . set_expanded ( need )
def icon_handler ( icon ) :
2014-02-08 08:10:55 -03:00
action_icon . set_from_icon_name ( icon , Gtk . IconSize . BUTTON )
2013-10-16 10:34:09 -03:00
def target_handler ( target ) :
progress_bar . set_text ( target )
def percent_handler ( percent ) :
if percent > 1 :
progress_bar . pulse ( )
else :
progress_bar . set_fraction ( percent )
def transaction_start_handler ( msg ) :
ProgressCancelButton . set_visible ( False )
def log_error ( msg ) :
ErrorDialog . format_secondary_text ( msg )
response = ErrorDialog . run ( )
while Gtk . events_pending ( ) :
Gtk . main_iteration ( )
if response :
ErrorDialog . hide ( )
def log_warning ( msg ) :
WarningDialog . format_secondary_text ( msg )
response = WarningDialog . run ( )
while Gtk . events_pending ( ) :
Gtk . main_iteration ( )
if response :
WarningDialog . hide ( )
2013-09-26 13:02:07 -03:00
def choose_provides ( data ) :
2013-10-16 10:34:09 -03:00
virtual_dep = str ( data [ 1 ] )
2013-09-26 13:02:07 -03:00
providers = data [ 0 ]
2013-11-08 11:21:38 -03:00
choose_label . set_markup ( ' <b> {} </b> ' . format ( _ ( ' {pkgname} is provided by {number} packages. \n Please choose those you would like to install: ' ) . format ( pkgname = virtual_dep , number = str ( len ( providers ) ) ) ) )
2013-09-26 13:02:07 -03:00
choose_list . clear ( )
2013-10-16 10:34:09 -03:00
for name in providers :
choose_list . append ( [ False , str ( name ) ] )
lenght = len ( to_add )
2013-09-26 13:02:07 -03:00
ChooseDialog . run ( )
2013-10-16 10:34:09 -03:00
if len ( to_add ) == lenght : # no choice was done by the user
to_add . add ( choose_list . get ( choose_list . get_iter_first ( ) , 1 ) [ 0 ] ) # add first provider
2013-09-26 13:02:07 -03:00
def on_choose_renderertoggle_toggled ( widget , line ) :
choose_list [ line ] [ 0 ] = not choose_list [ line ] [ 0 ]
2014-01-29 11:44:19 -03:00
def on_ChooseButton_clicked ( * args ) :
2013-09-26 13:02:07 -03:00
ChooseDialog . hide ( )
2013-10-16 10:34:09 -03:00
while Gtk . events_pending ( ) :
Gtk . main_iteration ( )
for row in choose_list :
if row [ 0 ] is True :
to_add . add ( row [ 1 ] . split ( ' : ' ) [ 0 ] ) # split done in case of optdep choice
2013-09-26 13:02:07 -03:00
2014-01-29 11:44:19 -03:00
def on_progress_textview_size_allocate ( * args ) :
2013-09-26 13:02:07 -03:00
#auto-scrolling method
adj = progress_textview . get_vadjustment ( )
adj . set_value ( adj . get_upper ( ) - adj . get_page_size ( ) )
2014-01-29 11:44:19 -03:00
def on_PreferencesValidButton_clicked ( * args ) :
data = [ ]
if EnableAURButton . get_active ( ) != config . enable_aur :
data . append ( ( ' EnableAUR ' , str ( EnableAURButton . get_active ( ) ) ) )
if RemoveUnrequiredDepsButton . get_active ( ) != config . recurse :
data . append ( ( ' RemoveUnrequiredDeps ' , str ( RemoveUnrequiredDepsButton . get_active ( ) ) ) )
if RefreshPeriodSpinButton . get_value ( ) != config . refresh_period :
data . append ( ( ' RefreshPeriod ' , str ( RefreshPeriodSpinButton . get_value_as_int ( ) ) ) )
if data :
WriteConfig ( data )
PreferencesWindow . hide ( )
def on_PreferencesCloseButton_clicked ( * args ) :
PreferencesWindow . hide ( )
2014-02-01 11:39:58 -03:00
def on_PreferencesWindow_delete_event ( * args ) :
PreferencesWindow . hide ( )
# return True is needed to not destroy the window
return True
2013-10-16 10:34:09 -03:00
def get_handle ( ) :
global handle
global syncdbs
global localdb
handle = config . handle ( )
syncdbs = handle . get_syncdbs ( )
localdb = handle . get_localdb ( )
def get_localpkg ( name ) :
return localdb . get_pkg ( name )
def get_syncpkg ( name ) :
for repo in syncdbs :
pkg = repo . get_pkg ( name )
if pkg :
return pkg
2013-11-08 11:21:38 -03:00
def refresh ( force_update = False ) :
2013-11-15 10:37:12 -03:00
while Gtk . events_pending ( ) :
Gtk . main_iteration ( )
2013-11-08 11:21:38 -03:00
action_handler ( _ ( ' Refreshing ' ) + ' ... ' )
2014-02-08 08:10:55 -03:00
icon_handler ( ' pamac-refresh ' )
2013-11-08 11:21:38 -03:00
target_handler ( ' ' )
percent_handler ( 0 )
2013-10-16 10:34:09 -03:00
ProgressCancelButton . set_visible ( True )
ProgressCloseButton . set_visible ( False )
2013-11-15 10:37:12 -03:00
progress_expander . set_visible ( True )
ProgressWindow . show ( )
2013-10-16 10:34:09 -03:00
while Gtk . events_pending ( ) :
Gtk . main_iteration ( )
Refresh ( force_update )
def init_transaction ( * * options ) :
return Init ( dbus . Dictionary ( options , signature = ' sb ' ) )
2013-11-08 11:21:38 -03:00
def check_to_build ( ) :
global to_build
2013-11-15 11:44:52 -03:00
global to_add
global to_mark_as_dep
2013-11-08 11:21:38 -03:00
global make_depends
global build_depends
2013-11-21 13:32:33 -03:00
make_depends = set ( )
builds_depends = set ( )
2013-11-15 11:44:52 -03:00
# check if base_devel packages are installed
for name in base_devel :
if not pyalpm . find_satisfier ( localdb . pkgcache , name ) :
make_depends . add ( name )
2013-11-08 11:21:38 -03:00
already_checked = set ( )
build_order = [ ]
i = 0
error = ' '
while i < len ( to_build ) :
2013-11-15 10:37:12 -03:00
while Gtk . events_pending ( ) :
Gtk . main_iteration ( )
2013-11-08 11:21:38 -03:00
pkg = to_build [ i ]
# if current pkg is not in build_order add it at the end of the list
if not pkg . name in build_order :
build_order . append ( pkg . name )
# download end extract tarball from AUR
srcdir = aur . get_extract_tarball ( pkg )
if srcdir :
# get PKGBUILD and parse it to create a new pkg object with makedeps and deps
new_pkgs = aur . get_pkgs ( srcdir + ' /PKGBUILD ' )
for new_pkg in new_pkgs :
2013-11-15 10:37:12 -03:00
while Gtk . events_pending ( ) :
Gtk . main_iteration ( )
2013-11-08 11:21:38 -03:00
print ( ' checking ' , new_pkg . name )
# check if some makedeps must be installed
for makedepend in new_pkg . makedepends :
2013-11-15 10:37:12 -03:00
while Gtk . events_pending ( ) :
Gtk . main_iteration ( )
2013-11-08 11:21:38 -03:00
if not makedepend in already_checked :
if not pyalpm . find_satisfier ( localdb . pkgcache , makedepend ) :
print ( ' found make dep: ' , makedepend )
for db in syncdbs :
2013-11-15 10:37:12 -03:00
provider = pyalpm . find_satisfier ( db . pkgcache , makedepend )
if provider :
break
2013-11-08 11:21:38 -03:00
if provider :
make_depends . add ( provider . name )
already_checked . add ( makedepend )
2013-11-15 10:37:12 -03:00
else :
# current makedep need to be built
raw_makedepend = common . format_pkg_name ( makedepend )
if raw_makedepend in build_order :
# add it in build_order before pkg
build_order . remove ( raw_makedepend )
index = build_order . index ( pkg . name )
build_order . insert ( index , raw_makedepend )
else :
# get infos about it
makedep_pkg = aur . info ( raw_makedepend )
if makedep_pkg :
# add it in to_build so it will be checked
to_build . append ( makedep_pkg )
# add it in build_order before pkg
index = build_order . index ( pkg . name )
build_order . insert ( index , raw_makedepend )
# add it in already_checked and to_add_as_as_dep
already_checked . add ( raw_makedepend )
2013-11-15 11:44:52 -03:00
to_mark_as_dep . add ( raw_makedepend )
2013-11-15 10:37:12 -03:00
else :
if error :
error + = ' \n '
error + = _ ( ' {pkgname} depends on {dependname} but it is not installable ' ) . format ( pkgname = pkg . name , dependname = makedepend )
2013-11-08 11:21:38 -03:00
# check if some deps must be installed or built
for depend in new_pkg . depends :
2013-11-15 10:37:12 -03:00
while Gtk . events_pending ( ) :
Gtk . main_iteration ( )
2013-11-08 11:21:38 -03:00
if not depend in already_checked :
if not pyalpm . find_satisfier ( localdb . pkgcache , depend ) :
print ( ' found dep: ' , depend )
for db in syncdbs :
2013-11-15 10:37:12 -03:00
provider = pyalpm . find_satisfier ( db . pkgcache , depend )
if provider :
break
2013-11-08 11:21:38 -03:00
if provider :
# current dep need to be installed
build_depends . add ( provider . name )
already_checked . add ( depend )
else :
# current dep need to be built
2013-11-15 10:37:12 -03:00
raw_depend = common . format_pkg_name ( depend )
if raw_depend in build_order :
# add it in build_order before pkg
build_order . remove ( raw_depend )
index = build_order . index ( pkg . name )
build_order . insert ( index , raw_depend )
else :
2013-11-08 11:21:38 -03:00
# get infos about it
2013-11-15 10:37:12 -03:00
dep_pkg = aur . info ( raw_depend )
2013-11-08 11:21:38 -03:00
if dep_pkg :
# add it in to_build so it will be checked
to_build . append ( dep_pkg )
# add it in build_order before pkg
index = build_order . index ( pkg . name )
2013-11-15 10:37:12 -03:00
build_order . insert ( index , raw_depend )
# add it in already_checked and to_add_as_as_dep
already_checked . add ( raw_depend )
2013-11-15 11:44:52 -03:00
to_mark_as_dep . add ( raw_depend )
2013-11-08 11:21:38 -03:00
else :
if error :
error + = ' \n '
error + = _ ( ' {pkgname} depends on {dependname} but it is not installable ' ) . format ( pkgname = pkg . name , dependname = depend )
else :
if error :
error + = ' \n '
error + = _ ( ' Failed to get {pkgname} archive from AUR ' ) . format ( pkgname = pkg . name )
i + = 1
if error :
return error
2013-11-15 11:44:52 -03:00
# add pkgname in make_depends and build_depends in to_add and to_mark_as_dep
2013-11-08 11:21:38 -03:00
for name in make_depends :
2013-11-15 11:44:52 -03:00
to_add . add ( name )
to_mark_as_dep . add ( name )
2013-11-08 11:21:38 -03:00
for name in build_depends :
2013-11-15 11:44:52 -03:00
to_add . add ( name )
to_mark_as_dep . add ( name )
2013-11-08 11:21:38 -03:00
# reorder to_build following build_order
to_build . sort ( key = lambda pkg : build_order . index ( pkg . name ) )
2014-01-29 12:21:37 -03:00
#print('order:', build_order)
2013-11-08 11:21:38 -03:00
print ( ' to build: ' , to_build )
print ( ' makedeps: ' , make_depends )
print ( ' builddeps: ' , build_depends )
return error
2014-01-29 11:44:19 -03:00
def run ( cascade = True , recurse = False ) :
2013-11-08 11:21:38 -03:00
if to_add or to_remove or to_load or to_build :
2013-11-15 10:37:12 -03:00
global progress_buffer
action_handler ( _ ( ' Preparing ' ) + ' ... ' )
2014-02-08 08:10:55 -03:00
icon_handler ( ' pamac-setup ' )
2013-11-15 10:37:12 -03:00
target_handler ( ' ' )
percent_handler ( 0 )
progress_buffer . delete ( progress_buffer . get_start_iter ( ) , progress_buffer . get_end_iter ( ) )
ProgressCancelButton . set_visible ( False )
ProgressCloseButton . set_visible ( False )
2014-01-29 14:52:32 -03:00
progress_expander . set_visible ( True )
2013-11-15 10:37:12 -03:00
ProgressWindow . show ( )
while Gtk . events_pending ( ) :
Gtk . main_iteration ( )
2014-02-01 11:39:58 -03:00
# we need to give some time to the window to refresh
2013-11-17 11:05:58 -03:00
sleep ( 0.1 )
error = ' '
2013-11-08 11:21:38 -03:00
if to_build :
# check if packages in to_build have deps or makedeps which need to be install first
error + = check_to_build ( )
2013-10-16 10:34:09 -03:00
if not error :
2013-11-15 11:44:52 -03:00
if to_add or to_remove or to_load :
2014-01-29 14:52:32 -03:00
ProgressCancelButton . set_visible ( True )
2013-11-17 11:05:58 -03:00
while Gtk . events_pending ( ) :
Gtk . main_iteration ( )
2014-01-29 11:44:19 -03:00
trans_flags = { ' cascade ' : cascade , ' recurse ' : recurse }
2013-11-08 11:21:38 -03:00
error + = init_transaction ( * * trans_flags )
if not error :
2013-11-15 11:44:52 -03:00
for name in to_add :
2013-11-08 11:21:38 -03:00
error + = Add ( name )
for name in to_remove :
error + = Remove ( name )
for path in to_load :
error + = Load ( path )
if not error :
error + = prepare ( * * trans_flags )
2013-10-16 10:34:09 -03:00
if not error :
2013-11-08 11:21:38 -03:00
set_transaction_sum ( )
ConfDialog . show_all ( )
while Gtk . events_pending ( ) :
Gtk . main_iteration ( )
2013-10-16 10:34:09 -03:00
if error :
2013-11-15 10:37:12 -03:00
ProgressWindow . hide ( )
2013-10-16 10:34:09 -03:00
Release ( )
return ( error )
else :
return ( _ ( ' Nothing to do ' ) )
2013-11-08 11:21:38 -03:00
def prepare ( * * trans_flags ) :
2013-10-16 10:34:09 -03:00
error = ' '
ret = Prepare ( )
2013-11-08 11:21:38 -03:00
# ret type is a(ass) so [([''], '')]
2013-10-16 10:34:09 -03:00
if ret [ 0 ] [ 0 ] : # providers are emitted
Release ( )
for item in ret :
choose_provides ( item )
error + = init_transaction ( * * trans_flags )
if not error :
2013-11-15 11:44:52 -03:00
for name in to_add :
2013-10-16 10:34:09 -03:00
error + = Add ( name )
for name in to_remove :
error + = Remove ( name )
for path in to_load :
error + = Load ( path )
if not error :
ret = Prepare ( )
if ret [ 0 ] [ 1 ] :
error = str ( ret [ 0 ] [ 1 ] )
elif ret [ 0 ] [ 1 ] : # an error is emitted
error = str ( ret [ 0 ] [ 1 ] )
return ( error )
2013-11-08 11:21:38 -03:00
def check_finished_build ( data ) :
2013-11-27 12:11:47 -03:00
def handle_timeout ( * args ) :
raise Exception ( ' timeout ' )
2013-11-29 05:49:28 -03:00
def no_handle_timeout ( * args ) :
try :
pass
except :
pass
2013-11-08 11:21:38 -03:00
global to_build
global build_proc
path = data [ 0 ]
pkg = data [ 1 ]
if build_proc . poll ( ) is None :
2013-11-27 12:11:47 -03:00
# Build no finished : read stdout to push it to text_buffer
# add a timeout to stop reading stdout if too long
# so the gui won't freeze
signal . signal ( signal . SIGALRM , handle_timeout )
signal . setitimer ( signal . ITIMER_REAL , 0.05 ) # 50 ms timeout
try :
line = build_proc . stdout . readline ( ) . decode ( encoding = ' UTF-8 ' )
2014-03-05 11:16:51 -03:00
line = re . sub ( colors_regexp , ' ' , line )
2013-11-27 12:11:47 -03:00
#print(line.rstrip('\n'))
progress_buffer . insert_at_cursor ( line )
except Exception :
2013-11-29 05:49:28 -03:00
pass
else :
signal . signal ( signal . SIGALRM , no_handle_timeout )
finally :
progress_bar . pulse ( )
2013-11-27 12:11:47 -03:00
while Gtk . events_pending ( ) :
Gtk . main_iteration ( )
return True
2013-11-17 11:05:58 -03:00
elif build_proc . poll ( ) == 0 :
2013-11-27 12:11:47 -03:00
# Build successfully finished
2013-11-08 11:21:38 -03:00
built = [ ]
# parse again PKGBUILD to have new pkg objects in case of a pkgver() function
# was used so pkgver was changed during build process
new_pkgs = aur . get_pkgs ( path + ' /PKGBUILD ' )
# find built packages
for new_pkg in new_pkgs :
for item in os . listdir ( path ) :
if os . path . isfile ( os . path . join ( path , item ) ) :
2013-11-24 13:02:04 -03:00
# add a * before pkgver if there an epoch variable
if fnmatch . fnmatch ( item , ' {} -* {} -*.pkg.tar.?z ' . format ( new_pkg . name , new_pkg . version ) ) :
2013-11-08 11:21:38 -03:00
built . append ( os . path . join ( path , item ) )
break
if built :
print ( ' successfully built: ' , built )
build_proc = None
2013-11-15 10:37:12 -03:00
if pkg in to_build :
to_build . remove ( pkg )
2013-11-08 11:21:38 -03:00
# install built packages
error = ' '
error + = init_transaction ( )
if not error :
for pkg_path in built :
error + = Load ( pkg_path )
if not error :
error + = prepare ( )
if not error :
if To_Remove ( ) :
set_transaction_sum ( )
ConfDialog . show_all ( )
while Gtk . events_pending ( ) :
Gtk . main_iteration ( )
else :
finalize ( )
if error :
Release ( )
2013-11-17 11:05:58 -03:00
ProgressCancelButton . set_visible ( False )
ProgressCloseButton . set_visible ( True )
ErrorDialog . format_secondary_text ( error )
response = ErrorDialog . run ( )
if response :
ErrorDialog . hide ( )
2013-11-24 13:02:04 -03:00
else :
ProgressCancelButton . set_visible ( False )
ProgressCloseButton . set_visible ( True )
action_long_handler ( _ ( ' Build process failed. ' ) )
2013-11-17 11:05:58 -03:00
return False
elif build_proc . poll ( ) == 1 :
2013-11-27 12:11:47 -03:00
# Build finish with an error
2013-11-17 11:05:58 -03:00
ProgressCancelButton . set_visible ( False )
ProgressCloseButton . set_visible ( True )
action_long_handler ( _ ( ' Build process failed. ' ) )
2013-11-08 11:21:38 -03:00
return False
def download ( url_list , path ) :
def write_file ( chunk ) :
nonlocal transferred
nonlocal f
if cancel_download :
if ftp :
ftp . quit ( )
raise Exception ( ' Download cancelled ' )
return
f . write ( chunk )
transferred + = len ( chunk )
if total_size > 0 :
percent = round ( transferred / total_size , 2 )
percent_handler ( percent )
if transferred < = total_size :
target = ' {transferred} / {size} ' . format ( transferred = common . format_size ( transferred ) , size = common . format_size ( total_size ) )
else :
target = ' '
target_handler ( target )
while Gtk . events_pending ( ) :
Gtk . main_iteration ( )
global cancel_download
cancel_download = False
ftp = None
total_size = 0
transferred = 0
2014-02-08 08:10:55 -03:00
icon_handler ( ' pamac-download ' )
2013-10-16 10:34:09 -03:00
ProgressCancelButton . set_visible ( True )
ProgressCloseButton . set_visible ( False )
2013-11-08 11:21:38 -03:00
parsed_urls = [ ]
for url in url_list :
url_components = urlparse ( url )
if url_components . scheme :
parsed_urls . append ( url_components )
print ( parsed_urls )
for url_components in parsed_urls :
if url_components . scheme == ' http ' :
total_size + = int ( requests . get ( url ) . headers [ ' Content-Length ' ] )
elif url_components . scheme == ' ftp ' :
ftp = FTP ( url_components . netloc )
ftp . login ( ' anonymous ' , ' ' )
total_size + = int ( ftp . size ( url_components . path ) )
print ( total_size )
for url_components in parsed_urls :
filename = url_components . path . split ( ' / ' ) [ - 1 ]
print ( filename )
action = _ ( ' Downloading {pkgname} ' ) . format ( pkgname = filename ) + ' ... '
action_long = action + ' \n '
action_handler ( action )
action_long_handler ( action_long )
ProgressWindow . show ( )
while Gtk . events_pending ( ) :
Gtk . main_iteration ( )
with open ( os . path . join ( path , filename ) , ' wb ' ) as f :
if url_components . scheme == ' http ' :
try :
r = requests . get ( url , stream = True )
for chunk in r . iter_content ( 1024 ) :
if cancel_download :
raise Exception ( ' Download cancelled ' )
break
else :
write_file ( chunk )
except Exception as e :
print ( e )
cancel_download = False
elif url_components . scheme == ' ftp ' :
try :
ftp = FTP ( url_components . netloc )
ftp . login ( ' anonymous ' , ' ' )
ftp . retrbinary ( ' RETR ' + url_components . path , write_file , blocksize = 1024 )
except Exception as e :
print ( e )
cancel_download = False
def build_next ( ) :
global build_proc
pkg = to_build [ 0 ]
2014-09-22 05:22:57 -03:00
path = os . path . join ( aur . srcpkgdir , aur . get_name ( pkg ) )
2013-11-08 11:21:38 -03:00
new_pkgs = aur . get_pkgs ( path + ' /PKGBUILD ' )
# sources are identicals for splitted packages
# (not complete) download(new_pkgs[0].source, path)
action = _ ( ' Building {pkgname} ' ) . format ( pkgname = pkg . name ) + ' ... '
action_handler ( action )
action_long_handler ( action + ' \n ' )
2014-02-08 08:10:55 -03:00
icon_handler ( ' pamac-setup ' )
2013-11-15 10:37:12 -03:00
target_handler ( ' ' )
percent_handler ( 0 )
2013-11-08 11:21:38 -03:00
ProgressCancelButton . set_visible ( True )
ProgressCloseButton . set_visible ( False )
2013-11-15 10:37:12 -03:00
progress_expander . set_visible ( True )
2013-11-08 11:21:38 -03:00
progress_expander . set_expanded ( True )
ProgressWindow . show ( )
2013-11-17 11:05:58 -03:00
build_proc = subprocess . Popen ( [ " makepkg " , " -cf " ] , cwd = path , stdout = subprocess . PIPE , stderr = subprocess . STDOUT )
2013-10-16 10:34:09 -03:00
while Gtk . events_pending ( ) :
Gtk . main_iteration ( )
2013-11-27 12:11:47 -03:00
GObject . timeout_add ( 100 , check_finished_build , ( path , pkg ) )
2013-11-08 11:21:38 -03:00
def finalize ( ) :
if To_Add ( ) or To_Remove ( ) :
try :
Commit ( )
except dbus . exceptions . DBusException as e :
Release ( )
elif to_build :
# packages in to_build have no deps or makedeps
# so we build and install the first one
# the next ones will be built by the caller
build_next ( )
2013-10-16 10:34:09 -03:00
2013-11-15 10:37:12 -03:00
def mark_needed_pkgs_as_dep ( ) :
2013-11-15 11:44:52 -03:00
global to_mark_as_dep
for name in to_mark_as_dep . copy ( ) :
if get_localpkg ( name ) :
error = SetPkgReason ( name , pyalpm . PKG_REASON_DEPEND )
if error :
print ( error )
else :
to_mark_as_dep . discard ( name )
2013-11-15 10:37:12 -03:00
2013-10-16 10:34:09 -03:00
def get_updates ( ) :
2013-11-15 10:37:12 -03:00
while Gtk . events_pending ( ) :
Gtk . main_iteration ( )
action_handler ( _ ( ' Checking for updates ' ) + ' ... ' )
2014-02-08 08:10:55 -03:00
icon_handler ( ' pamac-search ' )
2013-11-15 10:37:12 -03:00
target_handler ( ' ' )
percent_handler ( 0 )
ProgressCancelButton . set_visible ( False )
ProgressCloseButton . set_visible ( False )
progress_expander . set_visible ( False )
ProgressWindow . show ( )
while Gtk . events_pending ( ) :
Gtk . main_iteration ( )
CheckUpdates ( )
2013-10-16 10:34:09 -03:00
def get_transaction_sum ( ) :
2013-11-08 11:21:38 -03:00
transaction_dict = { ' to_remove ' : [ ] , ' to_build ' : [ ] , ' to_install ' : [ ] , ' to_update ' : [ ] , ' to_reinstall ' : [ ] , ' to_downgrade ' : [ ] }
for pkg in to_build :
transaction_dict [ ' to_build ' ] . append ( pkg . name + ' ' + pkg . version )
_to_remove = sorted ( To_Remove ( ) )
for name , version in _to_remove :
2013-10-16 10:34:09 -03:00
transaction_dict [ ' to_remove ' ] . append ( name + ' ' + version )
others = sorted ( To_Add ( ) )
for name , version , dsize in others :
pkg = get_localpkg ( name )
if pkg :
comp = pyalpm . vercmp ( version , pkg . version )
if comp == 1 :
transaction_dict [ ' to_update ' ] . append ( ( name + ' ' + version , dsize ) )
elif comp == 0 :
transaction_dict [ ' to_reinstall ' ] . append ( ( name + ' ' + version , dsize ) )
elif comp == - 1 :
transaction_dict [ ' to_downgrade ' ] . append ( ( name + ' ' + version , dsize ) )
2013-09-26 13:02:07 -03:00
else :
2013-10-16 10:34:09 -03:00
transaction_dict [ ' to_install ' ] . append ( ( name + ' ' + version , dsize ) )
2013-11-15 10:37:12 -03:00
#~ if transaction_dict['to_build']:
#~ print('To build:', [name for name in transaction_dict['to_build']])
#~ if transaction_dict['to_install']:
#~ print('To install:', [name for name, size in transaction_dict['to_install']])
#~ if transaction_dict['to_reinstall']:
#~ print('To reinstall:', [name for name, size in transaction_dict['to_reinstall']])
#~ if transaction_dict['to_downgrade']:
#~ print('To downgrade:', [name for name, size in transaction_dict['to_downgrade']])
#~ if transaction_dict['to_remove']:
#~ print('To remove:', [name for name in transaction_dict['to_remove']])
#~ if transaction_dict['to_update']:
#~ print('To update:', [name for name, size in transaction_dict['to_update']])
2013-10-16 10:34:09 -03:00
return transaction_dict
2013-11-08 11:21:38 -03:00
def set_transaction_sum ( show_updates = True ) :
dsize = 0
2013-10-16 10:34:09 -03:00
transaction_sum . clear ( )
transaction_dict = get_transaction_sum ( )
2013-11-08 11:21:38 -03:00
sum_top_label . set_markup ( ' <big><b> {} </b></big> ' . format ( _ ( ' Transaction Summary ' ) ) )
if transaction_dict [ ' to_remove ' ] :
transaction_sum . append ( [ _ ( ' To remove ' ) + ' : ' , transaction_dict [ ' to_remove ' ] [ 0 ] ] )
i = 1
while i < len ( transaction_dict [ ' to_remove ' ] ) :
transaction_sum . append ( [ ' ' , transaction_dict [ ' to_remove ' ] [ i ] ] )
i + = 1
if transaction_dict [ ' to_downgrade ' ] :
transaction_sum . append ( [ _ ( ' To downgrade ' ) + ' : ' , transaction_dict [ ' to_downgrade ' ] [ 0 ] [ 0 ] ] )
2013-11-26 12:33:45 -03:00
dsize + = transaction_dict [ ' to_downgrade ' ] [ 0 ] [ 1 ]
2013-11-08 11:21:38 -03:00
i = 1
while i < len ( transaction_dict [ ' to_downgrade ' ] ) :
transaction_sum . append ( [ ' ' , transaction_dict [ ' to_downgrade ' ] [ i ] [ 0 ] ] )
dsize + = transaction_dict [ ' to_downgrade ' ] [ i ] [ 1 ]
i + = 1
if transaction_dict [ ' to_build ' ] :
transaction_sum . append ( [ _ ( ' To build ' ) + ' : ' , transaction_dict [ ' to_build ' ] [ 0 ] ] )
i = 1
while i < len ( transaction_dict [ ' to_build ' ] ) :
transaction_sum . append ( [ ' ' , transaction_dict [ ' to_build ' ] [ i ] ] )
i + = 1
2013-10-16 10:34:09 -03:00
if transaction_dict [ ' to_install ' ] :
transaction_sum . append ( [ _ ( ' To install ' ) + ' : ' , transaction_dict [ ' to_install ' ] [ 0 ] [ 0 ] ] )
2013-11-26 12:33:45 -03:00
dsize + = transaction_dict [ ' to_install ' ] [ 0 ] [ 1 ]
2013-10-16 10:34:09 -03:00
i = 1
while i < len ( transaction_dict [ ' to_install ' ] ) :
2013-11-08 11:21:38 -03:00
transaction_sum . append ( [ ' ' , transaction_dict [ ' to_install ' ] [ i ] [ 0 ] ] )
dsize + = transaction_dict [ ' to_install ' ] [ i ] [ 1 ]
2013-09-26 13:02:07 -03:00
i + = 1
2013-10-16 10:34:09 -03:00
if transaction_dict [ ' to_reinstall ' ] :
transaction_sum . append ( [ _ ( ' To reinstall ' ) + ' : ' , transaction_dict [ ' to_reinstall ' ] [ 0 ] [ 0 ] ] )
2013-11-26 12:33:45 -03:00
dsize + = transaction_dict [ ' to_reinstall ' ] [ 0 ] [ 1 ]
2013-10-16 10:34:09 -03:00
i = 1
while i < len ( transaction_dict [ ' to_reinstall ' ] ) :
2013-11-08 11:21:38 -03:00
transaction_sum . append ( [ ' ' , transaction_dict [ ' to_reinstall ' ] [ i ] [ 0 ] ] )
dsize + = transaction_dict [ ' to_reinstall ' ] [ i ] [ 1 ]
2013-09-26 13:02:07 -03:00
i + = 1
2013-10-16 10:34:09 -03:00
if show_updates :
if transaction_dict [ ' to_update ' ] :
transaction_sum . append ( [ _ ( ' To update ' ) + ' : ' , transaction_dict [ ' to_update ' ] [ 0 ] [ 0 ] ] )
2013-11-26 12:33:45 -03:00
dsize + = transaction_dict [ ' to_update ' ] [ 0 ] [ 1 ]
2013-10-16 10:34:09 -03:00
i = 1
while i < len ( transaction_dict [ ' to_update ' ] ) :
2013-11-08 11:21:38 -03:00
transaction_sum . append ( [ ' ' , transaction_dict [ ' to_update ' ] [ i ] [ 0 ] ] )
dsize + = transaction_dict [ ' to_update ' ] [ i ] [ 1 ]
2013-09-26 13:02:07 -03:00
i + = 1
2013-11-26 12:33:45 -03:00
else :
for name , size in transaction_dict [ ' to_update ' ] :
dsize + = size
2013-10-16 10:34:09 -03:00
if dsize == 0 :
sum_bottom_label . set_markup ( ' ' )
else :
2013-11-08 11:21:38 -03:00
sum_bottom_label . set_markup ( ' <b> {} {} </b> ' . format ( _ ( ' Total download size: ' ) , common . format_size ( dsize ) ) )
2013-10-16 10:34:09 -03:00
2014-03-05 11:00:39 -03:00
def sysupgrade ( show_updates = True , downgrade = False ) :
2013-11-15 10:37:12 -03:00
syncfirst , updates = available_updates
2013-10-16 10:34:09 -03:00
if updates :
2014-01-29 14:52:32 -03:00
global to_update
global to_add
global to_remove
global progress_buffer
2013-11-08 11:21:38 -03:00
to_update . clear ( )
2013-10-16 10:34:09 -03:00
to_add . clear ( )
to_remove . clear ( )
2014-01-29 14:52:32 -03:00
action_handler ( _ ( ' Preparing ' ) + ' ... ' )
2014-02-08 08:10:55 -03:00
icon_handler ( ' pamac-setup ' )
2014-01-29 14:52:32 -03:00
target_handler ( ' ' )
percent_handler ( 0 )
progress_buffer . delete ( progress_buffer . get_start_iter ( ) , progress_buffer . get_end_iter ( ) )
ProgressCancelButton . set_visible ( False )
ProgressCloseButton . set_visible ( False )
progress_expander . set_visible ( True )
ProgressWindow . show ( )
while Gtk . events_pending ( ) :
Gtk . main_iteration ( )
2013-11-15 10:37:12 -03:00
for name , version , db , tarpath , size in updates :
if db == ' AUR ' :
# call AURPkg constructor directly to avoid a request to AUR
infos = { ' name ' : name , ' version ' : version , ' Description ' : ' ' , ' URLPath ' : tarpath }
pkg = aur . AURPkg ( infos )
2013-11-08 11:21:38 -03:00
to_build . append ( pkg )
else :
2013-11-15 10:37:12 -03:00
to_update . add ( name )
2013-10-16 10:34:09 -03:00
error = ' '
2013-11-15 10:37:12 -03:00
if syncfirst :
2014-01-29 14:52:32 -03:00
ProgressCancelButton . set_visible ( True )
2013-10-16 10:34:09 -03:00
error + = init_transaction ( )
if not error :
2013-10-20 07:19:36 -03:00
for name in to_update :
2013-10-16 10:34:09 -03:00
error + = Add ( name )
2013-11-08 11:21:38 -03:00
if not error :
error + = prepare ( )
2013-10-16 10:34:09 -03:00
else :
2013-11-08 11:21:38 -03:00
if to_build :
# check if packages in to_build have deps or makedeps which need to be install first
# grab errors differently here to not break regular updates
_error = check_to_build ( )
if to_update or to_add :
2014-01-29 14:52:32 -03:00
ProgressCancelButton . set_visible ( True )
2013-11-08 11:21:38 -03:00
error + = init_transaction ( )
if not error :
if to_update :
2014-03-05 11:00:39 -03:00
error + = Sysupgrade ( downgrade )
2013-11-08 11:21:38 -03:00
_error = ' '
for name in to_add :
_error + = Add ( name )
if _error :
print ( _error )
if not error :
error + = prepare ( )
2013-10-16 10:34:09 -03:00
if not error :
2013-11-08 11:21:38 -03:00
set_transaction_sum ( show_updates = show_updates )
if show_updates :
ConfDialog . show_all ( )
while Gtk . events_pending ( ) :
Gtk . main_iteration ( )
else :
if len ( transaction_sum ) != 0 :
ConfDialog . show_all ( )
while Gtk . events_pending ( ) :
Gtk . main_iteration ( )
else :
finalize ( )
2013-10-16 10:34:09 -03:00
if error :
2013-11-15 10:37:12 -03:00
ProgressWindow . hide ( )
2013-10-16 10:34:09 -03:00
Release ( )
return error