Previously, we wouldn't catch IOError's and OSError's when a file
couldn't be opened for reading or writing. Fix this by surrounding those
locations in try-except clauses and use the 'with' syntax to properly
close files when errors occur.

This resolves issues for users with a read-only home or otherwise
read-only directories. Sadly, the artwork code downloads images directly
to disk, and if the file cannot be opened there is no artwork shown.
Fixing this is a larger issue we can resolve later.

Fixes: #16355
---
 sonata/artwork.py |   31 ++++++++++++++++++++-----------
 sonata/config.py  |    7 ++++++-
 sonata/info.py    |   26 +++++++++++++++++---------
 sonata/misc.py    |    5 ++++-
 4 files changed, 47 insertions(+), 22 deletions(-)

diff --git a/sonata/artwork.py b/sonata/artwork.py
index 6441fa8..a6fb2a1 100644
--- a/sonata/artwork.py
+++ b/sonata/artwork.py
@@ -1,3 +1,4 @@
+from __future__ import with_statement
 import os
 import threading # artwork_update starts a thread _artwork_update
 import urllib, urllib2
@@ -107,8 +108,11 @@ def on_reset_image(self, _action):
                 
misc.remove_file(self.target_image_filename(consts.ART_LOCATION_HOMECOVERS))
                 # Use blank cover as the artwork
                 dest_filename = 
self.target_image_filename(consts.ART_LOCATION_HOMECOVERS)
-                emptyfile = open(dest_filename, 'w')
-                emptyfile.close()
+                try:
+                    emptyfile = open(dest_filename, 'w')
+                    emptyfile.close()
+                except IOError:
+                    pass
             self.artwork_update(True)
 
     def artwork_set_tooltip_art(self, pix):
@@ -281,19 +285,19 @@ def get_library_artwork_cached_pb(self, cache_key, 
origpb):
     def artwork_save_cache(self):
         misc.create_dir('~/.config/sonata/')
         filename = os.path.expanduser("~/.config/sonata/art_cache")
-        f = open(filename, 'w')
-        f.write(repr(self.cache))
-        f.close()
+        try:
+            with open(filename, 'w') as f:
+                f.write(repr(self.cache))
+        except IOError:
+            pass
 
     def artwork_load_cache(self):
         filename = os.path.expanduser("~/.config/sonata/art_cache")
         if os.path.exists(filename):
             try:
-                f = open(filename, 'r')
-                r = f.read()
-                self.cache = eval(r)
-                f.close()
-            except:
+                with open(filename, 'r') as f:
+                        self.cache = eval(f.read())
+            except (IOError, SyntaxError):
                 self.cache = {}
         else:
             self.cache = {}
@@ -558,7 +562,12 @@ def artwork_download_img_to_file(self, artist, album, 
dest_filename, all_images=
             return False
 
         if not all_images:
-            urllib.urlretrieve(imglist[-1], dest_filename)
+            try:
+                urllib.urlretrieve(imglist[-1], dest_filename)
+            except IOError:
+                self.downloading_image = False
+                return False
+
             self.downloading_image = False
             return True
         else:
diff --git a/sonata/config.py b/sonata/config.py
index 519dc15..8423d74 100644
--- a/sonata/config.py
+++ b/sonata/config.py
@@ -8,6 +8,7 @@
 # XXX We shouldn't have the default values contain localised parts:
 self.config = config.Config(_('Default Profile'), _("by") + " %A " + _("from") 
+ " %B")
 """
+from __future__ import with_statement
 
 import os, hashlib
 import ConfigParser
@@ -471,4 +472,8 @@ def settings_save_real(self, library_get_data):
         conf.add_section('tags')
         conf.set('tags', 'use_mpdpaths', self.tags_use_mpdpath)
 
-        conf.write(file(os.path.expanduser('~/.config/sonata/sonatarc'), 'w'))
+        try:
+            with open(os.path.expanduser('~/.config/sonata/sonatarc'), 'w') as 
rc:
+                conf.write(rc)
+        except IOError:
+            pass
diff --git a/sonata/info.py b/sonata/info.py
index 8eb77c9..067be9f 100644
--- a/sonata/info.py
+++ b/sonata/info.py
@@ -1,3 +1,4 @@
+from __future__ import with_statement
 
 import sys, os, locale, urllib
 import threading # get_lyrics_start starts a thread get_lyrics_thread
@@ -358,22 +359,27 @@ def get_lyrics_thread(self, search_artist, search_title, 
filename_artist, filena
         filename = self.info_check_for_local_lyrics(filename_artist, 
filename_title, song_dir)
         search_str = misc.link_markup(_("search"), True, True, self.linkcolor)
         edit_str = misc.link_markup(_("edit"), True, True, self.linkcolor)
+        lyrics = ""
         if filename:
             # If the lyrics only contain "not found", delete the file and try 
to
             # fetch new lyrics. If there is a bug in Sonata/SZI/LyricWiki that
             # prevents lyrics from being found, storing the "not found" will
             # prevent a future release from correctly fetching the lyrics.
-            f = open(filename, 'r')
-            lyrics = f.read()
-            f.close()
+            try:
+                with open(filename, 'r') as f:
+                    lyrics = f.read()
+            except IOError:
+                pass
             if lyrics == _("Lyrics not found"):
                 misc.remove_file(filename)
                 filename = self.info_check_for_local_lyrics(filename_artist, 
filename_title, song_dir)
         if filename:
             # Re-use lyrics from file:
-            f = open(filename, 'r')
-            lyrics = f.read()
-            f.close()
+            try:
+                with open(filename, 'r') as f:
+                    lyrics = f.read()
+            except IOError:
+                pass
             # Strip artist - title line from file if it exists, since we
             # now have that information visible elsewhere.
             header = filename_artist + " - " + filename_title + "\n\n"
@@ -403,9 +409,11 @@ def get_lyrics_thread(self, search_artist, search_title, 
filename_artist, filena
                     lyrics = misc.unescape_html(lyrics)
                     lyrics = misc.wiki_to_html(lyrics)
                     misc.create_dir('~/.lyrics/')
-                    f = open(filename, 'w')
-                    f.write(lyrics)
-                    f.close()
+                    try:
+                        with open(filename, 'w') as f:
+                            f.write(lyrics)
+                    except IOError:
+                        pass
                 else:
                     lyrics = _("Lyrics not found")
                 gobject.idle_add(self.info_show_lyrics, lyrics, 
filename_artist, filename_title)
diff --git a/sonata/misc.py b/sonata/misc.py
index d8adfdb..5bb9464 100644
--- a/sonata/misc.py
+++ b/sonata/misc.py
@@ -107,7 +107,10 @@ def lower_no_the(s):
 
 def create_dir(dirname):
     if not os.path.exists(os.path.expanduser(dirname)):
-        os.makedirs(os.path.expanduser(dirname))
+        try:
+            os.makedirs(os.path.expanduser(dirname))
+        except (IOError, OSError):
+            pass
 
 def remove_file(filename):
     if os.path.exists(filename):
-- 
1.6.5.1.126.gae4ab

_______________________________________________
Sonata-users mailing list
[email protected]
https://lists.berlios.de/mailman/listinfo/sonata-users

Reply via email to