banshee r3666 - in trunk/banshee: . src/Backends/Banshee.GStreamer/Banshee.GStreamer src/Backends/Banshee.Hal/Banshee.HalBackend src/Core/Banshee.Services/Banshee.Hardware src/Core/Banshee.Services/Banshee.MediaEngine src/Extensions/Banshee.AudioCd/Banshee.AudioCd
- From: abock svn gnome org
- To: svn-commits-list gnome org
- Subject: banshee r3666 - in trunk/banshee: . src/Backends/Banshee.GStreamer/Banshee.GStreamer src/Backends/Banshee.Hal/Banshee.HalBackend src/Core/Banshee.Services/Banshee.Hardware src/Core/Banshee.Services/Banshee.MediaEngine src/Extensions/Banshee.AudioCd/Banshee.AudioCd
- Date: Fri, 4 Apr 2008 01:23:07 +0100 (BST)
Author: abock
Date: Fri Apr 4 01:23:06 2008
New Revision: 3666
URL: http://svn.gnome.org/viewvc/banshee?rev=3666&view=rev
Log:
2008-04-03 Aaron Bockover <abock gnome org>
* src/Core/Banshee.Services/Banshee.MediaEngine/IAudioCdRipper.cs:
* src/Backends/Banshee.GStreamer/Banshee.GStreamer/AudioCdRipper.cs:
Added error reporting
* src/Backends/Banshee.Hal/Banshee.HalBackend/CdromDevice.cs:
* src/Core/Banshee.Services/Banshee.Hardware/ICdromDevice.cs:
* src/Extensions/Banshee.AudioCd/Banshee.AudioCd/AudioCdDiscModel.cs:
Added drive door locking support
* src/Extensions/Banshee.AudioCd/Banshee.AudioCd/AudioCdRipper.cs: Handle
errors and dispose better; lock and unlock the drive door
* src/Extensions/Banshee.AudioCd/Banshee.AudioCd/AudioCdSource.cs:
Better error handling and do not allow ejecting if the door is locked
Modified:
trunk/banshee/ChangeLog
trunk/banshee/src/Backends/Banshee.GStreamer/Banshee.GStreamer/AudioCdRipper.cs
trunk/banshee/src/Backends/Banshee.Hal/Banshee.HalBackend/CdromDevice.cs
trunk/banshee/src/Core/Banshee.Services/Banshee.Hardware/ICdromDevice.cs
trunk/banshee/src/Core/Banshee.Services/Banshee.MediaEngine/IAudioCdRipper.cs
trunk/banshee/src/Extensions/Banshee.AudioCd/Banshee.AudioCd/AudioCdDiscModel.cs
trunk/banshee/src/Extensions/Banshee.AudioCd/Banshee.AudioCd/AudioCdRipper.cs
trunk/banshee/src/Extensions/Banshee.AudioCd/Banshee.AudioCd/AudioCdSource.cs
Modified: trunk/banshee/src/Backends/Banshee.GStreamer/Banshee.GStreamer/AudioCdRipper.cs
==============================================================================
--- trunk/banshee/src/Backends/Banshee.GStreamer/Banshee.GStreamer/AudioCdRipper.cs (original)
+++ trunk/banshee/src/Backends/Banshee.GStreamer/Banshee.GStreamer/AudioCdRipper.cs Fri Apr 4 01:23:06 2008
@@ -39,6 +39,7 @@
{
public event AudioCdRipperProgressHandler Progress;
public event AudioCdRipperTrackFinishedHandler TrackFinished;
+ public event AudioCdRipperErrorHandler Error;
public void Begin ()
{
@@ -68,12 +69,12 @@
TimeSpan progress = TimeSpan.FromMilliseconds ((ellapsed.TotalMilliseconds
/ duration.TotalMilliseconds) * track.Duration.TotalMilliseconds);
- ThreadAssist.ProxyToMain (delegate { OnProgress (track, progress); });
+ OnProgress (track, progress);
Thread.Sleep (50);
}
- ThreadAssist.ProxyToMain (delegate { OnTrackFinished (track, outputUri); });
+ OnTrackFinished (track, outputUri);
});
return;
@@ -94,5 +95,13 @@
handler (this, new AudioCdRipperTrackFinishedArgs (track, outputUri));
}
}
+
+ protected virtual void OnError (TrackInfo track, string message)
+ {
+ AudioCdRipperErrorHandler handler = Error;
+ if (handler != null) {
+ handler (this, new AudioCdRipperErrorArgs (track, message));
+ }
+ }
}
}
Modified: trunk/banshee/src/Backends/Banshee.Hal/Banshee.HalBackend/CdromDevice.cs
==============================================================================
--- trunk/banshee/src/Backends/Banshee.Hal/Banshee.HalBackend/CdromDevice.cs (original)
+++ trunk/banshee/src/Backends/Banshee.Hal/Banshee.HalBackend/CdromDevice.cs Fri Apr 4 01:23:06 2008
@@ -27,8 +27,8 @@
//
using System;
-using System.Collections;
-using System.Collections.Generic;
+using System.Runtime.InteropServices;
+using Mono.Unix;
using Banshee.Hardware;
@@ -48,5 +48,49 @@
private CdromDevice (Hal.Manager manager, Hal.Device device) : base (manager, device)
{
}
+
+ [DllImport ("libc")]
+ private static extern int ioctl (int device, IoctlOperation request, bool lockdoor);
+
+ private enum IoctlOperation {
+ LockDoor = 0x5329
+ }
+
+ private bool is_door_locked = false;
+
+ private bool LockDeviceNode (string device, bool lockdoor)
+ {
+ try {
+ using (UnixStream stream = (new UnixFileInfo (device)).Open (
+ Mono.Unix.Native.OpenFlags.O_RDONLY |
+ Mono.Unix.Native.OpenFlags.O_NONBLOCK)) {
+ bool success = ioctl (stream.Handle, IoctlOperation.LockDoor, lockdoor) == 0;
+ is_door_locked = success && lockdoor;
+ return success;
+ }
+ } catch {
+ return false;
+ }
+ }
+
+ public bool LockDoor ()
+ {
+ lock (this) {
+ return LockDeviceNode (DeviceNode, true);
+ }
+ }
+
+ public bool UnlockDoor ()
+ {
+ lock (this) {
+ return LockDeviceNode (DeviceNode, false);
+ }
+ }
+
+ // FIXME: This is incredibly lame, there must be a way to query the
+ // device itself rather than hackisly attempting to keep track of it
+ public bool IsDoorLocked {
+ get { return is_door_locked; }
+ }
}
}
Modified: trunk/banshee/src/Core/Banshee.Services/Banshee.Hardware/ICdromDevice.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.Services/Banshee.Hardware/ICdromDevice.cs (original)
+++ trunk/banshee/src/Core/Banshee.Services/Banshee.Hardware/ICdromDevice.cs Fri Apr 4 01:23:06 2008
@@ -33,5 +33,8 @@
{
public interface ICdromDevice : IBlockDevice
{
+ bool LockDoor ();
+ bool UnlockDoor ();
+ bool IsDoorLocked { get; }
}
}
Modified: trunk/banshee/src/Core/Banshee.Services/Banshee.MediaEngine/IAudioCdRipper.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.Services/Banshee.MediaEngine/IAudioCdRipper.cs (original)
+++ trunk/banshee/src/Core/Banshee.Services/Banshee.MediaEngine/IAudioCdRipper.cs Fri Apr 4 01:23:06 2008
@@ -35,11 +35,13 @@
{
public delegate void AudioCdRipperProgressHandler (object o, AudioCdRipperProgressArgs args);
public delegate void AudioCdRipperTrackFinishedHandler (object o, AudioCdRipperTrackFinishedArgs args);
+ public delegate void AudioCdRipperErrorHandler (object o, AudioCdRipperErrorArgs args);
public interface IAudioCdRipper
{
event AudioCdRipperProgressHandler Progress;
event AudioCdRipperTrackFinishedHandler TrackFinished;
+ event AudioCdRipperErrorHandler Error;
void Begin ();
void Finish ();
@@ -91,4 +93,23 @@
get { return uri; }
}
}
+
+ public sealed class AudioCdRipperErrorArgs : EventArgs
+ {
+ public AudioCdRipperErrorArgs (TrackInfo track, string message)
+ {
+ this.track = track;
+ this.message = message;
+ }
+
+ private TrackInfo track;
+ public TrackInfo Track {
+ get { return track; }
+ }
+
+ private string message;
+ public string Message {
+ get { return message; }
+ }
+ }
}
Modified: trunk/banshee/src/Extensions/Banshee.AudioCd/Banshee.AudioCd/AudioCdDiscModel.cs
==============================================================================
--- trunk/banshee/src/Extensions/Banshee.AudioCd/Banshee.AudioCd/AudioCdDiscModel.cs (original)
+++ trunk/banshee/src/Extensions/Banshee.AudioCd/Banshee.AudioCd/AudioCdDiscModel.cs Fri Apr 4 01:23:06 2008
@@ -178,6 +178,29 @@
});
}
+ private ICdromDevice Drive {
+ get { return Volume == null ? null : (Volume.Parent as ICdromDevice); }
+ }
+
+ public bool LockDoor ()
+ {
+ ICdromDevice drive = Drive;
+ return drive != null ? drive.LockDoor () : false;
+ }
+
+ public bool UnlockDoor ()
+ {
+ ICdromDevice drive = Drive;
+ return drive != null ? drive.UnlockDoor () : false;
+ }
+
+ public bool IsDoorLocked {
+ get {
+ ICdromDevice drive = Drive;
+ return drive != null ? drive.IsDoorLocked : false;
+ }
+ }
+
public IDiscVolume Volume {
get { return volume; }
}
Modified: trunk/banshee/src/Extensions/Banshee.AudioCd/Banshee.AudioCd/AudioCdRipper.cs
==============================================================================
--- trunk/banshee/src/Extensions/Banshee.AudioCd/Banshee.AudioCd/AudioCdRipper.cs (original)
+++ trunk/banshee/src/Extensions/Banshee.AudioCd/Banshee.AudioCd/AudioCdRipper.cs Fri Apr 4 01:23:06 2008
@@ -39,7 +39,7 @@
namespace Banshee.AudioCd
{
- public class AudioCdRipper
+ public class AudioCdRipper : IDisposable
{
private static bool ripper_extension_queried = false;
private static TypeExtensionNode ripper_extension_node = null;
@@ -85,6 +85,7 @@
ripper = (IAudioCdRipper)ripper_extension_node.CreateInstance ();
ripper.TrackFinished += OnTrackFinished;
ripper.Progress += OnProgress;
+ ripper.Error += OnError;
} else {
throw new ApplicationException ("No AudioCdRipper extension is installed");
}
@@ -96,7 +97,7 @@
{
ResetState ();
- foreach (AudioCdTrackInfo track in (AudioCdDiscModel)source.TrackModel) {
+ foreach (AudioCdTrackInfo track in source.DiscModel) {
if (track.RipEnabled) {
total_duration += track.Duration;
queue.Enqueue (track);
@@ -111,15 +112,44 @@
user_job = new UserJob (Catalog.GetString ("Importing Audio CD"),
Catalog.GetString ("Initializing Drive"), "media-import-audio-cd");
+ user_job.CancelMessage = String.Format (Catalog.GetString (
+ "<i>{0}</i> is still being imported into the music library. Would you like to stop it?"
+ ), GLib.Markup.EscapeText (source.DiscModel.Title));
user_job.CanCancel = true;
user_job.CancelRequested += OnCancelRequested;
user_job.Finished += OnFinished;
user_job.Register ();
+ if (source != null && source.DiscModel != null) {
+ if (!source.DiscModel.LockDoor ()) {
+ Hyena.Log.Warning ("Could not lock CD-ROM door", false);
+ }
+ }
+
ripper.Begin ();
+
RipNextTrack ();
}
+ public void Dispose ()
+ {
+ ResetState ();
+
+ if (source != null && source.DiscModel != null) {
+ source.DiscModel.UnlockDoor ();
+ }
+
+ if (ripper != null) {
+ ripper.Finish ();
+ ripper = null;
+ }
+
+ if (user_job != null) {
+ user_job.Finish ();
+ user_job = null;
+ }
+ }
+
private void ResetState ()
{
track_index = 0;
@@ -135,15 +165,7 @@
private void RipNextTrack ()
{
if (queue.Count == 0) {
- ResetState ();
-
- if (ripper != null) {
- ripper.Finish ();
- }
-
- if (user_job != null) {
- user_job.Finish ();
- }
+ Dispose ();
return;
}
@@ -153,7 +175,7 @@
++track_index, source.TrackModel.Count);
status = String.Format("{0} - {1}", track.ArtistName, track.TrackTitle);
user_job.Status = status;
-
+
SafeUri uri = new SafeUri (FileNamePattern.BuildFull (track, "mp3"));
ripper.RipTrack (track, uri);
}
@@ -196,6 +218,12 @@
user_job.Status = last_speed_poll_factor > 1 ? String.Format ("{0} ({1:0.0}x)",
status, last_speed_poll_factor) : status;
}
+
+ private void OnError (object o, AudioCdRipperErrorArgs args)
+ {
+ Dispose ();
+ Hyena.Log.Error (Catalog.GetString ("Cannot Import CD"), args.Message, true);
+ }
#endregion
@@ -203,15 +231,7 @@
private void OnCancelRequested (object o, EventArgs args)
{
- ResetState ();
-
- if (ripper != null) {
- ripper.Cancel ();
- }
-
- if (user_job != null) {
- user_job.Finish ();
- }
+ Dispose ();
}
private void OnFinished (object o, EventArgs args)
Modified: trunk/banshee/src/Extensions/Banshee.AudioCd/Banshee.AudioCd/AudioCdSource.cs
==============================================================================
--- trunk/banshee/src/Extensions/Banshee.AudioCd/Banshee.AudioCd/AudioCdSource.cs (original)
+++ trunk/banshee/src/Extensions/Banshee.AudioCd/Banshee.AudioCd/AudioCdSource.cs Fri Apr 4 01:23:06 2008
@@ -144,9 +144,20 @@
private void OnImportDisc (object o, EventArgs args)
{
- if (AudioCdRipper.Supported) {
- AudioCdRipper ripper = new AudioCdRipper (this);
- ripper.Start ();
+ AudioCdRipper ripper = null;
+
+ try {
+ if (AudioCdRipper.Supported) {
+ ripper = new AudioCdRipper (this);
+ ripper.Start ();
+ }
+ } catch (Exception e) {
+ if (ripper != null) {
+ ripper.Dispose ();
+ }
+
+ Log.Error (Catalog.GetString ("Could not import CD"), e.Message, true);
+ Log.Exception (e);
}
}
@@ -293,7 +304,7 @@
}
public bool CanUnmap {
- get { return true; }
+ get { return DiscModel != null ? !DiscModel.IsDoorLocked : true; }
}
public bool ConfirmBeforeUnmap {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]