~ubuntu-branches/ubuntu/quantal/banshee/quantal

« back to all changes in this revision

Viewing changes to src/Extensions/Banshee.OpticalDisc/Banshee.OpticalDisc.AudioCd/AudioCdDiscModel.cs

  • Committer: Package Import Robot
  • Author(s): Chow Loong Jin
  • Date: 2011-11-08 13:15:58 UTC
  • mfrom: (6.3.19 experimental)
  • Revision ID: package-import@ubuntu.com-20111108131558-01mm4onctf35qgqo
Tags: 2.3.1-1ubuntu1
* Merge from Debian Experimental, remaining changes:
  + Enable SoundMenu and Disable NotificationArea by default
  + Disable boo and karma extensions
  + Enable and recommnd u1ms and soundmenu extensions
  + Move desktop file for Meego UI to /usr/share/une/applications
  + Change the url for the Amazon store redirector
  + [08dea2c] Revert "Fix invalid cast causing ftbfs with libgpod"

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//
 
2
// AudioCdDisc.cs
 
3
//
 
4
// Author:
 
5
//   Aaron Bockover <abockover@novell.com>
 
6
//   Alex Launi <alex.launi@canonical.com>
 
7
//
 
8
// Copyright (C) 2008 Novell, Inc.
 
9
//
 
10
// Permission is hereby granted, free of charge, to any person obtaining
 
11
// a copy of this software and associated documentation files (the
 
12
// "Software"), to deal in the Software without restriction, including
 
13
// without limitation the rights to use, copy, modify, merge, publish,
 
14
// distribute, sublicense, and/or sell copies of the Software, and to
 
15
// permit persons to whom the Software is furnished to do so, subject to
 
16
// the following conditions:
 
17
//
 
18
// The above copyright notice and this permission notice shall be
 
19
// included in all copies or substantial portions of the Software.
 
20
//
 
21
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 
22
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 
23
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 
24
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 
25
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 
26
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 
27
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
28
//
 
29
 
 
30
using System;
 
31
using System.Threading;
 
32
using System.Collections.Generic;
 
33
using System.Collections.ObjectModel;
 
34
 
 
35
using Mono.Unix;
 
36
using MusicBrainz;
 
37
 
 
38
using Hyena;
 
39
using Banshee.Base;
 
40
using Banshee.Hardware;
 
41
using Banshee.Collection;
 
42
using Banshee.Collection.Database;
 
43
 
 
44
namespace Banshee.OpticalDisc.AudioCd
 
