add AUR support :D

This commit is contained in:
guinux 2013-11-08 15:21:38 +01:00
parent b15b185957
commit 77d0f17154
7 changed files with 908 additions and 249 deletions

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.16.0 on Sun Oct 13 17:29:04 2013 -->
<!-- Generated with glade 3.16.0 on Wed Nov 6 15:14:37 2013 -->
<interface>
<!-- interface-requires gtk+ 3.6 -->
<object class="GtkAboutDialog" id="AboutDialog">
@ -248,10 +248,27 @@
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="search_aur_button">
<property name="label" translatable="yes">Search in AUR</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="focus_on_click">False</property>
<property name="xalign">0</property>
<property name="draw_indicator">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkScrolledWindow" id="scrolledwindow3">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="shadow_type">out</property>
<child>
<object class="GtkTreeView" id="search_treeview">
<property name="visible">True</property>
@ -282,7 +299,7 @@
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
<property name="position">2</property>
</packing>
</child>
</object>
@ -511,6 +528,19 @@
</child>
</object>
</child>
<child>
<object class="GtkTreeViewColumn" id="repo_column">
<property name="resizable">True</property>
<property name="sizing">autosize</property>
<property name="title" translatable="yes">Repo</property>
<property name="clickable">True</property>
<property name="sort_column_id">0</property>
<signal name="clicked" handler="on_repo_column_clicked" swapped="no"/>
<child>
<object class="GtkCellRendererText" id="repo_renderertext"/>
</child>
</object>
</child>
<child>
<object class="GtkTreeViewColumn" id="size_column">
<property name="resizable">True</property>
@ -537,7 +567,7 @@
<property name="visible">True</property>
<property name="can_focus">True</property>
<child>
<object class="GtkScrolledWindow" id="scrolledwindow10">
<object class="GtkScrolledWindow" id="infos_scrolledwindow">
<property name="visible">True</property>
<property name="can_focus">True</property>
<child>
@ -624,7 +654,7 @@
</packing>
</child>
<child>
<object class="GtkScrolledWindow" id="scrolledwindow9">
<object class="GtkScrolledWindow" id="deps_scrolledwindow">
<property name="visible">True</property>
<property name="can_focus">True</property>
<child>
@ -689,7 +719,7 @@
</packing>
</child>
<child>
<object class="GtkScrolledWindow" id="scrolledwindow7">
<object class="GtkScrolledWindow" id="details_scrolledwindow">
<property name="visible">True</property>
<property name="can_focus">True</property>
<child>

View File

@ -9,7 +9,7 @@ import re
import pyalpm
from multiprocessing import Process
from pamac import config, common
from pamac import config, common, aur
# i18n
import gettext
@ -159,7 +159,7 @@ class PamacDBusService(dbus.service.Object):
elif event == 'ALPM_EVENT_UPGRADE_START':
string = _('Upgrading {pkgname}').format(pkgname = tupel[1].name)
action = string+'...'
action_long = '{} ({} -> {})\n'.format(string, tupel[1].version, tupel[0].version)
action_long = '{} ({} => {})\n'.format(string, tupel[1].version, tupel[0].version)
icon = '/usr/share/pamac/icons/24x24/status/package-update.png'
elif event == 'ALPM_EVENT_UPGRADE_DONE':
formatted_event = 'Upgraded {pkgname} ({oldversion} -> {newversion})'.format(pkgname = tupel[1].name, oldversion = tupel[1].version, newversion = tupel[0].version)
@ -167,7 +167,7 @@ class PamacDBusService(dbus.service.Object):
elif event == 'ALPM_EVENT_DOWNGRADE_START':
string = _('Downgrading {pkgname}').format(pkgname = tupel[1].name)
action = string+'...'
action_long = '{} ({} -> {})'.format(string, tupel[1].version, tupel[0].version)
action_long = '{} ({} => {})'.format(string, tupel[1].version, tupel[0].version)
icon = '/usr/share/pamac/icons/24x24/status/package-add.png'
elif event == 'ALPM_EVENT_DOWNGRADE_DONE':
formatted_event = 'Downgraded {pkgname} ({oldversion} -> {newversion})'.format(pkgname = tupel[1].name, oldversion = tupel[1].version, newversion = tupel[0].version)
@ -315,7 +315,10 @@ class PamacDBusService(dbus.service.Object):
icon = '/usr/share/pamac/icons/24x24/status/package-download.png'
if self.total_size > 0:
percent = round((_transferred+self.already_transferred)/self.total_size, 2)
target = '{transferred}/{size}'.format(transferred = common.format_size(_transferred+self.already_transferred), size = common.format_size(self.total_size))
if _transferred+self.already_transferred <= self.total_size:
target = '{transferred}/{size}'.format(transferred = common.format_size(_transferred+self.already_transferred), size = common.format_size(self.total_size))
else:
target = ''
else:
percent = round(_transferred/_total, 2)
target = ''
@ -388,10 +391,22 @@ class PamacDBusService(dbus.service.Object):
updates += 1
if not updates:
for pkg in self.handle.get_localdb().pkgcache:
candidate = pyalpm.sync_newversion(pkg, self.handle.get_syncdbs())
if candidate:
if not candidate.name in _ignorepkgs:
if not pkg.name in _ignorepkgs:
candidate = pyalpm.sync_newversion(pkg, self.handle.get_syncdbs())
if candidate:
updates += 1
else:
sync_pkg = None
for db in self.handle.get_syncdbs():
sync_pkg = db.get_pkg(pkg.name)
if sync_pkg:
break
if not sync_pkg:
aur_pkg = aur.infos(pkg.name)
if aur_pkg:
comp = pyalpm.vercmp(aur_pkg.version, pkg.version)
if comp == 1:
updates += 1
self.EmitAvailableUpdates(updates)
@dbus.service.method('org.manjaro.pamac', 'b', 's', async_callbacks=('success', 'nosuccess'))
@ -602,15 +617,21 @@ class PamacDBusService(dbus.service.Object):
@dbus.service.method('org.manjaro.pamac', '', 'a(ss)')
def To_Remove(self):
liste = []
for pkg in self.t.to_remove:
liste.append((pkg.name, pkg.version))
try:
for pkg in self.t.to_remove:
liste.append((pkg.name, pkg.version))
except:
pass
return liste
@dbus.service.method('org.manjaro.pamac', '', 'a(ssi)')
def To_Add(self):
liste = []
for pkg in self.t.to_add:
liste.append((pkg.name, pkg.version, pkg.download_size))
try:
for pkg in self.t.to_add:
liste.append((pkg.name, pkg.version, pkg.download_size))
except:
pass
return liste
@dbus.service.method('org.manjaro.pamac', '', 's', async_callbacks=('success', 'nosuccess'))

View File

