private void PerformSyncThreadCycle ()
        {
            Hyena.Log.Debug ("Starting AppleDevice sync thread cycle");

            string message;
            int total, i = 0;
            var progressUpdater = new UserJob (Catalog.GetString ("Syncing iPod"),
                                               Catalog.GetString ("Preparing to synchronize..."), GetIconNames ());
            progressUpdater.Register ();
            MediaDatabase.StartSync ();
            message = Catalog.GetString ("Adding track {0} of {1}");
            total = tracks_to_add.Count;
            while (tracks_to_add.Count > 0) {
                AppleDeviceTrackInfo track = null;
                lock (sync_mutex) {
                    total = tracks_to_add.Count + i;
                    track = tracks_to_add.Dequeue ();
                }

                try {
                    UpdateProgress (progressUpdater, message, ++i, total);
                    track.CommitToIpod (MediaDatabase);
                    track.Save (false);
                    tracks_map[track.TrackId] = track;
                } catch (Exception e) {
                    Log.Exception ("Cannot save track to iPod", e);
                }
            }
            if (total > 0) {
                OnTracksAdded ();
                OnUserNotifyUpdated ();
            }

            while (tracks_to_update.Count > 0) {
                AppleDeviceTrackInfo track = null;
                lock (sync_mutex) {
                    track = tracks_to_update.Dequeue ();
                }

                try {
                    track.CommitToIpod (MediaDatabase);
                } catch (Exception e) {
                    Log.Exception ("Cannot save track to iPod", e);
                }
            }

            message = Catalog.GetString ("Removing track {0} of {1}");
            total = tracks_to_remove.Count;
            while (tracks_to_remove.Count > 0) {
                AppleDeviceTrackInfo track = null;
                lock (sync_mutex) {
                    track = tracks_to_remove.Dequeue ();
                }

                if (tracks_map.ContainsKey (track.TrackId)) {
                    tracks_map.Remove (track.TrackId);
                }

                try {
                    if (track.IpodTrack != null) {
                        UpdateProgress (progressUpdater, message, total - tracks_to_remove.Count, total);

                        foreach (var playlist in MediaDatabase.Playlists) {
                            playlist.Tracks.Remove (track.IpodTrack);
                        }

                        if (SupportsPodcasts && track.IpodTrack.MediaType == GPod.MediaType.Podcast) {
                            MediaDatabase.PodcastsPlaylist.Tracks.Remove (track.IpodTrack);
                        }

                        MediaDatabase.MasterPlaylist.Tracks.Remove (track.IpodTrack);
                        MediaDatabase.Tracks.Remove (track.IpodTrack);

                        Banshee.IO.File.Delete (new SafeUri (GPod.ITDB.GetLocalPath (Device, track.IpodTrack)));
                    } else {
                        Log.Error ("The ipod track was null");
                    }
                } catch (Exception e) {
                    Log.Exception ("Cannot remove track from iPod", e);
                }
            }

            if (SupportsPlaylists) {
                // Remove playlists on the device
                var device_playlists = new List<GPod.Playlist> (MediaDatabase.Playlists);
                foreach (var playlist in device_playlists) {
                    if (!playlist.IsMaster && !playlist.IsPodcast) {
                        MediaDatabase.Playlists.Remove (playlist);
                    }
                }

                // Add playlists from Banshee to the device
                foreach (Source child in Children) {
                    PlaylistSource from = child as PlaylistSource;
                    if (from != null && from.Count > 0) {
                        var playlist = new GPod.Playlist (from.Name);
                        MediaDatabase.Playlists.Add (playlist);
                        foreach (int track_id in ServiceManager.DbConnection.QueryEnumerable<int> (String.Format (
                            "SELECT CoreTracks.TrackID FROM {0} WHERE {1}",
                            from.DatabaseTrackModel.ConditionFromFragment, from.DatabaseTrackModel.Condition)))
                        {
                            if (tracks_map.ContainsKey (track_id)) {
                                playlist.Tracks.Add (tracks_map[track_id].IpodTrack);
                            }
                        }
                    }
                }
            }

            try {
                message = Catalog.GetString ("Writing media database");
                UpdateProgress (progressUpdater, message, 1, 1);
                MediaDatabase.Write ();
                Log.Information ("Wrote iPod database");
            } catch (Exception e) {
                Log.Exception ("Failed to save iPod database", e);
            }
            MediaDatabase.StopSync ();
            progressUpdater.Finish ();

            Hyena.Log.Debug ("Ending AppleDevice sync thread cycle");
        }
        void SyncTracksToRemove (UserJob progressUpdater)
        {
            string message = Catalog.GetString ("Removing track {0} of {1}");
            int total = tracks_to_remove.Count;
            while (tracks_to_remove.Count > 0) {
                AppleDeviceTrackInfo track = null;
                lock (sync_mutex) {
                    track = tracks_to_remove.Dequeue ();
                }

                if (tracks_map.ContainsKey (track.TrackId)) {
                    tracks_map.Remove (track.TrackId);
                }

                try {
                    if (track.IpodTrack != null) {
                        UpdateProgress (progressUpdater, message, total - tracks_to_remove.Count, total);

                        DeleteTrack (track.IpodTrack, true);
                    } else {
                        Log.Error ("The ipod track was null");
                    }
                } catch (Exception e) {
                    Log.Exception ("Cannot remove track from iPod", e);
                }
            }

            SyncRemovalOfInvalidTracks ();
        }
        void SyncDatabase (UserJob progressUpdater)
        {
            try {
                string message = Catalog.GetString ("Writing media database");
                UpdateProgress (progressUpdater, message, 1, 1);

                lock (write_mutex) {
                    MediaDatabase.Write ();
                }

                Log.Information ("Wrote iPod database");
            } catch (Exception e) {
                Log.Exception ("Failed to save iPod database", e);
            }
        }
 private void OnSubmissionEnd(object source, EventArgs args)
 {
     if (scrobble_job != null) {
         scrobble_job.Finish ();
         scrobble_job = null;
     }
 }
        void SyncTracksToAdd (UserJob progressUpdater)
        {
            string message = Catalog.GetString ("Adding track {0} of {1}");
            int total = tracks_to_add.Count;
            int i = 0;
            while (tracks_to_add.Count > 0) {
                AppleDeviceTrackInfo track = null;
                lock (sync_mutex) {
                    total = tracks_to_add.Count + i;
                    track = tracks_to_add.Dequeue ();
                }

                try {
                    UpdateProgress (progressUpdater, message, ++i, total);
                    track.CommitToIpod (MediaDatabase);
                    track.Save (false);
                    tracks_map[track.TrackId] = track;
                } catch (Exception e) {
                    Log.Exception ("Cannot save track to the Apple device", e);
                }
            }
            if (total > 0) {
                OnTracksAdded ();
                OnUserNotifyUpdated ();
            }
        }
        private void OnGetTagFromFingerprint(object sender, EventArgs args)
        {
            active = true;
            Source source = ServiceManager.SourceManager.ActiveSource;

            UserJob job = new UserJob (AddinManager.CurrentLocalizer.GetString ("Getting sound fingerprint"));
            job.SetResources (Resource.Cpu, Resource.Disk, Resource.Database);
            job.PriorityHints = PriorityHints.SpeedSensitive;
            job.Status = AddinManager.CurrentLocalizer.GetString ("Scanning...");
            job.IconNames = new string [] { "system-search", "gtk-find" };
            job.CanCancel = true;
            job.CancelRequested += HandleJobCancelRequested;
            job.Register ();

            if (account == null) {
                account = new LastfmAccount ();
                LoginDialog dialog = new LoginDialog (account, true);
                dialog.Run ();
                dialog.Destroy ();
            }

            //comment the timeout system for TOS because still have issue and not seems to be linked...
            //System.DateTime start = System.DateTime.MinValue;
            ThreadPool.QueueUserWorkItem (delegate {
                try {

                    var selection = ((ITrackModelSource)source).TrackModel.Selection;
                    int total = selection.Count;
                    int count = 0;

                    foreach (TrackInfo track in ((ITrackModelSource)source).TrackModel.SelectedItems) {
                        if (!active)
                            break;
                        ad = new AudioDecoder((int)track.Duration.TotalSeconds);
                        //respect last fm term of service :
                        //You will not make more than 5 requests per originating IP address per second, averaged over a 5 minute period
                        // 2 requests are done on each loop ==> time allowed by loop : 400ms
                        /*if (start != System.DateTime.MinValue) {
                            TimeSpan span = System.DateTime.Now - start;
                            if (lastFmTOSMinTimeout > span)
                                Thread.Sleep (lastFmTOSMinTimeout - span);
                        }
                        start = DateTime.Now;
                        */
                        byte[] fingerprint = ad.Decode (track.Uri.AbsolutePath);
                        FingerprintRequest request = new FingerprintRequest();
                        request.Send (track, fingerprint, account);

                        int fpid = request.GetFpId ();
                        //force GC to dispose
                        ad = null;

                        Log.DebugFormat ("Last.fm fingerprint id for {0} is {1}", track.TrackTitle, fpid);

                        if (fpid > 0) {
                            FetchMetadata (track, fpid);
                        } else {
                            Log.WarningFormat ("Could not find fingerprint id for the track {0} !", track.TrackTitle);
                        }

                        job.Progress = (double)++count / (double)total;
                    }

                } catch (Exception e) {
                    account = null;
                    Log.Exception (e);
                } finally {
                    job.Finish ();
                }
            });
        }
 private void DisposeSyncUserJob ()
 {
     if (sync_user_job != null) {
         sync_user_job.Finish ();
         sync_user_job = null;
     }
 }