45
{
 
46
    public class AudioCdDiscModel : DiscModel
 
47
    {
 
48
        // 44.1 kHz sample rate * 16 bit channel resolution * 2 channels (stereo)
 
49
        private const long PCM_FACTOR = 176400;
 
50
 
 
51
        public event EventHandler MetadataQueryStarted;
 
52
        public event EventHandler MetadataQueryFinished;
 
53
        public event EventHandler EnabledCountChanged;
 
54
 
 
55
        private bool metadata_query_success;
 
56
        private DateTime metadata_query_start_time;
 
57
 
 
58
        public bool MetadataQuerySuccess {
 
59
            get { return metadata_query_success; }
 
60
        }
 
61
 
 
62
        private TimeSpan duration;
 
63
        public TimeSpan Duration {
 
64
            get { return duration; }
 
65
        }
 
66
 
 
67
        private long file_size;
 
68
        public long FileSize {
 
69
            get { return file_size; }
 
70
        }
 
71
 
 
72
        public AudioCdDiscModel (IDiscVolume volume)
 
73
            : base (volume)
 
74
        {
 
75
            disc_title = Catalog.GetString ("Audio CD");
 
76
 
 
77
            MusicBrainzService.UserAgent = Banshee.Web.Browser.UserAgent;
 
78
        }
 
79
 
 
80
        public void NotifyUpdated ()
 
81
        {
 
82
            OnReloaded ();
 
83
        }
 
84
 
 
85
        public override void LoadModelFromDisc ()
 
86
        {
 
87
            Clear ();
 
88
 
 
89
            LocalDisc mb_disc = LocalDisc.GetFromDevice (Volume.DeviceNode);
 
90
            if (mb_disc == null) {
 
91
                throw new ApplicationException ("Could not read contents of the disc. Platform may not be supported.");
 
92
            }
 
93
 
 
94
            TimeSpan[] durations = mb_disc.GetTrackDurations ();
 
95
            for (int i = 0, n = durations.Length; i < n; i++) {
 
96
                AudioCdTrackInfo track = new AudioCdTrackInfo (this, Volume.DeviceNode, i);
 
97
                track.TrackNumber = i + 1;
 
98
                track.TrackCount = n;
 
99
                track.DiscNumber = 1;
 
100
                track.Duration = durations[i];
 
101
                track.ArtistName = Catalog.GetString ("Unknown Artist");
 
102
                track.AlbumTitle = Catalog.GetString ("Unknown Album");
 
103
                track.TrackTitle = String.Format (Catalog.GetString ("Track {0}"), track.TrackNumber);
 
104
                track.FileSize = PCM_FACTOR * (uint)track.Duration.TotalSeconds;
 
105
                Add (track);
 
106
 
 
107
                duration += track.Duration;
 
108
                file_size += track.FileSize;
 
109
            }
 
110
 
 
111
            EnabledCount = Count;
 
112
 
 
113
            Reload ();
 
114
 
 
115
            ThreadPool.QueueUserWorkItem (LoadDiscMetadata, mb_disc);
 
116
        }
 
117
 
 
118
        private void LoadDiscMetadata (object state)
 
119
        {
 
120
            try {
 
121
                LocalDisc mb_disc = (LocalDisc)state;
 
122
 
 
123
                OnMetadataQueryStarted (mb_disc);
 
124
 
 
125
                Release release = Release.Query (mb_disc).First ();
 
126
 
 
127
                if (release == null || release.Score < 100) {
 
128
                    OnMetadataQueryFinished (false);
 
129
                    return;
 
130
                }
 
131
                
 
132
                var tracks = release.GetTracks ();
 
133
                if (tracks.Count != Count) {
 
134
                    OnMetadataQueryFinished (false);
 
135
                    return;
 
136
                }
 
137
 
 
138
                disc_title = release.GetTitle ();
 
139
 
 
140
                int disc_number = 1;
 
141
                int i = 0;
 
142
 
 
143
                foreach (Disc disc in release.GetDiscs ()) {
 
144
                    i++;
 
145
                    if (disc.Id == mb_disc.Id) {
 
146
                        disc_number = i;
 
147
                    }
 
148
                }
 
149
 
 
150
                DateTime release_date = DateTime.MaxValue;
 
151
 
 
152
                foreach (Event release_event in release.GetEvents ()) {
 
153
                    if (release_event.Date != null) {
 
154
                        try {
 
155
                            // Handle "YYYY" dates
 
156
                            var date_str = release_event.Date;
 
157
                            DateTime date = DateTime.Parse (
 
158
                                date_str.Length > 4 ? date_str : date_str + "-01",
 
159
                                ApplicationContext.InternalCultureInfo
 
160
                            );
 
161
 
 
162
                            if (date < release_date) {
 
163
                                release_date = date;
 
164
                            }
 
165
                        } catch {
 
166
                        }
 
167
                    }
 
168
                }
 
169
 
 
170
                DatabaseArtistInfo artist = new DatabaseArtistInfo ();
 
171
                var mb_artist = release.GetArtist ();
 
172
                artist.Name = mb_artist.GetName ();
 
173
                artist.NameSort = mb_artist.GetSortName ();
 
174
                artist.MusicBrainzId = mb_artist.Id;
 
175
                bool is_compilation = false;
 
176
 
 
177
                DatabaseAlbumInfo album = new DatabaseAlbumInfo ();
 
178
                album.Title = disc_title;
 
179
                album.ArtistName = artist.Name;
 
180
                album.MusicBrainzId = release.Id;
 
181
                album.ReleaseDate = release_date == DateTime.MaxValue ? DateTime.MinValue : release_date;
 
182
 
 
183
                i = 0;
 
184
                foreach (Track track in tracks) {
 
185
                    AudioCdTrackInfo model_track = (AudioCdTrackInfo)this[i++];
 
186
                    var mb_track_artist = track.GetArtist ();
 
187
 
 
188
                    model_track.MusicBrainzId = track.Id;
 
189
                    model_track.TrackTitle = track.GetTitle ();
 
190
                    model_track.ArtistName = mb_track_artist.GetName ();
 
191
                    model_track.AlbumTitle = disc_title;
 
192
                    model_track.DiscNumber = disc_number;
 
193
                    model_track.Album = album;
 
194
 
 
195
                    model_track.Artist = new DatabaseArtistInfo ();
 
196
                    model_track.Artist.Name = model_track.ArtistName;
 
197
                    model_track.Artist.NameSort = mb_track_artist.GetSortName ();
 
198
                    model_track.Artist.MusicBrainzId = mb_track_artist.Id;
 
199
 
 
200
                    if (release_date != DateTime.MinValue) {
 
201
                        model_track.Year = release_date.Year;
 
202
                    }
 
203
 
 
204
                    if (!is_compilation && mb_track_artist.Id != artist.MusicBrainzId) {
 
205
                        is_compilation = true;
 
206
                    }
 
207
                }
 
208
 
 
209
                if (is_compilation) {
 
210
                    album.IsCompilation = true;
 
211
                    for (i = 0; i < tracks.Count; i++) {
 
212
                        AudioCdTrackInfo model_track = (AudioCdTrackInfo)this[i];
 
213
                        model_track.IsCompilation = true;
 
214
                        model_track.AlbumArtist = artist.Name;
 
215
                        model_track.AlbumArtistSort = artist.NameSort;
 
216
                    }
 
217
                }
 
218
 
 
219
                OnMetadataQueryFinished (true);
 
220
            } catch (Exception ex) {
 
221
                Log.DebugException (ex);
 
222
                OnMetadataQueryFinished (false);
 
223
            }
 
224
        }
 
225
 
 
226
        private void OnMetadataQueryStarted (LocalDisc mb_disc)
 
227
        {
 
228
            metadata_query_success = false;
 
229
            metadata_query_start_time = DateTime.Now;
 
230
            Log.InformationFormat ("Querying MusicBrainz for Disc Release ({0})", mb_disc.Id);
 
231
 
 
232
            ThreadAssist.ProxyToMain (delegate {
 
233
                EventHandler handler = MetadataQueryStarted;
 
234
                if (handler != null) {
 
235
                    handler (this, EventArgs.Empty);
 
236
                }
 
237
            });
 
238
        }
 
239
 
 
240
        private void OnMetadataQueryFinished (bool success)
 
241
        {
 
242
            metadata_query_success = success;
 
243
            Log.InformationFormat ("Query finished (success: {0}, {1} seconds)",
 
244
                success, (DateTime.Now - metadata_query_start_time).TotalSeconds);
 
245
 
 
246
            ThreadAssist.ProxyToMain (delegate {
 
247
                Reload ();
 
248
 
 
249
                EventHandler handler = MetadataQueryFinished;
 
250
                if (handler != null) {
 
251
                    handler (this, EventArgs.Empty);
 
252
                }
 
253
            });
 
254
        }
 
255
 
 
256
        private void OnEnabledCountChanged ()
 
257
        {
 
258
            EventHandler handler = EnabledCountChanged;
 
259
            if (handler != null) {
 
260
                handler (this, EventArgs.Empty);
 
261
            }
 
262
        }
 
263
 
 
264
        private string disc_title;
 
265
        public override string Title {
 
266
            get { return disc_title; }
 
267
        }
 
268
 
 
269
        private int enabled_count;
 
270
        public int EnabledCount {
 
271
            get { return enabled_count; }
 
272
            internal set {
 
273
                enabled_count = value;
 
274
                OnEnabledCountChanged ();
 
275
            }
 
276
        }
 
277
    }
 
278
}