@ -9,7 +9,7 @@ import pyalpm
import dbus
from time import strftime, localtime
from pamac import config, common, transaction
from pamac import config, common, transaction, aur
# i18n
import gettext
@ -23,25 +23,30 @@ interface = transaction.interface
interface.add_from_file('/usr/share/pamac/gui/manager.ui')
ManagerWindow = interface.get_object("ManagerWindow")
details_list = interface.get_object('details_list')
deps_list = interface.get_object('deps_list')
details_list = interface.get_object('details_list')
files_textview = interface.get_object('files_textview')
deps_scrolledwindow = interface.get_object('deps_scrolledwindow')
files_scrolledwindow = interface.get_object('files_scrolledwindow')
details_scrolledwindow = interface.get_object('details_scrolledwindow')
name_label = interface.get_object('name_label')
desc_label = interface.get_object('desc_label')
link_label = interface.get_object('link_label')
licenses_label = interface.get_object('licenses_label')
search_entry = interface.get_object('search_entry')
search_aur_button = interface.get_object('search_aur_button')
search_list = interface.get_object('search_list')
search_selection = interface.get_object('search_treeview_selection')
packages_list_treeview = interface.get_object('packages_list_treeview')
state_column = interface.get_object('state_column')
name_column = interface.get_object('name_column')
version_column = interface.get_object('version_column')
repo_column = interface.get_object('repo_column')
size_column = interface.get_object('size_column')
state_rendererpixbuf = interface.get_object('state_rendererpixbuf')
name_renderertext = interface.get_object('name_renderertext')
version_renderertext = interface.get_object('version_renderertext')
repo_renderertext = interface.get_object('repo_renderertext')
size_renderertext = interface.get_object('size_renderertext')
list_selection = interface.get_object('list_treeview_selection')
groups_list = interface.get_object('groups_list')
@ -84,6 +89,8 @@ def state_column_display_func(column, cell, treemodel, treeiter, data):
pixbuf = installed_icon
elif treemodel[treeiter][0].name in transaction.to_add:
pixbuf = to_install_icon
elif treemodel[treeiter][0] in transaction.to_build:
pixbuf = to_install_icon
else:
pixbuf = uninstalled_icon
cell.set_property("pixbuf", pixbuf)
@ -97,7 +104,7 @@ def state_column_sort_func(treemodel, treeiter1, treeiter2, data):
num2 = 1
else:
num2 = 0
return num2 - num1
return num1 - num2
def name_column_display_func(column, cell, treemodel, treeiter, data):
if treemodel[treeiter][0] == _('No package found'):
@ -124,15 +131,44 @@ def version_column_display_func(column, cell, treemodel, treeiter, data):
def version_column_sort_func(treemodel, treeiter1, treeiter2, data):
return pyalpm.vercmp(treemodel[treeiter1][0].version, treemodel[treeiter2][0].version)
def size_column_display_func(column, cell, treemodel, treeiter, data):
def repo_column_display_func(column, cell, treemodel, treeiter, data):
if treemodel[treeiter][0] == _('No package found'):
cell.set_property("text", '')
else:
cell.set_property("text", treemodel[treeiter][0].db.name)
def repo_column_sort_func(treemodel, treeiter1, treeiter2, data):
servers = list(config.pacman_conf.repos.keys())
servers.insert(0, 'local')
# display AUR at last
if treemodel[treeiter1][0].db.name == 'AUR':
num1 = 99
else:
num1 = servers.index(treemodel[treeiter1][0].db.name)
# display AUR at last
if treemodel[treeiter2][0].db.name == 'AUR':
num2 = 99
else:
num2 = servers.index(treemodel[treeiter2][0].db.name)
return num1 - num2
def size_column_display_func(column, cell, treemodel, treeiter, data):
if treemodel[treeiter][0] == _('No package found'):
cell.set_property("text", '')
elif treemodel[treeiter][0].isize:
cell.set_property("text", common.format_size(treemodel[treeiter][0].isize))
else:
cell.set_property("text", '')
def size_column_sort_func(treemodel, treeiter1, treeiter2, data):
num1 = treemodel[treeiter1][0].isize
num2 = treemodel[treeiter2][0].isize
if treemodel[treeiter1][0].isize:
num1 = treemodel[treeiter1][0].isize
else:
num1 = 0
if treemodel[treeiter2][0].isize:
num2 = treemodel[treeiter2][0].isize
else:
num2 = 0
return num1 - num2
def update_lists():
@ -215,28 +251,35 @@ def get_repo_list(repo):
repos_dict[repo].append([pkg])
return repos_dict[repo]
def search_pkgs(search_string):
def search_pkgs(data_tupel):
global search_dict
if search_string in search_dict.keys():
return search_dict[search_string]
search_string = data_tupel[0]
search_aur = data_tupel[1]
if (search_string, search_aur) in search_dict.keys():
return search_dict[(search_string, search_aur)]
else:
search_dict[search_string] = Gtk.ListStore(object)
search_dict[(search_string, search_aur)] = Gtk.ListStore(object)
names_list = []
for pkg in transaction.localdb.search(*search_string.split()):
if not pkg.name in names_list:
names_list.append(pkg.name)
search_dict[search_string].append([pkg])
search_dict[(search_string, search_aur)].append([pkg])
for db in transaction.syncdbs:
for pkg in db.search(*search_string.split()):
if not pkg.name in names_list:
names_list.append(pkg.name)
search_dict[search_string].append([pkg])
search_dict[(search_string, search_aur)].append([pkg])
if search_aur:
for pkg in aur.search(*search_string.split()):
if not pkg.name in names_list:
names_list.append(pkg.name)
search_dict[(search_string, search_aur)].append([pkg])
if not names_list:
search_dict[search_string].append([_('No package found')])
search_dict[(search_string, search_aur)].append([_('No package found')])
else:
if not search_string in [row[0] for row in search_list]:
search_list.append([search_string])
return search_dict[search_string]
return search_dict[(search_string, search_aur)]
def get_uninstalled_pkgs():
pkgs_list = []
@ -266,6 +309,7 @@ def refresh_packages_list(liststore):
state_column.set_sort_indicator(False)
name_column.set_sort_indicator(True)
version_column.set_sort_indicator(False)
repo_column.set_sort_indicator(False)
size_column.set_sort_indicator(False)
packages_list_treeview.thaw_child_notify()
ManagerWindow.get_window().set_cursor(None)
@ -356,14 +400,20 @@ def handle_error(error):
if response:
transaction.ErrorDialog.hide()
transaction.progress_buffer.delete(transaction.progress_buffer.get_start_iter(),transaction.progress_buffer.get_end_iter())
transaction.Release()
transaction.get_handle()
transaction.update_dbs()
transaction.to_add.clear()
transaction.to_remove.clear()
transaction.to_update.clear()
transaction.to_load.clear()
transaction.to_build.clear()
def handle_reply(reply):
if reply:
if transaction.to_build:
transaction.build_next()
elif reply:
transaction.Release()
transaction.ProgressCloseButton.set_visible(True)
transaction.action_icon.set_from_icon_name('dialog-information', Gtk.IconSize.BUTTON)
transaction.progress_label.set_text(str(reply))
@ -374,7 +424,7 @@ def handle_reply(reply):
transaction.ProgressWindow.hide()
while Gtk.events_pending():
Gtk.main_iteration()
error = transaction.sysupgrade(True)
error = transaction.sysupgrade()
ManagerWindow.get_window().set_cursor(None)
if error:
handle_error(error)
@ -383,9 +433,12 @@ def handle_reply(reply):
transaction.update_dbs()
transaction.to_add.clear()
transaction.to_remove.clear()
transaction.to_update.clear()
transaction.to_load.clear()
transaction.to_build.clear()
global search_dict
global groups_dict
global states_dict
global states_dict
global repos_dict
search_dict = {}
groups_dict = {}
@ -411,6 +464,9 @@ def on_TransCancelButton_clicked(*args):
while Gtk.events_pending():
Gtk.main_iteration()
transaction.Release()
transaction.to_update.clear()
# do it because deps are also added in to_build when check_to_build
transaction.to_build.clear()
if current_filter[0]:
refresh_packages_list(current_filter[0](current_filter[1]))
@ -420,12 +476,25 @@ def on_ProgressCloseButton_clicked(*args):
Gtk.main_iteration()
transaction.progress_buffer.delete(transaction.progress_buffer.get_start_iter(),transaction.progress_buffer.get_end_iter())
ManagerWindow.get_window().set_cursor(Gdk.Cursor(Gdk.CursorType.WATCH))
error = transaction.sysupgrade(True)
while Gtk.events_pending():
Gtk.main_iteration()
error = transaction.sysupgrade()
ManagerWindow.get_window().set_cursor(None)
if error:
handle_error(error)
def on_ProgressCancelButton_clicked(*args):
ManagerWindow.get_window().set_cursor(Gdk.Cursor(Gdk.CursorType.WATCH))
while Gtk.events_pending():
Gtk.main_iteration()
transaction.progress_buffer.delete(transaction.progress_buffer.get_start_iter(),transaction.progress_buffer.get_end_iter())
transaction.cancel_download = True
if transaction.build_proc:
if transaction.build_proc.poll() is None:
transaction.build_proc.kill()
transaction.build_proc.wait()
# do it because deps are also added in to_build when check_to_build
transaction.to_build.clear()
transaction.Interrupt()
ManagerWindow.get_window().set_cursor(None)
transaction.ProgressWindow.hide()
@ -440,8 +509,8 @@ def on_search_entry_activate(widget):
ManagerWindow.get_window().set_cursor(Gdk.Cursor(Gdk.CursorType.WATCH))
while Gtk.events_pending():
Gtk.main_iteration()
current_filter = (search_pkgs, search_entry.get_text())
refresh_packages_list(search_pkgs(search_entry.get_text()))
current_filter = (search_pkgs, (search_entry.get_text(), search_aur_button.get_active()))
refresh_packages_list(search_pkgs((search_entry.get_text(), search_aur_button.get_active())))
def mark_to_install(widget, pkg):
transaction.to_add.add(pkg.name)
@ -452,12 +521,12 @@ def mark_to_reinstall(widget, pkg):
def mark_to_remove(widget, pkg):
transaction.to_remove.add(pkg.name)
def mark_to_unselect(widget, pkg):
def mark_to_deselect(widget, pkg):
transaction.to_remove.discard(pkg.name)
transaction.to_add.discard(pkg.name)
def select_optdeps(widget, pkg, optdeps):
transaction.choose_label.set_markup(_('<b>{pkgname} has {number} uninstalled optional deps.\nPlease choose the one(s) you want to install:</b>').format(pkgname = pkg.name, number = str(len(optdeps))))
transaction.choose_label.set_markup('<b>{}</b>'.format(_('{pkgname} has {number} uninstalled optional deps.\nPlease choose those you would like to install:').format(pkgname = pkg.name, number = str(len(optdeps)))))
transaction.choose_list.clear()
for long_string in optdeps:
transaction.choose_list.append([False, long_string])
@ -480,10 +549,10 @@ def on_list_treeview_button_press_event(treeview, event):
if liststore[treeiter][0] != _('No package found') and not liststore[treeiter][0].name in config.holdpkg:
right_click_menu = Gtk.Menu()
if liststore[treeiter][0].name in transaction.to_add | transaction.to_remove:
item = Gtk.ImageMenuItem(_('Unselect'))
item = Gtk.ImageMenuItem(_('Deselect'))
item.set_image(Gtk.Image.new_from_stock('gtk-undo', Gtk.IconSize.MENU))
item.set_always_show_image(True)
item.connect('activate', mark_to_unselect, liststore[treeiter][0])
item.connect('activate', mark_to_deselect, liststore[treeiter][0])
right_click_menu.append(item)
elif liststore[treeiter][0].db.name == 'local':
item = Gtk.ImageMenuItem(_('Remove'))
@ -545,10 +614,18 @@ def on_list_treeview_selection_changed(treeview):
set_deps_list(liststore[treeiter][0], "local")
set_details_list(liststore[treeiter][0], "local")
set_files_list(liststore[treeiter][0])
deps_scrolledwindow.set_visible(True)
details_scrolledwindow.set_visible(True)
files_scrolledwindow.set_visible(True)
elif liststore[treeiter][0].db.name == 'AUR':
deps_scrolledwindow.set_visible(False)
details_scrolledwindow.set_visible(False)
files_scrolledwindow.set_visible(False)
else:
set_deps_list(liststore[treeiter][0], "sync")
set_details_list(liststore[treeiter][0], "sync")
deps_scrolledwindow.set_visible(True)
details_scrolledwindow.set_visible(True)
files_scrolledwindow.set_visible(False)
def on_search_treeview_selection_changed(widget):
@ -560,8 +637,8 @@ def on_search_treeview_selection_changed(widget):
ManagerWindow.get_window().set_cursor(Gdk.Cursor(Gdk.CursorType.WATCH))
while Gtk.events_pending():
Gtk.main_iteration()
current_filter = (search_pkgs, search_list[line][0])
refresh_packages_list(search_pkgs(search_list[line][0]))
current_filter = (search_pkgs, (search_list[line][0], search_aur_button.get_active()))
refresh_packages_list(search_pkgs((search_list[line][0], search_aur_button.get_active())))
def on_groups_treeview_selection_changed(widget):
global current_filter
@ -602,19 +679,19 @@ def on_repos_treeview_selection_changed(widget):
def on_list_treeview_row_activated(treeview, treeiter, column):
liststore = treeview.get_model()
if not liststore[treeiter][0] == _('No package found'):
if not liststore[treeiter][0].name in config.holdpkg:
if liststore[treeiter][0].db.name == 'local':
if liststore[treeiter][0].name in transaction.to_add:
transaction.to_add.discard(liststore[treeiter][0].name)
elif liststore[treeiter][0].name in transaction.to_remove:
transaction.to_remove.discard(liststore[treeiter][0].name)
else:
transaction.to_remove.add(liststore[treeiter][0].name)
else:
if liststore[treeiter][0].name in transaction.to_add:
transaction.to_add.discard(liststore[treeiter][0].name)
else:
transaction.to_add.add(liststore[treeiter][0].name)
if liststore[treeiter][0].name in transaction.to_add:
transaction.to_add.discard(liststore[treeiter][0].name)
elif liststore[treeiter][0] in transaction.to_build:
transaction.to_build.remove(liststore[treeiter][0])
elif liststore[treeiter][0].name in transaction.to_remove:
transaction.to_remove.discard(liststore[treeiter][0].name)
elif liststore[treeiter][0].db.name == 'local':
if not liststore[treeiter][0].name in config.holdpkg:
transaction.to_remove.add(liststore[treeiter][0].name)
elif liststore[treeiter][0].db.name == 'AUR':
transaction.to_build.append(liststore[treeiter][0])
else:
transaction.to_add.add(liststore[treeiter][0].name)
while Gtk.events_pending():
Gtk.main_iteration()
@ -639,6 +716,8 @@ def on_notebook1_switch_page(notebook, page, page_num):
def on_manager_valid_button_clicked(*args):
ManagerWindow.get_window().set_cursor(Gdk.Cursor(Gdk.CursorType.WATCH))
while Gtk.events_pending():
Gtk.main_iteration()
error = transaction.run()
ManagerWindow.get_window().set_cursor(None)
if error:
@ -647,12 +726,15 @@ def on_manager_valid_button_clicked(*args):
def on_manager_cancel_button_clicked(*args):
transaction.to_add.clear()
transaction.to_remove.clear()
transaction.to_build.clear()
if current_filter[0]:
refresh_packages_list(current_filter[0](current_filter[1]))
def on_refresh_item_activate(*args):
ManagerWindow.get_window().set_cursor(Gdk.Cursor(Gdk.CursorType.WATCH))
transaction.refresh(False)
while Gtk.events_pending():
Gtk.main_iteration()
transaction.refresh()
def on_local_item_activate(*args):
@ -678,6 +760,8 @@ def on_package_open_button_clicked(*args):
for path in packages_paths:
transaction.to_load.add(path)
ManagerWindow.get_window().set_cursor(Gdk.Cursor(Gdk.CursorType.WATCH))
while Gtk.events_pending():
Gtk.main_iteration()
error = transaction.run()
ManagerWindow.get_window().set_cursor(None)
if error:
@ -696,6 +780,7 @@ def on_state_column_clicked(column):
state_column.set_sort_indicator(True)
name_column.set_sort_indicator(False)
version_column.set_sort_indicator(False)
repo_column.set_sort_indicator(False)
size_column.set_sort_indicator(False)
liststore.set_sort_func(0, state_column_sort_func, None)
@ -704,6 +789,7 @@ def on_name_column_clicked(column):
state_column.set_sort_indicator(False)
name_column.set_sort_indicator(True)
version_column.set_sort_indicator(False)
repo_column.set_sort_indicator(False)
size_column.set_sort_indicator(False)
liststore.set_sort_func(0, name_column_sort_func, None)
@ -712,14 +798,25 @@ def on_version_column_clicked(column):
state_column.set_sort_indicator(False)
name_column.set_sort_indicator(False)
version_column.set_sort_indicator(True)
repo_column.set_sort_indicator(False)
size_column.set_sort_indicator(False)
liststore.set_sort_func(0, version_column_sort_func, None)
def on_repo_column_clicked(column):
liststore = packages_list_treeview.get_model()
state_column.set_sort_indicator(False)
name_column.set_sort_indicator(False)
version_column.set_sort_indicator(False)
repo_column.set_sort_indicator(True)
size_column.set_sort_indicator(False)
liststore.set_sort_func(0, repo_column_sort_func, None)
def on_size_column_clicked(column):
liststore = packages_list_treeview.get_model()
state_column.set_sort_indicator(False)
name_column.set_sort_indicator(False)
version_column.set_sort_indicator(False)
repo_column.set_sort_indicator(False)
size_column.set_sort_indicator(True)
liststore.set_sort_func(0, size_column_sort_func, None)
@ -752,6 +849,7 @@ signals = {'on_ManagerWindow_delete_event' : on_ManagerWindow_delete_event,
'on_state_column_clicked' : on_state_column_clicked,
'on_name_column_clicked' : on_name_column_clicked,
'on_version_column_clicked' : on_version_column_clicked,
'on_repo_column_clicked' : on_repo_column_clicked,
'on_size_column_clicked' : on_size_column_clicked}
def config_dbus_signals():
@ -773,13 +871,18 @@ else:
state_column.set_cell_data_func(state_rendererpixbuf, state_column_display_func)
name_column.set_cell_data_func(name_renderertext, name_column_display_func)
version_column.set_cell_data_func(version_renderertext, version_column_display_func)
repo_column.set_cell_data_func(repo_renderertext, repo_column_display_func)
size_column.set_cell_data_func(size_renderertext, size_column_display_func)
transaction.get_handle()
transaction.update_dbs()
# now localdb is defined, populate make_depends
for name in transaction.base_devel:
if not pyalpm.find_satisfier(transaction.localdb.pkgcache, name):
transaction.make_depends.add(name)
update_lists()
ManagerWindow.show_all()
ManagerWindow.get_window().set_cursor(Gdk.Cursor(Gdk.CursorType.WATCH))
transaction.refresh(False)
transaction.refresh()
while Gtk.events_pending():
Gtk.main_iteration()
Gtk.main()

