changeset 123:f2589475269f

file_management: unicode was badly handled. As a quick solution, we handle everything as unicode, and ignore badly encoded filenames, this may change in the future
author Goffi <goffi@goffi.org>
date Sat, 05 Mar 2016 14:32:35 +0100
parents 00b012549f88
children db9bc68ca0a8
files urwid_satext/files_management.py
diffstat 1 files changed, 34 insertions(+), 22 deletions(-) [+]
line wrap: on
line diff
--- a/urwid_satext/files_management.py	Sun Jan 03 16:58:04 2016 +0100
+++ b/urwid_satext/files_management.py	Sat Mar 05 14:32:35 2016 +0100
@@ -21,7 +21,7 @@
 import sat_widgets
 import os, os.path
 from xml.dom import minidom
-from logging import debug, info, error
+import logging as log
 from time import time
 from .keys import action_key_map as a_key
 
@@ -32,9 +32,9 @@
     """AdvancedEdit with manage file paths"""
 
     def keypress(self, size, key):
-        if key == '~' and self.edit_pos==0:
-            expanded = os.path.expanduser('~')
-            self.set_edit_text(os.path.normpath(expanded+'/'+self.edit_text))
+        if key == u'~' and self.edit_pos==0:
+            expanded = os.path.expanduser(u'~')
+            self.set_edit_text(os.path.normpath(expanded+u'/'+self.edit_text))
             self.set_edit_pos(len(expanded)+1)
         elif key == a_key['EDIT_DELETE_LAST_WORD']:
             if self.edit_pos<2:
@@ -91,13 +91,15 @@
             return self._w.keypress(size, key)
 
     def showDirectory(self, path):
-        path = path.encode('utf-8')
         self.path = path
         del self.files_list[:]
         directories = []
         files = []
         try:
             for filename in os.listdir(path):
+                if not isinstance(filename, unicode):
+                    log.warning(u"file [{}] has a badly encode filename, ignoring it".format(filename.decode('utf-8', 'replace')))
+                    continue
                 fullpath = os.path.join(path,filename)
                 if os.path.isdir(fullpath):
                     directories.append(filename)
@@ -107,19 +109,19 @@
            self.files_list.append(urwid.Text(("warning",_("Impossible to list directory")),'center'))
         directories.sort()
         files.sort()
-        if os.path.abspath(path)!='/' and os.path.abspath(path) != '//':
-            previous_wid = sat_widgets.ClickableText(('directory','..'))
+        if os.path.abspath(path)!=u'/' and os.path.abspath(path) != u'//':
+            previous_wid = sat_widgets.ClickableText((u'directory',u'..'))
             urwid.connect_signal(previous_wid,'click',self.onPreviousDir)
             self.files_list.append(previous_wid)
         for directory in directories:
             if directory.startswith('.') and not self.show_hidden:
                 continue
-            dir_wid = sat_widgets.ClickableText(('directory',directory))
+            dir_wid = sat_widgets.ClickableText((u'directory',directory))
             urwid.connect_signal(dir_wid,'click',self.onDirClick)
             self.files_list.append(dir_wid)
-        self.files_list.append(urwid.AttrMap(urwid.Divider('-'),'separator'))
+        self.files_list.append(urwid.AttrMap(urwid.Divider(u'-'),'separator'))
         for filename in files:
-            if filename.startswith('.') and not self.show_hidden:
+            if filename.startswith(u'.') and not self.show_hidden:
                 continue
             file_wid = sat_widgets.ClickableText(filename)
             if self.onFileClick:
@@ -127,7 +129,6 @@
             self.files_list.append(file_wid)
 
 
-
 class FileDialog(urwid.WidgetWrap):
 
     def __init__(self, ok_cb, cancel_cb, message=None, title=_("Please select a file"), style=[]):
