Blob Blame History Raw
diff -Nur soundconverter-2.0.4-orig/soundconverter/error.py soundconverter-2.0.4/soundconverter/error.py
--- soundconverter-2.0.4-orig/soundconverter/error.py	2012-01-04 00:23:34.000000000 +0100
+++ soundconverter-2.0.4/soundconverter/error.py	2013-02-24 16:01:24.704306433 +0100
@@ -60,7 +60,10 @@
 class ErrorPrinter:
 
     def show_error(self, primary, secondary):
-        sys.stderr.write(_('\n\nError: %s\n%s\n') % (primary, secondary))
+        try:
+            sys.stderr.write(_('\n\nError: %s\n%s\n') % (primary, secondary))
+        except:
+            pass
         sys.exit(1)
 
     def show_exception(self, e):
diff -Nur soundconverter-2.0.4-orig/soundconverter/fileoperations.py soundconverter-2.0.4/soundconverter/fileoperations.py
--- soundconverter-2.0.4-orig/soundconverter/fileoperations.py	2012-01-04 00:23:34.000000000 +0100
+++ soundconverter-2.0.4/soundconverter/fileoperations.py	2013-02-24 16:01:24.705306377 +0100
@@ -109,10 +109,10 @@
     """Convert a filename to a valid uri.
     Filename can be a relative or absolute path, or an uri.
     """
-    url = urlparse.urlparse(filename)
-    if not url[0]:
+    if '://' not in filename:
+        # convert local filename to uri
         filename = urllib.pathname2url(os.path.abspath(filename))
-        filename = str(gnomevfs.URI(filename))
+    filename = str(gnomevfs.URI(filename))
     return filename
 
 
diff -Nur soundconverter-2.0.4-orig/soundconverter/gstreamer.py soundconverter-2.0.4/soundconverter/gstreamer.py
--- soundconverter-2.0.4-orig/soundconverter/gstreamer.py	2012-10-04 13:56:26.000000000 +0200
+++ soundconverter-2.0.4/soundconverter/gstreamer.py	2013-02-25 19:04:02.270310794 +0100
@@ -142,6 +142,7 @@
         self.error = None
         self.connected_signals = []
         self.aborted = False
+        self.plugin_added = False
 
     def started(self):
         self.play()
@@ -181,13 +182,17 @@
             gst.update_registry()
             self.parsed = False
             self.duration = None
-            self.finished()
-            vfs_unlink(self.output_filename)
+            Pipeline.finished(self)
+            if hasattr(self,'output_filename'):
+                if vfs_exists(self.output_filename):
+                    vfs_unlink(self.output_filename)
+            self.plugin_added = True
             self.play()
             return
-        self.done()
+        self.error = 'Could not install missing GStreamer plug-in.'
+        self.done()  # this also emits 'finished'
         if result == gst.pbutils.INSTALL_PLUGINS_USER_ABORT:
-            show_error(_('Plugin installation aborted.'))
+            show_error('Error',_('Plugin installation aborted.'))
             return
 
         show_error('Error', 'failed to install plugins: %s' % gobject.markup_escape_text(str(result)))
@@ -456,10 +461,14 @@
 
     def finished(self):
         Pipeline.finished(self)
-        self.sound_file.tags_read = True
+        if not self.error:
+            # found_tag_hook must evaluate this properly as not to
+            # add the file to the converter queue on error condition
+            self.sound_file.tags_read = True
         if self.found_tag_hook:
             gobject.idle_add(self.found_tag_hook, self)
-        dontdelete.remove(self)
+        if self in dontdelete:
+            dontdelete.remove(self)
 
 
 class Converter(Decoder):
@@ -501,24 +510,23 @@
             'gst-profile': self.add_audio_profile,
         }
         self.add_command('audiorate')
-        self.add_command('audioresample')
         self.add_command('audioconvert')
+        self.add_command('audioresample')
 
-        # audio resampling support
-        if self.output_resample:
-            self.add_command('audio/x-raw-int,rate=%d' % self.resample_rate)
-            self.add_command('audioresample')
-            self.add_command('audioconvert')
-
-        if self.force_mono:
-            self.add_command('audio/x-raw-int,channels=1')
+        if self.output_resample or self.force_mono:
+            cmd = 'audio/x-raw-int'
+            if self.output_resample:
+                cmd += ',rate=%d' % self.resample_rate
+            if self.force_mono:
+                cmd += ',channels=1'
+            self.add_command(cmd)
             self.add_command('audioconvert')
 
         encoder = self.encoders[self.output_type]()
         if not encoder:
             # TODO: is this used ?
             # TODO: add proper error management when an encoder cannot be created