View File

@ -5,7 +5,7 @@ from gi.repository import Gtk, Gdk
import pyalpm
import dbus
from pamac import config, common, transaction
from pamac import config, common, transaction, aur
# i18n
import gettext
@ -24,33 +24,43 @@ update_top_label = interface.get_object('update_top_label')
update_bottom_label = interface.get_object('update_bottom_label')
UpdaterApplyButton = interface.get_object('UpdaterApplyButton')
update_top_label.set_markup(_('<big><b>Your system is up-to-date</b></big>'))
update_top_label.set_markup('<big><b>{}</b></big>'.format(_('Your system is up-to-date')))
update_bottom_label.set_markup('')
UpdaterApplyButton.set_sensitive(False)
def have_updates():
while Gtk.events_pending():
Gtk.main_iteration()
UpdaterWindow.get_window().set_cursor(Gdk.Cursor(Gdk.CursorType.WATCH))
while Gtk.events_pending():
Gtk.main_iteration()
do_syncfirst, updates = transaction.get_updates()
update_listore.clear()
update_top_label.set_justify(Gtk.Justification.CENTER)
if not updates:
update_bottom_label.set_markup('')
update_top_label.set_markup(_('<big><b>Your system is up-to-date</b></big>'))
update_top_label.set_markup('<big><b>{}</b></big>'.format(_('Your system is up-to-date')))
UpdaterApplyButton.set_sensitive(False)
else:
UpdaterApplyButton.set_sensitive(True)
dsize = 0
for pkg in updates:
pkgname = pkg.name+' '+pkg.version
update_listore.append([pkgname, common.format_size(pkg.size)])
if pkg.size:
size_str = common.format_size(pkg.size)
else:
size_str = ''
update_listore.append([pkgname, size_str])
dsize += pkg.download_size
if dsize == 0:
update_bottom_label.set_markup('')
else:
update_bottom_label.set_markup(_('<b>Total download size: </b>')+common.format_size(dsize))
update_bottom_label.set_markup('<b>{} {}</b>'.format(_('Total download size:'), common.format_size(dsize)))
if len(updates) == 1:
update_top_label.set_markup(_('<big><b>1 available update</b></big>'))
update_top_label.set_markup('<big><b>{}</b></big>'.format(_('1 available update')))
else:
update_top_label.set_markup(_('<big><b>{number} available updates</b></big>').format(number = len(updates)))
update_top_label.set_markup('<big><b>{}</b></big>'.format('{number} available updates'.format(number = len(updates))))
UpdaterWindow.get_window().set_cursor(None)
def handle_error(error):
UpdaterWindow.get_window().set_cursor(None)
@ -68,7 +78,10 @@ def handle_error(error):
transaction.update_dbs()
def handle_reply(reply):
if reply:
if transaction.to_build:
transaction.build_next()
elif reply:
transaction.Release()
transaction.ProgressCloseButton.set_visible(True)
transaction.action_icon.set_from_icon_name('dialog-information', Gtk.IconSize.BUTTON)
transaction.progress_label.set_text(str(reply))
@ -105,6 +118,9 @@ def on_TransCancelButton_clicked(*args):
while Gtk.events_pending():
Gtk.main_iteration()
transaction.Release()
transaction.to_update.clear()
# do it because deps are also added in to_build when check_to_build
transaction.to_build.clear()
def on_ProgressCloseButton_clicked(*args):
UpdaterWindow.get_window().set_cursor(None)
@ -115,6 +131,8 @@ def on_ProgressCloseButton_clicked(*args):
have_updates()
def on_ProgressCancelButton_clicked(*args):
# do it because deps are also added in to_build when check_to_build
transaction.to_build.clear()
transaction.Interrupt()
UpdaterWindow.get_window().set_cursor(None)
transaction.ProgressWindow.hide()
@ -122,16 +140,20 @@ def on_ProgressCancelButton_clicked(*args):
Gtk.main_iteration()
def on_Updater_ApplyButton_clicked(*args):
while Gtk.events_pending():
Gtk.main_iteration()
UpdaterWindow.get_window().set_cursor(Gdk.Cursor(Gdk.CursorType.WATCH))
while Gtk.events_pending():
Gtk.main_iteration()
transaction.sysupgrade(False)
transaction.sysupgrade(show_updates = False)
def on_Updater_RefreshButton_clicked(*args):
while Gtk.events_pending():
Gtk.main_iteration()
UpdaterWindow.get_window().set_cursor(Gdk.Cursor(Gdk.CursorType.WATCH))
transaction.refresh(False)
while Gtk.events_pending():
Gtk.main_iteration()
transaction.refresh()
def on_Updater_CloseButton_clicked(*args):
transaction.StopDaemon()
@ -170,5 +192,5 @@ else:
UpdaterWindow.get_window().set_cursor(Gdk.Cursor(Gdk.CursorType.WATCH))
while Gtk.events_pending():
Gtk.main_iteration()
transaction.refresh(False)
transaction.refresh()
Gtk.main()

