"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "fslint-gui" between
fslint-2.44.tar.gz and fslint-2.46.tar.gz

About: fslint is a toolkit to find and clean various forms of lint on a filesystem (for e.g. duplicate files).

fslint-gui  (fslint-2.44):fslint-gui  (fslint-2.46)
#!/usr/bin/env python #!/usr/bin/env python2
# vim:fileencoding=utf-8 # vim:fileencoding=utf-8
# Note both python and vim understand the above encoding declaration # Note both python and vim understand the above encoding declaration
# Note using env above will cause the system to register # Note using env above will cause the system to register
# the name (in ps etc.) as "python" rather than fslint-gui # the name (in ps etc.) as "python" rather than fslint-gui
# (because "python" is passed to exec by env). # (because "python" is passed to exec by env).
""" """
FSlint - A utility to find File System lint. FSlint - A utility to find File System lint.
Copyright © 2000-2010 by Pádraig Brady <P@draigBrady.com>. Copyright © 2000-2014 by Pádraig Brady <P@draigBrady.com>.
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or the Free Software Foundation; either version 2 of the License, or
any later version. any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details, See the GNU General Public License for more details,
which is available at www.gnu.org which is available at www.gnu.org
""" """
import types, os, sys, pipes, time, stat, tempfile, errno
import gettext import gettext
import locale import locale
import gtk
import gtk.glade
import types, os, sys, pipes, time, stat, tempfile, errno try:
import gtk
except RuntimeError:
etype, emsg, etb = sys.exc_info()
sys.stderr.write(str(emsg)+'\n')
sys.exit(1)
import gtk.glade
time_commands=False #print sub commands timing on status line time_commands=False #print sub commands timing on status line
def puts(string=""): #print is problematic in python 3 def puts(string=""): #print is problematic in python 3
sys.stdout.write(str(string)+'\n') sys.stdout.write(str(string)+'\n')
liblocation=os.path.dirname(os.path.abspath(sys.argv[0])) liblocation=os.path.dirname(os.path.abspath(sys.argv[0]))
locale_base=liblocation+'/po/locale' locale_base=liblocation+'/po/locale'
try: try:
import fslint import fslint
skipping to change at line 180 skipping to change at line 188
lOpts, lArgs = getopt.getopt(sys.argv[1:], "", ["help","version"]) lOpts, lArgs = getopt.getopt(sys.argv[1:], "", ["help","version"])
if len(lArgs) == 0: if len(lArgs) == 0:
lArgs = [os.getcwd()] lArgs = [os.getcwd()]
if ("--help","") in lOpts: if ("--help","") in lOpts:
Usage() Usage()
sys.exit(None) sys.exit(None)
if ("--version","") in lOpts: if ("--version","") in lOpts:
puts("FSlint 2.44") puts("FSlint 2.46")
sys.exit(None) sys.exit(None)
except getopt.error, msg: except getopt.error, msg:
puts(msg) puts(msg)
puts() puts()
Usage() Usage()
sys.exit(2) sys.exit(2)
def human_num(num, divisor=1, power=""): def human_num(num, divisor=1, power=""):
num=float(num) num=float(num)
if divisor == 1: if divisor == 1:
skipping to change at line 402 skipping to change at line 410
# Determine what type of distro we're on. # Determine what type of distro we're on.
class distroType: class distroType:
def __init__(self): def __init__(self):
types = ("rpm", "dpkg", "pacman") types = ("rpm", "dpkg", "pacman")
for dist in types: for dist in types:
setattr(self, dist, False) setattr(self, dist, False)
if os.path.exists("/etc/redhat-release"): if os.path.exists("/etc/redhat-release"):
self.rpm = True self.rpm = True
elif os.path.exists("/etc/debian_version"): elif os.path.exists("/etc/debian_version"):
self.dpkg = True self.dpkg = True
elif os.path.exists("/etc/arch-release"):
self.pacman = True
else: else:
for dist in types: for dist in types:
cmd = dist + " --version >/dev/null 2>&1" cmd = dist + " --version >/dev/null 2>&1"
# We check for != 127 rather than == 0 here if os.WEXITSTATUS(os.system(cmd)) == 0:
# because pacman --version returns 2 ?
if os.WEXITSTATUS(os.system(cmd)) != 127:
setattr(self, dist, True) setattr(self, dist, True)
break break
dist_type=distroType() dist_type=distroType()
def human_space_left(where): def human_space_left(where):
(device, total, used_b, avail, used_p, mount)=\ (device, total, used_b, avail, used_p, mount)=\
os.popen("df -Ph %s | tail -n1" % where).read().split() os.popen("df -Ph %s | tail -n1" % where).read().split()
translation_map={"percent":used_p, "disk":mount, "size":avail} translation_map={"percent":used_p, "disk":mount, "size":avail}
return _("%(percent)s of %(disk)s is used leaving %(size)sB available") %\ return _("%(percent)s of %(disk)s is used leaving %(size)sB available") %\
translation_map translation_map
# Avoid using clist.get_selectable() with is O(n) # Avoid using clist.get_selectable() which is O(n)
def get_selectable(row, row_data): def get_selectable(row, row_data):
return row_data[row][0] != '#' return row_data[row][0] != '#'
class dlgUserInteraction(GladeWrapper): class dlgUserInteraction(GladeWrapper):
""" """
Note input buttons tuple text should not be translated Note input buttons tuple text should not be translated
so that the stock buttons are used if possible. But the so that the stock buttons are used if possible. But the
translations should be available, so use N_ for input translations should be available, so use N_ for input
buttons tuple text. Note the returned response is not buttons tuple text. Note the returned response is not
translated either. Note also, that if you know a stock translated either. Note also, that if you know a stock
skipping to change at line 512 skipping to change at line 520
# to save results there # to save results there
self.GtkWindow.set_action(gtk.FILE_CHOOSER_ACTION_SAVE) self.GtkWindow.set_action(gtk.FILE_CHOOSER_ACTION_SAVE)
self.GtkWindow.set_current_folder(self.pwd) self.GtkWindow.set_current_folder(self.pwd)
self.GtkWindow.set_current_name(filename) self.GtkWindow.set_current_name(filename)
else: else:
self.GtkWindow.set_action(gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER) self.GtkWindow.set_action(gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER)
# set_filename doesn't highlight dir after first call # set_filename doesn't highlight dir after first call
# so using select_filename for consistency. Also I think # so using select_filename for consistency. Also I think
# select_filename is better than set_current_folder as # select_filename is better than set_current_folder as
# it allows one to more easily select items at the same level # it allows one to more easily select items at the same level
print self.pwd
self.GtkWindow.select_filename(self.pwd) self.GtkWindow.select_filename(self.pwd)
self.GtkWindow.set_transient_for(self.app.GtkWindow)#center on main win self.GtkWindow.set_transient_for(self.app.GtkWindow)#center on main win
self.GtkWindow.show() self.GtkWindow.show()
if self.GtkWindow.modal: if self.GtkWindow.modal:
gtk.main() #synchronous call from parent gtk.main() #synchronous call from parent
#else: not supported #else: not supported
################# #################
# Signal handlers # Signal handlers
################# #################
skipping to change at line 702 skipping to change at line 709
return "" return ""
if self.ok_dirs.rows == 0: if self.ok_dirs.rows == 0:
return _("No search paths specified") return _("No search paths specified")
search_dirs = "" search_dirs = ""
for row in range(self.ok_dirs.rows): for row in range(self.ok_dirs.rows):
search_dirs += " " + pipes.quote(self.ok_dirs.get_row_data(row)) search_dirs += " " + pipes.quote(self.ok_dirs.get_row_data(row))
exclude_dirs="" exclude_dirs=""
for row in range(self.bad_dirs.rows): # One can't remove directories listed as empty if
if exclude_dirs == "": # they have .git/ dirs etc. so ignore the exluded paths here
exclude_dirs = '\(' + ' -path ' if self.mode != self.mode_ed:
else: for row in range(self.bad_dirs.rows):
exclude_dirs += ' -o -path ' if exclude_dirs == "":
exclude_dirs += pipes.quote(self.bad_dirs.get_row_data(row)) exclude_dirs = '\(' + ' -path '
else:
exclude_dirs += ' -o -path '
exclude_dirs += pipes.quote(self.bad_dirs.get_row_data(row))
if exclude_dirs != "": if exclude_dirs != "":
exclude_dirs += ' \) -prune -o ' exclude_dirs += ' \) -prune -o '
if not self.recurseDirs.get_active(): if not self.recurseDirs.get_active():
recurseParam=" -r " recurseParam=" -r "
else: else:
recurseParam=" " recurseParam=" "
self.findParams = search_dirs + " -f " + recurseParam + exclude_dirs self.findParams = search_dirs + " -f " + recurseParam + exclude_dirs
if self.mode == self.mode_up:
min_size = self.min_size.get_text()
if min_size == '0' or min_size == '':
min_size=''
elif min_size[-1].isdigit():
min_size=str(int(min_size)-1)
min_size += 'c'
if min_size:
self.findParams += '-size +' + min_size + ' '
self.findParams += self.extra_find_params.get_text() self.findParams += self.extra_find_params.get_text()
return "" return ""
def addDirs(self, dirlist, dirs): def addDirs(self, dirlist, dirs):
"""Adds items to passed clist.""" """Adds items to passed clist."""
dirlist.append([I18N.displayable_utf8(dirs,path=True)]) dirlist.append([I18N.displayable_utf8(dirs,path=True)])
dirlist.set_row_data(dirlist.rows-1, dirs) dirlist.set_row_data(dirlist.rows-1, dirs)
def removeDirs(self, dirlist): def removeDirs(self, dirlist):
skipping to change at line 784 skipping to change at line 805
rows_left.reverse() rows_left.reverse()
for row in rows_left: for row in rows_left:
if not get_selectable(row, row_data): if not get_selectable(row, row_data):
if row == clist.rows-1 or not get_selectable(row+1, row_data): if row == clist.rows-1 or not get_selectable(row+1, row_data):
clist.remove(row) clist.remove(row)
row_data.pop(row) row_data.pop(row)
else: #remove single item groups else: #remove single item groups
if row == clist.rows-1 and not get_selectable(row-1, row_data): if row == clist.rows-1 and not get_selectable(row-1, row_data):
clist.remove(row) clist.remove(row)
row_data.pop(row) row_data.pop(row)
elif not (get_selectable(row-1, row_data) or elif not ((row!=0 and get_selectable(row-1, row_data)) or
get_selectable(row+1, row_data)): (row!=clist.rows-1 and get_selectable(row+1, row_data)
)):
clist.remove(row) clist.remove(row)
row_data.pop(row) row_data.pop(row)
def whatRequires(self, packages, level=0): def whatRequires(self, packages, level=0):
if not packages: return if not packages: return
if level==0: self.checked_pkgs={} if level==0: self.checked_pkgs={}
for package in packages: for package in packages:
#puts("\t"*level+package) #puts("\t"*level+package)
self.checked_pkgs[package]='' self.checked_pkgs[package]=''
if dist_type.rpm: if dist_type.rpm:
skipping to change at line 835 skipping to change at line 856
#Package names unique on debian #Package names unique on debian
cmd = r"dpkg-query -W --showformat='${Package}\t${Installed-Size}" cmd = r"dpkg-query -W --showformat='${Package}\t${Installed-Size}"
cmd += r"\t${Status}\n' | LANG=C grep -F 'installed' | cut -f1,2 | " cmd += r"\t${Status}\n' | LANG=C grep -F 'installed' | cut -f1,2 | "
cmd += r"sed 's/[^0-9]$/\t0/'" #packages with missing size = 0 cmd += r"sed 's/[^0-9]$/\t0/'" #packages with missing size = 0
elif dist_type.rpm: elif dist_type.rpm:
#Must include version names to uniquefy on redhat #Must include version names to uniquefy on redhat
cmd = r"rpm -qa --queryformat '%{N}-%{V}-%{R}.%{ARCH}\t%{SIZE}\n'" cmd = r"rpm -qa --queryformat '%{N}-%{V}-%{R}.%{ARCH}\t%{SIZE}\n'"
elif dist_type.pacman: elif dist_type.pacman:
cmd = r"pacman -Q | sed -n 's/^\([^ ]\{1,\}\) .*/\1/p' | " cmd = r"pacman -Q | sed -n 's/^\([^ ]\{1,\}\) .*/\1/p' | "
cmd += r"LC_ALL=C xargs pacman -Qi | sed -n -e " cmd += r"LC_ALL=C xargs pacman -Qi | sed -n -e "
cmd += r"'s/Name *: *\(.*\)/\1\t/p' -e " cmd += r"'s/Installed Size : \([^ ]*\) \([^ ]*\)B/\1\2/p' | "
cmd += r"'s/\(Installed \)\?Size *: *\([^ ]\+\)\( K\)\?/\2|/p' | " cmd += r"numfmt --from=auto"
cmd += r"tr '\n' ' ' | tr -d ' ' | tr '|' '\n'"
else: else:
return ("", _("Sorry, FSlint does not support this functionality \ return ("", _("Sorry, FSlint does not support this functionality \
on your system at present.")) on your system at present."))
po, pe = self.get_fslint(cmd + " | LANG=C sort -k2,2rn") po, pe = self.get_fslint(cmd + " | LANG=C sort -k2,2rn")
pkg_tot = 0 pkg_tot = 0
row = 0 row = 0
for pkg_info in po: for pkg_info in po:
pkg_name, pkg_size= pkg_info.split() pkg_name, pkg_size= pkg_info.split()
pkg_size = int(float(pkg_size)) pkg_size = int(float(pkg_size))
if dist_type.dpkg: if dist_type.dpkg:
pkg_size *= 1024 pkg_size *= 1024
elif dist_type.pacman:
frugalware_cmd="pacman-g2 --version >/dev/null 2>&1"
if os.WEXITSTATUS(os.system(frugalware_cmd)) == 127:
#Arch linux has trailing 'K' removed above
pkg_size *= 1024
pkg_tot += pkg_size pkg_tot += pkg_size
clist_pkgs.append([pkg_name,human_num(pkg_size,1000).strip(), clist_pkgs.append([pkg_name,human_num(pkg_size,1000).strip(),
"%010ld"%pkg_size,"0"]) "%010ld"%pkg_size,"0"])
clist_pkgs.set_row_data(row, pkg_name) clist_pkgs.set_row_data(row, pkg_name)
row += 1 row += 1
return (str(row) + _(" packages, ") + return (str(row) + _(" packages, ") +
_("consuming %sB. ") % human_num(pkg_tot,1000).strip() + _("consuming %sB. ") % human_num(pkg_tot,1000).strip() +
_("Note %s.") % human_space_left('/'), pe) _("Note %s.") % human_space_left('/'), pe)
#Note pkgs generally installed on root partition so report space left. #Note pkgs generally installed on root partition so report space left.
skipping to change at line 939 skipping to change at line 954
elif self.opt_bl_relative.get_active(): elif self.opt_bl_relative.get_active():
cmd += " -l" cmd += " -l"
elif self.opt_bl_absolute.get_active(): elif self.opt_bl_absolute.get_active():
cmd += " -A" cmd += " -A"
elif self.opt_bl_redundant.get_active(): elif self.opt_bl_redundant.get_active():
cmd += " -n" cmd += " -n"
po, pe = self.get_fslint(cmd) po, pe = self.get_fslint(cmd)
row = 0 row = 0
for line in po: for line in po:
link, target = line.split(" -> ", 2) link, target = line.split(" -> ", 2)
print target, ord(target)
self.clist_append_path(clist_bl, link, '', target) self.clist_append_path(clist_bl, link, '', target)
row += 1 row += 1
return (str(row) + _(" links"), pe) return (str(row) + _(" links"), pe)
def findtf(self, clist_tf): def findtf(self, clist_tf):
cmd = "./findtf " + self.findParams cmd = "./findtf " + self.findParams
cmd += " --age=" + str(int(self.spin_tf_core.get_value())) cmd += " --age=" + str(int(self.spin_tf_core.get_value()))
if self.chk_tf_core.get_active(): if self.chk_tf_core.get_active():
cmd += " -c" cmd += " -c"
skipping to change at line 1025 skipping to change at line 1039
sensitivity, '\0') sensitivity, '\0')
row=0 row=0
for record in po: for record in po:
self.clist_append_path(clist_nl, record, pathInfo(record).ls_colour) self.clist_append_path(clist_nl, record, pathInfo(record).ls_colour)
row += 1 row += 1
return (str(row) + _(" files"), pe) return (str(row) + _(" files"), pe)
def findup(self, clist_dups): def findup(self, clist_dups):
po, pe = self.get_fslint("./findup " + self.findParams) po, pe = self.get_fslint("./findup --gui" + self.findParams)
numdups = 0 numdups = 0
du = size = 0 du = size = 0
dups = [] dups = []
alldups = [] alldups = []
inodes = {} inodes = {}
#inodes required to correctly report disk usage of #inodes required to correctly report disk usage of
#duplicate files with seperate inode groups. #duplicate files with seperate inode groups.
for line in po: for line in po:
if line == '': #grouped == 1 if line == '': #grouped == 1
skipping to change at line 1237 skipping to change at line 1251
else: else:
self.hscale_findnl_level.show() self.hscale_findnl_level.show()
self.lbl_findnl_sensitivity.show() self.lbl_findnl_sensitivity.show()
def on_fslint_functions_switch_page(self, widget, dummy, pagenum): def on_fslint_functions_switch_page(self, widget, dummy, pagenum):
self.ClearErrors() self.ClearErrors()
self.mode=pagenum self.mode=pagenum
self.status.set_text(self.mode_descs[self.mode]) self.status.set_text(self.mode_descs[self.mode])
if self.mode == self.mode_up: if self.mode == self.mode_up:
self.autoMerge.show() self.autoMerge.show()
self.autoSymlink.show()
else: else:
self.autoMerge.hide() self.autoMerge.hide()
self.autoSymlink.hide()
if self.mode == self.mode_ns or self.mode == self.mode_rs: #bl in future if self.mode == self.mode_ns or self.mode == self.mode_rs: #bl in future
self.autoClean.show() self.autoClean.show()
else: else:
self.autoClean.hide() self.autoClean.hide()
def on_selection_menu_button_press_event(self, widget, event): def on_selection_menu_button_press_event(self, widget, event):
if self.mode == self.mode_up or self.mode == self.mode_sn: if self.mode == self.mode_up or self.mode == self.mode_sn:
self.groups_menu.show() self.groups_menu.show()
else: else:
self.groups_menu.hide() self.groups_menu.hide()
skipping to change at line 1291 skipping to change at line 1307
clist = self.clists[self.mode] clist = self.clists[self.mode]
os.chdir(liblocation+"/fslint/") os.chdir(liblocation+"/fslint/")
errors = self.buildFindParameters() errors = self.buildFindParameters()
if errors: if errors:
self.ShowErrors(errors) self.ShowErrors(errors)
return return
self.status.delete_text(0,-1) self.status.delete_text(0,-1)
clist.clear() clist.clear()
#All GtkClist operations seem to be O(n), #All GtkClist operations seem to be O(n),
#so doing the following for example will be O((n/2)*(n+1)) #so doing the following for example will be O((n/2)*(n+1))
# for row in range(clist.rows): # for row in xrange(clist.rows):
# path = clist.get_row_data(row) # path = clist.get_row_data(row)
#Therefore we use a python list to store row data. #Therefore we use a python list to store row data.
clist.set_data("row_data",[]) clist.set_data("row_data",[])
if self.mode == self.mode_pkgs: if self.mode == self.mode_pkgs:
self.pkg_info.get_buffer().set_text("") self.pkg_info.get_buffer().set_text("")
self.look_busy() self.look_busy()
self.stopflag=self.pauseflag=False self.stopflag=self.pauseflag=False
self.paused = False self.paused = False
while gtk.events_pending(): gtk.main_iteration(False)#update GUI while gtk.events_pending(): gtk.main_iteration(False)#update GUI
clist.freeze() clist.freeze()
skipping to change at line 1420 skipping to change at line 1436
self.ClearErrors() self.ClearErrors()
fileSaveAs = self.dlgPath.GtkWindow.get_filename() fileSaveAs = self.dlgPath.GtkWindow.get_filename()
try: try:
fileSaveAs = open(fileSaveAs, 'w') fileSaveAs = open(fileSaveAs, 'w')
except: except:
etype, emsg, etb = sys.exc_info() etype, emsg, etb = sys.exc_info()
self.ShowErrors(str(emsg)+'\n') self.ShowErrors(str(emsg)+'\n')
return return
rows_to_save = clist.selection rows_to_save = clist.selection
if self.mode == self.mode_pkgs: if self.mode == self.mode_pkgs:
for row in range(clist.rows): for row in xrange(clist.rows):
if len(rows_to_save): if len(rows_to_save):
if row not in rows_to_save: continue if row not in rows_to_save: continue
rowtext = '' rowtext = ''
for col in (0,2): #ignore "human number" col for col in (0,2): #ignore "human number" col
rowtext += clist.get_text(row,col) +'\t' rowtext += clist.get_text(row,col) +'\t'
fileSaveAs.write(rowtext[:-1]+'\n') fileSaveAs.write(rowtext[:-1]+'\n')
else: else:
row_data=clist.get_data("row_data") row_data=clist.get_data("row_data")
if len(rows_to_save): if len(rows_to_save):
for row in range(clist.rows): for row in xrange(clist.rows):
if get_selectable(row, row_data): if get_selectable(row, row_data):
if row not in rows_to_save: continue if row not in rows_to_save: continue
else: continue #don't save group headers else: continue #don't save group headers
fileSaveAs.write(row_data[row]) fileSaveAs.write(row_data[row])
else: else:
fileSaveAs.writelines(row_data) fileSaveAs.writelines(row_data)
def get_selected_path(self, row=None, folder=False): def get_selected_path(self, row=None, folder=False):
clist = self.clists[self.mode] clist = self.clists[self.mode]
if self.mode==self.mode_pkgs: if self.mode==self.mode_pkgs:
skipping to change at line 1490 skipping to change at line 1506
#could run again with os.popen3() to get actual error #could run again with os.popen3() to get actual error
#but that's a bit hacky I think? #but that's a bit hacky I think?
self.ShowErrors(_("Error starting xdg-open") + '\n') self.ShowErrors(_("Error starting xdg-open") + '\n')
# select all other duplicates from selected item folder # select all other duplicates from selected item folder
def on_select_from_that_folder_activate(self, src): def on_select_from_that_folder_activate(self, src):
clist = self.clists[self.mode] clist = self.clists[self.mode]
if self.mode==self.mode_pkgs or len(clist.selection)!=1: if self.mode==self.mode_pkgs or len(clist.selection)!=1:
return return
row = clist.selection[0] #menu item only enabled if 1 item selected row = clist.selection[0] #menu item only enabled if 1 item selected
path = clist.get_text(row, 1) row_data = clist.get_data("row_data")
path = os.path.split(row_data[row])[0]
select_func=clist.select_row select_func=clist.select_row
for row in range(clist.rows): for row in xrange(clist.rows):
if clist.get_text(row, 1) == path: if os.path.split(row_data[row])[0] == path:
select_func(row, 0) select_func(row, 0)
def on_rename_activate(self, src): def on_rename_activate(self, src):
clist = self.clists[self.mode] clist = self.clists[self.mode]
if self.mode==self.mode_pkgs or len(clist.selection)!=1: if self.mode==self.mode_pkgs or len(clist.selection)!=1:
return return
row_data=clist.get_data("row_data") row_data=clist.get_data("row_data")
row=clist.selection[0] #menu item only enabled if 1 item selected row=clist.selection[0] #menu item only enabled if 1 item selected
utf8_name=clist.get_text(row,0) utf8_name=clist.get_text(row,0)
skipping to change at line 1534 skipping to change at line 1551
if os.path.exists(new_encoded_path): if os.path.exists(new_encoded_path):
translation_map={"old_path":utf8_name, "new_path":new_path} translation_map={"old_path":utf8_name, "new_path":new_path}
self.ShowErrors(_( self.ShowErrors(_(
"Error: Can't rename [%(old_path)s] as "\ "Error: Can't rename [%(old_path)s] as "\
"[%(new_path)s] exists") % translation_map + '\n') "[%(new_path)s] exists") % translation_map + '\n')
else: else:
try: try:
os.rename(path_name, new_encoded_path) os.rename(path_name, new_encoded_path)
row_data.pop(row) row_data.pop(row)
clist.remove(row) clist.remove(row)
self.clist_remove_handled_groups(clist) if self.mode!=self.mode_up:
# We may want to delete the other item
# in a group of two
self.clist_remove_handled_groups(clist)
except OSError: except OSError:
self.ShowErrors(str(sys.exc_info()[1])+'\n') self.ShowErrors(str(sys.exc_info()[1])+'\n')
def on_unselect_using_wildcard_activate(self, event): def on_unselect_using_wildcard_activate(self, event):
self.select_using_wildcard(False) self.select_using_wildcard(False)
def on_select_using_wildcard_activate(self, event): def on_select_using_wildcard_activate(self, event):
self.select_using_wildcard(True) self.select_using_wildcard(True)
def select_using_wildcard(self, select): def select_using_wildcard(self, select):
clist = self.clists[self.mode] clist = self.clists[self.mode]
if clist.rows == 0: if clist.rows == 0:
skipping to change at line 1572 skipping to change at line 1592
#Convert to unicode to match unicode string below #Convert to unicode to match unicode string below
wildcard=unicode(wildcard, "utf-8") wildcard=unicode(wildcard, "utf-8")
select_func=(select and clist.select_row or clist.unselect_row) select_func=(select and clist.select_row or clist.unselect_row)
if '/' not in wildcard or self.mode == self.mode_pkgs: if '/' not in wildcard or self.mode == self.mode_pkgs:
#Convert to unicode so ? in glob matching works correctly #Convert to unicode so ? in glob matching works correctly
get_text = lambda row: unicode(clist.get_text(row,0),"utf-8") get_text = lambda row: unicode(clist.get_text(row,0),"utf-8")
else: #Note fnmatch ignores trailing \n else: #Note fnmatch ignores trailing \n
row_data = clist.get_data("row_data") row_data = clist.get_data("row_data")
get_text = lambda row: row_data[row] get_text = lambda row: row_data[row]
import fnmatch import fnmatch
for row in range(clist.rows): for row in xrange(clist.rows):
if fnmatch.fnmatch(get_text(row), wildcard): if fnmatch.fnmatch(get_text(row), wildcard):
select_func(row, 0) select_func(row, 0)
def on_select_all_but_first_in_each_group_activate(self, event): def on_select_all_but_first_in_each_group_activate(self, event):
self.on_select_all_but_one_in_each_group_activate("first") self.on_select_all_but_one_in_each_group_activate("first")
def on_select_all_but_newest_in_each_group_activate(self, event): def on_select_all_but_newest_in_each_group_activate(self, event):
self.on_select_all_but_one_in_each_group_activate("newest") self.on_select_all_but_one_in_each_group_activate("newest")
def on_select_all_but_oldest_in_each_group_activate(self, event): def on_select_all_but_oldest_in_each_group_activate(self, event):
self.on_select_all_but_one_in_each_group_activate("oldest") self.on_select_all_but_one_in_each_group_activate("oldest")
skipping to change at line 1601 skipping to change at line 1621
return row+1 return row+1
elif which == "newest": elif which == "newest":
unselect_mtime=-1 unselect_mtime=-1
comp=operator.gt comp=operator.gt
elif which == "oldest": elif which == "oldest":
unselect_mtime=2**32 unselect_mtime=2**32
comp=operator.lt comp=operator.lt
if row!=0 or not get_selectable(row, row_data): if row!=0 or not get_selectable(row, row_data):
row += 1 #for all except first row in clist_sn row += 1 #for all except first row in clist_sn
unselect_row = -1 # avoid rh bug 726252 (mtimes for group = -1?) unselect_row = -1 # avoid rh bug 726252 (mtimes for group = -1?)
while get_selectable(row, row_data) and row < clist.rows: while row < clist.rows and get_selectable(row, row_data):
mtime = clist.get_row_data(row) mtime = clist.get_row_data(row)
if comp(mtime,unselect_mtime): if comp(mtime,unselect_mtime):
unselect_mtime = mtime unselect_mtime = mtime
unselect_row=row unselect_row=row
row += 1 row += 1
return unselect_row return unselect_row
clist = self.clists[self.mode] clist = self.clists[self.mode]
row_data = clist.get_data("row_data") row_data = clist.get_data("row_data")
clist.freeze() clist.freeze()
clist.select_all() clist.select_all()
for row in range(clist.rows): for row in xrange(clist.rows):
if row==0 or not get_selectable(row, row_data): #New group if row==0 or not get_selectable(row, row_data): #New group
unselect_row = find_row_to_unselect(clist, row, which) unselect_row = find_row_to_unselect(clist, row, which)
if unselect_row == -1: if unselect_row == -1:
clist.unselect_all() clist.unselect_all()
clist.thaw() clist.thaw()
self.ShowErrors("Error getting age of group containing ["+ self.ShowErrors("Error getting age of group containing ["+
self.get_selected_path(row=row+1)+']\n') self.get_selected_path(row=row+1)+']\n')
return return
clist.unselect_row(unselect_row, 0) clist.unselect_row(unselect_row, 0)
clist.thaw() clist.thaw()
skipping to change at line 1640 skipping to change at line 1660
clist = self.clists[self.mode] clist = self.clists[self.mode]
selected = clist.selection selected = clist.selection
if not selected: if not selected:
return False return False
row_data = clist.get_data("row_data") row_data = clist.get_data("row_data")
def group_all_selected(clist, row): def group_all_selected(clist, row):
if row!=0 or not get_selectable(row, row_data): #for first sn row if row!=0 or not get_selectable(row, row_data): #for first sn row
row += 1 row += 1
while get_selectable(row, row_data) and row < clist.rows: while row < clist.rows and get_selectable(row, row_data):
if not row in selected: if not row in selected:
return False return False
row += 1 row += 1
return True return True
group=1 group=1
for row in range(clist.rows): for row in xrange(clist.rows):
if row==0 or not get_selectable(row, row_data): #New group if row==0 or not get_selectable(row, row_data): #New group
if group_all_selected(clist, row): if group_all_selected(clist, row):
if group > skip_groups: if group > skip_groups:
clist.moveto(row,0,0.0,0.0) clist.moveto(row,0,0.0,0.0)
return True return True
group += 1 group += 1
return False return False
def on_unselect_all_activate(self, event): def on_unselect_all_activate(self, event):
skipping to change at line 1680 skipping to change at line 1700
clist.select_all() clist.select_all()
for row in selected: for row in selected:
clist.unselect_row(row, 0) clist.unselect_row(row, 0)
clist.thaw() clist.thaw()
def on_selection_clicked(self, widget): def on_selection_clicked(self, widget):
self.on_selection_menu_button_press_event(self.selection, None) self.on_selection_menu_button_press_event(self.selection, None)
def clist_pkgs_sort_by_selection(self, clist): def clist_pkgs_sort_by_selection(self, clist):
selection = clist.selection selection = clist.selection
for row in range(clist.rows): for row in xrange(clist.rows):
if row in selection: if row in selection:
clist.set_text(row,3,"1") clist.set_text(row,3,"1")
else: else:
clist.set_text(row,3,"0") clist.set_text(row,3,"0")
clist.set_sort_type(gtk.SORT_DESCENDING) clist.set_sort_type(gtk.SORT_DESCENDING)
clist.set_sort_column(3) clist.set_sort_column(3)
clist.sort() clist.sort()
clist.moveto(0,0,0.0,0.0) clist.moveto(0,0,0.0,0.0)
def on_clist_pkgs_click_column(self, clist, col): def on_clist_pkgs_click_column(self, clist, col):
skipping to change at line 1803 skipping to change at line 1823
#determine if we need to select more packages #determine if we need to select more packages
self.status.set_text(_("Calculating dependencies...")) self.status.set_text(_("Calculating dependencies..."))
while gtk.events_pending(): gtk.main_iteration(False) while gtk.events_pending(): gtk.main_iteration(False)
all_deps=self.whatRequires(pkgs_selected) all_deps=self.whatRequires(pkgs_selected)
if len(all_deps) > len(pkgs_selected): if len(all_deps) > len(pkgs_selected):
num_new_pkgs = 0 num_new_pkgs = 0
for package in all_deps: for package in all_deps:
if package not in pkgs_selected: if package not in pkgs_selected:
num_new_pkgs += 1 num_new_pkgs += 1
#Note clist.find_row_from_data() only compares pointers #Note clist.find_row_from_data() only compares pointers
for row in range(clist.rows): for row in xrange(clist.rows):
if package == clist.get_row_data(row): if package == clist.get_row_data(row):
clist.select_row(row,0) clist.select_row(row,0)
#make it easy to review by grouping all selected packages #make it easy to review by grouping all selected packages
self.clist_pkgs_sort_by_selection(clist) self.clist_pkgs_sort_by_selection(clist)
self.set_cursor(None) self.set_cursor(None)
self.msgbox( self.msgbox(
_("%d extra packages need to be deleted.\n") % num_new_pkgs + _("%d extra packages need to be deleted.\n") % num_new_pkgs +
_("Please review the updated selection.") _("Please review the updated selection.")
skipping to change at line 1872 skipping to change at line 1892
clist.select_row(clist.focus_row,0) clist.select_row(clist.focus_row,0)
clist.thaw() clist.thaw()
status = str(numDeleted) + _(" items deleted") status = str(numDeleted) + _(" items deleted")
if self.mode == self.mode_pkgs: if self.mode == self.mode_pkgs:
status += ". " + human_space_left('/') status += ". " + human_space_left('/')
self.status.set_text(status) self.status.set_text(status)
self.set_cursor(None) self.set_cursor(None)
def on_autoSymlink_clicked(self, event):
self.on_autoMerge(symlink=True)
def on_autoMerge_clicked(self, event): def on_autoMerge_clicked(self, event):
self.on_autoMerge(symlink=False)
def on_autoMerge(self, symlink):
self.ClearErrors() self.ClearErrors()
self.status.delete_text(0,-1) self.status.delete_text(0,-1)
clist = self.clists[self.mode] clist = self.clists[self.mode]
if clist.rows < 3: if clist.rows < 3:
return return
question=_("Are you sure you want to merge ALL files?\n") if symlink:
question=_("Are you sure you want to symlink ALL files?\n")
else:
question=_("Are you sure you want to merge ALL files?\n")
paths_to_leave = clist.selection paths_to_leave = clist.selection
if len(paths_to_leave): if len(paths_to_leave):
question += _("(Ignoring those selected)\n") question += _("(Ignoring those selected)\n")
(response,) = self.msgbox(question, ('Yes', 'No')) (response,) = self.msgbox(question, ('Yes', 'No'))
if response != "Yes": if response != "Yes":
return return
self.set_cursor(self.WATCH) self.set_cursor(self.WATCH)
newGroup = False newGroup = False
row_data=clist.get_data("row_data") row_data=clist.get_data("row_data")
for row in range(clist.rows): for row in xrange(clist.rows):
if row in paths_to_leave: if row in paths_to_leave:
continue continue
if not get_selectable(row, row_data): #new group if not get_selectable(row, row_data): #new group
newGroup = True newGroup = True
else: else:
path = row_data[row][:-1] #strip '\n' path = row_data[row][:-1] #strip '\n'
if newGroup: if newGroup:
keepfile = path keepfile = path
newGroup = False newGroup = False
else: else:
dupfile = path dupfile = path
dupdir = os.path.dirname(dupfile) dupdir = os.path.dirname(dupfile)
tmpfile = tempfile.mktemp(dir=dupdir) tmpfile = tempfile.mktemp(dir=dupdir)
try: try:
try: try:
os.link(keepfile,tmpfile) if symlink:
os.symlink(os.path.realpath(keepfile),tmpfile)
else:
os.link(keepfile,tmpfile)
except OSError, value: except OSError, value:
if value.errno == errno.EXDEV: if value.errno == errno.EXDEV and not symlink:
os.symlink(os.path.realpath(keepfile),tmpfile) os.symlink(os.path.realpath(keepfile),tmpfile)
else: else:
raise raise
os.rename(tmpfile, dupfile) os.rename(tmpfile, dupfile)
clist.set_background(row, self.bg_colour) clist.set_background(row, self.bg_colour)
except OSError: except OSError:
self.ShowErrors(str(sys.exc_info()[1])+'\n') self.ShowErrors(str(sys.exc_info()[1])+'\n')
try: try:
#always try this as POSIX has bad requirement that #always try this as POSIX has bad requirement that
#rename(file1,file2) where both are links to the same #rename(file1,file2) where both are links to the same
 End of changes. 39 change blocks. 
47 lines changed or deleted 80 lines changed or added

Home  |  About  |  All  |  Newest  |  Fossies Dox  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTPS