Files
entropy/sulfur/src/repoman/__init__.py
2010-01-29 14:05:09 +01:00

3531 lines
132 KiB
Python

# -*- coding: utf-8 -*-
# Repository Manager Interface for Entropy
# Copyright: (C) 2007-2010 Fabio Erculiani < lxnay<AT>sabayonlinux<DOT>org >
#
# 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., 675 Mass Ave, Cambridge, MA 02139, USA.
import threading
import time, gtk, gobject, pty, sys
from entropy.i18n import _
from entropy.exceptions import *
from entropy.const import *
from entropy.misc import TimeScheduled, ParallelTask
from entropy.output import print_generic
import entropy.dump
from sulfur.core import UI
from sulfur.setup import const, cleanMarkupString, fakeoutfile, fakeinfile
from sulfur.dialogs import RmNoticeBoardMenu, okDialog, MenuSkel, PkgInfoMenu, \
SecurityAdvisoryMenu
class RemoteConnectionMenu(MenuSkel):
store_path = 'connection_manager'
def __init__( self, Entropy, verification_callback, window ):
self.Entropy = Entropy
# hostname, port, username, password, ssl will be passed as parameters
self.verification_callback = verification_callback
self.window = window
self.cm_ui = UI( const.GLADE_FILE, 'remoteConnManager', 'entropy' )
self.cm_ui.signal_autoconnect(self._getAllMethods())
self.cm_ui.remoteConnManager.set_transient_for(self.window)
self.cm_ui.remoteConnManager.add_events(gtk.gdk.BUTTON_PRESS_MASK)
self.connStore = gtk.ListStore( gobject.TYPE_PYOBJECT )
self.connView = self.cm_ui.connManagerConnView
self.connView.set_model(self.connStore)
self.button_pressed = False
self.loaded = False
self.parameters = None
self.connection_data = self.get_stored_connection_data()
self.setup_view()
if self.connection_data: self.set_connection_object(self.connection_data[0])
def on_connManagerAddConnButton_clicked(self, widget):
def fake_callback(s):
return s
def fake_callback_cb(s):
return True
input_params = [
('name', _("Connection name"), fake_callback, False),
('hostname', _("Hostname"), fake_callback, False),
('port', _("Port"), fake_callback, False),
('user', _("Username"), fake_callback, False),
('ssl', ('checkbox', _('SSL Connection'),), fake_callback_cb, False),
]
data = self.Entropy.input_box(
_('Choose what kind of test you would like to run'),
input_params,
cancel_button = True
)
if data == None: return
self.store_connection_data_item(data)
self.fill_connection_view()
self.store_connection_data()
def on_connManagerConnView_row_activated(self, treeview, path, column):
self.on_connManagerSetConnButton_clicked(treeview)
def set_connection_object(self, obj):
self.cm_ui.connManagerHostnameEntry.set_text(obj['hostname'])
try:
self.cm_ui.connManagerPortSpinButton.set_value(float(obj['port']))
except ValueError:
if obj['ssl']:
self.cm_ui.connManagerPortSpinButton.set_value(
float(etpConst['socket_service']['ssl_port']))
else:
self.cm_ui.connManagerPortSpinButton.set_value(
float(etpConst['socket_service']['port']))
self.cm_ui.connManagerUsernameEntry.set_text(obj['user'])
self.cm_ui.connManagerPasswordEntry.set_text('')
self.cm_ui.connManagerSSLCheckButton.set_active(obj['ssl'])
def on_connManagerSetConnButton_clicked(self, widget):
model, myiter = self.connView.get_selection().get_selected()
if not myiter: return
obj = model.get_value(myiter, 0)
self.set_connection_object(obj)
def on_connManagerRemoveConnButton_clicked(self, widget):
model, myiter = self.connView.get_selection().get_selected()
if not myiter: return
obj = model.get_value(myiter, 0)
self.remove_connection_data_item(obj)
self.fill_connection_view()
self.store_connection_data()
def get_stored_connection_data(self):
obj = entropy.dump.loadobj(self.store_path)
if not obj: return []
return obj
def remove_connection_data_item(self, item):
if item in self.connection_data:
self.connection_data.remove(item)
def store_connection_data_item(self, item):
self.connection_data.append(item)
def store_connection_data(self):
entropy.dump.dumpobj(self.store_path, self.connection_data)
def fill_connection_view(self):
self.connStore.clear()
for item in self.connection_data:
self.connStore.append( (item,) )
self.connView.queue_draw()
def setup_view(self):
self.create_text_column( self.connView, _( "Connection" ), 'name', size = 200, expand = True)
self.create_text_column( self.connView, _( "Hostname" ), 'hostname', size = 100)
self.create_text_column( self.connView, _( "Port" ), 'port', size = 50)
# SSL
cell = gtk.CellRendererPixbuf()
column = gtk.TreeViewColumn( _("SSL"), cell ) # Document Type
column.set_cell_data_func( cell, self.ssl_pixbuf )
column.set_sizing( gtk.TREE_VIEW_COLUMN_FIXED )
column.set_fixed_width( 50 )
column.set_sort_column_id( -1 )
self.connView.append_column( column )
self.fill_connection_view()
def ssl_pixbuf( self, column, cell, model, myiter ):
obj = model.get_value( myiter, 0 )
if obj:
if obj['ssl']:
cell.set_property( 'stock-id', 'gtk-apply' )
return
cell.set_property( 'stock-id', 'gtk-cancel' )
def get_data_text( self, column, cell, model, myiter, property ):
obj = model.get_value( myiter, 0 )
if obj: cell.set_property('markup', obj[property])
def create_text_column( self, view, hdr, property, size, sortcol = None, expand = False, set_height = 0, cell_data_func = None, sort_col_id = -1):
if cell_data_func == None: cell_data_func = self.get_data_text
cell = gtk.CellRendererText()
if set_height: cell.set_property('height', set_height)
column = gtk.TreeViewColumn( hdr, cell )
column.set_resizable( True )
column.set_cell_data_func( cell, cell_data_func, property )
column.set_sizing( gtk.TREE_VIEW_COLUMN_FIXED )
column.set_fixed_width( size )
column.set_expand(expand)
column.set_sort_column_id( sort_col_id )
view.append_column( column )
return column
def load( self ):
bold_items = [
self.cm_ui.connManagerTitleLabel,
]
for item in bold_items:
item.set_markup("<b>%s</b>" % ( item.get_text(),))
self.loaded = True
self.cm_ui.remoteConnManager.show_all()
def run(self):
if not self.loaded:
return None
tries = 3
while tries:
while not self.button_pressed:
time.sleep(0.05)
while gtk.events_pending():
gtk.main_iteration()
continue
if self.parameters:
valid, error_msg = self.verification_callback(
self.parameters['hostname'],
self.parameters['port'],
self.parameters['username'],
self.parameters['password'],
self.parameters['ssl']
)
if not valid:
okDialog(self.window, error_msg, title = _("Connection Error"))
self.button_pressed = False
tries -= 1
continue
break
self.destroy()
if not tries:
return None
return self.parameters
def on_remoteConnEventBox_key_release_event(self, widget, event):
if event.string == "\r":
self.cm_ui.connManagerConnectButton.clicked()
return True
return False # propagate
def on_connManagerConnectButton_clicked(self, widget):
self.parameters = {
'hostname': self.cm_ui.connManagerHostnameEntry.get_text(),
'port': self.cm_ui.connManagerPortSpinButton.get_value(),
'username': self.cm_ui.connManagerUsernameEntry.get_text(),
'password': self.cm_ui.connManagerPasswordEntry.get_text(),
'ssl': self.cm_ui.connManagerSSLCheckButton.get_active()
}
self.button_pressed = True
def on_remoteConnCloseButton_clicked(self, widget):
self.parameters = None
self.button_pressed = True
def destroy( self ):
self.cm_ui.remoteConnManager.hide()
self.cm_ui.remoteConnManager.destroy()
class RepositoryManagerMenu(MenuSkel):
class SocketLock:
""" Socket lock, this is used for stopping updaters too """
def __init__(self, repoman_intf):
self.__intf = repoman_intf
self.__lock = threading.Lock()
def __enter__(self):
self.__intf.pause_updaters(True)
return self.__lock.acquire()
def __exit__(self, exc_type, exc_value, traceback):
self.__intf.pause_updaters(False)
self.__lock.release()
def __init__(self, Entropy, window):
self.ui_locked = True
self.do_debug = False
if etpUi['debug']:
self.do_debug = True
self.BufferLock = RepositoryManagerMenu.SocketLock(self)
self.Entropy = Entropy
self.window = window
self.sm_ui = UI( const.GLADE_FILE, 'repositoryManager', 'entropy' )
self.sm_ui.signal_autoconnect(self._getAllMethods())
self.sm_ui.repositoryManager.set_transient_for(self.window)
self.DataStore = None
self.DataView = None
self.QueueLock = threading.Lock()
self.OutputLock = threading.Lock()
self.paused_queue_id = None
self.is_processing = None
self.is_writing_output = False
self.Output = None
self.output_pause = False
self.queue_pause = False
self.ssl_mode = True
self.repos_loaded = False
self.PinboardData = {}
self.Queue = {}
self.setup_queue_view()
self.setup_pinboard_view()
self.setup_console()
self.queue_timer = 5
self.output_timer = 3
self.pinboard_timer = 60
self.QueueUpdater = TimeScheduled(self.queue_timer,
self.update_queue_view)
self.OutputUpdater = TimeScheduled(self.output_timer,
self.update_output_view)
self.PinboardUpdater = TimeScheduled(self.pinboard_timer,
self.update_pinboard_view)
self.notebook_pages = {
'queue': 0,
'commands': 1,
'data': 2,
'output': 3
}
self.dict_queue_keys = ['queue', 'processing', 'processed', 'errored']
self.DataScroll = self.sm_ui.dataViewScrollWin
self.DataViewBox = self.sm_ui.repoManagerDataViewBox
self.DataViewButtons = {}
self.setup_data_view_buttons()
self.data_tree_selection_mode = None
self.DataViewVbox = self.sm_ui.dataViewVbox
from entropy.client.services.system.interfaces import Client as \
SystemManagerClientInterface
from entropy.client.services.system.commands import Repository as \
SystemManagerRepositoryClientCommands
from entropy.client.services.system.methods import Repository as \
SystemManagerRepositoryMethodsInterface
self.Service = SystemManagerClientInterface(
self.Entropy,
MethodsInterface = SystemManagerRepositoryMethodsInterface,
ClientCommandsInterface = SystemManagerRepositoryClientCommands
)
self.CommandsStore = None
self.setup_commands_view()
self.fill_commands_view(self.Service.get_available_client_commands())
self.ServiceStatus = True
self.connection_done = False
self.setup_available_repositories()
def __del__(self):
if hasattr(self, 'connection_done'):
if self.connection_done:
self.Service.kill_all_connections()
def pause_updaters(self, pause):
self.debug_print("pause_updaters", str(pause))
self.QueueUpdater.pause(pause)
self.OutputUpdater.pause(pause)
self.PinboardUpdater.pause(pause)
def ui_lock(self, action):
self.ui_locked = action
self.sm_ui.repositoryManager.set_sensitive(not action)
def set_notebook_page(self, page):
self.sm_ui.repoManagerNotebook.set_current_page(page)
def stdout_writer(self, txt):
self.console.feed_child(txt + '\n\r')
def setup_console(self):
self.pty = pty.openpty()
self.std_output = fakeoutfile(self.pty[1])
self.std_input = fakeinfile(self.pty[1])
# setup add repository window
self.console_menu_xml = gtk.glade.XML( const.GLADE_FILE, "terminalMenu", domain="entropy" )
self.console_menu = self.console_menu_xml.get_widget( "terminalMenu" )
self.console_menu_xml.signal_autoconnect(self)
from sulfur.widgets import SulfurConsole
self.console = SulfurConsole()
self.console.set_scrollback_lines(1024)
self.console.set_scroll_on_output(True)
# this is a workaround for buggy vte.Terminal when using
# file descriptors. This will make fakeoutfile to use
# our external writer instead of using os.write
self.std_output.external_writer = self.stdout_writer
self.console.set_pty(self.pty[0])
self.console.connect("button-press-event", self.on_console_click)
self.console.connect("commit", self.on_console_commit)
termScroll = gtk.VScrollbar(self.console.get_adjustment())
self.sm_ui.repoManagerVteBox.pack_start(self.console, True, True)
self.sm_ui.repoManagerTermScrollBox.pack_start(termScroll, False)
self.sm_ui.repoManagerTermHBox.show_all()
def debug_print(self, f, msg):
if self.do_debug:
print_generic("repoman debug:", repr(self), f, msg)
def clear_console(self):
self.std_input.text_read = ''
self.console.reset()
def clear_data_store_and_view(self):
self.debug_print("clear_data_store_and_view", "enter")
self.reset_data_view()
self.hide_all_data_view_buttons()
self.DataViewVbox.queue_draw()
while gtk.events_pending():
gtk.main_iteration()
def reset_data_view(self):
if self.DataView != None:
self.debug_print("reset_data_view", "removing old DataView")
self.DataScroll.remove(self.DataView)
self.DataScroll.queue_draw()
self.DataView.destroy()
self.DataView = None
self.debug_print("reset_data_view", "removal of old DataView done")
def on_repoManagerConsoleEvent_enter_notify_event(self, widget, event):
self.console.grab_focus()
def on_console_click(self, widget, event):
if event.button == 3:
self.console_menu.popup( None, None, None, event.button, event.time )
return True
def on_console_commit(self, widget, txt, txtlen):
if txt == "\r":
self.on_repoManagerStdinEntry_activate(None, False, self.std_input.text_read)
self.std_input.text_read = ''
elif txt == '\x7f':
self.std_input.text_read = self.std_input.text_read[:-1]
else:
self.std_input.text_read += txt
def on_terminal_clear_activate(self, widget):
self.clear_console()
def on_terminal_copy_activate(self, widget):
self.console.select_all()
self.console.copy_clipboard()
self.console.select_none()
def setup_data_view_buttons(self):
glsa_package_info_button = gtk.Button(label = _("Packages information"))
glsa_package_info_image = gtk.Image()
glsa_package_info_image.set_from_stock(gtk.STOCK_INFO, 4)
glsa_package_info_button.set_image(glsa_package_info_image)
glsa_adv_info_button = gtk.Button(label = _("Advisory information"))
glsa_adv_info_image = gtk.Image()
glsa_adv_info_image.set_from_stock(gtk.STOCK_EDIT, 4)
glsa_adv_info_button.set_image(glsa_adv_info_image)
#
mirror_updates_execute_button = gtk.Button(label = _("Execute"))
mirror_updates_execute_button_image = gtk.Image()
mirror_updates_execute_button_image.set_from_stock(gtk.STOCK_EXECUTE, 4)
mirror_updates_execute_button.set_image(mirror_updates_execute_button_image)
#
database_updates_package_info_button = gtk.Button(label = _("Packages information"))
database_updates_package_info_image = gtk.Image()
database_updates_package_info_image.set_from_stock(gtk.STOCK_INFO, 4)
database_updates_package_info_button.set_image(database_updates_package_info_image)
database_updates_change_repo_button = gtk.Button(label = _("Destination repository"))
database_updates_change_repo_image = gtk.Image()
database_updates_change_repo_image.set_from_stock(gtk.STOCK_CONVERT, 4)
database_updates_change_repo_button.set_image(database_updates_change_repo_image)
database_updates_execute_button = gtk.Button(label = _("Execute"))
database_updates_execute_button_image = gtk.Image()
database_updates_execute_button_image.set_from_stock(gtk.STOCK_EXECUTE, 4)
database_updates_execute_button.set_image(database_updates_execute_button_image)
#
available_packages_package_info_button = gtk.Button(label = _("Packages information"))
available_packages_package_info_image = gtk.Image()
available_packages_package_info_image.set_from_stock(gtk.STOCK_INFO, 4)
available_packages_package_info_button.set_image(available_packages_package_info_image)
available_packages_remove_package_button = gtk.Button(label = _("Remove packages"))
available_packages_remove_package_image = gtk.Image()
available_packages_remove_package_image.set_from_stock(gtk.STOCK_REMOVE, 4)
available_packages_remove_package_button.set_image(available_packages_remove_package_image)
available_packages_move_package_button = gtk.Button(label = _("Copy/move packages"))
available_packages_move_package_image = gtk.Image()
available_packages_move_package_image.set_from_stock(gtk.STOCK_COPY, 4)
available_packages_move_package_button.set_image(available_packages_move_package_image)
categories_updates_compile_button = gtk.Button(label = _("Compile selected"))
categories_updates_compile_image = gtk.Image()
categories_updates_compile_image.set_from_stock(gtk.STOCK_GOTO_BOTTOM, 4)
categories_updates_compile_button.set_image(categories_updates_compile_image)
categories_updates_add_use_button = gtk.Button(label = _("Add USE"))
categories_updates_add_use_image = gtk.Image()
categories_updates_add_use_image.set_from_stock(gtk.STOCK_ADD, 4)
categories_updates_add_use_button.set_image(categories_updates_add_use_image)
categories_updates_remove_use_button = gtk.Button(label = _("Remove USE"))
categories_updates_remove_use_image = gtk.Image()
categories_updates_remove_use_image.set_from_stock(gtk.STOCK_REMOVE, 4)
categories_updates_remove_use_button.set_image(categories_updates_remove_use_image)
#
notice_board_view_button = gtk.Button(label = _("View"))
notice_board_view_image = gtk.Image()
notice_board_view_image.set_from_stock(gtk.STOCK_ZOOM_IN, 4)
notice_board_view_button.set_image(notice_board_view_image)
notice_board_add_button = gtk.Button(label = _("Add"))
notice_board_add_image = gtk.Image()
notice_board_add_image.set_from_stock(gtk.STOCK_ADD, 4)
notice_board_add_button.set_image(notice_board_add_image)
notice_board_remove_button = gtk.Button(label = _("Remove"))
notice_board_remove_image = gtk.Image()
notice_board_remove_image.set_from_stock(gtk.STOCK_REMOVE, 4)
notice_board_remove_button.set_image(notice_board_remove_image)
notice_board_refresh_button = gtk.Button(label = _("Refresh"))
notice_board_refresh_image = gtk.Image()
notice_board_refresh_image.set_from_stock(gtk.STOCK_REFRESH, 4)
notice_board_refresh_button.set_image(notice_board_refresh_image)
self.DataViewButtons = {
'glsa': {
'package_info_button': glsa_package_info_button,
'adv_info_button': glsa_adv_info_button,
'order': ['package_info_button', 'adv_info_button'],
'handler_ids': [],
},
'mirror_updates': {
'execute_button': mirror_updates_execute_button,
'order': ['execute_button'],
'handler_ids': [],
},
'database_updates': {
'package_info_button': database_updates_package_info_button,
'change_repo_button': database_updates_change_repo_button,
'execute_button': database_updates_execute_button,
'order': ['package_info_button', 'change_repo_button', 'execute_button'],
'handler_ids': [],
},
'available_packages': {
'package_info_button': available_packages_package_info_button,
'remove_package_button': available_packages_remove_package_button,
'move_package_button': available_packages_move_package_button,
'order': ['package_info_button', 'remove_package_button', 'move_package_button'],
'handler_ids': [],
},
'categories_updates': {
'compile_button': categories_updates_compile_button,
'add_use_button': categories_updates_add_use_button,
'remove_use_button': categories_updates_remove_use_button,
'order': ['compile_button', 'add_use_button', 'remove_use_button'],
'handler_ids': [],
},
'notice_board': {
'add_button': notice_board_add_button,
'remove_button': notice_board_remove_button,
'refresh_button': notice_board_refresh_button,
'view_button': notice_board_view_button,
'order': ['view_button', 'add_button', 'remove_button', 'refresh_button'],
'handler_ids': [],
}
}
for cat in self.DataViewButtons:
for w_id in self.DataViewButtons[cat]['order']:
self.DataViewBox.pack_start(self.DataViewButtons[cat][w_id], False, False, 1)
def show_data_view_buttons_cat(self, cat):
if cat in self.DataViewButtons:
for w_id in self.DataViewButtons[cat]['order']:
self.DataViewButtons[cat][w_id].show()
# disconnect all signal handlers
for h_id in self.DataViewButtons[cat]['handler_ids']:
w = self.DataViewButtons[cat][w_id]
if w.handler_is_connected(h_id): w.disconnect(h_id)
del self.DataViewButtons[cat]['handler_ids'][:]
def hide_all_data_view_buttons(self):
self.debug_print("hide_all_data_view_buttons", "enter")
for cat in self.DataViewButtons:
for w_id in self.DataViewButtons[cat]['order']:
self.debug_print("hide_all_data_view_buttons", "hiding button %s,%s" % (cat, w_id,))
self.DataViewButtons[cat][w_id].hide()
self.debug_print("hide_all_data_view_buttons", "quit")
def setup_available_repositories(self):
self.EntropyRepositories = {
'available': [],
'current': ''
}
self.EntropyRepositoryCombo = self.sm_ui.repoManagerRepositoryCombo
self.EntropyRepositoryStore = gtk.ListStore( gobject.TYPE_STRING )
self.EntropyRepositoryCombo.set_model(self.EntropyRepositoryStore)
cell = gtk.CellRendererText()
self.EntropyRepositoryCombo.pack_start(cell, True)
self.EntropyRepositoryCombo.add_attribute(cell, 'text', 0)
self.EntropyRepositoryComboLoader = ParallelTask(self.load_available_repositories)
def setup_commands_view(self):
# setup commands view
self.CommandsView = self.sm_ui.repoManagerCommandsView
self.CommandsStore = gtk.ListStore( gobject.TYPE_PYOBJECT )
self.CommandsView.set_model( self.CommandsStore )
# command col
self.create_text_column( self.CommandsView, _( "Command" ), 'commands:command', size = 270, set_height = 40)
# desc col
self.create_text_column( self.CommandsView, _( "Description" ), 'commands:desc', size = 200, expand = True, set_height = 40)
def fill_commands_view(self, data):
self.CommandsStore.clear()
keys = sorted(data.keys())
for key in keys:
if data[key]['private']: continue
item = data[key].copy()
item['key'] = key
params = ' | '.join([cleanMarkupString(str(x)) for x in item['params']])
if not params:
params = _("None")
txt = "<small><b>%s</b>: %s\n<b>%s</b>: %s</small>" % (
_("Description"),
cleanMarkupString(item['desc']),
_("Parameters"),
params,
)
item['myinfo'] = txt
self.CommandsStore.append((item,))
self.CommandsView.queue_draw()
def setup_queue_view(self):
# setup queue view
self.QueueView = self.sm_ui.repoManagerQueueView
self.QueueStore = gtk.ListStore( gobject.TYPE_PYOBJECT, gobject.TYPE_STRING )
self.QueueView.set_model( self.QueueStore )
# selection pixmap
cell = gtk.CellRendererPixbuf()
column = gtk.TreeViewColumn( _("Status"), cell )
column.set_cell_data_func( cell, self.queue_pixbuf )
column.set_sizing( gtk.TREE_VIEW_COLUMN_FIXED )
column.set_fixed_width( 80 )
column.set_sort_column_id( 0 )
self.QueueView.append_column( column )
# command col
self.create_text_column( self.QueueView, _( "Command" ), 'queue:command_name', size = 180)
# description col
self.create_text_column( self.QueueView, _( "Parameters" ), 'queue:command_text', size = 200, expand = True)
# date col
self.create_text_column( self.QueueView, _( "Date" ), 'queue:ts', size = 120, sort_col_id = 1)
def setup_data_view(self):
store = gtk.TreeStore( gobject.TYPE_PYOBJECT )
self.debug_print("setup_data_view", "enter")
self.reset_data_view()
self.debug_print("setup_data_view", "creating new DataView")
dv = gtk.TreeView()
dv.set_model(store)
self.data_tree_selection_mode = dv.get_selection().get_mode()
self.DataStore = store
self.DataView = dv
self.debug_print("setup_data_view", "quit")
def show_data_view(self):
self.DataScroll.add(self.DataView)
self.debug_print("show_data_view", "adding to DataScroll")
self.DataView.show()
self.debug_print("show_data_view", "showing DataView")
def setup_pinboard_view(self):
# setup pinboard view
self.PinboardView = self.sm_ui.repoManagerPinboardView
self.PinboardStore = gtk.ListStore( gobject.TYPE_PYOBJECT, gobject.TYPE_STRING )
self.PinboardView.set_model( self.PinboardStore )
self.PinboardView.get_selection().set_mode(gtk.SELECTION_MULTIPLE)
self.PinboardView.set_rubber_banding(True)
# selection pixmap
cell = gtk.CellRendererPixbuf()
column = gtk.TreeViewColumn( _("Status"), cell )
column.set_cell_data_func( cell, self.pinboard_pixbuf )
column.set_sizing( gtk.TREE_VIEW_COLUMN_FIXED )
column.set_fixed_width( 80 )
column.set_sort_column_id( 0 )
self.PinboardView.append_column( column )
# date
self.create_text_column( self.PinboardView, _( "Date" ), 'pinboard:date', size = 130, sort_col_id = 1)
# note
self.create_text_column( self.PinboardView, _( "Note" ), 'pinboard:note', size = 200, expand = True)
def create_text_column( self, view, hdr, property, size, sortcol = None, expand = False, set_height = 0, cell_data_func = None, sort_col_id = -1):
if cell_data_func == None: cell_data_func = self.get_data_text
cell = gtk.CellRendererText()
if set_height: cell.set_property('height', set_height)
column = gtk.TreeViewColumn( hdr, cell )
column.set_resizable( True )
column.set_cell_data_func( cell, cell_data_func, property )
column.set_sizing( gtk.TREE_VIEW_COLUMN_FIXED )
column.set_fixed_width( size )
column.set_expand(expand)
column.set_sort_column_id( sort_col_id )
view.append_column( column )
return column
def queue_pixbuf( self, column, cell, model, myiter ):
obj = model.get_value( myiter, 0 )
if isinstance(obj, dict):
st = self.get_status_from_queue_item(obj.copy())
if st != None:
cell.set_property('stock-id', st)
def pinboard_pixbuf( self, column, cell, model, myiter ):
obj = model.get_value( myiter, 0 )
if isinstance(obj, dict):
if obj['done']:
cell.set_property('stock-id', 'gtk-apply')
else:
cell.set_property('stock-id', 'gtk-cancel')
def spm_package_obj_to_cell(self, obj, cell):
use_data = []
if 'use' in obj:
if 'use_string' in obj['use']:
use_data = obj['use']['use_string'].split()
max_chars = 100
use_string = []
for use in use_data:
max_chars -= len(use)
use_string.append(use)
if max_chars < 0:
use_string.append("\n")
max_chars = 100
use_string = ' '.join(use_string).strip()
installed_string = ''
available_string = ''
if 'installed_atom' in obj:
installed_string = '<b>%s</b>: %s\n' % (_("Installed"), cleanMarkupString(str(obj['installed_atom'])),)
if 'available_atom' in obj:
available_string = '<b>%s</b>: %s\n' % (_("Available"), cleanMarkupString(str(obj['available_atom'])),)
atom = obj.get('atom')
key = obj.get('key')
slot = obj.get('slot')
description = obj.get('description')
txt = "<i>%s</i>\n<small><b>%s</b>: %s, <b>%s</b>: %s\n" % (
cleanMarkupString(atom),
_("Key"),
cleanMarkupString(key),
_("Slot"),
cleanMarkupString(slot),
)
txt += installed_string
txt += available_string
if len(use_string) > 160:
use_string = use_string[:160]
txt += "<b>%s</b>: %s\n<b>%s</b>: %s</small>" % (
_("Description"),
cleanMarkupString(description),
_("USE Flags"),
cleanMarkupString(use_string),
)
cell.set_property('markup', txt)
def entropy_package_obj_to_cell(self, obj, cell):
mytxt = '<small><i>%s</i>\n%s\n<b>%s</b>: %s | <b>%s</b>: %s | <b>%s</b>: %s | <b>%s</b>: %s | <b>%s</b>: %s\n<b>%s</b>: %s</small>' % (
obj['atom'],
cleanMarkupString(obj['description']),
_("Size"),
entropy.tools.bytes_into_human(obj['size']),
_("Branch"),
obj['branch'],
_("Slot"),
cleanMarkupString(obj['slot']),
_("Tag"),
cleanMarkupString(obj['versiontag']),
_("Injected"),
obj['injected'],
_("Homepage"),
cleanMarkupString(obj['homepage']),
)
cell.set_property('markup', mytxt)
def get_status_from_queue_item(self, item):
if 'errored_ts' in item:
return "gtk-cancel"
elif 'processed_ts' in item:
return "gtk-apply"
elif 'processing_ts' in item:
return "gtk-refresh"
elif 'queue_ts' in item:
return "gtk-up"
return "gtk-apply"
def get_ts_from_queue_item(self, item):
if 'errored_ts' in item:
return item['errored_ts']
elif 'processed_ts' in item:
return item['processed_ts']
elif 'processing_ts' in item:
return item['processing_ts']
elif 'queue_ts' in item:
return item['queue_ts']
return None
def get_data_text( self, column, cell, model, myiter, property ):
obj = model.get_value( myiter, 0 )
if isinstance(obj, dict):
if property == "queue:ts":
cell.set_property('markup', self.get_ts_from_queue_item(obj))
elif property == "queue:command_text":
cell.set_property('markup', cleanMarkupString(obj['command_text']))
elif property == "queue:command_name":
cell.set_property('markup', cleanMarkupString(obj['command_name']))
elif property == "commands:command":
cell.set_property('markup', obj['key'])
elif property == "commands:desc":
cell.set_property('markup', obj['myinfo'])
elif property == "pinboard:date":
cell.set_property('markup', str(obj['ts']))
elif property == "pinboard:note":
cell.set_property('markup', cleanMarkupString(obj['note']))
def connection_verification_callback(self, host, port, username, password, ssl):
self.Service.setup_connection(
host,
int(port),
username,
password,
ssl
)
# test connection
srv = self.Service.get_service_connection(timeout = 5)
if srv == None:
return False, _("No connection to host, please check your data")
try:
session = srv.open_session()
if session == None:
return False, _("Unable to create a remote session. Try again later.")
try:
logged, error = self.Service.login(srv, session)
if not logged:
return False, _("Login failed. Please retry.")
except Exception as e:
entropy.tools.print_traceback()
return False, "%s: %s" % (_("Connection Error"), e,)
srv.close_session(session)
srv.disconnect()
self.connection_done = True
return True, None
except SSLError:
return False, _("SSL Error, are you sure the server supports SSL?")
def load(self):
my = RemoteConnectionMenu(self.Entropy, self.connection_verification_callback, self.window)
my.load()
login_data = my.run()
if not login_data:
return False
self.sm_ui.repositoryManager.show_all()
self.hide_all_data_view_buttons()
# spawn parallel tasks
self.QueueUpdater.start()
self.OutputUpdater.start()
self.PinboardUpdater.start()
# ui will be unlocked by the thread below
self.ui_lock(True)
self.EntropyRepositoryComboLoader.start()
return True
def get_item_by_queue_id(self, queue_id):
with self.QueueLock:
for key in self.Queue:
if key not in self.dict_queue_keys:
continue
item = self.Queue[key].get(queue_id)
if item != None:
return item, key
return None, None
def service_status_message(self, e):
entropy.tools.print_traceback()
def do_ok():
okDialog(self.sm_ui.repositoryManager, str(e),
title = _("Communication error"))
return False
gobject.idle_add(do_ok)
def get_available_repositories(self):
with self.BufferLock:
try:
status, repo_info = self.Service.Methods.get_available_repositories()
if not status:
return None
except Exception as e:
self.service_status_message(e)
return
return repo_info
def load_available_repositories(self, repo_info = None):
if repo_info == None:
repo_info = self.get_available_repositories()
if not repo_info:
return
if isinstance(repo_info, dict):
def task(repo_info):
self.EntropyRepositories = repo_info.copy()
self.EntropyRepositoryStore.clear()
for repoid in list(self.EntropyRepositories['available'].keys()):
item = self.EntropyRepositoryStore.append( (repoid,) )
if repoid == self.EntropyRepositories['current']:
self.EntropyRepositoryCombo.set_active_iter(item)
mytxt = "<small><b>%s</b>: %s [<b>%s</b>: %s | <b>%s</b>: %s | <b>%s</b>: %s]</small>" % (
_("Current"),
self.EntropyRepositories['current'],
_("c.mode"),
self.EntropyRepositories['community_mode'],
_("branch"),
self.EntropyRepositories['branch'],
_("repositories"),
len(self.EntropyRepositories['available']),
)
try:
self.sm_ui.repoManagerCurrentRepoLabel.set_markup(mytxt)
except AttributeError: # user might have closed the win
pass
if not self.repos_loaded:
self.repos_loaded = True
self.ui_lock(False)
return False
gobject.idle_add(task, repo_info)
def update_queue_view(self):
def task():
self.do_update_queue_view()
t = ParallelTask(task)
t.start()
def do_update_queue_view(self):
with self.BufferLock:
try:
status, queue = self.Service.Methods.get_queue()
if not status:
return
except ConnectionError as err:
self.debug_print("do_update_queue_view", str(err))
return
except Exception as e:
self.service_status_message(e)
return
with self.QueueLock:
if queue == self.Queue:
return
self.Queue = queue.copy()
gobject.idle_add(self.fill_queue_view, queue)
def fill_queue_view(self, queue):
self.QueueStore.clear()
keys = list(queue.keys())
if "processing_order" in keys:
for queue_id in queue['processing_order']:
item = queue['processing'].get(queue_id)
if item == None: continue
item = item.copy()
item['from'] = "processing"
self.QueueStore.append((item, item['queue_ts'],))
if not queue['processing']:
self.is_processing = None
self.is_writing_output = False
else:
self.is_processing = None
self.is_writing_output = False
if "processed_order" in keys:
mylist = queue['processed_order'][:]
mylist.reverse()
for queue_id in mylist:
item = queue['processed'].get(queue_id)
if item == None: continue
item = item.copy()
item['from'] = "processed"
self.QueueStore.append((item, item['queue_ts'],))
if "queue_order" in keys:
for queue_id in queue['queue_order']:
item = queue['queue'].get(queue_id)
if item == None: continue
item = item.copy()
item['from'] = "queue"
self.QueueStore.append((item, item['queue_ts'],))
if "errored_order" in keys:
mylist = queue['errored_order'][:]
mylist.reverse()
for queue_id in mylist:
item = queue['errored'].get(queue_id)
if item == None: continue
item = item.copy()
item['from'] = "errored"
self.QueueStore.append((item, item['queue_ts'],))
return False
def update_pinboard_view(self, force = False):
with self.BufferLock:
try:
status, pindata = self.Service.Methods.get_pinboard_data()
except Exception as e:
self.service_status_message(e)
return
if (pindata == self.PinboardData) and (not force):
return
if isinstance(pindata, dict):
def task(pindata):
self.fill_pinboard_view(pindata)
self.PinboardData = pindata.copy()
return False
gobject.idle_add(task, pindata)
def fill_pinboard_view(self, pinboard_data):
if isinstance(pinboard_data, dict):
gtk.gdk.threads_enter()
self.PinboardStore.clear()
identifiers = sorted(pinboard_data.keys())
for identifier in identifiers:
item = pinboard_data[identifier].copy()
item['pinboard_id'] = identifier
self.PinboardStore.append((item, item['ts'],))
gtk.gdk.threads_leave()
def update_output_view(self, force = False, queue_id = None, n_bytes = 40000):
def clean_output(myin):
s = ''
for x in myin:
if ord(x) < 8:
continue
s += x
return s
with self.OutputLock:
if self.output_pause and not force: return
if not queue_id:
if self.is_processing == None: return
if not self.is_writing_output: return
obj = self.is_processing.copy()
if 'queue_id' not in obj: return
queue_id = obj['queue_id']
with self.BufferLock:
try:
status, stdout = self.Service.Methods.get_queue_id_stdout(queue_id, n_bytes)
except Exception as e:
self.service_status_message(e)
return
if not status: return
stdout = stdout[-1*n_bytes:]
if (stdout == self.Output) and (not force): return
self.Output = stdout
self.clear_console()
stdout = stdout.replace("\n", "\n\r")
self.console.feed_child(stdout)
return False
def load_queue_info_menu(self, obj):
my = SmQueueMenu(self.window)
my.load(obj)
def clear_data_view(self):
self.debug_print("clear_data_view", "enter")
self.setup_data_view()
ts_mode = self.DataView.get_selection().get_mode()
if ts_mode != self.data_tree_selection_mode:
self.DataView.get_selection().set_mode(self.data_tree_selection_mode)
self.debug_print("clear_data_view", "ts_mode set")
self.DataView.set_rubber_banding(False)
self.debug_print("clear_data_view", "rubber banding set")
self.debug_print("clear_data_view", "exit")
def collect_data_view_iters(self):
self.debug_print("collect_data_view_iters", "enter")
model, paths = self.DataView.get_selection().get_selected_rows()
if not model:
self.debug_print("collect_data_view_iters", "quit (nothing)")
return [], model
data = []
for path in paths:
myiter = model.get_iter(path)
data.append(myiter)
self.debug_print("collect_data_view_iters", "quit")
return data, model
def wait_queue_id_to_complete(self, queue_id):
self.debug_print("wait_queue_id_to_complete", "waiting for queue id %s" % (queue_id,))
key = None
while key not in ("processed", "errored",):
item, key = self.get_item_by_queue_id(queue_id)
time.sleep(0.5)
with self.BufferLock:
try:
rcvd_data = self.Service.Methods.get_queue_id_result(queue_id)
if rcvd_data is None:
raise SystemError("received malformed data")
status, (result, extended_result,) = rcvd_data
if not status:
return
except Exception as e:
self.service_status_message(e)
return
self.debug_print("wait_queue_id_to_complete", "done waiting for queue id %s" % (queue_id,))
item = item.copy()
if extended_result != None:
item['result'] = True, extended_result
if key == "errored":
return
return item
def glsa_data_view(self, data):
self.debug_print("glsa_data_view", "enter")
self.clear_data_view()
self.debug_print("glsa_data_view", "setting GFX")
self.debug_print("glsa_data_view", "all buttons hidden")
self.show_data_view_buttons_cat('glsa')
self.debug_print("glsa_data_view", "all glsa buttons shown")
self.DataView.get_selection().set_mode(gtk.SELECTION_MULTIPLE)
self.DataView.set_rubber_banding(True)
self.debug_print("glsa_data_view", "done setting DataView rb")
self.debug_print("glsa_data_view", "done setting GFX")
def is_affected(obj):
if obj['status'] == "[A]":
return False
elif obj['status'] == "[N]":
return True
else:
return False
def my_data_text( column, cell, model, myiter, property ):
obj = model.get_value( myiter, 0 )
if obj:
if property == "glsa_id":
cell.set_property('markup', cleanMarkupString(obj['number']))
elif property == "title":
cell.set_property('markup', cleanMarkupString(obj['title']))
cell.set_property('cell-background', obj['color'])
def my_data_pix( column, cell, model, myiter ):
obj = model.get_value( myiter, 0 )
if obj:
affected = is_affected(obj)
if affected:
cell.set_property( 'stock-id', 'gtk-cancel' )
else:
cell.set_property( 'stock-id', 'gtk-apply' )
cell.set_property('cell-background', obj['color'])
def package_info_clicked(widget):
myiters, model = self.collect_data_view_iters()
if model == None: return
atoms = set()
for myiter in myiters:
obj = model.get_value(myiter, 0)
for atom in obj['packages']:
for atom_info in obj['packages'][atom]:
if 'unaff_atoms' in atom_info:
atoms |= set(atom_info['unaff_atoms'])
if atoms:
self.on_repoManagerPkgInfo_clicked(None, atoms = atoms, clear = True)
def adv_info_button_clicked(widget):
myiters, model = self.collect_data_view_iters()
if model == None: return
for myiter in myiters:
obj = model.get_value(myiter, 0)
my = SecurityAdvisoryMenu(self.window)
item = obj['number'], is_affected(obj), obj
my.load(item)
self.debug_print("glsa_data_view", "done setting functions")
# Package information
h1 = self.DataViewButtons['glsa']['package_info_button'].connect('clicked', package_info_clicked)
# GLSA information button
h2 = self.DataViewButtons['glsa']['adv_info_button'].connect('clicked', adv_info_button_clicked)
self.DataViewButtons['glsa']['handler_ids'].extend([h1, h2])
self.debug_print("glsa_data_view", "done connecting buttons")
# selection pixmap
cell = gtk.CellRendererPixbuf()
column = gtk.TreeViewColumn( _("Status"), cell )
column.set_cell_data_func( cell, my_data_pix )
column.set_sizing( gtk.TREE_VIEW_COLUMN_FIXED )
column.set_fixed_width( 80 )
column.set_sort_column_id( -1 )
self.debug_print("glsa_data_view", "appending status img to DataView")
self.DataView.append_column( column )
self.debug_print("glsa_data_view", "creating glsa column")
# glsa id
self.create_text_column( self.DataView, _( "GLSA Id." ), 'glsa_id', size = 80, cell_data_func = my_data_text)
self.debug_print("glsa_data_view", "creating title column")
# glsa title
self.create_text_column( self.DataView, _( "Title" ), 'title', size = 300, cell_data_func = my_data_text, expand = True)
self.debug_print("glsa_data_view", "done setting DataView columns")
colors = ["#CDEEFF", "#AFCBDA"]
counter = 0
for myid in data:
counter += 1
obj = data[myid].copy()
obj['color'] = colors[counter%len(colors)]
self.DataStore.append( None, (obj,) )
self.debug_print("glsa_data_view", "done adding to DataStore")
self.set_notebook_page(self.notebook_pages['data'])
self.debug_print("glsa_data_view", "done switching page")
self.show_data_view()
self.debug_print("glsa_data_view", "done unmasking widgets")
self.debug_print("glsa_data_view", "exit")
return False
def retrieve_entropy_idpackage_data_and_show(self, idpackage, repoid):
with self.BufferLock:
try:
self.debug_print("retrieve_entropy_idpackage_data_and_show",
"called for: %s, %s" % (idpackage, repoid,))
status, package_data = self.Service.Methods.get_entropy_idpackage_information(idpackage, repoid)
self.debug_print("retrieve_entropy_idpackage_data_and_show",
"done for: %s, %s" % (idpackage, repoid,))
if not status:
return
except Exception as e:
self.service_status_message(e)
return
if not package_data:
return
from sulfur.packages import EntropyPackage
pkg = EntropyPackage((idpackage, repoid,), remote = package_data)
mymenu = PkgInfoMenu(self.Entropy, pkg, self.window)
mymenu.load(remote = True)
def remove_entropy_packages(self, matched_atoms, reload_func = None):
rc = self.Entropy.ask_question(_("Are you sure you want to remove the selected packages ? (For EVA!)"))
if rc != _("Yes"):
return
rc = self.Entropy.ask_question(_("This is your last chance, are you really really really sure?"))
if rc != _("Yes"):
return
with self.BufferLock:
try:
status, msg = self.Service.Methods.remove_entropy_packages(matched_atoms)
except Exception as e:
self.service_status_message(e)
return
if not status:
self.service_status_message(msg)
return
if status and hasattr(reload_func, '__call__'):
reload_func()
def handle_uses_for_atoms(self, atoms, use):
def fake_callback(s):
return s
input_params = []
data = {}
data['atoms'] = atoms
data['use'] = use
if not atoms:
input_params.append(('atoms', _('Atoms, space separated'), fake_callback, False),)
if not use:
input_params.append(('use', _('USE flags, space separated'), fake_callback, False),)
if input_params:
mydata = self.Entropy.input_box(
_('Insert command parameters'),
input_params,
cancel_button = True
)
if mydata == None:
return
data.update(mydata)
if not atoms:
data['atoms'] = data['atoms'].split()
if not use:
data['use'] = data['use'].split()
return data
def run_get_notice_board(self, repoid):
with self.BufferLock:
try:
status, queue_id = self.Service.Methods.get_noticeboard(repoid)
except Exception as e:
self.service_status_message(e)
return
def task(queue_id, repoid):
item = self.wait_queue_id_to_complete(queue_id)
if item == None:
return
status, repo_data = item['result']
if not status:
return
self.update_notice_board_data_view(repo_data, repoid)
if status:
t = ParallelTask(task, queue_id, repoid)
t.start()
def run_write_to_running_command_pipe(self, queue_id, write_to_stdout, txt):
with self.BufferLock:
try:
status, data = self.Service.Methods.write_to_running_command_pipe(queue_id, write_to_stdout, txt)
except Exception as e:
self.service_status_message(e)
return
def run_remove_from_pinboard(self, remove_ids):
with self.BufferLock:
try:
status, queue_id = self.Service.Methods.remove_from_pinboard(remove_ids)
except Exception as e:
self.service_status_message(e)
return
if status:
self.on_repoManagerPinboardRefreshButton_clicked(None)
def run_add_to_pinboard(self, note, extended_text):
with self.BufferLock:
try:
status, err_msg = self.Service.Methods.add_to_pinboard(note, extended_text)
except Exception as e:
self.service_status_message(e)
return
if status:
self.on_repoManagerPinboardRefreshButton_clicked(None)
else:
self.service_status_message(err_msg)
def run_run_custom_shell_command(self, command):
with self.BufferLock:
try:
status, queue_id = self.Service.Methods.run_custom_shell_command(command)
except Exception as e:
self.service_status_message(e)
return
if status:
self.is_writing_output = True
self.is_processing = {'queue_id': queue_id}
self.set_notebook_page(self.notebook_pages['output'])
def run_get_spm_categories_installed(self, categories, world):
with self.BufferLock:
try:
status, queue_id = self.Service.Methods.get_spm_categories_installed(categories)
except Exception as e:
self.service_status_message(e)
return
def task(queue_id, categories, world):
item = self.wait_queue_id_to_complete(queue_id)
if item == None:
return
status, data = item['result']
if not status:
return
def reload_function():
self.on_repoManagerInstalledPackages_clicked(None,
categories = categories, world = world)
return False
gobject.idle_add(self.categories_updates_data_view, data,
categories, True, reload_function)
if status:
t = ParallelTask(task, queue_id, categories, world)
t.start()
def run_sync_spm(self):
with self.BufferLock:
try:
status, data = self.Service.Methods.sync_spm()
except Exception as e:
self.service_status_message(e)
return
if status:
self.set_notebook_page(self.notebook_pages['output'])
def run_spm_remove_atoms(self, data):
def task(data):
with self.BufferLock:
try:
status, queue_id = self.Service.Methods.spm_remove_atoms(
data['atoms'],
data['pretend'],
data['verbose'],
data['nocolor'],
)
except Exception as e:
self.service_status_message(e)
return
if status:
self.is_writing_output = True
self.is_processing = {'queue_id': queue_id}
self.set_notebook_page(self.notebook_pages['output'])
t = ParallelTask(task, data)
t.start()
def run_compile_atoms(self, data):
with self.BufferLock:
try:
status, queue_id = self.Service.Methods.compile_atoms(
data['atoms'],
data['pretend'],
data['oneshot'],
data['verbose'],
data['nocolor'],
data['fetchonly'],
data['buildonly'],
data['nodeps'],
data['custom_use'],
data['ldflags'],
data['cflags'],
)
except Exception as e:
self.service_status_message(e)
return
if status:
self.is_writing_output = True
self.is_processing = {'queue_id': queue_id}
self.set_notebook_page(self.notebook_pages['output'])
def run_spm_info(self):
with self.BufferLock:
try:
status, queue_id = self.Service.Methods.run_spm_info()
except Exception as e:
self.service_status_message(e)
return
if status:
self.is_writing_output = True
self.is_processing = {'queue_id': queue_id}
self.set_notebook_page(self.notebook_pages['output'])
# fine without ParallelTask
def run_enable_uses_for_atoms(self, atoms, use, load_view):
with self.BufferLock:
try:
status, queue_id = self.Service.Methods.enable_uses_for_atoms(atoms, use)
except Exception as e:
self.service_status_message(e)
return
if load_view and status:
self.on_repoManagerPkgInfo_clicked(None, atoms = atoms)
return status
# fine without ParallelTask
def run_disable_uses_for_atoms(self, atoms, use, load_view):
with self.BufferLock:
try:
status, queue_id = self.Service.Methods.disable_uses_for_atoms(atoms, use)
except Exception as e:
self.service_status_message(e)
return
if load_view and status:
self.clear_data_store_and_view()
self.on_repoManagerPkgInfo_clicked(None, atoms = atoms)
return status
def run_get_spm_atoms_info(self, categories, atoms, clear):
with self.BufferLock:
try:
status, queue_id = self.Service.Methods.get_spm_atoms_info(atoms)
except Exception as e:
self.service_status_message(e)
return
def task(categories, atoms):
item = self.wait_queue_id_to_complete(queue_id)
if item == None: return
status, data = item['result']
if not status: return
def reload_function():
self.on_repoManagerPkgInfo_clicked(None, atoms = atoms, clear = clear)
gobject.idle_add(self.categories_updates_data_view, data,
categories, True, reload_function)
if status:
t = ParallelTask(task, categories, atoms)
t.start()
def run_kill_processing_queue_id(self, queue_id):
with self.BufferLock:
try:
self.Service.Methods.kill_processing_queue_id(queue_id)
except Exception as e:
self.service_status_message(e)
return
def run_remove_queue_ids(self, queue_ids):
with self.BufferLock:
try:
self.Service.Methods.remove_queue_ids(queue_ids)
except Exception as e:
self.service_status_message(e)
return
def run_spm_categories_updates(self, categories, expand):
with self.BufferLock:
try:
status, queue_id = self.Service.Methods.get_spm_categories_updates(categories)
except Exception as e:
self.service_status_message(e)
return
def task(queue_id, categories, expand):
item = self.wait_queue_id_to_complete(queue_id)
if item == None: return
status, data = item['result']
if not status: return
gobject.idle_add(self.categories_updates_data_view, data,
categories, expand)
if status:
t = ParallelTask(queue_id, task, categories, expand)
t.start()
def run_entropy_deptest(self):
with self.BufferLock:
try:
status, queue_id = self.Service.Methods.run_entropy_dependency_test()
except Exception as e:
self.service_status_message(e)
return
if status:
self.is_writing_output = True
self.is_processing = {'queue_id': queue_id }
self.set_notebook_page(self.notebook_pages['output'])
else:
self.service_status_message(queue_id)
def run_entropy_treeupdates(self, repoid):
with self.BufferLock:
try:
status, queue_id = self.Service.Methods.run_entropy_treeupdates(repoid)
except Exception as e:
self.service_status_message(e)
return
if status:
self.is_writing_output = True
self.is_processing = {'queue_id': queue_id }
self.set_notebook_page(self.notebook_pages['output'])
else:
self.service_status_message(queue_id)
def run_entropy_checksum_test(self, repoid, mode):
with self.BufferLock:
try:
status, queue_id = self.Service.Methods.run_entropy_checksum_test(repoid, mode)
except Exception as e:
self.service_status_message(e)
return
if status:
self.is_writing_output = True
self.is_processing = {'queue_id': queue_id }
self.set_notebook_page(self.notebook_pages['output'])
else:
self.service_status_message(queue_id)
def run_entropy_mirror_updates(self, repos):
with self.BufferLock:
try:
status, queue_id = self.Service.Methods.scan_entropy_mirror_updates(repos)
except Exception as e:
self.service_status_message(e)
return
def task(queue_id, repos):
item = self.wait_queue_id_to_complete(queue_id)
if item == None: return
status, repo_data = item['result']
if not status: return
gobject.idle_add(self.entropy_mirror_updates_data_view,
repo_data)
if status:
t = ParallelTask(task, queue_id, repos)
t.start()
else:
self.service_status_message(queue_id)
def execute_entropy_mirror_updates(self, repo_data):
with self.BufferLock:
try:
status, queue_id = self.Service.Methods.run_entropy_mirror_updates(repo_data)
except Exception as e:
self.service_status_message(e)
return
if status:
self.is_writing_output = True
self.is_processing = {'queue_id': queue_id }
self.set_notebook_page(self.notebook_pages['output'])
else:
self.service_status_message(queue_id)
def run_entropy_libtest(self):
with self.BufferLock:
status = False
data = {}
try:
status, queue_id = self.Service.Methods.run_entropy_library_test()
except Exception as e:
self.service_status_message(e)
return
if status:
# enable output
self.is_writing_output = True
self.is_processing = {'queue_id': queue_id }
self.set_notebook_page(self.notebook_pages['output'])
else:
self.service_status_message(queue_id)
def run_package_search(self, search_type, search_string, repoid):
with self.BufferLock:
try:
status, data = self.Service.Methods.search_entropy_packages(search_type, search_string, repoid)
except Exception as e:
self.service_status_message(e)
return
if status:
def reload_func():
self.run_package_search(search_type, search_string, repoid)
gobject.idle_add(self.entropy_available_packages_data_view,
data, repoid, reload_func)
else:
self.service_status_message(data)
def move_entropy_packages(self, matches, reload_function):
idpackages = []
repoids = set()
for idpackage, repoid in matches:
repoids.add(repoid)
idpackages.append(idpackage)
if len(repoids) > 1:
self.service_status_message(_("Cannot move/copy packages from different repositories"))
return
from_repo = list(repoids)[0]
avail_repos = list(self.EntropyRepositories['available'].keys())
if not avail_repos: return
def fake_callback_repos(s):
entryid, myrepoid = s
if myrepoid == from_repo:
return False
return True
def fake_callback_cb(s):
return True
input_params = [
('to_repo', ('combo', (_('To repository'), avail_repos),), fake_callback_repos, False),
('do_copy', ('checkbox', _('Execute copy'),), fake_callback_cb, False),
]
data = self.Entropy.input_box(
_('Entropy packages move/copy'),
input_params,
cancel_button = True
)
if data == None: return
data['to_repo'] = data['to_repo'][1]
with self.BufferLock:
status = False
try:
status, queue_id = self.Service.Methods.move_entropy_packages_to_repository(idpackages, from_repo, data['to_repo'], do_copy = data['do_copy'])
except Exception as e:
self.service_status_message(e)
return
if not status:
self.service_status_message(queue_id)
return
self.reload_after_package_move(queue_id, reload_function)
def reload_after_package_move(self, queue_id, reload_func):
def task(queue_id, reload_func):
item = self.wait_queue_id_to_complete(queue_id)
if item == None: return
status, data = item['result']
if not status: return
gobject.idle_add(reload_func)
t = ParallelTask(task, queue_id, reload_func)
t.start()
def run_entropy_database_updates_scan(self):
with self.BufferLock:
status = False
data = {}
try:
status, queue_id = self.Service.Methods.scan_entropy_packages_database_changes()
except Exception as e:
self.service_status_message(e)
return
def task(queue_id):
item = self.wait_queue_id_to_complete(queue_id)
if item == None:
return
status, data = item['result']
if not status:
return
gobject.idle_add(self.entropy_database_updates_data_view,
data)
if status:
t = ParallelTask(task, queue_id)
t.start()
else:
self.service_status_message(queue_id)
def run_entropy_database_updates(self, to_add, to_remove, to_inject, reload_func = None):
if reload_func == None:
def reload_func():
return False
with self.BufferLock:
try:
status, queue_id = self.Service.Methods.run_entropy_database_updates(to_add, to_remove, to_inject)
except Exception as e:
self.service_status_message(e)
return
def task(queue_id, reload_func):
self.reload_after_package_move(queue_id, reload_func)
if status:
self.is_writing_output = True
self.is_processing = {'queue_id': queue_id }
self.set_notebook_page(self.notebook_pages['output'])
t = ParallelTask(task, queue_id, reload_func)
t.start()
else:
self.service_status_message(queue_id)
def run_add_notice_board_entry(self, repoid, title, notice_text, link, reload_func = None):
if reload_func == None:
def reload_func():
return False
with self.BufferLock:
try:
status, queue_id = self.Service.Methods.add_notice_board_entry(repoid, title, notice_text, link)
except Exception as e:
self.service_status_message(e)
return
def task(queue_id, repoid, title, notice_text, link, reload_func):
item = self.wait_queue_id_to_complete(queue_id)
if item == None: return
status, result = item['result']
if not status: return
gobject.idle_add(reload_func)
if status:
t = ParallelTask(task, queue_id, repoid, title, notice_text, link, reload_func)
t.start()
def run_remove_notice_board_entries(self, repoid, ids, reload_func = None):
if reload_func == None:
def reload_func():
return False
with self.BufferLock:
try:
status, queue_id = self.Service.Methods.remove_notice_board_entries(repoid, list(ids))
except Exception as e:
self.service_status_message(e)
return
def task(queue_id, repoid, ids, reload_func):
item = self.wait_queue_id_to_complete(queue_id)
if item == None: return
status, result = item['result']
if not status: return
gobject.idle_add(reload_func)
if status:
t = ParallelTask(task, queue_id, repoid, ids, reload_func)
t.start()
def update_notice_board_data_view(self, repo_data, repoid):
self.clear_data_view()
self.show_data_view_buttons_cat('notice_board')
self.DataView.get_selection().set_mode(gtk.SELECTION_MULTIPLE)
self.DataView.set_rubber_banding(True)
def my_data_text( column, cell, model, myiter, property ):
obj = model.get_value( myiter, 0 )
if obj:
mytxt = '<b><u>%s</u></b>\n<small><b>%s</b>: %s</small>' % (
cleanMarkupString(obj['pubDate']),
_("Title"),
cleanMarkupString(obj['title']),
)
cell.set_property('markup', mytxt)
cell.set_property('cell-background', obj['color'])
def add_button_clicked(widget):
def fake_callback(s):
return s
input_params = [
('title', _('Notice title'), fake_callback, False),
('link', _('Link (URL)'), fake_callback, False),
('notice_text', ("text", _('Notice text'),), fake_callback, False),
]
data = self.Entropy.input_box(
_('Insert your new notice board entry'),
input_params,
cancel_button = True
)
if data == None: return
def reload_func():
self.on_repoManagerNoticeBoardButton_clicked(None, repoid = repoid)
self.run_add_notice_board_entry(repoid, data['title'], data['notice_text'], data['link'], reload_func)
def remove_button_clicked(widget):
myiters, model = self.collect_data_view_iters()
if model == None: return
ids = set()
for myiter in myiters:
obj = model.get_value(myiter, 0)
ids.add(obj['id'])
if ids:
def reload_func():
self.on_repoManagerNoticeBoardButton_clicked(None, repoid = repoid)
self.run_remove_notice_board_entries(repoid, ids, reload_func)
def refresh_button_clicked(widget):
self.on_repoManagerNoticeBoardButton_clicked(None, repoid = repoid)
def view_button_clicked(widget):
myiters, model = self.collect_data_view_iters()
if model == None: return
for myiter in myiters:
obj = model.get_value(myiter, 0)
my = RmNoticeBoardMenu(self.window)
my.load(obj)
h1 = self.DataViewButtons['notice_board']['add_button'].connect('clicked', add_button_clicked)
h2 = self.DataViewButtons['notice_board']['remove_button'].connect('clicked', remove_button_clicked)
h3 = self.DataViewButtons['notice_board']['refresh_button'].connect('clicked', refresh_button_clicked)
h4 = self.DataViewButtons['notice_board']['view_button'].connect('clicked', view_button_clicked)
self.DataViewButtons['notice_board']['handler_ids'].extend([h1, h2, h3, h4])
self.create_text_column( self.DataView, _( "Notice board" ), 'nb', size = 300, cell_data_func = my_data_text, expand = True, set_height = 36)
self.fill_notice_board_view(repo_data)
self.set_notebook_page(self.notebook_pages['data'])
self.show_data_view()
def fill_notice_board_view(self, repo_data):
colors = ["#CDEEFF", "#AFCBDA"]
counter = 0
items, lenght = repo_data
keys = sorted(items.keys())
for key in keys:
counter += 1
item = items[key].copy()
item['color'] = colors[counter%len(colors)]
item['id'] = key
self.DataStore.append( None, (item,) )
def entropy_mirror_updates_data_view(self, repo_data):
self.clear_data_view()
self.show_data_view_buttons_cat('mirror_updates')
self.DataView.get_selection().set_mode(gtk.SELECTION_MULTIPLE)
self.DataView.set_rubber_banding(True)
def my_data_text( column, cell, model, myiter, property ):
obj = model.get_value( myiter, 0 ) # cleanMarkupString
if obj:
if 'is_master' in obj:
if obj['from'] == "repoid":
cell.set_property('markup', "<big><b>%s</b>: <i>%s</i></big>" % (_("Repository"), cleanMarkupString(obj['text']),))
elif obj['from'] == "pkg_master":
cell.set_property('markup', "<b>%s</b>: <i>%s</i>" % (_("Action"), cleanMarkupString(obj['text']),))
elif obj['from'] == "uri":
cell.set_property('markup', "<b>%s</b>: <u>%s</u>" % (_("Server"), cleanMarkupString(obj['text']),))
elif obj['from'] == "db":
yes = _("Yes")
no = _("No")
up_action = yes
if not obj['upload_queue']: up_action = no
down_action = yes
if not obj['download_latest']: down_action = no
cell.set_property('markup', "<b>%s</b>: %s: %s, %s: %s, %s: %s, %s: %s" % (
_("Database"),
_("current revision"),
obj['current_revision'],
_("remote revision"),
obj['remote_revision'],
_("upload"),
up_action,
_("download"),
down_action,
)
)
else:
if obj['from'] == "pkg":
cell.set_property('markup', "%s [%s]" % (cleanMarkupString(obj['filename']), cleanMarkupString(obj['size']),))
cell.set_property('cell-background', obj['color'])
def execute_button_clicked(widget):
def fake_callback(s):
return s
input_params = [
('exec_type', ('combo', (_('Execution mode'), [_("Execute all"), _("Execute only selected")]),), fake_callback, False)
]
mydata = self.Entropy.input_box(
_('Choose the execution mode'),
input_params,
cancel_button = True
)
if mydata == None: return
myiters = []
if mydata['exec_type'][0] == 0:
self.DataView.get_selection().select_all()
myiters, model = self.collect_data_view_iters()
if model == None: return
objects = []
for myiter in myiters:
obj = model.get_value(myiter, 0)
#if not obj.has_key('is_master'): continue
objects.append(obj)
run_data = {}
for obj in objects:
repoid, dbsync, pkgsync = obj['run']
if repoid in run_data: continue
run_data[repoid] = {
'db': dbsync,
'pkg': pkgsync,
'pretend': True,
'mirrors': [],
}
if not run_data: return
def fake_callback_cb(s):
return True
def fake_callback(s):
return True
# now ask for mirrors
for repoid in list(run_data.keys()):
input_params = [
('commit_msg', _("Commit message"), fake_callback, False,),
('do_pretend', ('checkbox', _("Pretend mode"),), fake_callback_cb, False,),
('pkg_check', ('checkbox', _("Packages check"),), fake_callback_cb, False,),
]
data = self.Entropy.input_box(
"[%s] %s" % (repoid, _('Choose sync options'),),
input_params,
cancel_button = True
)
if data == None:
run_data.pop(repoid)
continue
run_data[repoid]['pretend'] = data['do_pretend']
run_data[repoid]['pkg_check'] = data['pkg_check']
run_data[repoid]['commit_msg'] = data['commit_msg']
if run_data:
self.clear_data_store_and_view()
t = ParallelTask(self.execute_entropy_mirror_updates, run_data)
t.start()
h1 = self.DataViewButtons['mirror_updates']['execute_button'].connect('clicked', execute_button_clicked)
self.DataViewButtons['mirror_updates']['handler_ids'].extend([h1])
self.create_text_column( self.DataView, _( "Mirror updates information" ), 'info', size = 300, cell_data_func = my_data_text, expand = True)
self.fill_mirror_updates_view(repo_data)
self.set_notebook_page(self.notebook_pages['data'])
self.show_data_view()
return False
def entropy_database_updates_data_view(self, data):
self.clear_data_view()
self.show_data_view_buttons_cat('database_updates')
self.DataView.get_selection().set_mode(gtk.SELECTION_MULTIPLE)
self.DataView.set_rubber_banding(True)
def my_data_text( column, cell, model, myiter, property ):
obj = model.get_value( myiter, 0 )
if obj:
if property == "package":
is_cat = False
if 'is_master' in obj:
is_cat = True
if is_cat:
mytxt = "<big><b>%s</b></big>" % (obj['text'],)
cell.set_property('markup', mytxt)
elif obj['from'] == "add":
self.spm_package_obj_to_cell(obj, cell)
else:
self.entropy_package_obj_to_cell(obj, cell)
elif property == "repoid":
if 'repoid' in obj:
cell.set_property('markup', "<small>%s</small>" % (cleanMarkupString(obj['repoid']),))
else:
cell.set_property('markup', '')
elif property == "toggle":
cell.set_active(obj['select'])
cell.set_property('cell-background', obj['color'])
def package_info_clicked(widget):
myiters, model = self.collect_data_view_iters()
if model == None: return
for myiter in myiters:
obj = model.get_value(myiter, 0)
if 'is_master' in obj: continue
if obj['from'] != "add":
self.retrieve_entropy_idpackage_data_and_show(obj['idpackage'], obj['repoid'])
def change_repo_clicked(widget):
myiters, model = self.collect_data_view_iters()
if model == None: return
avail_repos = list(self.EntropyRepositories['available'].keys())
if not avail_repos: return
def fake_callback(s):
return s
input_params = [
('repoid', ('combo', (_('Repository'), avail_repos),), fake_callback, False)
]
objects = []
for myiter in myiters:
obj = model.get_value(myiter, 0)
if 'is_master' in obj: continue
if obj['from'] != "add": continue
objects.append(obj)
if objects:
mydata = self.Entropy.input_box(
_('Choose the destination repository'),
input_params,
cancel_button = True
)
if mydata == None: return
to_repoid = mydata['repoid'][1]
for obj in objects:
obj['repoid'] = to_repoid
self.DataView.queue_draw()
def execute_button_clicked(widget):
def fake_callback(s):
return s
input_params = [
('exec_type', ('combo', (_('Execution mode'), [_("Execute all"), _("Execute only selected")]),), fake_callback, False)
]
mydata = self.Entropy.input_box(
_('Choose the execution mode'),
input_params,
cancel_button = True
)
if mydata == None: return
myiters = []
if mydata['exec_type'][0] == 0:
self.DataView.get_selection().select_all()
myiters, model = self.collect_data_view_iters()
if model == None: return
objects = []
for myiter in myiters:
obj = model.get_value(myiter, 0)
if 'is_master' in obj: continue
objects.append(obj)
to_add = []
to_remove = []
to_inject = []
for obj in objects:
if obj['from'] == "add":
to_add.append(obj['match_key']+(obj['repoid'],))
elif obj['from'] == "remove":
to_remove.append(obj['match_key'])
elif obj['from'] == "inject":
to_inject.append(obj['match_key'])
if to_add or to_remove or to_inject:
def reload_func():
self.on_repoManagerEntropyDbUpdatesButton_clicked(None)
self.clear_data_store_and_view()
self.run_entropy_database_updates(to_add, to_remove, to_inject, reload_func)
h1 = self.DataViewButtons['database_updates']['change_repo_button'].connect('clicked', change_repo_clicked)
h2 = self.DataViewButtons['database_updates']['package_info_button'].connect('clicked', package_info_clicked)
h3 = self.DataViewButtons['database_updates']['execute_button'].connect('clicked', execute_button_clicked)
self.DataViewButtons['database_updates']['handler_ids'].extend([h1, h2, h3])
cell_height = 80
# package
self.create_text_column( self.DataView, _( "Package" ), 'package', size = 300, set_height = cell_height, cell_data_func = my_data_text, expand = True)
# repository
self.create_text_column( self.DataView, _( "Repository" ), 'repoid', size = 130, set_height = cell_height, cell_data_func = my_data_text)
self.fill_db_updates_view(data)
self.set_notebook_page(self.notebook_pages['data'])
self.show_data_view()
return False
def fill_db_updates_view(self, data):
master_add = {
'is_master': True,
'type': "add",
'text': _("To be added"),
'color': '#CDEEFF',
'select': True,
}
master_remove = {
'is_master': True,
'type': "remove",
'text': _("To be removed"),
'color': '#CDEEFF',
'select': True,
}
master_inject = {
'is_master': True,
'type': "inject",
'text': _("To be injected"),
'color': '#CDEEFF',
'select': True,
}
add_cats_data = {}
for spm_atom, spm_counter in data['add_data']:
cat = entropy.tools.dep_getkey(spm_atom).split("/")[0]
if cat not in add_cats_data:
add_cats_data[cat] = []
item = data['add_data'][(spm_atom, spm_counter,)]
item['repoid'] = self.EntropyRepositories['current']
item['select'] = True
item['match_key'] = (spm_atom, spm_counter,)
add_cats_data[cat].append(item)
remove_cats_data = {}
for idpackage, repoid in data['remove_data']:
if (idpackage, repoid,) not in data['remove_data']:
continue
item = data['remove_data'][(idpackage, repoid,)]
if not item: continue
item['select'] = True
item['match_key'] = (idpackage, repoid,)
cat = item['category']
if cat not in remove_cats_data:
remove_cats_data[cat] = []
remove_cats_data[cat].append(item)
inject_cats_data = {}
for idpackage, repoid in data['inject_data']:
if (idpackage, repoid,) not in data['inject_data']:
continue
item = data['inject_data'][(idpackage, repoid,)]
if not item: continue
item['select'] = True
item['match_key'] = (idpackage, repoid,)
cat = item['category']
if cat not in inject_cats_data:
inject_cats_data[cat] = []
inject_cats_data[cat].append(item)
colors = ["#CDEEFF", "#AFCBDA"]
cat_counter = 0
counter = 0
add_cat_keys = sorted(add_cats_data.keys())
remove_cat_keys = sorted(remove_cats_data.keys())
inject_cat_keys = sorted(inject_cats_data.keys())
# first add
if add_cats_data: add_parent = self.DataStore.append( None, (master_add,) )
if remove_cats_data: remove_parent = self.DataStore.append( None, (master_remove,) )
if inject_cats_data: inject_parent = self.DataStore.append( None, (master_inject,) )
for category in add_cat_keys:
cat_counter += 1
mydict = {
'color': colors[cat_counter%len(colors)],
'is_master': True,
'type': "category",
'text': category,
'select': True,
}
myparent = self.DataStore.append( add_parent, (mydict,) )
for item in add_cats_data[category]:
counter += 1
item['color'] = colors[counter%len(colors)]
item['from'] = 'add'
item['select'] = True
self.DataStore.append( myparent, (item,) )
cat_counter = 0
counter = 0
for category in remove_cat_keys:
cat_counter += 1
mydict = {
'color': colors[cat_counter%len(colors)],
'is_master': True,
'type': "category",
'text': category,
'select': True,
}
myparent = self.DataStore.append( remove_parent, (mydict,) )
for item in remove_cats_data[category]:
counter += 1
item['color'] = colors[counter%len(colors)]
item['from'] = 'remove'
item['select'] = True
self.DataStore.append( myparent, (item,) )
cat_counter = 0
counter = 0
for category in inject_cat_keys:
cat_counter += 1
mydict = {
'color': colors[cat_counter%len(colors)],
'is_master': True,
'type': "category",
'text': category,
'select': True,
}
myparent = self.DataStore.append( inject_parent, (mydict,) )
for item in inject_cats_data[category]:
counter += 1
item['color'] = colors[counter%len(colors)]
item['from'] = 'inject'
item['select'] = True
self.DataStore.append( myparent, (item,) )
self.DataView.expand_all()
def fill_mirror_updates_view(self, data):
color_odd = '#FFF7C2'
color_even = '#E6FFCA'
repos = list(data.keys())
for repoid in repos:
color = color_odd
master = {
'is_master': True,
'text': repoid,
'from': "repoid",
'color': color,
'repoid': repoid,
'run': (repoid, True, True,) # repoid, dbsync, pkgsync
}
parent = self.DataStore.append( None, (master,))
for uri in data[repoid]:
color = color_odd
if 'packages' not in data[repoid][uri]:
color = color_even
uri_master = {
'is_master': True,
'text': uri,
'from': "uri",
'color': color,
'repoid': repoid,
'run': (repoid, True, True,) # repoid, dbsync, pkgsync
}
uri_parent = self.DataStore.append( parent, (uri_master,))
# db
db_item = data[repoid][uri]['database']
db_color = "#FFF7C2"
if db_item['remote_revision'] == db_item['current_revision']:
db_color = "#E6FFCA"
db_item['color'] = db_color
db_item['from'] = "db"
db_item['is_master'] = True
db_item['repoid'] = repoid
db_item['run'] = (repoid, True, True,) # repoid, dbsync, pkgsync
self.DataStore.append( uri_parent, (db_item,))
if 'packages' in data[repoid][uri]:
for action in data[repoid][uri]['packages']:
if data[repoid][uri]['packages'][action]:
pkgmaster = {
'is_master': True,
'text': action,
'from': "pkg_master",
'color': color,
'repoid': repoid,
'run': (repoid, False, True,)
}
pkg_parent = self.DataStore.append( uri_parent, (pkgmaster,))
for mypath, mysize in data[repoid][uri]['packages'][action]:
pkg_item = {
'from': "pkg",
'filename': os.path.basename(mypath),
'size': entropy.tools.bytes_into_human(mysize),
'color': color,
'repoid': repoid,
'run': (repoid, False, True,)
}
self.DataStore.append( pkg_parent, (pkg_item,))
self.DataView.expand_all()
def entropy_available_packages_data_view(self, packages_data, repoid, reload_func = None):
if not isinstance(packages_data, dict):
return
if reload_func == None:
def reload_func():
self.on_repoManagerAvailablePackagesButton_clicked(None, repoid = repoid)
self.clear_data_view()
self.show_data_view_buttons_cat('available_packages')
self.DataView.get_selection().set_mode(gtk.SELECTION_MULTIPLE)
self.DataView.set_rubber_banding(True)
def my_data_text( column, cell, model, myiter, property ):
obj = model.get_value( myiter, 0 )
if obj:
if property == "package":
is_cat = False
if 'is_cat' in obj:
is_cat = True
if is_cat:
mytxt = "<big><b>%s</b></big>" % (obj['name'],)
cell.set_property('markup', mytxt)
else:
self.entropy_package_obj_to_cell(obj, cell)
elif property == "repoid":
cell.set_property('markup', "<small>%s</small>" % (cleanMarkupString(obj['repoid']),))
cell.set_property('cell-background', obj['color'])
def package_info_clicked(widget):
myiters, model = self.collect_data_view_iters()
if model == None: return
for myiter in myiters:
obj = model.get_value(myiter, 0)
if 'is_cat' in obj: continue
self.retrieve_entropy_idpackage_data_and_show(obj['idpackage'], obj['repoid'])
def remove_package_button_clicked(widget):
myiters, model = self.collect_data_view_iters()
if model == None: return
items = []
for myiter in myiters:
obj = model.get_value(myiter, 0)
if 'is_cat' in obj: continue
items.append((obj['idpackage'], obj['repoid'],))
if items:
self.remove_entropy_packages(items, reload_func = reload_func)
def move_package_button_clicked(widget):
myiters, model = self.collect_data_view_iters()
if model == None: return
items = []
for myiter in myiters:
obj = model.get_value(myiter, 0)
if 'is_cat' in obj: continue
items.append((obj['idpackage'], obj['repoid'],))
if items:
self.move_entropy_packages(items, reload_func)
h1 = self.DataViewButtons['available_packages']['package_info_button'].connect('clicked', package_info_clicked)
h2 = self.DataViewButtons['available_packages']['remove_package_button'].connect('clicked', remove_package_button_clicked)
h3 = self.DataViewButtons['available_packages']['move_package_button'].connect('clicked', move_package_button_clicked)
self.DataViewButtons['available_packages']['handler_ids'].extend([h1, h2, h3])
# glsa id
self.create_text_column( self.DataView, _( "Package" ), 'package', size = 300, set_height = 60, cell_data_func = my_data_text, expand = True)
# glsa title
self.create_text_column( self.DataView, _( "Repository" ), 'repoid', size = 130, set_height = 60, cell_data_func = my_data_text)
cats_data = {}
for idpackage in packages_data['ordered_idpackages']:
item = packages_data['data'].get(idpackage)
if item == None: continue
mycat = item['category']
if mycat not in cats_data:
cats_data[mycat] = []
cats_data[mycat].append(item)
colors = ["#CDEEFF", "#AFCBDA"]
counter = 0
cat_keys = sorted(cats_data.keys())
for category in cat_keys:
counter += 1
mydict = {
'is_cat': True,
'name': category,
'color': colors[0],
'repoid': repoid,
}
parent = self.DataStore.append( None, (mydict,) )
for item in cats_data[category]:
counter += 1
item['color'] = colors[counter%len(colors)]
item['repoid'] = repoid
self.DataStore.append( parent, (item,) )
self.set_notebook_page(self.notebook_pages['data'])
self.show_data_view()
return False
def categories_updates_data_view(self, data, categories, expand = False, reload_function = None):
if reload_function == None:
def reload_function():
self.on_repoManagerCategoryUpdButton_clicked(None, categories = categories, expand = True)
return False
self.clear_data_view()
self.show_data_view_buttons_cat('categories_updates')
self.DataView.get_selection().set_mode(gtk.SELECTION_MULTIPLE)
self.DataView.set_rubber_banding(True)
def my_data_text( column, cell, model, myiter, property ):
obj = model.get_value( myiter, 0 )
if obj:
if 'is_cat' in obj:
txt = "<big><b>%s</b></big>" % (obj['name'],)
cell.set_property('markup', txt)
else:
self.spm_package_obj_to_cell(obj, cell)
cell.set_property('cell-background', obj['color'])
def compile_button_clicked(widget):
myiters, model = self.collect_data_view_iters()
atoms = []
for myiter in myiters:
obj = model.get_value(myiter, 0)
if obj:
if 'available_atom' in obj:
if not obj['available_atom']:
continue
atom = obj['available_atom']
else:
atom = obj['atom']
atoms.append("="+atom)
if atoms:
self.on_compileAtom_clicked(None, atoms)
def add_use_button_clicked(widget):
myiters, model = self.collect_data_view_iters()
atoms = []
for myiter in myiters:
obj = model.get_value(myiter, 0)
if 'key' in obj and 'slot' in obj:
atom_string = "%s%s%s" % (obj['key'],
etpConst['entropyslotprefix'], obj['slot'],)
atoms.append(atom_string)
if atoms:
status = self.on_addUseAtom_clicked(None, atoms = atoms, load_view = False, parallel = False)
if status:
gobject.idle_add(reload_function)
def remove_use_button_clicked(widget):
myiters, model = self.collect_data_view_iters()
atoms = []
for myiter in myiters:
obj = model.get_value(myiter, 0)
if 'key' in obj and 'slot' in obj:
atom_string = "%s%s%s" % (obj['key'],
etpConst['entropyslotprefix'], obj['slot'],)
atoms.append(atom_string)
if atoms:
status = self.on_removeUseAtom_clicked(None, atoms = atoms, load_view = False, parallel = False)
if status:
gobject.idle_add(reload_function)
h1 = self.DataViewButtons['categories_updates']['compile_button'].connect('clicked', compile_button_clicked)
h2 = self.DataViewButtons['categories_updates']['add_use_button'].connect('clicked', add_use_button_clicked)
h3 = self.DataViewButtons['categories_updates']['remove_use_button'].connect('clicked', remove_use_button_clicked)
self.DataViewButtons['categories_updates']['handler_ids'].extend([h1, h2, h3])
# atom
self.create_text_column( self.DataView, _( "Atom" ), 'atom', size = 220, cell_data_func = my_data_text, set_height = 150, expand = True)
colors = ["#D2FFB9", "#B0D69B"]
counter = 0
for category in data:
counter += 1
master = {'is_cat': True, 'name': category, 'color': colors[counter%len(colors)]}
parent = self.DataStore.append( None, (master,) )
for atom in data[category]:
counter += 1
obj = data[category][atom].copy()
obj['atom'] = atom
obj['color'] = colors[counter%len(colors)]
self.DataStore.append( parent, (obj,) )
if expand:
self.DataView.expand_all()
self.set_notebook_page(self.notebook_pages['data'])
self.show_data_view()
return False
def on_repoManagerQueueDown_clicked(self, widget):
( model, iterator ) = self.QueueView.get_selection().get_selected()
if not iterator: return
next_iterator = model.iter_next(iterator)
if iterator and next_iterator:
item1 = model.get_value(iterator, 0)
item2 = model.get_value(next_iterator, 0)
if item1 and item2:
item1 = item1.copy()
item2 = item2.copy()
def task():
with self.BufferLock:
try:
status, msg = self.Service.Methods.swap_items_in_queue(item1['queue_id'], item2['queue_id'])
self.debug_print("on_repoManagerQueueDown_clicked", "%s, %s" % (status, msg,))
self.debug_print("on_repoManagerQueueDown_clicked", "%s, %s" % (item1, item2,))
if status:
self.QueueStore.swap(iterator, next_iterator)
except Exception as e:
self.service_status_message(e)
return
self.update_queue_view()
t = ParallelTask(task)
t.start()
def on_repoManagerQueueUp_clicked(self, widget):
( model, next_iterator ) = self.QueueView.get_selection().get_selected()
if not next_iterator: return
path = model.get_path(next_iterator)[0]
iterator = model.get_iter(path-1)
if iterator and next_iterator:
item1 = model.get_value(iterator, 0)
item2 = model.get_value(next_iterator, 0)
if item1 and item2:
item1 = item1.copy()
item2 = item2.copy()
def task():
with self.BufferLock:
try:
status, msg = self.Service.Methods.swap_items_in_queue(item1['queue_id'], item2['queue_id'])
self.debug_print("on_repoManagerQueueUp_clicked", "%s, %s" % (status, msg,))
self.debug_print("on_repoManagerQueueUp_clicked", "%s, %s" % (item1, item2,))
if status:
self.QueueStore.swap(iterator, next_iterator)
except Exception as e:
self.service_status_message(e)
return
self.update_queue_view()
t = ParallelTask(task)
t.start()
def on_repoManagerCategoryUpdButton_clicked(self, widget, categories = [], expand = False):
def fake_callback(s):
return s
input_params = []
if not categories:
input_params += [
('categories', _('Categories, space separated'), fake_callback, False),
]
data = {}
data['categories'] = categories
if input_params:
mydata = self.Entropy.input_box(
_('Insert categories'),
input_params,
cancel_button = True
)
if mydata == None: return
data.update(mydata)
if not categories:
data['categories'] = data['categories'].split()
if data['categories']:
self.clear_data_store_and_view()
self.run_spm_categories_updates(data['categories'], expand)
def on_repoManagerCustomRunButton_clicked(self, widget):
command = self.sm_ui.repoManagerCustomCmdEntry.get_text().strip()
if not command: return
self.run_run_custom_shell_command(command)
def on_repoManagerInstalledPackages_clicked(self, widget, categories = [], world = False):
def fake_callback_true(s):
return True
if world: categories = []
input_params = []
if not world:
input_params += [
('categories', _('Categories, space separated'), fake_callback_true, False),
]
data = {}
data['categories'] = categories
if input_params:
mydata = self.Entropy.input_box(
_('Insert categories (if you want)'),
input_params,
cancel_button = True
)
if mydata == None: return
data.update(mydata)
if not categories:
data['categories'] = data['categories'].split()
self.clear_data_store_and_view()
self.run_get_spm_categories_installed(data['categories'], world)
def on_repoManagerRunButton_clicked(self, widget):
command = self.sm_ui.repoManagerRunEntry.get_text().strip()
if not command: return
command = command.split()
cmd = command[0]
avail_cmds = self.Service.get_available_client_commands()
if cmd not in avail_cmds:
okDialog(self.window, _("Invalid Command"), title = _("Custom command Error"))
return
cmd_data = avail_cmds.get(cmd)
params = command[1:]
mandatory_cmds = []
for item in cmd_data['params']:
if item[3]: mandatory_cmds.append(item)
evalued_params = []
for param in params:
try:
evalued_params.append(eval(param))
except (NameError, SyntaxError):
evalued_params.append(param)
except TypeError:
pass
if len(evalued_params) < len(mandatory_cmds):
okDialog(self.window, _("Not enough parameters"), title = _("Custom command Error"))
return
with self.BufferLock:
try:
cmd_data['call'](*evalued_params)
except Exception as e:
okDialog(self.window, "%s: %s" % (_("Error executing call"), e,), title = _("Custom command Error"))
def on_repoManagerPauseQueueButton_toggled(self, widget):
with self.BufferLock:
try:
do_pause = not self.queue_pause
self.Service.Methods.pause_queue(do_pause)
self.queue_pause = do_pause
except Exception as e:
self.service_status_message(e)
return
def on_repoManagerQueueView_row_activated(self, treeview, path, column):
( model, iterator ) = treeview.get_selection().get_selected()
if model != None and iterator != None:
obj = model.get_value( iterator, 0 )
if obj:
self.load_queue_info_menu(obj)
def on_repoManagerOutputPauseButton_toggled(self, widget):
if not self.output_pause:
if isinstance(self.is_processing, dict):
try:
self.paused_queue_id = self.is_processing['queue_id']
except:
pass
else:
# back from pause, schedule refresh
gobject.idle_add(self.update_output_view, True,
self.paused_queue_id)
self.paused_queue_id = None
self.output_pause = not self.output_pause
def on_repoManagerQueueRefreshButton_clicked(self, widget):
self.Queue = {}
self.do_update_queue_view()
def on_repoManagerOutputCleanButton_clicked(self, widget):
self.Output = None
self.clear_console()
def on_repoManagerCleanQueue_clicked(self, widget):
clear_ids = set()
for item in self.QueueStore:
obj = item[0]
if obj['from'] not in ("processed", "errored"):
continue
clear_ids.add(obj['queue_id'])
if clear_ids: self.run_remove_queue_ids(clear_ids)
def on_repoManagerClose_clicked(self, *args, **kwargs):
self.QueueUpdater.kill()
self.OutputUpdater.kill()
self.PinboardUpdater.kill()
self.destroy()
def on_portageSync_clicked(self, widget):
self.run_sync_spm()
def on_removeAtom_clicked(self, widget, atoms = [], pretend = True, verbose = True, nocolor = True):
def fake_callback(s):
return s
def fake_bool_cb(s):
return True
def fake_true_callback(s):
return True
input_params = []
data = {}
data['atoms'] = atoms
data['pretend'] = pretend
data['verbose'] = verbose
data['nocolor'] = nocolor
if not atoms:
input_params.append(('atoms', _('Atoms, space separated'), fake_callback, False),)
input_params += [
('pretend', ('checkbox', _('Pretend'),), fake_bool_cb, pretend,),
('verbose', ('checkbox', _('Verbose'),), fake_bool_cb, verbose,),
('nocolor', ('checkbox', _('No color'),), fake_bool_cb, nocolor,),
]
mydata = self.Entropy.input_box(
_('Insert packages removal parameters'),
input_params,
cancel_button = True
)
if mydata == None: return
data.update(mydata)
if not atoms:
data['atoms'] = data['atoms'].split()
if data['atoms']:
self.run_spm_remove_atoms(data)
def on_compileAtom_clicked(self, widget, atoms = [], pretend = False, oneshot = False, verbose = True, nocolor = True, fetchonly = False, buildonly = False, nodeps = False, custom_use = '', ldflags = '', cflags = ''):
def fake_callback(s):
return s
def fake_bool_cb(s):
return True
def fake_true_callback(s):
return True
input_params = []
data = {}
data['atoms'] = atoms
data['pretend'] = pretend
data['oneshot'] = oneshot
data['verbose'] = verbose
data['nocolor'] = nocolor
data['fetchonly'] = fetchonly
data['buildonly'] = buildonly
data['nodeps'] = nodeps
data['custom_use'] = custom_use
data['ldflags'] = ldflags
data['cflags'] = cflags
if not atoms:
input_params.append(('atoms', _('Atoms, space separated'), fake_callback, False),)
input_params += [
('pretend', ('checkbox', _('Pretend'),), fake_bool_cb, pretend,),
('oneshot', ('checkbox', _('Oneshot'),), fake_bool_cb, oneshot,),
('verbose', ('checkbox', _('Verbose'),), fake_bool_cb, verbose,),
('nocolor', ('checkbox', _('No color'),), fake_bool_cb, nocolor,),
('fetchonly', ('checkbox', _('Fetch only'),), fake_bool_cb, fetchonly,),
('buildonly', ('checkbox', _('Build only'),), fake_bool_cb, buildonly,),
('nodeps', ('checkbox', _('No dependencies'),), fake_bool_cb, nodeps,),
('custom_use', _('Custom USE flags'), fake_true_callback, False),
('ldflags', _('Custom LDFLAGS'), fake_true_callback, False),
('cflags', _('Custom CFLAGS'), fake_true_callback, False),
]
mydata = self.Entropy.input_box(
_('Insert compilation parameters'),
input_params,
cancel_button = True
)
if mydata == None: return
data.update(mydata)
if not atoms:
data['atoms'] = data['atoms'].split()
if data['atoms']:
self.run_compile_atoms(data)
def on_repoManagerSpmInfo_clicked(self, widget):
self.run_spm_info()
def on_addUseAtom_clicked(self, widget, atoms = [], use = [], load_view = True, parallel = True):
data = self.handle_uses_for_atoms(atoms, use)
if data == None: return False
self.set_notebook_page(self.notebook_pages['data'])
if data['atoms'] and data['use']:
if parallel:
def do_add():
self.run_enable_uses_for_atoms(data['atoms'], data['use'], load_view)
return False
gobject.idle_add(do_add)
else:
return self.run_enable_uses_for_atoms(data['atoms'], data['use'], load_view)
def on_removeUseAtom_clicked(self, widget, atoms = [], use = [], load_view = True, parallel = True):
data = self.handle_uses_for_atoms(atoms, use)
if data == None: return False
self.set_notebook_page(self.notebook_pages['data'])
if data['atoms'] and data['use']:
if parallel:
def do_remove():
self.run_disable_uses_for_atoms(data['atoms'], data['use'], load_view)
return False
gobject.idle_add(do_remove)
else:
return self.run_disable_uses_for_atoms(data['atoms'], data['use'], load_view)
def on_repoManagerPkgInfo_clicked(self, widget, atoms = [], clear = True):
def fake_callback(s):
return s
input_params = []
data = {}
data['atoms'] = atoms
if not atoms:
input_params.append(('atoms', _('Atoms, space separated'), fake_callback, False),)
if input_params:
mydata = self.Entropy.input_box(
_('Insert Package Information parameters'),
input_params,
cancel_button = True
)
if mydata == None: return
data.update(mydata)
if not atoms:
data['atoms'] = data['atoms'].split()
if data['atoms']:
categories = []
for atom in data['atoms']:
categories.append(entropy.tools.dep_getkey(atom).split("/")[0])
if clear: self.clear_data_store_and_view()
self.run_get_spm_atoms_info(categories, data['atoms'], clear)
def on_repoManagerRemoveButton_clicked(self, widget):
model, myiter = self.QueueView.get_selection().get_selected()
if myiter:
obj = model.get_value( myiter, 0 )
if obj and (obj['from'] != "processing"):
self.run_remove_queue_ids([obj['queue_id']])
def on_repoManagerStopButton_clicked(self, widget):
model, myiter = self.QueueView.get_selection().get_selected()
if myiter:
obj = model.get_value( myiter, 0 )
if obj and (obj['from'] == "processing"):
self.run_kill_processing_queue_id(obj['queue_id'])
def on_repoManagerQueueGetOutputButton_clicked(self, widget, queue_id = None, myfrom = None):
def fake_callback_cb(s):
return True
model, myiter = self.QueueView.get_selection().get_selected()
if myiter:
obj = model.get_value( myiter, 0 )
if obj:
queue_id = obj['queue_id']
myfrom = obj['from']
if not queue_id: return
input_params = [
('full', ("checkbox", _('Full output'),), fake_callback_cb, False),
]
if myfrom == "processing":
input_params.append(('autorefresh', ("checkbox", _('Auto refresh'),), fake_callback_cb, True))
data = self.Entropy.input_box(
_('Insert output parameters'),
input_params,
cancel_button = True
)
if data == None: return
if 'autorefresh' in data:
if data['autorefresh']:
self.is_writing_output = True
self.is_processing = {'queue_id': queue_id}
self.set_notebook_page(self.notebook_pages['output'])
if data.get('full'):
gobject.idle_add(self.update_output_view, True, queue_id, 0)
else:
gobject.idle_add(self.update_output_view, True, queue_id)
def on_repoManagerPinboardRefreshButton_clicked(self, widget):
self.update_pinboard_view(force = True)
def on_repoManagerPinboardAddButton_clicked(self, widget):
def fake_callback(s):
return s
input_params = [
('note', _('Note'), fake_callback, False),
('extended_text', ("text", _('Extended note'),), fake_callback, False),
]
data = self.Entropy.input_box(
_('Insert your new pinboard item'),
input_params,
cancel_button = True
)
if data == None: return
self.run_add_to_pinboard(data['note'], data['extended_text'])
def collect_pinboard_view_iters(self):
model, paths = self.PinboardView.get_selection().get_selected_rows()
if not model:
return [], model
data = []
for path in paths:
myiter = model.get_iter(path)
data.append(myiter)
return data, model
def on_repoManagerPinboardRemoveButton_clicked(self, widget):
myiters, model = self.collect_pinboard_view_iters()
if model == None: return
remove_ids = []
for myiter in myiters:
obj = model.get_value( myiter, 0 )
if obj:
remove_ids.append(obj['pinboard_id'])
if remove_ids:
self.run_remove_from_pinboard(remove_ids)
def on_repoManagerPinboardDoneButton_clicked(self, widget):
self._set_pinboard_items_status(widget, True)
def on_repoManagerPinboardNotDoneButton_clicked(self, widget):
self._set_pinboard_items_status(widget, False)
def _set_pinboard_items_status(self, widget, status):
myiters, model = self.collect_pinboard_view_iters()
if model == None: return
done_ids = []
for myiter in myiters:
obj = model.get_value( myiter, 0 )
if obj:
done_ids.append(obj['pinboard_id'])
def set_pinboard_status(done_ids, status):
if done_ids:
with self.BufferLock:
try:
status, queue_id = self.Service.Methods.set_pinboard_items_done(done_ids, status)
except Exception as e:
self.service_status_message(e)
return
if status:
self.on_repoManagerPinboardRefreshButton_clicked(widget)
set_pinboard_status(done_ids, status)
def on_repoManagerPinboardView_row_activated(self, treeview, path, column):
model = treeview.get_model()
myiter = model.get_iter(path)
obj = model.get_value(myiter, 0)
if obj:
my = SmPinboardMenu(self.window)
my.load(obj.copy())
def on_repoManagerSecurityUpdatesButton_clicked(self, widget):
def fake_callback(s):
return s
input_params = [
('list_type', ('combo', (_('List type'), ['affected', 'new', 'all']),), fake_callback, False),
]
data = self.Entropy.input_box(
_('Choose what kind of list you want to see'),
input_params,
cancel_button = True
)
if data == None:
return
self.clear_data_store_and_view()
with self.BufferLock:
try:
status, queue_id = self.Service.Methods.get_spm_glsa_data(data['list_type'][1])
except Exception as e:
self.service_status_message(e)
return
def task(queue_id, data):
item = self.wait_queue_id_to_complete(queue_id)
if item == None:
return
data = None
try:
status, data = item['result']
except TypeError:
status = False
if not status:
return
gobject.idle_add(self.glsa_data_view, data)
if status:
t = ParallelTask(task, queue_id, data)
t.start()
else:
self.service_status_message(queue_id)
def on_repoManagerSwitchRepoButton_clicked(self, widget):
# get current combo iter
model = self.EntropyRepositoryStore
myiter = self.EntropyRepositoryCombo.get_active_iter()
repoid = model.get_value(myiter, 0)
if not repoid:
return
with self.BufferLock:
try:
status, queue_id = self.Service.Methods.set_default_repository(repoid)
except Exception as e:
self.service_status_message(e)
return
def task():
repo_info = self.get_available_repositories()
if repo_info:
gobject.idle_add(self.load_available_repositories,
repo_info)
if status:
t = ParallelTask(task)
t.start()
else:
self.service_status_message(queue_id)
def on_repoManagerAvailablePackagesButton_clicked(self, widget, repoid = None):
def fake_callback(s):
return s
data = {}
data['repoid'] = repoid
avail_repos = list(self.EntropyRepositories['available'].keys())
if not avail_repos: return
input_params = []
if not repoid:
input_params.append(('repoid', ('combo', (_('Repository'), avail_repos),), fake_callback, False))
if input_params:
mydata = self.Entropy.input_box(
_('Choose from which repository'),
input_params,
cancel_button = True
)
if mydata == None: return
mydata['repoid'] = mydata['repoid'][1]
data.update(mydata)
self.clear_data_store_and_view()
with self.BufferLock:
try:
status, repo_data = self.Service.Methods.get_available_entropy_packages(data['repoid'])
except Exception as e:
self.service_status_message(e)
return
def task(repo_data, data):
def reload_func():
self.on_repoManagerAvailablePackagesButton_clicked(widget,
repoid = data['repoid'])
gobject.idle_add(self.entropy_available_packages_data_view,
repo_data, data['repoid'], reload_func)
if status:
t = ParallelTask(task, repo_data, data)
t.start()
else:
self.service_status_message(repo_data)
def on_repoManagerPackageSearchButton_clicked(self, widget):
def fake_callback(s):
return s
avail_repos = list(self.EntropyRepositories['available'].keys())
if not avail_repos: return
search_reference = {
0: 'atom',
1: 'needed',
2: 'depends',
3: 'tag',
4: 'file',
5: 'description',
6: 'eclass',
}
search_types = [
_("Atom"), _("Needed Libraries"), _("Reverse dependencies"), _("Tag"), _("File"), _("Description"), _("Eclass")
]
input_params = [
('repoid', ('combo', (_('Repository'), avail_repos),), fake_callback, False),
('search_type', ('combo', (_('Search type'), search_types),), fake_callback, False),
('search_string', _('Search string'), fake_callback, False)
]
data = self.Entropy.input_box(
_('Entropy Search'),
input_params,
cancel_button = True
)
if data == None: return
data['search_type'] = search_reference.get(data['search_type'][0])
data['repoid'] = data['repoid'][1]
self.clear_data_store_and_view()
self.run_package_search(data['search_type'], data['search_string'], data['repoid'])
def on_repoManagerEntropyDbUpdatesButton_clicked(self, widget):
self.clear_data_store_and_view()
self.run_entropy_database_updates_scan()
def on_repoManagerDepTestButton_clicked(self, widget):
self.run_entropy_deptest()
def on_repoManagerLibTestButton_clicked(self, widget):
self.run_entropy_libtest()
def on_repoManagerSpmTreeupdatesButton_clicked(self, widget):
avail_repos = list(self.EntropyRepositories['available'].keys())
if not avail_repos: return
def fake_callback_cb(s):
return True
input_params = [
('repoid', ('combo', (_('Repository'), avail_repos),), fake_callback_cb, False),
]
data = self.Entropy.input_box(
_('Choose the repository'),
input_params,
cancel_button = True
)
if data == None: return
data['repoid'] = data['repoid'][1]
self.run_entropy_treeupdates(data['repoid'])
def on_repoManagerMirrorUpdatesButton_clicked(self, widget):
avail_repos = list(self.EntropyRepositories['available'].keys())
if not avail_repos: return
def fake_callback_cb(s):
return True
input_params = []
for repo in avail_repos:
input_params.append((repo, ('checkbox', "%s: %s" % (_('Repository'), repo,),), fake_callback_cb, False))
data = self.Entropy.input_box(
_('Choose the repositories you want to scan'),
input_params,
cancel_button = True
)
if data == None: return
repos = []
for key in data:
if data[key]:
repos.append(key)
if not repos: return
self.clear_data_store_and_view()
self.run_entropy_mirror_updates(repos)
def on_repoManagerChecksumTestButton_clicked(self, widget):
avail_repos = list(self.EntropyRepositories['available'].keys())
if not avail_repos: return
def fake_callback(s):
return s
input_params = [
('repoid', ('combo', (_('Repository'), avail_repos),), fake_callback, False),
('mode', ('combo', (_('Choose mode'), [_("Server check"), _("Mirrors check")]),), fake_callback, False),
]
data = self.Entropy.input_box(
_('Choose what kind of test you would like to run'),
input_params,
cancel_button = True
)
if data == None: return
if data['mode'][0] == 0:
mode = "local"
else:
mode = "remote"
data['repoid'] = data['repoid'][1]
self.run_entropy_checksum_test(data['repoid'], mode)
def on_repoManagerStdinExecButton_clicked(self, widget):
self.sm_ui.repoManagerStdinEntry.activate()
def on_repoManagerStdinEntry_activate(self, widget, write_to_stdout = True, txt = ''):
if not self.is_processing: return
try: queue_id = self.is_processing.get('queue_id')
except: return
if not txt:
txt = self.sm_ui.repoManagerStdinEntry.get_text()
if not txt: return
self.sm_ui.repoManagerStdinEntry.set_text('')
self.run_write_to_running_command_pipe(queue_id, write_to_stdout, txt)
def on_repoManagerNoticeBoardButton_clicked(self, widget, repoid = None):
avail_repos = list(self.EntropyRepositories['available'].keys())
if not avail_repos: return
def fake_callback(s):
return s
input_params = []
if not repoid:
input_params += [
('repoid', ('combo', (_('Repository'), avail_repos),), fake_callback, False),
]
if input_params:
data = self.Entropy.input_box(
_('Choose what notice board you want to see'),
input_params,
cancel_button = True
)
if data == None: return
repoid = data['repoid'][1]
if repoid in avail_repos:
self.run_get_notice_board(repoid)
def destroy(self):
self.sm_ui.repositoryManager.destroy()
class SmPinboardMenu(MenuSkel):
def __init__(self, window):
self.window = window
self.sm_ui = UI( const.GLADE_FILE, 'smPinboardInfo', 'entropy' )
self.sm_ui.signal_autoconnect(self._getAllMethods())
self.sm_ui.smPinboardInfo.set_transient_for(self.window)
self.sm_ui.smPinboardInfo.add_events(gtk.gdk.BUTTON_PRESS_MASK)
def on_smPinboardCloseButton_clicked(self, widget):
self.sm_ui.smPinboardInfo.hide()
def destroy(self):
self.sm_ui.smPinboardInfo.destroy()
def load(self, item):
na = _("N/A")
self.sm_ui.smPinboardId.set_text(item['pinboard_id'])
self.sm_ui.smPinboardDate.set_text(item['ts'])
self.sm_ui.smPinboardDone.set_text(item['done'])
self.sm_ui.smPinboardNote.set_text(item['note'])
mybuffer = gtk.TextBuffer()
mybuffer.set_text(item['extended_text'])
self.sm_ui.smPinboardExtendedNote.set_buffer(mybuffer)
bold_items = [
self.sm_ui.smPinboardIdLabel,
self.sm_ui.smPinboardDateLabel,
self.sm_ui.smPinboardDoneLabel,
self.sm_ui.smPinboardNoteLabel,
self.sm_ui.smPinboardExtendedNoteLabel
]
small_items = [
self.sm_ui.smPinboardId,
self.sm_ui.smPinboardDate,
self.sm_ui.smPinboardDone,
self.sm_ui.smPinboardNote,
]
for item in bold_items:
t = item.get_text()
item.set_markup("<small><b>%s</b></small>" % (t,))
for item in small_items:
t = item.get_text()
item.set_markup("<small>%s</small>" % (t,))
self.sm_ui.smPinboardInfo.show_all()
class SmQueueMenu(MenuSkel):
def __init__(self, window):
self.window = window
self.sm_ui = UI( const.GLADE_FILE, 'smQueueInfo', 'entropy' )
self.sm_ui.signal_autoconnect(self._getAllMethods())
self.sm_ui.smQueueInfo.set_transient_for(self.window)
self.sm_ui.smQueueInfo.add_events(gtk.gdk.BUTTON_PRESS_MASK)
def on_smQueueCloseButton_clicked(self, widget):
self.sm_ui.smQueueInfo.hide()
def destroy(self):
self.sm_ui.smQueueInfo.destroy()
def load(self, item):
na = _("N/A")
self.sm_ui.smQueueIdL.set_text(item['queue_id'])
self.sm_ui.smCommandNameL.set_text(item['command_name'])
self.sm_ui.smCommandDescL.set_text(item['command_desc'])
args = "None"
if isinstance(item['args'], list):
args = ' '.join([x for x in item['args']])
self.sm_ui.smCommandArgsL.set_text(args)
self.sm_ui.smCallL.set_text(item['call'])
self.sm_ui.smUserGroupL.set_text("%s / %s " % (item.get('user_id'), item.get('group_id'),))
self.sm_ui.smQueuedAtL.set_text(item['queue_ts'])
self.sm_ui.smProcessingAtL.set_text(item.get('processing_ts'))
self.sm_ui.smCompletedAtL.set_text(item.get('completed_ts'))
self.sm_ui.smErroredAtL.set_text(item.get('errored_ts'))
self.sm_ui.smStdoutFileL.set_text(item['stdout'])
self.sm_ui.smProcessResultL.set_text(item.get('result', ''))
bold_items = [
self.sm_ui.smQueueIdLabel,
self.sm_ui.smCommandNameLabel,
self.sm_ui.smCommandDescLabel,
self.sm_ui.smCommandArgsLabel,
self.sm_ui.smCallLabel,
self.sm_ui.smUserGroupLabel,
self.sm_ui.smQueuedAtLabel,
self.sm_ui.smProcessingAtLabel,
self.sm_ui.smCompletedAtLabel,
self.sm_ui.smErroredAtLabel,
self.sm_ui.smStdoutFileLabel,
self.sm_ui.smProcessResultLabel
]
small_items = [
self.sm_ui.smQueueIdL,
self.sm_ui.smCommandNameL,
self.sm_ui.smCommandDescL,
self.sm_ui.smCommandArgsL,
self.sm_ui.smCallL,
self.sm_ui.smUserGroupL,
self.sm_ui.smQueuedAtL,
self.sm_ui.smProcessingAtL,
self.sm_ui.smCompletedAtL,
self.sm_ui.smErroredAtL,
self.sm_ui.smStdoutFileL,
self.sm_ui.smProcessResultL
]
for item in bold_items:
t = item.get_text()
item.set_markup("<small><b>%s</b></small>" % (t,))
for item in small_items:
t = item.get_text()
item.set_markup("<small>%s</small>" % (t,))
self.sm_ui.smQueueInfo.show_all()