616adf9432
git-svn-id: http://svn.sabayonlinux.org/projects/entropy/trunk@373 cd1c1023-2f26-0410-ae45-c471fc1f0318
616 lines
22 KiB
Python
616 lines
22 KiB
Python
#!/usr/bin/python -tt
|
|
# -*- coding: iso-8859-1 -*-
|
|
# Yum Exteder (yumex) - A GUI for yum
|
|
# Copyright (C) 2006 Tim Lauridsen < tim<AT>yum-extender<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 gtk
|
|
import gobject
|
|
import logging
|
|
import glob
|
|
import sys,os
|
|
import ConfigParser
|
|
|
|
from i18n import _
|
|
|
|
|
|
class YumexCategoryView:
|
|
def __init__( self, treeview):
|
|
self.view = treeview
|
|
self.model = self.setup_view()
|
|
|
|
def setup_view( self ):
|
|
""" Setup Category View """
|
|
model = gtk.TreeStore( gobject.TYPE_STRING,gobject.TYPE_STRING )
|
|
self.view.set_model( model )
|
|
cell1 = gtk.CellRendererText()
|
|
column1= gtk.TreeViewColumn( _( "Categories" ), cell1, markup=0 )
|
|
column1.set_resizable( True )
|
|
column1.set_sizing( gtk.TREE_VIEW_COLUMN_FIXED )
|
|
column1.set_fixed_width( 150 )
|
|
|
|
self.view.append_column( column1 )
|
|
self.view.set_headers_visible(False)
|
|
return model
|
|
|
|
def populate(self,data,tree=False):
|
|
self.model.clear()
|
|
if tree:
|
|
keys = data.keys()
|
|
keys.sort()
|
|
for key in keys:
|
|
lst = data[key]
|
|
lst.sort()
|
|
keyroot = self.model.append(None,[key,''])
|
|
for el in lst:
|
|
full = '%s/%s' % (key,el)
|
|
self.model.append(keyroot,[el,full])
|
|
else:
|
|
for el in data:
|
|
self.model.append(None,[el,el])
|
|
|
|
|
|
class YumexPackageView:
|
|
def __init__( self, treeview,qview ):
|
|
self.view = treeview
|
|
self.headers = [_( "Package" ), _( "Ver" ), _( "Summary" ), _( "Repo" ), _( "Architecture" ), _( "Size" )]
|
|
self.store = self.setupView()
|
|
self.queue = qview.queue
|
|
self.queueView = qview
|
|
|
|
def setupView( self ):
|
|
store = gtk.ListStore( gobject.TYPE_PYOBJECT,str)
|
|
self.view.set_model( store )
|
|
# Setup selection column
|
|
cell1 = gtk.CellRendererToggle() # Selection
|
|
cell1.set_property( 'activatable', True )
|
|
column1 = gtk.TreeViewColumn( "", cell1 )
|
|
column1.set_cell_data_func( cell1, self.get_data_bool, 'selected' )
|
|
column1.set_sizing( gtk.TREE_VIEW_COLUMN_FIXED )
|
|
column1.set_fixed_width( 20 )
|
|
column1.set_sort_column_id( -1 )
|
|
self.view.append_column( column1 )
|
|
cell1.connect( "toggled", self.on_toggled )
|
|
column1.set_clickable( True )
|
|
# Setup resent column
|
|
cell2 = gtk.CellRendererPixbuf() # new
|
|
cell2.set_property( 'stock-id', gtk.STOCK_ADD )
|
|
column2 = gtk.TreeViewColumn( "", cell2 )
|
|
column2.set_cell_data_func( cell2, self.new_pixbuf )
|
|
column2.set_sizing( gtk.TREE_VIEW_COLUMN_FIXED )
|
|
column2.set_fixed_width( 20 )
|
|
column2.set_sort_column_id( -1 )
|
|
self.view.append_column( column2 )
|
|
column2.set_clickable( True )
|
|
|
|
self.create_text_column( _( "Package" ), 'name' , size=240)
|
|
self.create_text_column( _( "Arch." ), 'arch' , size = 50 )
|
|
self.create_text_column( _( "Ver." ), 'ver', size = 100 )
|
|
self.create_text_column( _( "Summary" ), 'summaryFirst', size=400 )
|
|
self.create_text_column( _( "Repo." ), 'repoid' , size=100 )
|
|
self.create_text_column( _( "Size." ), 'sizeFmt' , size=100 )
|
|
self.view.set_search_column( 1 )
|
|
self.view.set_enable_search(True)
|
|
#store.set_sort_column_id(1, gtk.SORT_ASCENDING)
|
|
self.view.set_reorderable( False )
|
|
return store
|
|
|
|
def create_text_column( self, hdr, property, size,sortcol = None):
|
|
"""
|
|
Create a TreeViewColumn with text and set
|
|
the sorting properties and add it to the view
|
|
"""
|
|
cell = gtk.CellRendererText() # Size Column
|
|
column = gtk.TreeViewColumn( hdr, cell )
|
|
column.set_resizable( True )
|
|
column.set_cell_data_func( cell, self.get_data_text, property )
|
|
column.set_sizing( gtk.TREE_VIEW_COLUMN_FIXED )
|
|
column.set_fixed_width( size )
|
|
column.set_sort_column_id( -1 )
|
|
self.view.append_column( column )
|
|
return column
|
|
|
|
def get_data_text( self, column, cell, model, iter,property ):
|
|
obj = model.get_value( iter, 0 )
|
|
if obj:
|
|
try:
|
|
cell.set_property( 'text', getattr( obj, property ) )
|
|
cell.set_property('foreground',obj.color)
|
|
except:
|
|
# FIXME: Ugly Hack, find a better way
|
|
# This should catch
|
|
# sqlite3.ProgrammingError:
|
|
# SqLite objects created in a thread can only be used in
|
|
# that same thread.
|
|
# This occurs sometimes because the view updates are
|
|
# triggered by the gtk event processor running in a thread
|
|
# It should not break something, because we are only reading.
|
|
pass
|
|
|
|
def get_data_bool( self, column, cell, model, iter, property ):
|
|
obj = model.get_value( iter, 0 )
|
|
cell.set_property( "visible", True )
|
|
if obj:
|
|
cell.set_property( "active", getattr( obj, property ) )
|
|
|
|
def on_toggled( self, widget, path ):
|
|
""" Package selection handler """
|
|
iter = self.store.get_iter( path )
|
|
obj = self.store.get_value( iter, 0 )
|
|
self.togglePackage(obj)
|
|
self.queueView.refresh()
|
|
|
|
def togglePackage(self,obj):
|
|
if obj.queued == obj.action:
|
|
obj.queued = None
|
|
self.queue.remove(obj)
|
|
else:
|
|
obj.queued = obj.action
|
|
self.queue.add(obj)
|
|
obj.set_select( not obj.selected )
|
|
|
|
|
|
def selectAll(self):
|
|
for el in self.store:
|
|
obj = el[0]
|
|
if not obj.queued == obj.action:
|
|
obj.queued = obj.action
|
|
self.queue.add(obj)
|
|
obj.set_select( not obj.selected )
|
|
self.queueView.refresh()
|
|
self.view.queue_draw()
|
|
|
|
def deselectAll(self):
|
|
for el in self.store:
|
|
obj = el[0]
|
|
if obj.queued == obj.action:
|
|
obj.queued = None
|
|
self.queue.remove(obj)
|
|
obj.set_select( not obj.selected )
|
|
self.queueView.refresh()
|
|
self.view.queue_draw()
|
|
|
|
def new_pixbuf( self, column, cell, model, iter ):
|
|
"""
|
|
Cell Data function for recent Column, shows pixmap
|
|
if recent Value is True.
|
|
"""
|
|
pkg = model.get_value( iter, 0 )
|
|
if pkg:
|
|
action = pkg.queued
|
|
if action:
|
|
if action in ( 'u', 'i' ):
|
|
icon = 'network-server'
|
|
else:
|
|
icon = 'edit-delete'
|
|
cell.set_property( 'visible', True )
|
|
cell.set_property( 'icon-name', icon )
|
|
else:
|
|
cell.set_property( 'visible', pkg.recent )
|
|
cell.set_property( 'icon-name', 'document-new' )
|
|
else:
|
|
cell.set_property( 'visible', False )
|
|
|
|
|
|
def get_selected( self, package=True ):
|
|
""" Get selected packages in current packageList """
|
|
selected = []
|
|
for row in self.store:
|
|
col = row[0]
|
|
#print col,len(col)
|
|
if col:
|
|
pkg = row[0][0]
|
|
#print pkg
|
|
if pkg.selected:
|
|
selected.append( pkg )
|
|
return selected
|
|
|
|
|
|
class YumexQueueView:
|
|
""" Queue View Class"""
|
|
def __init__( self, widget,queue ):
|
|
self.view = widget
|
|
self.model = self.setup_view()
|
|
self.queue = queue
|
|
|
|
def setup_view( self ):
|
|
""" Create Notebook list for single page """
|
|
model = gtk.TreeStore( gobject.TYPE_STRING, gobject.TYPE_STRING )
|
|
self.view.set_model( model )
|
|
cell1 = gtk.CellRendererText()
|
|
column1= gtk.TreeViewColumn( _( "Packages" ), cell1, markup=0 )
|
|
column1.set_resizable( True )
|
|
self.view.append_column( column1 )
|
|
|
|
cell2 = gtk.CellRendererText()
|
|
column2= gtk.TreeViewColumn( _( "Summary" ), cell2, text=1 )
|
|
column2.set_resizable( True )
|
|
self.view.append_column( column2 )
|
|
model.set_sort_column_id( 0, gtk.SORT_ASCENDING )
|
|
self.view.get_selection().set_mode( gtk.SELECTION_MULTIPLE )
|
|
return model
|
|
|
|
def deleteSelected( self ):
|
|
rmvlist = []
|
|
model, paths = self.view.get_selection().get_selected_rows()
|
|
for p in paths:
|
|
row = model[p]
|
|
if row.parent != None:
|
|
rmvlist.append( row[0] )
|
|
for pkg in self.getPkgsFromList( rmvlist ):
|
|
pkg.queued = None
|
|
pkg.set_select( not pkg.selected )
|
|
f = lambda x: str( x ) not in rmvlist
|
|
for action in ['u', 'i', 'r']:
|
|
list = self.queue.get(action)
|
|
if list:
|
|
self.queue.packages[action] = filter( f, list )
|
|
self.refresh()
|
|
|
|
|
|
def getPkgsFromList( self, rlist ):
|
|
rclist = []
|
|
f = lambda x: str( x ) in rlist
|
|
for action in ['u', 'i', 'r']:
|
|
list = self.queue.packages[action]
|
|
if list:
|
|
rclist += filter( f, list )
|
|
return rclist
|
|
|
|
def refresh ( self ):
|
|
""" Populate view with data from queue """
|
|
self.model.clear()
|
|
label = _( "<b>Packages To Update</b>" )
|
|
list = self.queue.packages['u']
|
|
if len( list ) > 0:
|
|
self.populate_list( label, list )
|
|
label = _( "<b>Packages To Install</b>" )
|
|
list = self.queue.packages['i']
|
|
if len( list ) > 0:
|
|
self.populate_list( label, list )
|
|
label = _( "<b>Packages To Remove</b>" )
|
|
list = self.queue.packages['r']
|
|
if len( list ) > 0:
|
|
self.populate_list( label, list )
|
|
self.view.expand_all()
|
|
|
|
def populate_list( self, label, list ):
|
|
parent = self.model.append( None, [label, ""] )
|
|
for pkg in list:
|
|
self.model.append( parent, [str( pkg ), pkg.summaryFirst] )
|
|
|
|
class YumexGroupsCategoryView:
|
|
def __init__( self, treeview):
|
|
self.view = treeview
|
|
self.model = self.setup_view()
|
|
|
|
def setup_view( self ):
|
|
""" Setup Category View """
|
|
model = gtk.ListStore( gobject.TYPE_STRING,gobject.TYPE_STRING)
|
|
self.view.set_model( model )
|
|
cell1 = gtk.CellRendererText()
|
|
column1= gtk.TreeViewColumn( _( "Categories" ), cell1, markup=0 )
|
|
column1.set_resizable( True )
|
|
column1.set_sizing( gtk.TREE_VIEW_COLUMN_FIXED )
|
|
column1.set_fixed_width( 150 )
|
|
|
|
self.view.append_column( column1 )
|
|
self.view.set_headers_visible(False)
|
|
return model
|
|
|
|
def populate(self,data):
|
|
self.model.clear()
|
|
for el in data:
|
|
name,id = el
|
|
self.model.append([name,id])
|
|
|
|
class YumexGroupsView:
|
|
def __init__( self, treeview,qview):
|
|
self.view = treeview
|
|
self.model = self.setup_view()
|
|
self.queue = qview.queue
|
|
self.queueView = qview
|
|
self.yumbase = None # it will se set later
|
|
|
|
def setup_view( self ):
|
|
""" Setup Group View """
|
|
model = gtk.ListStore(gobject.TYPE_BOOLEAN, # Installed
|
|
gobject.TYPE_STRING, # Group Name
|
|
gobject.TYPE_STRING, # Group Id
|
|
gobject.TYPE_BOOLEAN) # In queue
|
|
|
|
self.view.set_model( model )
|
|
# Setup selection column
|
|
|
|
cell1 = gtk.CellRendererToggle() # Selection
|
|
cell1.set_property( 'activatable', True )
|
|
column1 = gtk.TreeViewColumn( "", cell1)
|
|
column1.add_attribute( cell1, "active", 0 )
|
|
column1.set_sizing( gtk.TREE_VIEW_COLUMN_FIXED )
|
|
column1.set_fixed_width( 20 )
|
|
column1.set_sort_column_id( -1 )
|
|
self.view.append_column( column1 )
|
|
cell1.connect( "toggled", self.on_toggled )
|
|
|
|
cell2 = gtk.CellRendererPixbuf() # Queue Status
|
|
column2 = gtk.TreeViewColumn( "", cell2 )
|
|
column2.set_cell_data_func( cell2, self.new_pixbuf )
|
|
column2.set_sizing( gtk.TREE_VIEW_COLUMN_FIXED )
|
|
column2.set_fixed_width( 20 )
|
|
column2.set_sort_column_id( -1 )
|
|
self.view.append_column( column2 )
|
|
|
|
cell3 = gtk.CellRendererText()
|
|
column3= gtk.TreeViewColumn( _( "Groups" ), cell3, markup=1 )
|
|
column3.set_resizable( True )
|
|
column3.set_sizing( gtk.TREE_VIEW_COLUMN_FIXED )
|
|
column3.set_fixed_width( 150 )
|
|
|
|
self.view.append_column( column3 )
|
|
self.view.set_headers_visible(False)
|
|
return model
|
|
|
|
def on_toggled( self, widget, path ):
|
|
""" Group selection handler """
|
|
iter = self.model.get_iter( path )
|
|
grpid = self.model.get_value( iter, 2 )
|
|
inst = self.model.get_value( iter, 0 )
|
|
action = self.queue.hasGroup(grpid)
|
|
if action:
|
|
self.queue.removeGroup(grpid,action)
|
|
self._updatePackages(grpid,False,None)
|
|
self.model.set_value( iter, 3,False )
|
|
else:
|
|
if inst:
|
|
self.queue.addGroup(grpid,'r') # Add for remove
|
|
self._updatePackages(grpid,True,'r')
|
|
else:
|
|
self.queue.addGroup(grpid,'i') # Add for install
|
|
self._updatePackages(grpid,True,'i')
|
|
self.model.set_value( iter, 3,True )
|
|
self.model.set_value( iter, 0, not inst )
|
|
|
|
|
|
def _updatePackages(self,id,add,action):
|
|
grp = self.yumbase.comps.return_group(id)
|
|
pkgs = self.yumbase.getByGroup(grp,['m','d'])
|
|
# Add group packages to queue
|
|
if add:
|
|
for po in pkgs:
|
|
if not po.queued:
|
|
if action == 'i' and po.available : # Install
|
|
po.queued = po.action
|
|
self.queue.add(po)
|
|
po.set_select( True )
|
|
elif action == 'r' and not po.available: # Remove
|
|
po.queued = po.action
|
|
self.queue.add(po)
|
|
po.set_select( False )
|
|
# Remove group packages from queue
|
|
else:
|
|
for po in pkgs:
|
|
if po.queued:
|
|
po.queued = None
|
|
self.queue.remove(po)
|
|
po.set_select( not po.selected )
|
|
self.queueView.refresh()
|
|
|
|
def populate(self,data):
|
|
self.model.clear()
|
|
for el in data:
|
|
name,id,inst = el
|
|
self.model.append([inst,name,id,False])
|
|
|
|
|
|
def new_pixbuf( self, column, cell, model, iter ):
|
|
"""
|
|
Cell Data function for recent Column, shows pixmap
|
|
if recent Value is True.
|
|
"""
|
|
grpid = model.get_value( iter, 2 )
|
|
queued = model.get_value( iter, 3 )
|
|
action = self.queue.hasGroup(grpid)
|
|
if action:
|
|
if action == 'i':
|
|
icon = gtk.STOCK_APPLY
|
|
else:
|
|
icon = gtk.STOCK_CANCEL
|
|
cell.set_property( 'visible', True )
|
|
cell.set_property( 'stock-id', icon )
|
|
cell.set_property( 'visible', queued )
|
|
|
|
class YumexRepoView:
|
|
"""
|
|
This class controls the repo TreeView
|
|
"""
|
|
def __init__( self, widget):
|
|
self.view = widget
|
|
self.headers = [_('Repository'),_('Filename')]
|
|
self.store = self.setup_view()
|
|
|
|
|
|
def on_toggled( self, widget, path):
|
|
""" Repo select/unselect handler """
|
|
iter = self.store.get_iter( path )
|
|
state = self.store.get_value(iter,0)
|
|
self.store.set_value(iter,0, not state)
|
|
|
|
def setup_view( self ):
|
|
""" Create models and columns for the Repo TextView """
|
|
store = gtk.ListStore( 'gboolean', gobject.TYPE_STRING,gobject.TYPE_STRING,'gboolean')
|
|
self.view.set_model( store )
|
|
# Setup Selection Column
|
|
cell1 = gtk.CellRendererToggle() # Selection
|
|
cell1.set_property( 'activatable', True )
|
|
column1 = gtk.TreeViewColumn( " ", cell1 )
|
|
column1.add_attribute( cell1, "active", 0 )
|
|
column1.set_resizable( True )
|
|
column1.set_sort_column_id( -1 )
|
|
self.view.append_column( column1 )
|
|
cell1.connect( "toggled", self.on_toggled )
|
|
# Setup resent column
|
|
cell2 = gtk.CellRendererPixbuf() # gpgcheck
|
|
cell2.set_property( 'stock-id', gtk.STOCK_DIALOG_AUTHENTICATION )
|
|
column2 = gtk.TreeViewColumn( "", cell2 )
|
|
column2.set_cell_data_func( cell2, self.new_pixbuf )
|
|
column2.set_sizing( gtk.TREE_VIEW_COLUMN_FIXED )
|
|
column2.set_fixed_width( 20 )
|
|
column2.set_sort_column_id( -1 )
|
|
self.view.append_column( column2 )
|
|
column2.set_clickable( True )
|
|
|
|
# Setup reponame & repofile column's
|
|
self.create_text_column( _('Repository'),1 )
|
|
self.create_text_column( _('Name'),2 )
|
|
self.view.set_search_column( 1 )
|
|
self.view.set_reorderable( False )
|
|
return store
|
|
|
|
def create_text_column( self, hdr,colno):
|
|
cell = gtk.CellRendererText() # Size Column
|
|
column = gtk.TreeViewColumn( hdr, cell, text=colno )
|
|
column.set_resizable( True )
|
|
self.view.append_column( column )
|
|
|
|
def populate( self, data ):
|
|
""" Populate a repo liststore with data """
|
|
self.store.clear()
|
|
for state,id,name,gpg in data:
|
|
self.store.append([state,id,name,gpg])
|
|
|
|
def new_pixbuf( self, column, cell, model, iter ):
|
|
gpg = model.get_value( iter, 3 )
|
|
if gpg:
|
|
cell.set_property( 'visible', True )
|
|
else:
|
|
cell.set_property( 'visible',False)
|
|
|
|
def get_selected( self ):
|
|
selected = []
|
|
for elem in self.store:
|
|
state = elem[0]
|
|
name = elem[1]
|
|
if state:
|
|
selected.append( name )
|
|
return selected
|
|
|
|
def get_notselected( self ):
|
|
notselected = []
|
|
for elem in self.store:
|
|
state = elem[0]
|
|
name = elem[1]
|
|
if not state:
|
|
notselected.append( name )
|
|
return notselected
|
|
|
|
def deselect_all( self ):
|
|
iterator = self.store.get_iter_first()
|
|
while iterator != None:
|
|
self.store.set_value( iterator, 0, False )
|
|
iterator = self.store.iter_next( iterator )
|
|
|
|
def select_all( self ):
|
|
iterator = self.store.get_iter_first()
|
|
while iterator != None:
|
|
self.store.set_value( iterator, 0, True )
|
|
iterator = self.store.iter_next( iterator )
|
|
|
|
|
|
def select_by_keys( self, keys):
|
|
self.store
|
|
iterator = self.store.get_iter_first()
|
|
while iterator != None:
|
|
repoid = self.store.get_value( iterator, 1 )
|
|
if repoid in keys:
|
|
self.store.set_value( iterator, 0, True )
|
|
else:
|
|
self.store.set_value( iterator, 0, False)
|
|
iterator = self.store.iter_next( iterator )
|
|
|
|
class YumexPluginView:
|
|
def __init__( self, widget ):
|
|
self.view = widget
|
|
self.model = self.setup_view()
|
|
self.plugins = self.load()
|
|
self.populate_view()
|
|
|
|
def on_toggled( self, cell, path, model ):
|
|
#print path
|
|
newstate = not model[path][0]
|
|
model[path][0] = newstate
|
|
conf = model[path][2]
|
|
if newstate:
|
|
val = '1'
|
|
else:
|
|
val = '0'
|
|
conf.set( 'main', 'enabled', val )
|
|
return
|
|
|
|
def setup_view( self ):
|
|
""" Create Notebook list for single page """
|
|
model = gtk.ListStore( 'gboolean', gobject.TYPE_STRING, gobject.TYPE_PYOBJECT )
|
|
self.view.set_model( model )
|
|
# Setup Selection Column
|
|
cell1 = gtk.CellRendererToggle() # Selection
|
|
cell1.set_property( 'activatable', True )
|
|
column1 = gtk.TreeViewColumn( " ", cell1 )
|
|
column1.add_attribute( cell1, "active", 0 )
|
|
column1.set_resizable( True )
|
|
self.view.append_column( column1 )
|
|
cell1.connect( "toggled", self.on_toggled, model )
|
|
cell2 = gtk.CellRendererText()
|
|
column2= gtk.TreeViewColumn( _( "Plugin" ), cell2, text=1 )
|
|
column2.set_resizable( True )
|
|
self.view.append_column( column2 )
|
|
return model
|
|
|
|
def populate_view( self ):
|
|
self.model.clear()
|
|
keys = self.plugins.keys()
|
|
for key in keys:
|
|
conf = self.plugins[key]
|
|
state = conf.get( 'main', 'enabled' ) == '1'
|
|
el = [state, key, conf]
|
|
self.model.append( el )
|
|
|
|
def dump( self ):
|
|
for row in self.model:
|
|
print "--> %s is %s" % ( row[1], row[0] )
|
|
|
|
def load( self ):
|
|
""" Create a dict with parsers to available plugings"""
|
|
dict = {}
|
|
for modulefile in glob.glob( '/etc/yum/pluginconf.d/*.conf' ):
|
|
#print "Loading : %s" % modulefile
|
|
dir, modname = os.path.split( modulefile )
|
|
modname = modname.split( '.conf' )[0]
|
|
try:
|
|
parser = ConfigParser.ConfigParser()
|
|
parser.read( modulefile )
|
|
dict[modname] = parser
|
|
except:
|
|
print "Error loading : %s" % modulefile
|
|
|
|
return dict
|
|
|
|
|
|
def save( self ):
|
|
""" Write plugins configs back to disk """
|
|
for row in self.model:
|
|
fp = open( "/etc/yum/pluginconf.d/%s.conf" % row[1], "wt" )
|
|
row[2].write( fp )
|
|
fp.close()
|