201
pamac.pot
View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: pamac 0.9\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-10-18 20:35+0200\n"
"POT-Creation-Date: 2013-03-30 15:09+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -16,6 +16,10 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
#: data/polkit/org.manjaro.pamac.policy:10
msgid "Authentication is required"
msgstr ""
#: pamac-daemon.py:114
msgid "Checking dependencies"
msgstr ""
@ -117,199 +121,195 @@ msgstr ""
msgid "Refreshing {repo}"
msgstr ""
#: pamac-daemon.py:313
#: pamac-daemon.py:313 pamac/transaction.py:465
#, python-brace-format
msgid "Downloading {pkgname}"
msgstr ""
#: pamac-daemon.py:480 pamac-install.py:81
#: pamac-daemon.py:493 pamac-install.py:81
#, python-brace-format
msgid "{pkgname} is not a valid path or package name"
msgstr ""
#: pamac-daemon.py:589
#: pamac-daemon.py:602
#, python-brace-format
msgid ""
"The transaction cannot be performed because it needs to remove {pkgname1} "
"which is a locked package"
msgstr ""
#: pamac-daemon.py:596 pamac/transaction.py:230
#: pamac-daemon.py:609 pamac/transaction.py:346
msgid "Nothing to do"
msgstr ""
#: pamac-daemon.py:654
#: pamac-daemon.py:673
msgid "Transaction successfully finished"
msgstr ""
#: pamac-daemon.py:658 pamac-daemon.py:666
#: pamac-daemon.py:677 pamac-daemon.py:685
msgid "Authentication failed"
msgstr ""
#: pamac-manager.py:74 pamac-manager.py:103 pamac-manager.py:104
#: pamac-manager.py:119 pamac-manager.py:128 pamac-manager.py:227
#: pamac-manager.py:472 pamac-manager.py:533 pamac-manager.py:595
#: pamac-manager.py:79 pamac-manager.py:110 pamac-manager.py:111
#: pamac-manager.py:126 pamac-manager.py:135 pamac-manager.py:156
#: pamac-manager.py:278 pamac-manager.py:549 pamac-manager.py:611
#: pamac-manager.py:681
msgid "No package found"
msgstr ""
#: pamac-manager.py:143 pamac-manager.py:195
#: pamac-manager.py:179 pamac-manager.py:239
msgid "local"
msgstr ""
#: pamac-manager.py:145 pamac-manager.py:178 pamac-manager.py:284
#: pamac-manager.py:181 pamac-manager.py:222 pamac-manager.py:336
msgid "Installed"
msgstr ""
#: pamac-manager.py:145 pamac-manager.py:181
#: pamac-manager.py:181 pamac-manager.py:225
msgid "Uninstalled"
msgstr ""
#: pamac-manager.py:145 pamac-manager.py:184
#: pamac-manager.py:181 pamac-manager.py:228
msgid "Orphans"
msgstr ""
#: pamac-manager.py:145 pamac-manager.py:164 pamac/transaction.py:353
#: pamac-manager.py:181 pamac-manager.py:200 pamac/transaction.py:637
msgid "To install"
msgstr ""
#: pamac-manager.py:145 pamac-manager.py:169 pamac/transaction.py:371
#: pamac-manager.py:181 pamac-manager.py:211 pamac/transaction.py:618
msgid "To remove"
msgstr ""
#: pamac-manager.py:274
#: pamac-manager.py:326
msgid "Licenses"
msgstr ""
#: pamac-manager.py:279
#: pamac-manager.py:331
msgid "Depends On"
msgstr ""
#: pamac-manager.py:287
#: pamac-manager.py:339
msgid "Optional Deps"
msgstr ""
#: pamac-manager.py:290
#: pamac-manager.py:342
msgid "Required By"
msgstr ""
#: pamac-manager.py:292
#: pamac-manager.py:344
msgid "Provides"
msgstr ""
#: pamac-manager.py:294
#: pamac-manager.py:346
msgid "Replaces"
msgstr ""
#: pamac-manager.py:296
#: pamac-manager.py:348
msgid "Conflicts With"
msgstr ""
#: pamac-manager.py:301
#: pamac-manager.py:353
msgid "Repository"
msgstr ""
#: pamac-manager.py:303 gui/manager.ui:340
#: pamac-manager.py:355 gui/manager.ui:357
msgid "Groups"
msgstr ""
#: pamac-manager.py:305
#: pamac-manager.py:357
msgid "Compressed Size"
msgstr ""
#: pamac-manager.py:306
#: pamac-manager.py:358
msgid "Download Size"
msgstr ""
#: pamac-manager.py:308
#: pamac-manager.py:360
msgid "Installed Size"
msgstr ""
#: pamac-manager.py:309
#: pamac-manager.py:361
msgid "Packager"
msgstr ""
#: pamac-manager.py:310
#: pamac-manager.py:362
msgid "Architecture"
msgstr ""
#: pamac-manager.py:313
#: pamac-manager.py:365
msgid "Install Date"
msgstr ""
#: pamac-manager.py:315
#: pamac-manager.py:367
msgid "Explicitly installed"
msgstr ""
#: pamac-manager.py:317
#: pamac-manager.py:369
msgid "Installed as a dependency for another package"
msgstr ""
#: pamac-manager.py:319
#: pamac-manager.py:371
msgid "Unknown"
msgstr ""
#: pamac-manager.py:320
#: pamac-manager.py:372
msgid "Install Reason"
msgstr ""
#: pamac-manager.py:325
#: pamac-manager.py:377
msgid "Signatures"
msgstr ""
#: pamac-manager.py:329
#: pamac-manager.py:381
msgid "Backup files"
msgstr ""
#: pamac-manager.py:452
#: pamac-manager.py:529
#, python-brace-format
msgid ""
"<b>{pkgname} has {number} uninstalled optional deps.\n"
"Please choose the one(s) you want to install:</b>"
"{pkgname} has {number} uninstalled optional deps.\n"
"Please choose those you would like to install:"
msgstr ""
#: pamac-manager.py:475
msgid "Unselect"
#: pamac-manager.py:552
msgid "Deselect"
msgstr ""
#: pamac-manager.py:481
#: pamac-manager.py:558
msgid "Remove"
msgstr ""
#: pamac-manager.py:487
#: pamac-manager.py:565
msgid "Reinstall"
msgstr ""
#: pamac-manager.py:500
#: pamac-manager.py:578
msgid "Install optional deps"
msgstr ""
#: pamac-manager.py:506
#: pamac-manager.py:584
msgid "Install"
msgstr ""
#: pamac-manager.py:519
#: pamac-manager.py:597
msgid "Install with optional deps"
msgstr ""
#: pamac-manager.py:754 pamac-updater.py:159 pamac-install.py:110
#: pamac-manager.py:861 pamac-updater.py:181 pamac-install.py:110
msgid "Pamac is already running"
msgstr ""
#: pamac-updater.py:27 pamac-updater.py:37
msgid "<big><b>Your system is up-to-date</b></big>"
#: pamac-updater.py:27 pamac-updater.py:42 pamac-tray.py:20
msgid "Your system is up-to-date"
msgstr ""
#: pamac-updater.py:49 pamac/transaction.py:389
msgid "<b>Total download size: </b>"
#: pamac-updater.py:58 pamac/transaction.py:661
msgid "Total download size:"
msgstr ""
#: pamac-updater.py:51
msgid "<big><b>1 available update</b></big>"
msgstr ""
#: pamac-updater.py:53
#, python-brace-format
msgid "<big><b>{number} available updates</b></big>"
#: pamac-updater.py:60 pamac-tray.py:18
msgid "1 available update"
msgstr ""
#: pamac-tray.py:17
@ -317,15 +317,7 @@ msgstr ""
msgid "{number} available updates"
msgstr ""
#: pamac-tray.py:18
msgid "1 available update"
msgstr ""
#: pamac-tray.py:20
msgid "Your system is up-to-date"
msgstr ""
#: pamac-tray.py:30 pamac-tray.py:85 pamac-tray.py:95 gui/updater.ui:24
#: pamac-tray.py:30 pamac-tray.py:87 pamac-tray.py:97 gui/updater.ui:24
msgid "Update Manager"
msgstr ""
@ -343,34 +335,53 @@ msgid ""
"Please update your system first"
msgstr ""
#: pamac/transaction.py:151
#: pamac/transaction.py:176
#, python-brace-format
msgid ""
"<b>{pkgname} is provided by {number} packages.\n"
"Please choose the one(s) you want to install:</b>"
"{pkgname} is provided by {number} packages.\n"
"Please choose those you would like to install:"
msgstr ""
#: pamac/transaction.py:199
#: pamac/transaction.py:224
msgid "Refreshing"
msgstr ""
#: pamac/transaction.py:271
#: pamac/transaction.py:297
#, python-brace-format
msgid "{pkgname} depends on {dependname} but it is not installable"
msgstr ""
#: pamac/transaction.py:301
#, python-brace-format
msgid "Failed to get {pkgname} archive from AUR"
msgstr ""
#: pamac/transaction.py:503
#, python-brace-format
msgid "Building {pkgname}"
msgstr ""
#: pamac/transaction.py:519
msgid "Preparing"
msgstr ""
#: pamac/transaction.py:351
msgid "<big><b>Transaction Summary</b></big>"
#: pamac/transaction.py:616
msgid "Transaction Summary"
msgstr ""
#: pamac/transaction.py:359
msgid "To reinstall"
msgstr ""
#: pamac/transaction.py:365
#: pamac/transaction.py:624
msgid "To downgrade"
msgstr ""
#: pamac/transaction.py:378
#: pamac/transaction.py:631
msgid "To build"
msgstr ""
#: pamac/transaction.py:644
msgid "To reinstall"
msgstr ""
#: pamac/transaction.py:652
msgid "To update"
msgstr ""
@ -400,43 +411,51 @@ msgstr ""
msgid "Install local packages"
msgstr ""
#: gui/manager.ui:294
#: gui/manager.ui:253
msgid "Search in AUR"
msgstr ""
#: gui/manager.ui:311
msgid "Search"
msgstr ""
#: gui/manager.ui:387 gui/manager.ui:479
#: gui/manager.ui:404 gui/manager.ui:496
msgid "State"
msgstr ""
#: gui/manager.ui:434
#: gui/manager.ui:451
msgid "Repos"
msgstr ""
#: gui/manager.ui:492
#: gui/manager.ui:509
msgid "Name"
msgstr ""
#: gui/manager.ui:505
#: gui/manager.ui:522
msgid "Version"
msgstr ""
#: gui/manager.ui:518
#: gui/manager.ui:535
msgid "Repo"
msgstr ""
#: gui/manager.ui:548
msgid "Size"
msgstr ""
#: gui/manager.ui:620
#: gui/manager.ui:650
msgid "Infos"
msgstr ""
#: gui/manager.ui:684
#: gui/manager.ui:714
msgid "Deps"
msgstr ""
#: gui/manager.ui:753
#: gui/manager.ui:783
msgid "Details"
msgstr ""
#: gui/manager.ui:782
#: gui/manager.ui:812
msgid "Files"
msgstr ""

