import pygtk import gtk import gtk.glade import gnomevfs import threading import time import zipfile import re import shutil import os.path import gettext import locale import sys import net.Lliurex.JClic import net.Lliurex.JClic.Settings import net.Lliurex.Setup import net.Lliurex.Base import net.Lliurex.Desktop import net.Lliurex.Moodle import dbus __version__ = "1.5.5" print __version__ locale.textdomain("lliurex-recursos") gettext.textdomain("lliurex-recursos") _=gettext.gettext pygtk.require('2.0') sys.setrecursionlimit(2048) def mkdirp(path): dirs = path.split(os.sep) root="" for dir in dirs: root = root + dir + os.sep if not os.path.exists(root): print "Creating dir: ", root """ Graph """ class Node: def __init__(self,name,path): self.name=name self.path=path self.children=[] class File: def __init__(self,name,path): self.name=name self.path=path class Pool: def __init__(self,name,path): self.name=name self.path=path class Core(net.Lliurex.Base.Base): #resource_path = ["/usr/share/recursos","/usr/share/icons/Crux"] Resources = [] target_path = os.environ["HOME"] + os.sep+ "lliurex-recursos" global_conf = "/etc/lliurex-recursos/lliurex-recursos.conf" def __init__(self): gtk.gdk.threads_init() self.load_pool_config() if len(Core.Resources)==0: self.info("No resource pools configured") exit(0) print "Target path: ",self.target_path if not os.path.exists(self.target_path): self.info("target path not found, creating resource directory") os.mkdir(self.target_path) #properties self.refresh_request = False self.quit_request = False self.jclics = [] self.cache_icons = [] self.all_icons = gtk.icon_theme_get_default().list_icons() self.icon_default = self.load_icon("gnome-package") self.icon_jclic = gtk.gdk.pixbuf_new_from_file("/usr/share/pixmaps/lliurex-recursos/jclic.png") self.icon_scorm = gtk.gdk.pixbuf_new_from_file("/usr/share/pixmaps/lliurex-recursos/scorm.png") self.register_stock_icons() #pool directory graph self.pool_tree= [] self.install_cache=[] self.remove_cache=[] self.desktops_cache=[] #UI designer file self.uiTree = gtk.glade.XML("/usr/share/lliurex-recursos/glade/ui.glade") self.questionTree = gtk.glade.XML("/usr/share/lliurex-recursos/glade/dlgQuestion.glade") self.aboutTree = gtk.glade.XML("/usr/share/lliurex-recursos/glade/dlgAbout.glade") self.dlgQuestion = self.questionTree.get_widget("dlgQuestion") self.dlg_lblMessage = self.questionTree.get_widget("lblMessage") self.dlgAbout = self.aboutTree.get_widget("dlgAbout") self.winMain=self.uiTree.get_widget("winMain") self.winMain.connect("delete_event",self.OnWinMainDelete) self.winMain.set_title(_("Lliurex Resource Manager")) self.barProgress = self.uiTree.get_widget("barProgress") self.treePackets = self.uiTree.get_widget("treePackets") self.btnInstall = self.uiTree.get_widget("btnInstall") self.btnInstall.set_label("lx-install") self.btnInstall.connect("clicked",self.OnBtnInstallClick) self.btnRemove = self.uiTree.get_widget("btnRemove") self.btnRemove.connect("clicked",self.OnBtnRemoveClick) self.btnRemove.set_label("lx-remove") self.btnRefresh = self.uiTree.get_widget("btnRefresh") self.btnRefresh.connect("clicked",self.OnBtnRefreshClick) self.btnSetup = self.uiTree.get_widget("btnSetup") self.btnSetup.connect("clicked",self.OnBtnSetupClick) self.btnExport = self.uiTree.get_widget("btnExport") self.btnExport.set_label("lx-export") self.btnExport.connect("clicked",self.OnBtnExportClick) self.imgitemAbout = self.uiTree.get_widget("imgitemAbout") self.imgitemAbout.connect("activate",self.OnAboutClick) self.imgitemQuit = self.uiTree.get_widget("imgitemQuit") self.imgitemQuit.connect("activate",self.OnImgItemQuitActivate) #toggle,pixbuf, name, status, status-id, repo-version,installed-version, complete file-name description self.treeStore = gtk.TreeStore(bool,gtk.gdk.Pixbuf,str,str,int,str,str,str,str) self.treePackets.set_model(self.treeStore) colToggle = gtk.TreeViewColumn("") colToggle.set_sort_column_id(0) colPix = gtk.TreeViewColumn("") colText = gtk.TreeViewColumn(_("name")) colText.set_sort_column_id(2) colStatus = gtk.TreeViewColumn(_("status")) colStatus.set_sort_column_id(3) colRepo = gtk.TreeViewColumn(_("pool version")) colInstalled = gtk.TreeViewColumn(_("installed version")) coldescription = gtk.TreeViewColumn(_("description")) self.treePackets.append_column(colToggle) self.treePackets.append_column(colPix) self.treePackets.append_column(colText) self.treePackets.append_column(colStatus) #self.treePackets.append_column(colRepo) #self.treePackets.append_column(colInstalled) self.treePackets.append_column(coldescription) cell = gtk.CellRendererToggle() cell.connect("toggled",self.OnTreePacketsToggle) colToggle.pack_start(cell,True) cell.set_property('activatable', True) colToggle.add_attribute(cell, 'active', 0) cell = gtk.CellRendererPixbuf() colPix.pack_start(cell, True) colPix.add_attribute(cell, 'pixbuf', 1) cell = gtk.CellRendererText() colText.pack_start(cell, True) colText.add_attribute(cell, 'text', 2) cell = gtk.CellRendererText() colStatus.pack_start(cell,True) colStatus.add_attribute(cell,"text",3) cell = gtk.CellRendererText() colRepo.pack_start(cell,True) colRepo.add_attribute(cell,"text",5) cell = gtk.CellRendererText() colInstalled.pack_start(cell,True) colInstalled.add_attribute(cell,"text",6) cell = gtk.CellRendererText() coldescription.pack_start(cell,True) coldescription.add_attribute(cell,"text",8) #pdb.set_trace() self.jclic_settings = net.Lliurex.JClic.Settings.Settings() self.jclic_settings.look_up_settings() self.jclic_settings.read_settings() if not self.jclic_settings.get_is_configured(): dlg = gtk.MessageDialog(type=gtk.MESSAGE_WARNING,message_format=_("JClic has not been configured yet!"),buttons=gtk.BUTTONS_OK) dlg.run() dlg.destroy() return #self.winMain.show() self.main_thread=threading.Thread(target=self.run) self.main_thread.start() self.jclic_settings.read_lib_config() self.setup = net.Lliurex.Setup.Setup(self.jclic_settings) self.scan_thread=threading.Thread(target=self.scan_resources) self.scan_thread.start() def load_pool_config(self): self.info("Loading global config") try: file = open(Core.global_conf,"r") for line in file: tmp = line.split(":") if len(tmp)==2: name=tmp[0].strip() path=tmp[1].strip() if not path.find("$HOME")==-1: path=path.replace("$HOME",os.environ["HOME"]) print "Home: " + path if not os.path.exists(path): os.makedirs(path) print "Pool name: " + name print "Pool path: " + path Core.Resources.append(Pool(name,path)) file.close() except: pass self.info("Trying to load personal config") if not os.path.exists(os.environ["HOME"]+os.sep+".lliurex-recursos"): self.info("No conf path found, creating an empty one") os.mkdir(os.environ["HOME"]+os.sep+".lliurex-recursos") open(os.environ["HOME"]+os.sep+".lliurex-recursos"+os.sep+"lliurex-recursos.conf", 'w').close() else: try: file = open(os.environ["HOME"]+os.sep+".lliurex-recursos"+os.sep+"lliurex-recursos.conf","r") for line in file: tmp = line.split(":") if len(tmp)==2: name=tmp[0].strip() path=tmp[1].strip() print "Pool name: " + name print "Pool path: " + path Core.Resources.append(Pool(name,path)) file.close() except: pass def run(self): wait_for_threads = True while(gtk.main_iteration_do(True)): if self.refresh_request: self.refresh_request = False self.refresh() if self.quit_request: break self.info(_("waiting for threads")) #core employs two threads, main default one and this one, running event messages while(threading.activeCount()>2): gtk.main_iteration_do(True) self.info(_("terminating")) def check_on_target(self,file): if os.path.exists(Core.target_path + os.sep + file): return True return False def get_package_status(self, id): if id==1: return "" if id==2: return _("Local") if id==3: return _("Installed") def add_folder(self,root): path = Core.resource_path + os.path.sep + root items=[] for file in os.listdir(path): if os.path.isdir(path+os.path.sep+file): ret=self.add_folder(root+os.path.sep+file) items = items + ret else: items.append(root+os.path.sep+file) return items def add_target_folder(self,root): path = Core.target_path + os.path.sep + root items=[] for file in os.listdir(path): if os.path.isdir(path+os.path.sep+file): ret=self.add_target_folder(root+os.path.sep+file) items = items + ret else: items.append(root+os.path.sep+file) return items # ******************************** # Builds pool directory tree recursively # ******************************** def build_directory_tree(self,node): #print "** Node " + node.name+"-->"+node.path for file in os.listdir(node.path): if os.access(node.path+os.sep+file,os.R_OK): if os.path.isdir(node.path+os.sep+file): tmp = Node(file,node.path+os.sep+file) node.children.append(tmp) self.build_directory_tree(tmp) else: node.children.append(File(file,node.path+os.sep+file)) else: self.info("Unable to read due to privileges lack: " + node.path+os.sep+file) def print_directory_tree(self,node): if node.__class__ is Node: self.info("- "+node.name) for n in node.children: self.print_directory_tree(n) else: self.info("* " + node.name) def build_packages_list(self,node,list,offset): if node.__class__ is Node: for n in node.children: self.build_packages_list(n,list,offset + os.sep + n.name) else: list.append(offset) def build_packages_store(self,node,item,offset): status="" #self.treeStore = gtk.TreeStore(bool,gtk.gdk.Pixbuf,str,str,int,str,str,str,str) if not item==None: mystr = offset + os.sep + node.name mystr = mystr.replace("/pool","") filetype,icon,name,description = self.get_package_info(mystr) else: filetype="none" icon = self.icon_default name = node.name description = "" mystr = node.path if name==None: name=node.name for desktop in self.desktops_cache: if desktop.data[1]==mystr: status=_("Installed") break if filetype=="jclic": for cache in net.Lliurex.JClic.Settings.Settings.jclics: caption,path=cache if path==mystr: status=_("Installed") me = self.treeStore.append(item,[False,icon,name,status,0,"",mystr,filetype,description]) if node.__class__ is Node: for n in node.children: self.build_packages_store(n,me,mystr) def get_package_info(self,path): mime=None icon=self.icon_default mime=gnomevfs.get_mime_type(path) icon=self.load_icon(self.get_icon(path)) name=None filetype="none" description="" #trying to guess what kind of zip package we are dealing with if mime=="application/zip": try: zip = zipfile.ZipFile(path) except: print "Invalid zipfile: " + path return (filetype,icon,name,description) for zip_file in zip.namelist(): #Jclics detection match=re.match(".*\.jclic$",zip_file) if not match==None: #Deprecated for python 2.6 xmlstr = zip.read(zip_file) jclic = net.Lliurex.JClic.JClic(xmlstr) #mime_name = self.get_icon(file_path) name = jclic.title resource_version = jclic.date icon = self.icon_jclic filetype="jclic" break match = re.match("moodle.xml",zip_file) if not match == None: xmlstr = zip.read(zip_file) moodle = net.Lliurex.Moodle.Moodle(xmlstr) name = moodle.name resource_version = moodle.version description = moodle.description icon = self.icon_scorm #filetype="moodle" break match = re.match("imsmanifest.xml",zip_file) if not match == None: icon=self.icon_scorm filetype="scorm" return (filetype,icon,name,description) def scan_desktops(self): del self.desktops_cache[:] for file in os.listdir(Core.target_path): match = re.match(".*\.desktop",file) if not match == None: #print "desktop :"+Core.target_path+os.sep+file desktop = net.Lliurex.Desktop.Desktop(None) desktop.Load(Core.target_path+os.sep+file) self.desktops_cache.append(desktop) # ******************************** # Pool Scan # ******************************** def scan_resources(self): gtk.gdk.threads_enter() #self.treePackets.set_model(None) self.treeStore.clear() gtk.gdk.threads_leave() self.info(_("Scanning resources")) gtk.gdk.threads_enter() self.barProgress.set_text(_("Refreshing")) self.set_app_sensible_state(False) gtk.gdk.threads_leave() self.info(_("Scanning installed jclics")) del net.Lliurex.JClic.Settings.Settings.jclics[:] if self.jclic_settings.get_is_lib_configured(): self.jclic_settings.get_current_installed() self.info(_("Scanning installed desktops")) self.scan_desktops() """ for resource in self.resource_path: self.pool_tree = self.pool_tree= Node("pool",resource) self.build_directory_tree(self.pool_tree) #self.print_directory_tree(self.pool_tree) self.build_packages_store(self.pool_tree,None,resource) """ del self.pool_tree[:] for pool in Core.Resources: node = Node(pool.name,pool.path) self.pool_tree.append(node) self.build_directory_tree(node) self.build_packages_store(node,None,pool.path) self.info(_("Scan completed")) gtk.gdk.threads_enter() self.set_app_sensible_state(True) self.barProgress.set_text(_("Scan completed")) gtk.gdk.threads_leave() def refresh(self): #self.treeView.set_model(None) #print "Threads: ",threading.enumerate() self.info(_("Refreshing")) self.scan_thread=threading.Thread(target=self.scan_resources) self.scan_thread.start() # ************************************ # Copy process # ************************************ def copy_files(self): self.info(_("Starting copy process...")) gtk.gdk.threads_enter() self.set_app_sensible_state(False) gtk.gdk.threads_leave() self.barProgress.set_text(_("Copying files")) iter = self.treeStore.get_iter_root() while not iter==None: value = self.treeStore.get_value(iter,0) if value: file = self.treeStore.get_value(iter,7) #creating target directory #todo: threaded n = file.rfind(os.path.sep) if not n==-1: if not os.path.exists(Core.target_path + os.sep +file[0:n]): os.makedirs(Core.target_path + os.sep +file[0:n]) self.info(_("Copying: ") + file) #shutil.copyfile(Core.resource_path + os.sep + file, Core.target_path + os.sep + file) copy_thread = threading.Thread(target=shutil.copyfile,args=(Core.resource_path + os.sep + file, Core.target_path + os.sep + file)) copy_thread.start() while copy_thread.isAlive(): gtk.gdk.threads_enter() self.barProgress.pulse() gtk.gdk.threads_leave() time.sleep(0.15) #self.barProgress.pulse() iter = self.treeStore.iter_next(iter) gtk.gdk.threads_enter() self.barProgress.set_text(_("Completed")) self.barProgress.set_fraction(0.0) self.info(_("Completed")) self.set_app_sensible_state(True) gtk.gdk.threads_leave() self.refresh_request = True #self.refresh() # ************************************ # Remove process # ************************************ def remove_files(self): self.info(_("Starting remove process...")) gtk.gdk.threads_enter() self.set_app_sensible_state(False) self.barProgress.set_text(_("Removing files")) gtk.gdk.threads_leave() iter = self.treeStore.get_iter_root() while not iter==None: value = self.treeStore.get_value(iter,0) id = self.treeStore.get_value(iter,4) if value: if not id==1: file = self.treeStore.get_value(iter,7) self.info(_("Removing: ") + Core.target_path +os.sep + file) #remove here #os.remove(Core.target_path +os.sep + file) params = ((Core.target_path +os.sep + file),"crap") remove_thread=threading.Thread(target=self.remove,args=params[:1]) remove_thread.start() while remove_thread.isAlive(): gtk.gdk.threads_enter() self.barProgress.pulse() time.sleep(0.15) gtk.gdk.threads_leave() iter = self.treeStore.iter_next(iter) gtk.gdk.threads_enter() self.barProgress.set_text(_("Completed")) self.barProgress.set_fraction(0.0) self.info(_("Completed")) self.set_app_sensible_state(True) gtk.gdk.threads_leave() #self.refresh() self.refresh_request = True def remove(self,file): print file os.remove(file) def set_app_sensible_state(self,value): self.treePackets.set_sensitive(value) self.btnInstall.set_sensitive(value) self.btnRemove.set_sensitive(value) self.btnRefresh.set_sensitive(value) self.btnSetup.set_sensitive(value) self.btnExport.set_sensitive(value) # ************************************ # Generates custom stock icons # ************************************ def register_stock_icons(self): items = [('lx-install', _('_Install'), 0, 0, None), ('lx-remove', _('_Remove'), 0, 0, None),("lx-export",_("_Export"),0, 0,None)] aliases = [('lx-install',gtk.STOCK_ADD),('lx-remove', gtk.STOCK_DELETE),("lx-export","drive-removable-media")] gtk.stock_add(items) factory = gtk.IconFactory() factory.add_default() for new_stock, alias in aliases: icon_set = gtk.icon_factory_lookup_default(alias) if icon_set==None: icon_set=gtk.IconSet(self.load_icon(alias)) factory.add(new_stock, icon_set) # ************************************ # Loads an icon given its gnome keyname # ************************************ def load_icon(self,name,size = 48): for iname,idata in self.cache_icons: if iname==name: return idata theme = gtk.icon_theme_get_default() idata = theme.load_icon(name, size, 0) self.cache_icons.append((name,idata)) return idata # ************************************ # Gets proper icon name based on mime-type # ************************************ def get_icon(self,path): icon_name=None mime_type = gnomevfs.get_mime_type(path).replace( '/', '-' ) #try gnome mime items = mime_type.split('-') items_len=len(items) #try simple mime for aux in xrange(len(items)-1): name = '-'.join(items[:len(items)-aux]) if name in self.all_icons: icon_name = name #print "found: ",name break if icon_name==None: for aux in xrange(items_len-1): name = "gnome-mime-" + '-'.join(items[:items_len-aux]) if name in self.all_icons: icon_name = name #print "gnome found: ",name break if icon_name==None and os.path.isdir(path): icon_name="folder" if icon_name==None: icon_name="document-new" tmp = mime_type.split("-") if len(tmp)>1: if tmp[0]=="image": icon_name="image-x-generic" if tmp[0]=="audio": icon_name="audio-x-generic" return icon_name def ToggleChild(self,iter,value): child = self.treeStore.iter_children(iter) self.treeStore.set_value(iter,0,value) if not child==None: self.ToggleChild(child,value) next = self.treeStore.iter_next(iter) if not next==None: self.ToggleChild(next,value) def ExportChild(self,iter,namespace): child = self.treeStore.iter_children(iter) value = self.treeStore.get_value(iter,0) name = self.treeStore.get_value(iter,2) complete_path=self.treeStore.get_value(iter,6) if child==None: if value: if os.path.isdir(complete_path): print "To export Dir: ", complete_path else: print "To export File: ", complete_path else: self.ExportChild(child,namespace+os.sep+name) next = self.treeStore.iter_next(iter) if not next==None: self.ExportChild(next,namespace) def InstallChild(self,iter,namespace): child = self.treeStore.iter_children(iter) if not child ==None: name = self.treeStore.get_value(iter,2) if namespace==None: self.InstallChild(child,name) else: self.InstallChild(child,namespace + "." + name) else: value = self.treeStore.get_value(iter,0) name = self.treeStore.get_value(iter,2) if value: #print "To install: ",namespace + "." + name if namespace==None: desktopname = name else: desktopname = namespace+ "." + name #desktopname = desktopname.replace(".pool.","") completepath = self.treeStore.get_value(iter,6) iconname = self.get_icon(completepath) # [type , desktopname , completepath, name, mime] self.install_cache.append([self.treeStore.get_value(iter,7),desktopname,completepath,name,iconname]) next = self.treeStore.iter_next(iter) if not next==None: self.InstallChild(next,namespace) def RemoveChild(self,iter,namespace): child = self.treeStore.iter_children(iter) if not child ==None: name = self.treeStore.get_value(iter,2) if namespace==None: self.RemoveChild(child, name) else: self.RemoveChild(child,namespace + "." + name) else: value = self.treeStore.get_value(iter,0) name = self.treeStore.get_value(iter,2) if value: if not namespace==None: desktopname = namespace+"."+name else: desktopname = name #desktopname = desktopname.replace(".pool.","") completepath = self.treeStore.get_value(iter,6) # [type , desktopname , completepath, name] self.remove_cache.append([self.treeStore.get_value(iter,7),desktopname,completepath,name]) next = self.treeStore.iter_next(iter) if not next==None: self.RemoveChild(next,namespace) # ************************************* #events def OnTreePacketsToggle(self,cell,path): print "Toggle: ",path iter = self.treeStore.get_iter(path) value = self.treeStore.get_value(iter,0) child = self.treeStore.iter_children(iter) #self.treeStore.set_value(iter,0,not value) if not child == None: #self.ToggleChild(child,not value) q=child found=False while not q==None: name = self.treeStore.get_value(q,2) if name=="index.html": self.treeStore.set_value(q,0,not value) self.treeStore.set_value(iter,0,not value) found=True break q = self.treeStore.iter_next(q) if not found: self.info("No index.html found") self.treePackets.expand_to_path(path) else: self.treeStore.set_value(iter,0,not value) return def OnBtnInstallClick(self,event): del self.install_cache[:] #del net.Lliurex.JClic.Settings.Settings.jclics[:] self.InstallChild(self.treeStore.get_iter_root(),None) self.info(_("Installing resources...")) for todo in self.install_cache: if todo[0]=="none": self.info("File: " + todo[1]) desktop = net.Lliurex.Desktop.Desktop(todo) desktop.Save(self.target_path) if todo[0]=="jclic": net.Lliurex.JClic.Settings.Settings.jclics.append((todo[3],todo[2])) if todo[0]=="scorm": self.info("File: " + todo[1]) desktop = net.Lliurex.Desktop.Desktop(todo) desktop.Save(self.target_path,mode="scorm") self.info(_("Syncying jclic database")) if self.jclic_settings.get_is_lib_configured(): self.jclic_settings.sync_dir() self.info(_("Completed")) self.info("Refreshing lliurex-do...") try: bus = dbus.SessionBus() refresh_service = bus.get_object('net.Lliurex.do', '/net/Lliurex/do') lliurex_do_refresh = refresh_service.get_dbus_method('query_refresh', 'net.Lliurex.do') lliurex_do_refresh() except dbus.exceptions.DBusException: self.info("Lliurex do is not ready or there is no dbus") self.refresh_request = True """ if not self.jclic_settings.get_is_lib_configured(): dlg = gtk.MessageDialog(type=gtk.MESSAGE_WARNING,message_format=_("Please, set a jclic destination before continue"),buttons=gtk.BUTTONS_OK) dlg.run() dlg.destroy() return iter = self.treeStore.get_iter_root() to_install = 0 to_upgrade = 0 #just taking into account selected and installed packages while not iter==None: value = self.treeStore.get_value(iter,0) id = self.treeStore.get_value(iter,4) if value: if id==1: to_install = to_install + 1 if id==3: to_upgrade = to_upgrade + 1 iter = self.treeStore.iter_next(iter) if (to_upgrade + to_install)>0: self.dlg_lblMessage.set_label(_("JClic manager will do the following tasks:\n* Files to install: ")+str(to_install)+_("\n* Files to upgrade: ")+str(to_upgrade)+_("\nDo you want to continue?")) response=self.dlgQuestion.run() self.dlgQuestion.hide() if response==1: self.info(_("Copying selected files")) #self.copy_files() copy_thread=threading.Thread(target=self.copy_files) copy_thread.start() """ def OnBtnRemoveClick(self,event): del self.remove_cache[:] self.RemoveChild(self.treeStore.get_iter_root(),None) self.info(_("Removing files...")) for todo in self.remove_cache: if todo[0]=="none" or todo[0]=="scorm": print "Removing :" + self.target_path+os.sep+todo[1] if (os.path.exists(self.target_path+os.sep+todo[1]+".desktop")): os.remove(self.target_path+os.sep+todo[1]+".desktop") if todo[0]=="jclic": #TODO for cache in net.Lliurex.JClic.Settings.Settings.jclics: caption,path=cache #print "DEBUG: " + caption + "," + path + "," + todo[2] if path==todo[2]: net.Lliurex.JClic.Settings.Settings.jclics.remove(cache) #print "This JClic needs to be removed: ",todo[2] break if self.jclic_settings.get_is_lib_configured(): self.jclic_settings.sync_dir() self.info("Refreshing lliurex-do...") try: bus = dbus.SessionBus() refresh_service = bus.get_object('net.Lliurex.do', '/net/Lliurex/do') lliurex_do_refresh = refresh_service.get_dbus_method('query_refresh', 'net.Lliurex.do') lliurex_do_refresh() except dbus.exceptions.DBusException: self.info("Lliurex do is not ready or there is no dbus") self.refresh_request = True """ iter = self.treeStore.get_iter_root() to_remove = 0 #just taking into account selected and installed packages while not iter==None: value = self.treeStore.get_value(iter,0) id = self.treeStore.get_value(iter,4) if value: if not id==1: to_remove = to_remove + 1 iter = self.treeStore.iter_next(iter) if to_remove>0: self.dlg_lblMessage.set_label(_("JClic manager will remove ") + str(to_remove) + _(" files from your home folder\nDo you want to continue?")) response=self.dlgQuestion.run() self.dlgQuestion.hide() if response==1: self.info(_("Deleting selected files")) copy_thread=threading.Thread(target=self.remove_files) copy_thread.start() """ def OnBtnRefreshClick(self,event): self.refresh() def OnBtnSetupClick(self,event): self.setup.show() def OnBtnExportClick(self,event): dlg=gtk.FileChooserDialog(title=_("Select a folder"),parent=self.winMain,action=gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER,buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OPEN, gtk.RESPONSE_OK) ) res=dlg.run() dlg.hide() if res==gtk.RESPONSE_OK: disk = os.statvfs(dlg.get_filename()) size = (disk.f_bavail * disk.f_frsize) size = size / 1024 print "Available Space: ", size self.ExportChild(self.treeStore.get_iter_root(),"") else: print "Result Cancel" def OnAboutClick(self,event): response=self.dlgAbout.run() self.dlgAbout.hide() def OnWindowState(self,widget,event): print "State: ",event.state def OnImgItemQuitActivate(self,event): self.quit_request = True def OnWinMainDelete(self, widget, event, data=None): self.info( _("Quit request")) self.jclic_settings.save_lib_settings() self.quit_request = True return False