Beispiel #8
0
        public void Start()
        {
            ResetState ();

            foreach (AudioCdTrackInfo track in source.Model) {
                if (track.RipEnabled) {
                    total_duration += track.Duration;
                    queue.Enqueue (track);
                }
            }

            if (queue.Count == 0) {
                return;
            }

            source.LockAllTracks ();

            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.Model.Title));
            user_job.SetResources (Resource.Cpu);
            user_job.PriorityHints = PriorityHints.SpeedSensitive | PriorityHints.DataLossIfStopped;
            user_job.CanCancel = true;
            user_job.CancelRequested += OnCancelRequested;
            user_job.Finished += OnFinished;
            user_job.Register ();

            if (source != null && source.Model != null) {
                if (!source.Model.LockDoor ()) {
                    Hyena.Log.Warning ("Could not lock CD-ROM door", false);
                }
            }

            ripper.Begin (source.Model.Volume.DeviceNode, AudioCdService.ErrorCorrection.Get ());

            RipNextTrack ();
        }
Beispiel #9
0
        private void OnFinished(object o, EventArgs args)
        {
            if (user_job != null) {
                user_job.CancelRequested -= OnCancelRequested;
                user_job.Finished -= OnFinished;
                user_job = null;
            }

            source.UnlockAllTracks ();
        }
        private void OnReadyToScrobble (object source, ScrobblingBatchEventArgs args)
        {
            var scrobble_job = new UserJob (Catalog.GetString ("Scrobbling from device"),
                                            Catalog.GetString ("Scrobbling from device..."));

            scrobble_job.PriorityHints = PriorityHints.DataLossIfStopped;
            scrobble_job.Register ();

            try {
                if (!connection.Started) {
                    connection.Start ();
                }
    
                int added_track_count = 0, processed_track_count = 0;
                string message = Catalog.GetString ("Processing track {0} of {1} ...");
                var batchCount = args.ScrobblingBatch.Count;
    
                foreach (var track_entry in args.ScrobblingBatch) {
                    TrackInfo track = track_entry.Key;
    
                    if (IsValidForSubmission (track)) {
                        IList<DateTime> playtimes = track_entry.Value;
    
                        foreach (DateTime playtime in playtimes) {
                            queue.Add (track, playtime);
                            added_track_count++;
                        }
                        Log.DebugFormat ("Added to Last.fm queue: {0} - Number of plays: {1}", track, playtimes.Count);
                    } else {
                        Log.DebugFormat ("Track {0} failed validation check for Last.fm submission, skipping...",
                                         track);
                    }
    
                    scrobble_job.Status = String.Format (message, ++processed_track_count, batchCount);
                    scrobble_job.Progress = processed_track_count / (double) batchCount;
                }
    
                Log.InformationFormat ("Number of played tracks from device added to Last.fm queue: {0}", added_track_count);

            } finally {
                scrobble_job.Finish ();
            }
        }