161
pamac/aur.py Normal file
View File

@ -0,0 +1,161 @@
#! /usr/bin/python3
# -*- coding:utf-8 -*-
import os
import urllib
import Namcap
import requests
import tarfile
# i18n
import gettext
import locale
locale.bindtextdomain('pamac', '/usr/share/locale')
gettext.bindtextdomain('pamac', '/usr/share/locale')
gettext.textdomain('pamac')
_ = gettext.gettext
aur_url = 'http://aur.archlinux.org'
rpc_url = aur_url + '/rpc.php'
srcpkgdir = '/tmp/pamac'
class AURPkg():
def __init__(self, pkginfo):
self.db = FakeDB()
self.isize = None
self.size = None
self.download_size = 0
keys = pkginfo.keys()
if 'URL' in keys:
self.url = pkginfo['URL']
if 'URLPath' in keys:
self.tarpath = pkginfo['URLPath']
if 'name' in keys:
self.name = pkginfo['name']
else:
self.name = pkginfo['Name']
if 'version' in keys:
self.version = pkginfo['version']
else:
self.version = pkginfo['Version']
if 'desc' in keys:
self.desc = pkginfo['desc']
else:
self.desc = pkginfo['Description']
if 'licenses' in keys:
self.licenses = pkginfo['licenses']
elif 'License' in keys:
self.licenses = [pkginfo['License']]
else:
self.licenses = []
if 'source' in keys:
self.source = pkginfo['source']
else:
self.source = []
if 'orig_depends' in keys:
self.depends = pkginfo['orig_depends']
else:
self.depends = []
#~ if 'orig_optdepends' in keys:
#~ self.optdepends = pkginfo['orig_optdepends']
#~ else:
#~ self.optdepends = []
#~ if 'orig_provides' in keys:
#~ self.provides = pkginfo['orig_provides']
#~ else:
#~ self.provides = []
if 'orig_makedepends' in keys:
self.makedepends = pkginfo['orig_makedepends']
else:
self.makedepends = []
#~ if 'replaces' in keys:
#~ self.replaces = pkginfo['replaces']
#~ else:
#~ self.replaces = []
#~ if 'conflicts' in keys:
#~ self.conflicts = pkginfo['conflicts']
#~ else:
#~ self.conflicts = []
#~ if 'groups' in keys:
#~ self.groups = pkginfo['groups']
#~ else:
#~ self.groups = []
def __repr__(self):
return '{}-{}'.format(self.name, self.version)
class FakeDB():
def __init__(self):
self.name = 'AUR'
def get_pkgs(pkgbuild_path):
pkgbuild_info = Namcap.package.load_from_pkgbuild(pkgbuild_path)
pkgs = []
if pkgbuild_info.is_split:
for infos in pkgbuild_info.subpackages:
pkg = AURPkg(infos)
pkgs.append(pkg)
else:
pkg = AURPkg(pkgbuild_info)
pkgs.append(pkg)
return pkgs
def search(args):
spec = {'type':'search', 'arg':args}
try:
r = requests.get(rpc_url, params = spec)
r.raise_for_status()
except Exception as e:
print(e)
return []
else:
results_dict = r.json()
pkgs = []
for result in results_dict['results']:
pkgs.append(AURPkg(result))
return pkgs
def infos(pkgname):
spec = {'type':'info', 'arg':pkgname}
try:
r = requests.get(rpc_url, params = spec)
r.raise_for_status()
except Exception as e:
print(e)
return []
else:
results_dict = r.json()
result = results_dict['results']
if result:
pkg = AURPkg(result)
return pkg
else:
print('failed to get infos about {} from AUR'.format(pkgname))
return None
def get_extract_tarball(pkg):
try:
r = requests.get(aur_url + pkg.tarpath)
r.raise_for_status()
except Exception as e:
print(e)
return None
else:
if not os.path.exists(srcpkgdir):
os.makedirs(srcpkgdir)
tarpath = os.path.join(srcpkgdir, os.path.basename(pkg.tarpath))
try:
with open(tarpath, 'wb') as f:
f.write(r.content)
except Exception as e:
print(e)
return None
else:
try:
tar = tarfile.open(tarpath)
tar.extractall(path = srcpkgdir)
except Exception as e:
print(e)
return None
else:
return os.path.join(srcpkgdir, pkg.name)