@@ -141,12 +142,12 @@
         """
         self.ok_cb = ok_cb
         self._type = 'dir' if 'dir' in style else 'normal'
-        self.__home_path = os.path.expanduser('~')
+        self.__home_path = os.path.expanduser(u'~')
         widgets = []
         if message:
             widgets.append(urwid.Text(message))
             widgets.append(urwid.Divider(u'─'))
-        self.path_wid = PathEdit(_('Path: '))
+        self.path_wid = PathEdit(_(u'Path: '))
         self.path_wid.setCompletionMethod(self._directory_completion)
         urwid.connect_signal(self.path_wid, 'change', self.onPathChange)
         widgets.append(self.path_wid)
@@ -157,11 +158,11 @@
         self.bookmarks.sort()
         for bookmark in self.bookmarks:
             if bookmark.startswith(self.__home_path):
-                bookmark="~"+bookmark[len(self.__home_path):]
+                bookmark=u"~"+bookmark[len(self.__home_path):]
             book_wid = sat_widgets.ClickableText(bookmark)
             urwid.connect_signal(book_wid, 'click', self.onBookmarkSelected)
             bookm_list.append(book_wid)
-        bookm_wid = urwid.Frame(urwid.ListBox(bookm_list), urwid.AttrMap(urwid.Text(_('Bookmarks'),'center'),'title'))
+        bookm_wid = urwid.Frame(urwid.ListBox(bookm_list), urwid.AttrMap(urwid.Text(_(u'Bookmarks'),'center'),'title'))
         self.files_wid = FilesViewer(self.onPreviousDir, self.onDirClick, self.onFileClick if self._type == 'normal' else None)
         center_row = urwid.Columns([('weight',2,bookm_wid),
                      ('weight',8,sat_widgets.VerticalSeparator(self.files_wid))])
@@ -184,14 +185,25 @@
             self.ok_cb(path)
 
     def _directory_completion(self, path, completion_data):
+        assert isinstance(path, unicode)
         path=os.path.abspath(path)
         if not os.path.isdir(path):
             head,dir_start = os.path.split(path)
         else:
             head=path
-            dir_start=''
+            dir_start=u''
         try:
             filenames = os.listdir(head)
+            to_remove = []
+
+            # we remove badly encoded files
+            for filename in filenames:
+                if not isinstance(filename, unicode):
+                    log.warning(u"file [{}] has a badly encode filename, ignoring it".format(filename.decode('utf-8', 'replace')))
+                    to_remove.append(filename)
+            for filename in to_remove:
+                filenames.remove(filename)
+
             filenames.sort()
             try:
                 start_idx=filenames.index(completion_data['last_dir'])+1
@@ -209,16 +221,16 @@
         return path
 
     def getBookmarks(self):
-        gtk_bookm = os.path.expanduser("~/.gtk-bookmarks")
-        kde_bookm = os.path.expanduser("~/.kde/share/apps/kfileplaces/bookmarks.xml")
+        gtk_bookm = os.path.expanduser(u"~/.gtk-bookmarks")
+        kde_bookm = os.path.expanduser(u"~/.kde/share/apps/kfileplaces/bookmarks.xml")
         bookmarks = set()
         try:
             with open(gtk_bookm) as gtk_fd:
                 for bm in gtk_fd.readlines():
                     if bm.startswith("file:///"):
-                        bookmarks.add(bm[7:].replace('\n',''))
+                        bookmarks.add(bm[7:].replace('\n','').decode('utf-8', 'replace'))
         except IOError:
-            info(_('No GTK bookmarks file found'))
+            log.info(_(u'No GTK bookmarks file found'))
             pass
 
         try:
@@ -226,9 +238,9 @@
             for elem in dom.getElementsByTagName('bookmark'):
                 bm = elem.getAttribute("href")
                 if bm.startswith("file:///"):
-                    bookmarks.add(bm[7:])
+                    bookmarks.add(bm[7:].decode('utf-8', 'replace'))
         except IOError:
-            info(_('No KDE bookmarks file found'))
+            log.info(_('No KDE bookmarks file found'))
             pass
 
         return bookmarks