-            show_error(_("Cannot create a decoder for \'%s\' format.") % 
+            show_error('Error',_("Cannot create a decoder for \'%s\' format.") % 
                         self.output_type)
             return
 
@@ -529,7 +537,7 @@
         if dirname and not gnomevfs.exists(dirname):
             log('Creating folder: \'%s\'' % dirname)
             if not vfs_makedirs(str(dirname)):
-                show_error(_("Cannot create \'%s\' folder.") % dirname)
+                show_error('Error',_("Cannot create \'%s\' folder.") % dirname)
                 return
 
         self.add_command('%s location="%s"' % (
@@ -828,6 +836,7 @@
         self.errors.append(task.error)
         if task.error:
             self.error_count += 1
+        task.sound_file.progress = 1.0
 
     def finished(self):
         if self.running_tasks:
diff -Nur soundconverter-2.0.4-orig/soundconverter/ui.py soundconverter-2.0.4/soundconverter/ui.py
--- soundconverter-2.0.4-orig/soundconverter/ui.py	2012-10-06 12:43:23.000000000 +0200
+++ soundconverter-2.0.4/soundconverter/ui.py	2013-02-24 17:30:25.781472411 +0100
@@ -93,7 +93,10 @@
     def show_error(self, primary, secondary):
         self.primary.set_markup(primary)
         self.secondary.set_markup(secondary)
-        sys.stderr.write(_('\nError: %s\n%s\n') % (primary, secondary))
+        try:
+            sys.stderr.write(_('\nError: %s\n%s\n') % (primary, secondary))
+        except:
+            pass
         self.dialog.run()
         self.dialog.hide()
 
@@ -109,7 +112,10 @@
         self.primary = builder.get_object('label_error')
 
     def show_error(self, primary, secondary):
-        sys.stderr.write(_('\nError: %s\n%s\n') % (primary, secondary))
+        try:
+            sys.stderr.write(_('\nError: %s\n%s\n') % (primary, secondary))
+        except:
+            pass
         #self.msg_area.set_text_and_icon(gtk.STOCK_DIALOG_ERROR, primary, secondary)
         #self.msg_area.show()
         self.primary.set_text(primary)
@@ -177,6 +183,7 @@
     def drag_data_received(self, widget, context, x, y, selection,
                              mime_id, time):
 
+        widget.stop_emission('drag_data_received')
         if mime_id >= 0 and mime_id < len(self.drop_mime_types):
             self.add_uris([uri.strip() for uri in selection.data.split('\n')])
             context.finish(True, False, time)
@@ -248,8 +255,13 @@
                 files.append(uri)
 
         if not base:
-            base, notused = os.path.split(os.path.commonprefix(files))
-        base += '/'
+            base = os.path.commonprefix(files)
+            if base and not base.endswith('/'):
+                # we want a common folder
+                base = base[0:base.rfind('/')]
+                base += '/'
+        else:
+            base += '/'
 
         for f in files:
             sound_file = SoundFile(f, base)
@@ -542,6 +554,9 @@
         for b in widgets:
             mime, encoder_name = b
             encoder_present = encoder_name in available_elements
+            # special brute-force check to disable this encoder
+            if mime == 'gst-profile' and len(audio_profiles_list) == 0:
+                encoder_name = 'no GNOME Audio Profiles available'
             if encoder_name and not encoder_present:
                 del model[i]
                 if mime_type == mime:
@@ -812,9 +827,9 @@
 
     def on_choose_folder_clicked(self, button):
         ret = self.target_folder_chooser.run()
+        folder = self.target_folder_chooser.get_uri()
         self.target_folder_chooser.hide()
         if ret == gtk.RESPONSE_OK:
-            folder = self.target_folder_chooser.get_uri()
             if folder:
                 self.set_string('selected-folder', urllib.unquote(folder))
                 self.update_selected_folder()
@@ -1254,8 +1269,8 @@
             self.addchooser.set_current_folder_uri(last_folder)
 
         ret = self.addchooser.run()
-        self.addchooser.hide()
         folder = self.addchooser.get_current_folder_uri()
+        self.addchooser.hide()
         if ret == gtk.RESPONSE_OK and folder:
             self.filelist.add_uris(self.addchooser.get_uris())
             self.prefs.set_string('last-used-folder', folder)
@@ -1267,18 +1282,15 @@
             self.addfolderchooser.set_current_folder_uri(last_folder)
 
         ret = self.addfolderchooser.run()
+        folders = self.addfolderchooser.get_uris()
+        folder = self.addfolderchooser.get_current_folder_uri()
         self.addfolderchooser.hide()
         if ret == gtk.RESPONSE_OK:
-
-            folders = self.addfolderchooser.get_uris()
-
             extensions = None
             if self.combo.get_active():
                 patterns = filepattern[self.combo.get_active()][1].split(';')
                 extensions = [os.path.splitext(p)[1] for p in patterns]
             self.filelist.add_uris(folders, extensions=extensions)
-
-            folder = self.addfolderchooser.get_current_folder_uri()
             if folder:
                 self.prefs.set_string('last-used-folder', folder)
 
@@ -1287,7 +1299,8 @@
     def on_remove_activate(self, *args):
         model, paths = self.filelist_selection.get_selected_rows()
         while paths:
-            i = self.filelist.model.get_iter(paths[0])
+            childpath = model.convert_path_to_child_path(paths[0])
+            i = self.filelist.model.get_iter(childpath)
             self.filelist.remove(i)
             model, paths = self.filelist_selection.get_selected_rows()
         self.set_sensitive()
@@ -1305,11 +1318,22 @@
 
         tagreader = TagReader(sound_file)
         tagreader.set_found_tag_hook(self.tags_read)
+        self.tag_reader_tasks.append(tagreader)
         tagreader.start()
 
     def tags_read(self, tagreader):
+        self.tag_reader_tasks.remove(tagreader)
+        if tagreader.plugin_added:
+            self.plugin_added = True
         sound_file = tagreader.get_sound_file()
-        self.converter.add(sound_file)
+        try:
+            if not sound_file.tags_read:
+                raise ConverterQueueError
+            self.converter.add(sound_file)
+        except ConverterQueueCanceled:
+            self.tag_reader_exception = ConverterQueueCanceled
+        except ConverterQueueError:
+            self.tag_reader_exception = ConverterQueueError
 
     def on_progress(self):
         if self.pulse_progress >= 0: # still waiting for tags
@@ -1335,7 +1359,11 @@
                     sound_file.progress = None
         return running
 
-    def do_convert(self):
+    def do_convert_real(self):
+        self.plugin_added = False
+        self.tag_reader_exception = None
+        self.tag_reader_tasks = []
+        self.converter.abort()  # to start with empty queues
         try:
             self.pulse_progress = -1
             gobject.timeout_add(100, self.on_progress)
@@ -1347,6 +1375,10 @@
             total = len(files)
             for i, sound_file in enumerate(files):
                 gtk_iteration()
+                e = self.tag_reader_exception
+                if e:
+                    log("Forwarded exception!")
+                    raise e
                 self.pulse_progress = float(i)/total
                 sound_file.progress = None
                 if self.prefs.require_tags:
@@ -1354,6 +1386,15 @@
                 else:
                     self.converter.add(sound_file)
 
+            while len(self.tag_reader_tasks)>0 and len(self.converter.waiting_tasks) < total:
+                gtk_sleep(1)
+                e = self.tag_reader_exception
+                if e:
+                    log("Forwarded exception!")
+                    raise e
+                if self.plugin_added:
+                    break
+
         except ConverterQueueCanceled:
             log('cancelling conversion.')
             self.conversion_ended()
@@ -1362,12 +1403,22 @@
             self.conversion_ended()
             self.set_status(_('Error when converting'))
         else:
+            if self.plugin_added:
+                print "Restarting after GStreamer plug-in installation!"
+                return False
             self.set_status('')
             self.pulse_progress = None
             self.converter.start()
             self.set_sensitive()
         return False
 
+    def do_convert(self):
+        while (1):
+            r = self.do_convert_real()
+            if not self.plugin_added:
+                break
+        return r
+
     def on_convert_button_clicked(self, *args):
         # reset and show progress bar
         self.set_progress(0)
@@ -1395,6 +1446,8 @@
 
     def on_button_cancel_clicked(self, *args):
         self.converter.abort()
+        self.tag_reader_tasks = []
+        self.converter.waiting_tasks = []
         self.set_status(_('Canceled'))
         self.set_sensitive()
         self.conversion_ended()
@@ -1430,6 +1483,7 @@
         self.filelist.hide_row_progress()
         self.status_frame.show()
         self.widget.set_sensitive(True)
+        self.converter.abort()
         try:
             from gi.repository import Unity
             launcher = Unity.LauncherEntry.get_for_desktop_id ("soundconverter.desktop")