Beispiel #11
0
        public void Dispose()
        {
            ResetState ();

            if (source != null && source.Model != null) {
                source.Model.UnlockDoor ();
            }

            if (ripper != null) {
                ripper.Finish ();
                ripper = null;
            }

            if (user_job != null) {
                user_job.Finish ();
                user_job = null;
            }
        }
        protected void DestroyUserJob()
        {
            lock (sync) {
                if (user_job == null) {
                    return;
                }

                ResetCounters ();

                user_job.CancelRequested -= OnCancelRequested;
                user_job.Finish ();
                user_job = null;
            }
        }
        protected void CreateUserJob()
        {
            lock (sync) {
                if (user_job != null) {
                    return;
                }

                user_job = new UserJob (Title, Catalog.GetString ("Initializing"));
                user_job.SetResources (Resource.Cpu, Resource.Disk);
                user_job.PriorityHints = PriorityHints.SpeedSensitive | PriorityHints.DataLossIfStopped;
                user_job.IconNames = new string [] { Gtk.Stock.Network };
                user_job.CancelMessage = CancelMessage;
                user_job.CanCancel = true;
                user_job.CancelRequested += OnCancelRequested;
                user_job.Register ();
            }
        }
Beispiel #14
0
        private void OnSubmissionStart(object source, SubmissionStartEventArgs args)
        {
            // We only want to display something if more than one track is being submitted
            if (args.TotalCount <= 1) {
                return;
            }

            if (scrobble_job == null) {
                scrobble_job = new UserJob (Catalog.GetString ("Scrobbling to Last.FM"),
                                            Catalog.GetString ("Scrobbling to Last.FM..."));

                scrobble_job.PriorityHints = PriorityHints.None;
                scrobble_job.CanCancel = true;
                scrobble_job.CancelRequested += OnScrobbleJobCancelRequest;
                scrobble_job.Register ();

                job_tracks_count = 0;
                job_tracks_total = args.TotalCount;
            }
            UpdateJob ();
        }
 private void UpdateProgress (UserJob job, string message, int completed, int total)
 {
     job.Status = string.Format (message, completed, total);
     job.Progress = completed / (double) total;
 }
        void SyncTracksToUpdate (UserJob progressUpdater)
        {
            string message = Catalog.GetString ("Updating metadata in track {0} of {1}");
            int total = tracks_to_update.Count;
            while (tracks_to_update.Count > 0) {
                AppleDeviceTrackInfo track = null;
                lock (sync_mutex) {
                    track = tracks_to_update.Dequeue ();
                }

                try {
                    UpdateProgress (progressUpdater, message, total - tracks_to_update.Count, total);

                    track.CommitToIpod (MediaDatabase);
                } catch (Exception e) {
                    Log.Exception ("Cannot save track to iPod", e);
                }
            }
        }
        private void PerformSyncThreadCycle ()
        {
            string message;
            int total;
            var progressUpdater = new UserJob (Catalog.GetString ("Syncing iPod"),
                                               Catalog.GetString ("Preparing to synchronize..."), GetIconNames ());
            progressUpdater.Register ();

            message = Catalog.GetString ("Adding track {0} of {1}");
            total = tracks_to_add.Count;
            while (tracks_to_add.Count > 0) {
                AppleDeviceTrackInfo track = null;
                lock (sync_mutex) {
                    track = tracks_to_add.Dequeue ();
                }

                try {
                    UpdateProgress (progressUpdater, message, total - tracks_to_add.Count, total);
                    track.CommitToIpod (MediaDatabase);
                    tracks_map[track.TrackId] = track;
                } catch (Exception e) {
                    Log.Exception ("Cannot save track to iPod", e);
                }
            }

            // TODO sync updated metadata to changed tracks
            message = Catalog.GetString ("Removing track {0} of {1}");
            total = tracks_to_remove.Count;
            while (tracks_to_remove.Count > 0) {
                AppleDeviceTrackInfo track = null;
                lock (sync_mutex) {
                    track = tracks_to_remove.Dequeue ();
                }

                if (tracks_map.ContainsKey (track.TrackId)) {
                    tracks_map.Remove (track.TrackId);
                }

                try {
                    if (track.IpodTrack != null) {
                        UpdateProgress (progressUpdater, message, total - tracks_to_remove.Count, total);
                        foreach (var playlist in MediaDatabase.Playlists)
                            playlist.Tracks.Remove (track.IpodTrack);
                        MediaDatabase.MasterPlaylist.Tracks.Remove (track.IpodTrack);
                        MediaDatabase.Tracks.Remove (track.IpodTrack);
                        Banshee.IO.File.Delete (new SafeUri (GPod.ITDB.GetLocalPath (Device, track.IpodTrack)));
                    } else {
                        Log.Error ("The ipod track was null");
                    }
                } catch (Exception e) {
                    Log.Exception ("Cannot remove track from iPod", e);
                }
            }

//            // Remove playlists on the device
//            List<IPod.Playlist> device_playlists = new List<IPod.Playlist> (ipod_device.TrackDatabase.Playlists);
//            foreach (IPod.Playlist playlist in device_playlists) {
//                if (!playlist.IsOnTheGo) {
//                    ipod_device.TrackDatabase.RemovePlaylist (playlist);
//                }
//            }
//            device_playlists.Clear ();
//
//            if (SupportsPlaylists) {
//                // Add playlists from Banshee to the device
//                foreach (Source child in Children) {
//                    PlaylistSource from = child as PlaylistSource;
//                    if (from != null && from.Count > 0) {
//                        IPod.Playlist playlist = ipod_device.TrackDatabase.CreatePlaylist (from.Name);
//                        foreach (int track_id in ServiceManager.DbConnection.QueryEnumerable<int> (String.Format (
//                            "SELECT CoreTracks.TrackID FROM {0} WHERE {1}",
//                            from.DatabaseTrackModel.ConditionFromFragment, from.DatabaseTrackModel.Condition)))
//                        {
//                            if (tracks_map.ContainsKey (track_id)) {
//                                playlist.AddTrack (tracks_map[track_id].IpodTrack);
//                            }
//                        }
//                    }
//                }
//            }

            try {
                message = Catalog.GetString ("Writing media database");
                UpdateProgress (progressUpdater, message, 1, 1);
                MediaDatabase.Write ();
                Log.Information ("Wrote iPod database");
            } catch (Exception e) {
                Log.Exception ("Failed to save iPod database", e);
            }
            progressUpdater.Finish ();
        }
 void SyncRemovalOfInvalidTracks (UserJob progressUpdater)
 {
     string message = Catalog.GetString ("Cleaning up, removing invalid track {0} of {1}");
     int total = invalid_tracks_in_device.Count;
     while (invalid_tracks_in_device.Count > 0) {
         try {
             UpdateProgress (progressUpdater, message, total - invalid_tracks_in_device.Count, total);
             DeleteTrack (invalid_tracks_in_device.Dequeue (), false);
         } catch (Exception e) {
             Log.Exception ("Cannot remove invalid track from iPod", e);
         }
     }
 }
        private void OnIpodDatabaseSaveStarted (object o, EventArgs args)
        {
            DisposeSyncUserJob ();

            sync_user_job = new UserJob (Catalog.GetString ("Syncing iPod"),
                Catalog.GetString ("Preparing to synchronize..."), GetIconNames ());
            sync_user_job.Register ();
        }
        private void PerformSyncThreadCycle ()
        {
            Hyena.Log.Debug ("Starting AppleDevice sync thread cycle");

            var progressUpdater = new UserJob (Catalog.GetString ("Syncing iPod"),
                                               Catalog.GetString ("Preparing to synchronize..."), GetIconNames ());
            progressUpdater.Register ();
            MediaDatabase.StartSync ();

            SyncTracksToAdd (progressUpdater);

            SyncTracksToUpdate ();

            SyncTracksToRemove (progressUpdater);

            SyncTracksToPlaylists ();

            SyncDatabase (progressUpdater);

            MediaDatabase.StopSync ();
            progressUpdater.Finish ();

            Hyena.Log.Debug ("Ending AppleDevice sync thread cycle");
        }
        private void RefreshMetadataThread (object state)
        {
            int total = ServiceManager.DbConnection.Query<int> ("SELECT count(*) FROM CoreTracks");

            if (total <= 0) {
                return;
            }

            UserJob job = new UserJob (Catalog.GetString ("Refreshing Metadata"));
            job.SetResources (Resource.Cpu, Resource.Disk, Resource.Database);
            job.PriorityHints = PriorityHints.SpeedSensitive;
            job.Status = Catalog.GetString ("Scanning...");
            job.IconNames = new string [] { "system-search", "gtk-find" };
            job.Register ();

            HyenaSqliteCommand select_command = new HyenaSqliteCommand (
                String.Format (
                    "SELECT {0} FROM {1} WHERE {2}",
                    DatabaseTrackInfo.Provider.Select,
                    DatabaseTrackInfo.Provider.From,
                    DatabaseTrackInfo.Provider.Where
                )
            );

            int count = 0;
            using (var reader = ServiceManager.DbConnection.Query (select_command)) {
                while (reader.Read ()) {
                    DatabaseTrackInfo track = null;
                    try {
                        track = DatabaseTrackInfo.Provider.Load (reader);

                        if (track != null && track.Uri != null && track.Uri.IsFile) {
                            try {
                                using (var file = StreamTagger.ProcessUri (track.Uri)) {
                                    StreamTagger.TrackInfoMerge (track, file, true);
                                }
                            } catch (Exception e) {
                                Log.Warning (String.Format ("Failed to update metadata for {0}", track),
                                    e.GetType ().ToString (), false);
                            }

                            track.Save (false);
                            track.Artist.Save ();
                            track.Album.Save ();

                            job.Status = String.Format ("{0} - {1}", track.DisplayArtistName, track.DisplayTrackTitle);
                        }
                    } catch (Exception e) {
                        Log.Warning (String.Format ("Failed to update metadata for {0}", track), e.ToString (), false);
                    }

                    job.Progress = (double)++count / (double)total;
                }
            }

            if (ServiceManager.DbConnection.Query<int> ("SELECT count(*) FROM CoreConfiguration WHERE Key = 'MetadataVersion'") == 0) {
                Execute (String.Format ("INSERT INTO CoreConfiguration (EntryID, Key, Value) VALUES (null, 'MetadataVersion', {0})", CURRENT_METADATA_VERSION));
            } else {
                Execute (String.Format ("UPDATE CoreConfiguration SET Value = {0} WHERE Key = 'MetadataVersion'", CURRENT_METADATA_VERSION));
            }

            job.Finish ();
            ServiceManager.SourceManager.MusicLibrary.NotifyTracksChanged ();
        }
Beispiel #22
0
 private void OnScrobbleJobCancelRequest(object source, EventArgs args)
 {
     scrobble_job.Finish ();
     scrobble_job = null;
 }