View File

@ -2,18 +2,33 @@
# -*- coding:utf-8 -*-
import pyalpm
from gi.repository import Gtk, GObject
import subprocess
import os
import fnmatch
#import requests
#from ftplib import FTP
#from urllib.parse import urlparse
import dbus
from gi.repository import Gtk
from dbus.mainloop.glib import DBusGMainLoop
from pamac import config, common
from pamac import config, common, aur
to_remove = set()
to_add = set()
to_update = set()
to_load = set()
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()
handle = None
syncdbs =None
syncdbs = None
localdb = None
# i18n
@ -46,8 +61,8 @@ progress_label = interface.get_object('progresslabel2')
action_icon = interface.get_object('action_icon')
ProgressCancelButton = interface.get_object('ProgressCancelButton')
ProgressCloseButton = interface.get_object('ProgressCloseButton')
progress_textview = interface.get_object('progress_textview')
progress_expander = interface.get_object('progress_expander')
progress_textview = interface.get_object('progress_textview')
progress_buffer = progress_textview.get_buffer()
@ -95,6 +110,16 @@ def config_dbus_signals():
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 write_to_buffer(fd, condition):
if condition == GObject.IO_IN: # if there's something interesting to read
line = fd.readline().decode(encoding='UTF-8')
print(line.rstrip('\n'))
progress_buffer.insert_at_cursor(line)
progress_bar.pulse()
return True # FUNDAMENTAL, otherwise the callback isn't recalled
else:
return False # Raised an error: exit
def action_handler(action):
progress_label.set_text(action)
@ -148,7 +173,7 @@ def log_warning(msg):
def choose_provides(data):
virtual_dep = str(data[1])
providers = data[0]
choose_label.set_markup(_('<b>{pkgname} is provided by {number} packages.\nPlease choose the one(s) you want to install:</b>').format(pkgname = virtual_dep, number = str(len(providers))))
choose_label.set_markup('<b>{}</b>'.format(_('{pkgname} is provided by {number} packages.\nPlease choose those you would like to install:').format(pkgname = virtual_dep, number = str(len(providers)))))
choose_list.clear()
for name in providers:
choose_list.append([False, str(name)])
@ -195,11 +220,11 @@ def get_syncpkg(name):
if pkg:
return pkg
def refresh(force_update):
progress_label.set_text(_('Refreshing')+'...')
action_icon.set_from_file('/usr/share/pamac/icons/24x24/status/refresh-cache.png')
progress_bar.set_text('')
progress_bar.set_fraction(0)
def refresh(force_update = False):
action_handler(_('Refreshing')+'...')
icon_handler('/usr/share/pamac/icons/24x24/status/refresh-cache.png')
target_handler('')
percent_handler(0)
ProgressCancelButton.set_visible(True)
ProgressCloseButton.set_visible(False)
while Gtk.events_pending():
@ -209,30 +234,121 @@ def refresh(force_update):
def init_transaction(**options):
return Init(dbus.Dictionary(options, signature='sb'))
def check_to_build():
global to_build
global to_add
global make_depends
global build_depends
already_checked = set()
build_order = []
i = 0
error = ''
while i < len(to_build):
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:
print('checking', new_pkg.name)
# check if some makedeps must be installed
for makedepend in new_pkg.makedepends:
if not makedepend in already_checked:
if not pyalpm.find_satisfier(localdb.pkgcache, makedepend):
print('found make dep:',makedepend)
for db in syncdbs:
provider = pyalpm.find_satisfier(db.pkgcache, makedepend)
if provider:
break
if provider:
make_depends.add(provider.name)
already_checked.add(makedepend)
# check if some deps must be installed or built
for depend in new_pkg.depends:
if not depend in already_checked:
if not pyalpm.find_satisfier(localdb.pkgcache, depend):
print('found dep:',depend)
for db in syncdbs:
provider = pyalpm.find_satisfier(db.pkgcache, depend)
if provider:
break
if provider:
# current dep need to be installed
build_depends.add(provider.name)
already_checked.add(depend)
else:
# current dep need to be built
if not depend in build_order:
# get infos about it
dep_pkg = aur.infos(depend)
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)
build_order.insert(index, dep_pkg.name)
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
# add pkgname in make_depends and build_depends in to_add
for name in make_depends:
to_add.add(name)
for name in build_depends:
to_add.add(name)
# reorder to_build following build_order
to_build.sort(key = lambda pkg: build_order.index(pkg.name))
print('order:', build_order)
print('to build:',to_build)
print('makedeps:',make_depends)
print('builddeps:',build_depends)
return error
def run():
if to_add | to_remove | to_load:
if to_add or to_remove or to_load or to_build:
error = ''
trans_flags = {'cascade' : True}
error += init_transaction(**trans_flags)
if to_build:
# check if packages in to_build have deps or makedeps which need to be install first
error += check_to_build()
if not error:
for name in to_add:
error += Add(name)
for name in to_remove:
error += Remove(name)
for path in to_load:
error += Load(path)
if to_add or to_remove or to_load:
trans_flags = {'cascade' : True}
error += init_transaction(**trans_flags)
if not error:
for name in to_add:
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)
if not error:
error += prepare(False, **trans_flags)
set_transaction_sum()
ConfDialog.show_all()
while Gtk.events_pending():
Gtk.main_iteration()
if error:
Release()
return(error)
else:
return (_('Nothing to do'))
def prepare(show_updates, **trans_flags):
global to_add
def prepare(**trans_flags):
error = ''
ret = Prepare()
# ret type is a(ass) so [([''], '')]
if ret[0][0]: # providers are emitted
Release()
for item in ret:
@ -251,36 +367,173 @@ def prepare(show_updates, **trans_flags):
error = str(ret[0][1])
elif ret[0][1]: # an error is emitted
error = str(ret[0][1])
if not error:
set_transaction_sum(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()
return(error)
def finalize():
global progress_buffer
progress_label.set_text(_('Preparing')+'...')
action_icon.set_from_file('/usr/share/pamac/icons/24x24/status/package-setup.png')
progress_bar.set_text('')
progress_bar.set_fraction(0)
progress_buffer.delete(progress_buffer.get_start_iter(), progress_buffer.get_end_iter())
def check_finished_build(data):
global to_build
global build_proc
path = data[0]
pkg = data[1]
if build_proc.poll() is None:
return True
else:
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)):
if fnmatch.fnmatch(item, '{}-{}-*.pkg.tar*'.format(new_pkg.name, new_pkg.version)):
built.append(os.path.join(path, item))
break
if built:
print('successfully built:', built)
build_proc = None
to_build_pkgs = to_build.copy()
for to_build_pkg in to_build_pkgs:
if pkg.name == to_build_pkg.name:
to_build.remove(pkg)
# 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()
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
icon_handler('/usr/share/pamac/icons/24x24/status/package-download.png')
ProgressCancelButton.set_visible(True)
ProgressCloseButton.set_visible(False)
try:
Commit()
except dbus.exceptions.DBusException as e:
Release()
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]
path = os.path.join(aur.srcpkgdir, pkg.name)
new_pkgs = aur.get_pkgs(path + '/PKGBUILD')
# sources are identicals for splitted packages
# (not complete) download(new_pkgs[0].source, path)
icon_handler('/usr/share/pamac/icons/24x24/status/package-setup.png')
target_handler('')
action = _('Building {pkgname}').format(pkgname = pkg.name)+'...'
action_handler(action)
action_long_handler(action+'\n')
ProgressCancelButton.set_visible(True)
ProgressCloseButton.set_visible(False)
progress_expander.set_expanded(True)
ProgressWindow.show()
while Gtk.events_pending():
Gtk.main_iteration()
build_proc = subprocess.Popen(["makepkg", "-cf"], cwd = path, stdout = subprocess.PIPE, stderr=subprocess.STDOUT)
GObject.io_add_watch(build_proc.stdout, GObject.IO_IN, write_to_buffer)
GObject.timeout_add(500, check_finished_build, (path, pkg))
def finalize():
if To_Add() or To_Remove():
global progress_buffer
action_handler(_('Preparing')+'...')
icon_handler('/usr/share/pamac/icons/24x24/status/package-setup.png')
target_handler('')
percent_handler(0)
progress_buffer.delete(progress_buffer.get_start_iter(), progress_buffer.get_end_iter())
ProgressCancelButton.set_visible(True)
ProgressCloseButton.set_visible(False)
try:
Commit()
except dbus.exceptions.DBusException as e:
Release()
while Gtk.events_pending():
Gtk.main_iteration()
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()
def get_updates():
do_syncfirst = False
@ -309,16 +562,25 @@ def get_updates():
return do_syncfirst, list_first
result = []
for pkg in localdb.pkgcache:
candidate = pyalpm.sync_newversion(pkg, syncdbs)
if candidate:
if not candidate.name in _ignorepkgs:
if not pkg.name in _ignorepkgs:
candidate = pyalpm.sync_newversion(pkg, syncdbs)
if candidate:
result.append(candidate)
else:
if not get_syncpkg(pkg.name):
aur_pkg = aur.infos(pkg.name)
if aur_pkg:
comp = pyalpm.vercmp(aur_pkg.version, pkg.version)
if comp == 1:
result.append(aur_pkg)
return do_syncfirst, result
def get_transaction_sum():
transaction_dict = {'to_remove': [], 'to_install': [], 'to_update': [], 'to_reinstall': [], 'to_downgrade': []}
to_remove = sorted(To_Remove())
for name, version in to_remove:
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:
transaction_dict['to_remove'].append(name+' '+version)
others = sorted(To_Add())
for name, version, dsize in others:
@ -333,82 +595,123 @@ def get_transaction_sum():
transaction_dict['to_downgrade'].append((name+' '+version, dsize))
else:
transaction_dict['to_install'].append((name+' '+version, dsize))
#~ 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']])
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']])
return transaction_dict
def set_transaction_sum(show_updates):
def set_transaction_sum(show_updates = True):
dsize = 0
transaction_sum.clear()
transaction_dict = get_transaction_sum()
sum_top_label.set_markup(_('<big><b>Transaction Summary</b></big>'))
if transaction_dict['to_install']:
transaction_sum.append([_('To install')+':', transaction_dict['to_install'][0][0]])
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_install']):
transaction_sum.append([' ', transaction_dict['to_install'][i][0]])
i += 1
if transaction_dict['to_reinstall']:
transaction_sum.append([_('To reinstall')+':', transaction_dict['to_reinstall'][0][0]])
i = 1
while i < len(transaction_dict['to_reinstall']):
transaction_sum.append([' ', transaction_dict['to_reinstall'][i][0]])
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]])
i = 1
while i < len(transaction_dict['to_downgrade']):
transaction_sum.append([' ', transaction_dict['to_downgrade'][i][0]])
transaction_sum.append(['', transaction_dict['to_downgrade'][i][0]])
dsize += transaction_dict['to_downgrade'][i][1]
i += 1
if transaction_dict['to_remove']:
transaction_sum.append([_('To remove')+':', transaction_dict['to_remove'][0]])
if transaction_dict['to_build']:
transaction_sum.append([_('To build')+':', transaction_dict['to_build'][0]])
i = 1
while i < len(transaction_dict['to_remove']):
transaction_sum.append([' ', transaction_dict['to_remove'][i]])
while i < len(transaction_dict['to_build']):
transaction_sum.append(['', transaction_dict['to_build'][i]])
i += 1
if transaction_dict['to_install']:
transaction_sum.append([_('To install')+':', transaction_dict['to_install'][0][0]])
i = 1
while i < len(transaction_dict['to_install']):
transaction_sum.append(['', transaction_dict['to_install'][i][0]])
dsize += transaction_dict['to_install'][i][1]
i += 1
if transaction_dict['to_reinstall']:
transaction_sum.append([_('To reinstall')+':', transaction_dict['to_reinstall'][0][0]])
i = 1
while i < len(transaction_dict['to_reinstall']):
transaction_sum.append(['', transaction_dict['to_reinstall'][i][0]])
dsize += transaction_dict['to_reinstall'][i][1]
i += 1
if show_updates:
if transaction_dict['to_update']:
transaction_sum.append([_('To update')+':', transaction_dict['to_update'][0][0]])
i = 1
while i < len(transaction_dict['to_update']):
transaction_sum.append([' ', transaction_dict['to_update'][i][0]])
transaction_sum.append(['', transaction_dict['to_update'][i][0]])
dsize += transaction_dict['to_update'][i][1]
i += 1
dsize = 0
for nameversion, size in transaction_dict['to_install'] + transaction_dict['to_update'] + transaction_dict['to_reinstall'] + transaction_dict['to_downgrade']:
dsize += size
if dsize == 0:
sum_bottom_label.set_markup('')
else:
sum_bottom_label.set_markup(_('<b>Total download size: </b>')+common.format_size(dsize))
sum_bottom_label.set_markup('<b>{} {}</b>'.format(_('Total download size:'), common.format_size(dsize)))
def sysupgrade(show_updates):
def sysupgrade(show_updates = True):
global to_update
global to_add
global to_remove
do_syncfirst, updates = get_updates()
if updates:
to_update = set([pkg.name for pkg in updates])
to_update.clear()
to_add.clear()
to_remove.clear()
for pkg in updates:
if pkg.db.name == 'AUR':
to_build.append(pkg)
else:
to_update.add(pkg.name)
error = ''
if do_syncfirst:
error += init_transaction()
if not error:
for name in to_update:
error += Add(name)
if not error:
error += prepare()
else:
error += init_transaction()
if not error:
error += Sysupgrade()
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:
error += init_transaction()
if not error:
if to_update:
error += Sysupgrade()
_error = ''
for name in to_add:
_error += Add(name)
if _error:
print(_error)
if not error:
error += prepare()
if not error:
error += prepare(show_updates)
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()
if error:
Release()
return error