コード例 #1
0
        private void LoadFromDevice(bool refresh)
        {
            // bool previous_database_supported = database_supported;

            if (refresh)
            {
                ipod_device.TrackDatabase.Reload();
            }

            tracks_map.Clear();

            if (database_supported || (ipod_device.HasTrackDatabase &&
                                       ipod_device.ModelInfo.DeviceClass == "shuffle"))
            {
                foreach (Track ipod_track in ipod_device.TrackDatabase.Tracks)
                {
                    try {
                        IpodTrackInfo track = new IpodTrackInfo(ipod_track);
                        track.PrimarySource = this;
                        track.Save(false);
                        tracks_map.Add(track.TrackId, track);
                    } catch (Exception e) {
                        Log.Exception(e);
                    }
                }

                Hyena.Data.Sqlite.HyenaSqliteCommand insert_cmd = new Hyena.Data.Sqlite.HyenaSqliteCommand(
                    @"INSERT INTO CorePlaylistEntries (PlaylistID, TrackID)
                        SELECT ?, TrackID FROM CoreTracks WHERE PrimarySourceID = ? AND ExternalID = ?");
                foreach (IPod.Playlist playlist in ipod_device.TrackDatabase.Playlists)
                {
                    if (playlist.IsOnTheGo)   // || playlist.IsPodcast) {
                    {
                        continue;
                    }
                    PlaylistSource pl_src = new PlaylistSource(playlist.Name, this);
                    pl_src.Save();
                    // We use the IPod.Track.Id here b/c we just shoved it into ExternalID above when we loaded
                    // the tracks, however when we sync, the Track.Id values may/will change.
                    foreach (IPod.Track track in playlist.Tracks)
                    {
                        ServiceManager.DbConnection.Execute(insert_cmd, pl_src.DbId, this.DbId, track.Id);
                    }
                    pl_src.UpdateCounts();
                    AddChildSource(pl_src);
                }
            }

            /*else {
             *  BuildDatabaseUnsupportedWidget ();
             * }*/

            /*if(previous_database_supported != database_supported) {
             *  OnPropertiesChanged();
             * }*/
        }
コード例 #2
0
        private void OnImportFinished(object o, EventArgs args)
        {
            importer.Finished -= OnImportFinished;

            if (CanSyncPlaylists)
            {
                var insert_cmd = new Hyena.Data.Sqlite.HyenaSqliteCommand(
                    "INSERT INTO CorePlaylistEntries (PlaylistID, TrackID) VALUES (?, ?)");
                foreach (string playlist_path in PlaylistFiles)
                {
                    // playlist_path has a file:// prefix, and GetDirectoryName messes it up,
                    // so we need to convert it to a regular path
                    string base_folder = ms_device.RootPath != null ? BaseDirectory :
                                         System.IO.Path.GetDirectoryName(SafeUri.UriToFilename(playlist_path));

                    IPlaylistFormat loaded_playlist = PlaylistFileUtil.Load(playlist_path,
                                                                            new Uri(base_folder),
                                                                            ms_device.RootPath);
                    if (loaded_playlist == null)
                    {
                        continue;
                    }

                    string         name     = System.IO.Path.GetFileNameWithoutExtension(SafeUri.UriToFilename(playlist_path));
                    PlaylistSource playlist = new PlaylistSource(name, this);
                    playlist.Save();
                    //Hyena.Data.Sqlite.HyenaSqliteCommand.LogAll = true;
                    foreach (PlaylistElement element in loaded_playlist.Elements)
                    {
                        string track_path = element.Uri.LocalPath;
                        long   track_id   = DatabaseTrackInfo.GetTrackIdForUri(new SafeUri(track_path), DbId);
                        if (track_id == 0)
                        {
                            Log.DebugFormat("Failed to find track {0} in DAP library to load it into playlist {1}", track_path, playlist_path);
                        }
                        else
                        {
                            ServiceManager.DbConnection.Execute(insert_cmd, playlist.DbId, track_id);
                        }
                    }
                    //Hyena.Data.Sqlite.HyenaSqliteCommand.LogAll = false;
                    playlist.UpdateCounts();
                    AddChildSource(playlist);
                }
            }

            import_reset_event.Set();
        }
コード例 #3
0
        private void OnImportFinished(object o, EventArgs args)
        {
            importer.Finished -= OnImportFinished;

            if (CanSyncPlaylists)
            {
                var insert_cmd = new Hyena.Data.Sqlite.HyenaSqliteCommand(
                    "INSERT INTO CorePlaylistEntries (PlaylistID, TrackID) VALUES (?, ?)");
                int [] psources = new int [] { DbId };
                foreach (string playlist_path in PlaylistFiles)
                {
                    IPlaylistFormat loaded_playlist = PlaylistFileUtil.Load(playlist_path, new Uri(PlaylistsPath));
                    if (loaded_playlist == null)
                    {
                        continue;
                    }

                    PlaylistSource playlist = new PlaylistSource(System.IO.Path.GetFileNameWithoutExtension(playlist_path), this);
                    playlist.Save();
                    //Hyena.Data.Sqlite.HyenaSqliteCommand.LogAll = true;
                    foreach (Dictionary <string, object> element in loaded_playlist.Elements)
                    {
                        string track_path = (element["uri"] as Uri).LocalPath;
                        int    track_id   = DatabaseTrackInfo.GetTrackIdForUri(new SafeUri(track_path), psources);
                        if (track_id == 0)
                        {
                            Log.DebugFormat("Failed to find track {0} in DAP library to load it into playlist {1}", track_path, playlist_path);
                        }
                        else
                        {
                            ServiceManager.DbConnection.Execute(insert_cmd, playlist.DbId, track_id);
                        }
                    }
                    //Hyena.Data.Sqlite.HyenaSqliteCommand.LogAll = false;
                    playlist.UpdateCounts();
                    AddChildSource(playlist);
                }
            }

            import_reset_event.Set();
        }
コード例 #4
0
ファイル: MtpSource.cs プロジェクト: fatman2021/gnome-apps
        protected override void LoadFromDevice ()
        {
            track_map = new Dictionary<int, Track> ();
            try {
                List<Track> files = null;
                lock (mtp_device) {
                    files = mtp_device.GetAllTracks (delegate (ulong current, ulong total, IntPtr data) {
                        //user_event.Progress = (double)current / total;
                        // Translators: {0} is the name of the MTP audio device (eg Gabe's Zen Player), {1} is the
                        // track currently being loaded, and {2} is the total # of tracks that will be loaded.
                        SetStatus (String.Format (Catalog.GetString ("Loading {0} - {1} of {2}"), Name, current, total), false);
                        return 0;
                    });
                }

                /*if (user_event.IsCancelRequested) {
                    return;
                }*/

                // Delete any empty albums
                lock (mtp_device) {
                    foreach (Album album in mtp_device.GetAlbums ()) {
                        if (album.Count == 0) {
                            album.Remove ();
                        }
                    }
                }

                foreach (Track mtp_track in files) {
                    int track_id;
                    if ((track_id = DatabaseTrackInfo.GetTrackIdForUri (MtpTrackInfo.GetPathFromMtpTrack (mtp_track), DbId )) > 0) {
                        track_map[track_id] = mtp_track;
                    } else {
                        MtpTrackInfo track = new MtpTrackInfo (mtp_device, mtp_track);
                        track.PrimarySource = this;
                        track.Save (false);
                        track_map[track.TrackId] = mtp_track;
                    }
                }

                Hyena.Data.Sqlite.HyenaSqliteCommand insert_cmd = new Hyena.Data.Sqlite.HyenaSqliteCommand (
                    @"INSERT INTO CorePlaylistEntries (PlaylistID, TrackID)
                        SELECT ?, TrackID FROM CoreTracks WHERE PrimarySourceID = ? AND ExternalID = ?");

                lock (mtp_device) {
                    var playlists = mtp_device.GetPlaylists ();
                    if (playlists != null) {
                        foreach (MTP.Playlist playlist in playlists) {
                            PlaylistSource pl_src = new PlaylistSource (playlist.Name, this);
                            pl_src.Save ();
                            // TODO a transaction would make sense here (when the threading issue is fixed)
                            foreach (uint id in playlist.TrackIds) {
                                ServiceManager.DbConnection.Execute (insert_cmd, pl_src.DbId, this.DbId, id);
                            }
                            pl_src.UpdateCounts ();
                            AddChildSource (pl_src);
                        }
                    }
                }

            } catch (Exception e) {
                Log.Exception (e);
            }
            OnTracksAdded ();
        }
コード例 #5
0
        private void OnImportFinished (object o, EventArgs args)
        {
            importer.Finished -= OnImportFinished;

            if (CanSyncPlaylists) {
                var insert_cmd = new Hyena.Data.Sqlite.HyenaSqliteCommand (
                    "INSERT INTO CorePlaylistEntries (PlaylistID, TrackID) VALUES (?, ?)");
                int [] psources = new int [] {DbId};
                foreach (string playlist_path in PlaylistFiles) {
                    IPlaylistFormat loaded_playlist = PlaylistFileUtil.Load (playlist_path, new Uri (PlaylistsPath));
                    if (loaded_playlist == null)
                        continue;

                    PlaylistSource playlist = new PlaylistSource (System.IO.Path.GetFileNameWithoutExtension (playlist_path), this);
                    playlist.Save ();
                    //Hyena.Data.Sqlite.HyenaSqliteCommand.LogAll = true;
                    foreach (Dictionary<string, object> element in loaded_playlist.Elements) {
                        string track_path = (element["uri"] as Uri).LocalPath;
                        int track_id = DatabaseTrackInfo.GetTrackIdForUri (new SafeUri (track_path), psources);
                        if (track_id == 0) {
                            Log.DebugFormat ("Failed to find track {0} in DAP library to load it into playlist {1}", track_path, playlist_path);
                        } else {
                            ServiceManager.DbConnection.Execute (insert_cmd, playlist.DbId, track_id);
                        }
                    }
                    //Hyena.Data.Sqlite.HyenaSqliteCommand.LogAll = false;
                    playlist.UpdateCounts ();
                    AddChildSource (playlist);
                }
            }

            import_reset_event.Set ();
        }
コード例 #6
0
ファイル: AppleDeviceSource.cs プロジェクト: shaw1337/banshee
        private void LoadFromDevice(bool refresh)
        {
            tracks_map.Clear();
            if (refresh || MediaDatabase == null)
            {
                if (MediaDatabase != null)
                {
                    MediaDatabase.Dispose();
                }

                try {
                    MediaDatabase = new GPod.ITDB(Device.Mountpoint);
                } catch (GLib.GException e) {
                    Log.Exception("iPod database could not be loaded, creating a new one", e);
                    if (GPod.ITDB.InitIpod(Volume.MountPoint, null, Volume.Name))
                    {
                        // this may throw again. In the future we need to implement some kind of alert
                        // mechanism to let the user know that something more serious is wrong with their
                        // apple device a la the other iPod extension.
                        MediaDatabase = new GPod.ITDB(Device.Mountpoint);
                    }
                    else
                    {
                        Log.Error("Failed to init iPod database");
                        return;
                    }
                }
            }

            if (MediaDatabase.MasterPlaylist == null)
            {
                MediaDatabase.Playlists.Add(new GPod.Playlist(Name)
                {
                    IsMaster = true
                });
            }

            if (SupportsPodcasts && MediaDatabase.PodcastsPlaylist == null)
            {
                MediaDatabase.Playlists.Add(new GPod.Playlist(Catalog.GetString("Podcasts"))
                {
                    IsPodcast = true
                });
            }

            var invalid_tracks = new List <GPod.Track> ();

            foreach (var ipod_track in MediaDatabase.Tracks)
            {
                if (String.IsNullOrEmpty(ipod_track.IpodPath))
                {
                    invalid_tracks.Add(ipod_track);
                    continue;
                }

                try {
                    var track = new AppleDeviceTrackInfo(ipod_track);
                    if (!tracks_map.ContainsKey(track.TrackId))
                    {
                        track.PrimarySource = this;
                        track.Save(false);
                        tracks_map.Add(track.TrackId, track);
                    }
                } catch (Exception e) {
                    Log.Exception(e);
                }
            }
            if (invalid_tracks.Count > 0)
            {
                Log.Warning(String.Format("Found {0} invalid tracks on the device", invalid_tracks.Count));
                foreach (var track in invalid_tracks)
                {
                    DeleteTrack(track, false);
                }
            }


            Hyena.Data.Sqlite.HyenaSqliteCommand insert_cmd = new Hyena.Data.Sqlite.HyenaSqliteCommand(
                @"INSERT INTO CorePlaylistEntries (PlaylistID, TrackID)
                    SELECT ?, TrackID FROM CoreTracks WHERE PrimarySourceID = ? AND ExternalID = ?");
            foreach (var playlist in MediaDatabase.Playlists)
            {
                if (playlist.IsMaster || playlist.IsPodcast)
                {
                    continue;
                }

                PlaylistSource pl_src = new PlaylistSource(playlist.Name, this);
                pl_src.Save();
                // We use the GPod.Track.DBID here b/c we just shoved it into ExternalID above when we loaded
                // the tracks, however when we sync, the Track.DBID values may/will change.
                foreach (var track in playlist.Tracks)
                {
                    // DBID will be stored in a long, so we need to cast it. See bgo#650011
                    ServiceManager.DbConnection.Execute(insert_cmd, pl_src.DbId, this.DbId, (long)track.DBID);
                }
                pl_src.UpdateCounts();
                AddChildSource(pl_src);
            }

            RaiseReadyToScrobble();
        }
コード例 #7
0
        private void LoadFromDevice (bool refresh)
        {
            // bool previous_database_supported = database_supported;

            if (refresh) {
                ipod_device.TrackDatabase.Reload ();
            }

            tracks_map.Clear ();

            if (database_supported || (ipod_device.HasTrackDatabase &&
                ipod_device.ModelInfo.DeviceClass == "shuffle")) {
                foreach (Track ipod_track in ipod_device.TrackDatabase.Tracks) {
                    try {
                        IpodTrackInfo track = new IpodTrackInfo (ipod_track);
                        track.PrimarySource = this;
                        track.Save (false);
                        tracks_map.Add (track.TrackId, track);
                    } catch (Exception e) {
                        Log.Exception (e);
                    }
                }

                Hyena.Data.Sqlite.HyenaSqliteCommand insert_cmd = new Hyena.Data.Sqlite.HyenaSqliteCommand (
                    @"INSERT INTO CorePlaylistEntries (PlaylistID, TrackID)
                        SELECT ?, TrackID FROM CoreTracks WHERE PrimarySourceID = ? AND ExternalID = ?");
                foreach (IPod.Playlist playlist in ipod_device.TrackDatabase.Playlists) {
                    if (playlist.IsOnTheGo) { // || playlist.IsPodcast) {
                        continue;
                    }
                    PlaylistSource pl_src = new PlaylistSource (playlist.Name, this);
                    pl_src.Save ();
                    // We use the IPod.Track.Id here b/c we just shoved it into ExternalID above when we loaded
                    // the tracks, however when we sync, the Track.Id values may/will change.
                    foreach (IPod.Track track in playlist.Tracks) {
                        ServiceManager.DbConnection.Execute (insert_cmd, pl_src.DbId, this.DbId, track.Id);
                    }
                    pl_src.UpdateCounts ();
                    AddChildSource (pl_src);
                }
            }

            /*else {
                BuildDatabaseUnsupportedWidget ();
            }*/

            /*if(previous_database_supported != database_supported) {
                OnPropertiesChanged();
            }*/
        }
コード例 #8
0
ファイル: MtpSource.cs プロジェクト: rucker/banshee
        protected override void LoadFromDevice()
        {
            if (null == mtp_device)
            {
                return;
            }

            // Translators: {0} is the file currently being loaded
            // and {1} is the total # of files that will be loaded.
            string format = Catalog.GetString("Reading File - {0} of {1}");

            track_map = new Dictionary <long, Track> ();
            try {
                List <Track> files = null;
                lock (mtp_device) {
                    files = mtp_device.GetAllTracks(delegate(ulong current, ulong total, IntPtr data) {
                        SetStatus(String.Format(format, current + 1, total), false);
                        return(0);
                    });
                }

                /*if (user_event.IsCancelRequested) {
                 *  return;
                 * }*/

                // Delete any empty albums
                lock (mtp_device) {
                    foreach (Album album in mtp_device.GetAlbums())
                    {
                        if (album.Count == 0)
                        {
                            album.Remove();
                        }
                    }
                }

                // Translators: {0} is the track currently being loaded
                // and {1} is the total # of tracks that will be loaded.
                format = Catalog.GetString("Loading Track - {0} of {1}");
                for (int current = 0, total = files.Count; current < total; ++current)
                {
                    SetStatus(String.Format(format, current + 1, total), false);
                    Track mtp_track = files [current];
                    long  track_id;
                    if ((track_id = DatabaseTrackInfo.GetTrackIdForUri(MtpTrackInfo.GetPathFromMtpTrack(mtp_track), DbId)) > 0)
                    {
                        track_map[track_id] = mtp_track;
                    }
                    else
                    {
                        MtpTrackInfo track = new MtpTrackInfo(mtp_device, mtp_track);
                        track.PrimarySource = this;
                        track.Save(false);
                        track_map[track.TrackId] = mtp_track;
                    }
                }

                Hyena.Data.Sqlite.HyenaSqliteCommand insert_cmd = new Hyena.Data.Sqlite.HyenaSqliteCommand(
                    @"INSERT INTO CorePlaylistEntries (PlaylistID, TrackID)
                        SELECT ?, TrackID FROM CoreTracks WHERE PrimarySourceID = ? AND ExternalID = ?");

                // Translators: {0} is the playlist currently being loaded
                // and {1} is the total # of playlists that will be loaded.
                format = Catalog.GetString("Loading Playlist - {0} of {1}");
                lock (mtp_device) {
                    var playlists = mtp_device.GetPlaylists();
                    if (playlists != null)
                    {
                        for (int current = 0, total = playlists.Count; current < total; ++current)
                        {
                            MTP.Playlist playlist = playlists [current];
                            SetStatus(String.Format(format, current + 1, total), false);
                            PlaylistSource pl_src = new PlaylistSource(playlist.Name, this);
                            pl_src.Save();
                            // TODO a transaction would make sense here (when the threading issue is fixed)
                            foreach (uint id in playlist.TrackIds)
                            {
                                ServiceManager.DbConnection.Execute(insert_cmd, pl_src.DbId, this.DbId, id);
                            }
                            pl_src.UpdateCounts();
                            AddChildSource(pl_src);
                        }
                    }
                }
            } catch (Exception e) {
                Log.Error(e);
            }
            OnTracksAdded();
        }
コード例 #9
0
        private void LoadFromDevice (bool refresh)
        {
            tracks_map.Clear ();
            if (refresh || MediaDatabase  == null) {
                if (MediaDatabase != null)
                    MediaDatabase.Dispose ();

                try {
                    MediaDatabase = new GPod.ITDB (Device.Mountpoint);
                } catch (GLib.GException e) {
                    Log.Exception ("iPod database could be loaded, creating a new one", e);
                    if (GPod.ITDB.InitIpod (Volume.MountPoint, null, Volume.Name)) {
                        // this may throw again. In the future we need to implement some kind of alert
                        // mechanism to let the user know that something more serious is wrong with their
                        // apple device a la the other iPod extension.
                        MediaDatabase = new GPod.ITDB (Device.Mountpoint);
                    } else {
                        Log.Error ("Failed to init iPod database");
                        return;
                    }
                }
            }

            if (MediaDatabase.MasterPlaylist == null) {
                MediaDatabase.Playlists.Add (new GPod.Playlist (Name) {
                    IsMaster = true
                });
            }

            if (SupportsPodcasts && MediaDatabase.PodcastsPlaylist == null) {
                MediaDatabase.Playlists.Add (new GPod.Playlist (Catalog.GetString ("Podcasts")) {
                    IsPodcast = true
                });
            }

            foreach (var ipod_track in MediaDatabase.Tracks) {
                try {
                    var track = new AppleDeviceTrackInfo (ipod_track);
                    if (!tracks_map.ContainsKey (track.TrackId)) {
                        track.PrimarySource = this;
                        track.Save (false);
                        tracks_map.Add (track.TrackId, track);
                    }
                } catch (Exception e) {
                    Log.Exception (e);
                }
            }

            Hyena.Data.Sqlite.HyenaSqliteCommand insert_cmd = new Hyena.Data.Sqlite.HyenaSqliteCommand (
                @"INSERT INTO CorePlaylistEntries (PlaylistID, TrackID)
                    SELECT ?, TrackID FROM CoreTracks WHERE PrimarySourceID = ? AND ExternalID = ?");
            foreach (var playlist in MediaDatabase.Playlists) {
                if (playlist.IsMaster || playlist.IsPodcast)
                    continue;

                PlaylistSource pl_src = new PlaylistSource (playlist.Name, this);
                pl_src.Save ();
                // We use the IPod.Track.Id here b/c we just shoved it into ExternalID above when we loaded
                // the tracks, however when we sync, the Track.Id values may/will change.
                foreach (var track in playlist.Tracks) {
                    ServiceManager.DbConnection.Execute (insert_cmd, pl_src.DbId, this.DbId, track.DBID);
                }
                pl_src.UpdateCounts ();
                AddChildSource (pl_src);
            }
        }
コード例 #10
0
        private void OnImportFinished(object o, EventArgs args)
        {
            importer.Finished -= OnImportFinished;

            if (CanSyncPlaylists) {
                var insert_cmd = new Hyena.Data.Sqlite.HyenaSqliteCommand (
                    "INSERT INTO CorePlaylistEntries (PlaylistID, TrackID) VALUES (?, ?)");
                foreach (string playlist_path in PlaylistFiles) {
                    // playlist_path has a file:// prefix, and GetDirectoryName messes it up,
                    // so we need to convert it to a regular path
                    string base_folder = ms_device.RootPath != null ? BaseDirectory :
                        System.IO.Path.GetDirectoryName (SafeUri.UriToFilename (playlist_path));

                    IPlaylistFormat loaded_playlist = PlaylistFileUtil.Load (playlist_path,
                                                                             new Uri (base_folder),
                                                                             ms_device.RootPath);
                    if (loaded_playlist == null)
                        continue;

                    string name = System.IO.Path.GetFileNameWithoutExtension (SafeUri.UriToFilename (playlist_path));
                    PlaylistSource playlist = new PlaylistSource (name, this);
                    playlist.Save ();
                    //Hyena.Data.Sqlite.HyenaSqliteCommand.LogAll = true;
                    foreach (PlaylistElement element in loaded_playlist.Elements) {
                        string track_path = element.Uri.LocalPath;
                        long track_id = DatabaseTrackInfo.GetTrackIdForUri (new SafeUri (track_path), DbId);
                        if (track_id == 0) {
                            Log.DebugFormat ("Failed to find track {0} in DAP library to load it into playlist {1}", track_path, playlist_path);
                        } else {
                            ServiceManager.DbConnection.Execute (insert_cmd, playlist.DbId, track_id);
                        }
                    }
                    //Hyena.Data.Sqlite.HyenaSqliteCommand.LogAll = false;
                    playlist.UpdateCounts ();
                    AddChildSource (playlist);
                }
            }

            import_reset_event.Set ();
        }
コード例 #11
0
        protected override void LoadFromDevice()
        {
            track_map = new Dictionary <int, Track> ();
            try {
                List <Track> files = null;
                lock (mtp_device) {
                    files = mtp_device.GetAllTracks(delegate(ulong current, ulong total, IntPtr data) {
                        //user_event.Progress = (double)current / total;
                        // Translators: {0} is the name of the MTP audio device (eg Gabe's Zen Player), {1} is the
                        // track currently being loaded, and {2} is the total # of tracks that will be loaded.
                        SetStatus(String.Format(Catalog.GetString("Loading {0} - {1} of {2}"), Name, current, total), false);
                        return(0);
                    });
                }

                /*if (user_event.IsCancelRequested) {
                 *  return;
                 * }*/

                // Delete any empty albums
                lock (mtp_device) {
                    foreach (Album album in mtp_device.GetAlbums())
                    {
                        if (album.Count == 0)
                        {
                            album.Remove();
                        }
                    }
                }

                foreach (Track mtp_track in files)
                {
                    int track_id;
                    if ((track_id = DatabaseTrackInfo.GetTrackIdForUri(MtpTrackInfo.GetPathFromMtpTrack(mtp_track), DbId)) > 0)
                    {
                        track_map[track_id] = mtp_track;
                    }
                    else
                    {
                        MtpTrackInfo track = new MtpTrackInfo(mtp_device, mtp_track);
                        track.PrimarySource = this;
                        track.Save(false);
                        track_map[track.TrackId] = mtp_track;
                    }
                }

                Hyena.Data.Sqlite.HyenaSqliteCommand insert_cmd = new Hyena.Data.Sqlite.HyenaSqliteCommand(
                    @"INSERT INTO CorePlaylistEntries (PlaylistID, TrackID)
                        SELECT ?, TrackID FROM CoreTracks WHERE PrimarySourceID = ? AND ExternalID = ?");

                lock (mtp_device) {
                    var playlists = mtp_device.GetPlaylists();
                    if (playlists != null)
                    {
                        foreach (MTP.Playlist playlist in playlists)
                        {
                            PlaylistSource pl_src = new PlaylistSource(playlist.Name, this);
                            pl_src.Save();
                            // TODO a transaction would make sense here (when the threading issue is fixed)
                            foreach (uint id in playlist.TrackIds)
                            {
                                ServiceManager.DbConnection.Execute(insert_cmd, pl_src.DbId, this.DbId, id);
                            }
                            pl_src.UpdateCounts();
                            AddChildSource(pl_src);
                        }
                    }
                }
            } catch (Exception e) {
                Log.Exception(e);
            }
            OnTracksAdded();
        }