protected override void AddTrackToDevice(DatabaseTrackInfo track, SafeUri fromUri) { if (track.PrimarySourceId == DbId) { return; } lock (mtp_device) { Track mtp_track = TrackInfoToMtpTrack(track, fromUri); bool video = track.HasAttribute(TrackMediaAttributes.VideoStream); mtp_device.UploadTrack(fromUri.LocalPath, mtp_track, GetFolderForTrack(track), OnUploadProgress); // Add/update album art if (!video) { string key = MakeAlbumKey(track.AlbumArtist, track.AlbumTitle); if (!album_cache.ContainsKey(key)) { Album album = new Album(mtp_device, track.AlbumTitle, track.AlbumArtist, track.Genre, track.Composer); album.AddTrack(mtp_track); if (supports_jpegs && can_sync_albumart) { try { Gdk.Pixbuf pic = ServiceManager.Get <Banshee.Collection.Gui.ArtworkManager> ().LookupScalePixbuf( track.ArtworkId, thumb_width ); if (pic != null) { byte [] bytes = pic.SaveToBuffer("jpeg"); album.Save(bytes, (uint)pic.Width, (uint)pic.Height); Banshee.Collection.Gui.ArtworkManager.DisposePixbuf(pic); } album_cache[key] = album; } catch (Exception e) { Log.Debug("Failed to create MTP Album", e.Message); } } else { album.Save(); album_cache[key] = album; } } else { Album album = album_cache[key]; album.AddTrack(mtp_track); album.Save(); } } MtpTrackInfo new_track = new MtpTrackInfo(mtp_device, mtp_track); new_track.PrimarySource = this; new_track.Save(false); track_map[new_track.TrackId] = mtp_track; } }
protected override void AddTrackToDevice(DatabaseTrackInfo track, SafeUri fromUri) { if (track.PrimarySourceId == DbId) { return; } lock (mtp_device) { Track mtp_track = TrackInfoToMtpTrack(track, fromUri); bool video = track.HasAttribute(TrackMediaAttributes.VideoStream); Folder folder = GetFolderForTrack(track); mtp_device.UploadTrack(fromUri.LocalPath, mtp_track, folder, OnUploadProgress); // Add/update album art if (!video) { string key = MakeAlbumKey(track); if (!album_cache.ContainsKey(key)) { // LIBMTP 1.0.3 BUG WORKAROUND // In libmtp.c the 'LIBMTP_Create_New_Album' function invokes 'create_new_abstract_list'. // The latter calls strlen on the 'name' parameter without null checking. If AlbumTitle is // null, this causes a sigsegv. Lets be safe and always pass non-null values. Album album = new Album(mtp_device, track.AlbumTitle ?? "", track.AlbumArtist ?? "", track.Genre ?? "", track.Composer ?? ""); album.AddTrack(mtp_track); if (supports_jpegs && can_sync_albumart) { ArtworkManager art = ServiceManager.Get <ArtworkManager> (); Exception ex = null; Gdk.Pixbuf pic = null; byte[] bytes = null; uint width = 0, height = 0; ThreadAssist.BlockingProxyToMain(() => { try { pic = art.LookupScalePixbuf(track.ArtworkId, thumb_width); if (pic != null) { bytes = pic.SaveToBuffer("jpeg"); width = (uint)pic.Width; height = (uint)pic.Height; } } catch (Exception e) { ex = e; } }); try { if (ex != null) { throw ex; } if (bytes != null) { ArtworkManager.DisposePixbuf(pic); album.Save(bytes, width, height); album_cache [key] = Tuple.Create(album, folder); } } catch (Exception e) { Log.Debug("Failed to create MTP Album", e.Message); } } else { album.Save(); album_cache[key] = Tuple.Create(album, folder); } } else { Album album = album_cache[key].Item1; album.AddTrack(mtp_track); album.Save(); } } MtpTrackInfo new_track = new MtpTrackInfo(mtp_device, mtp_track); new_track.PrimarySource = this; new_track.Save(false); track_map[new_track.TrackId] = mtp_track; } }
protected override void AddTrackToDevice(DatabaseTrackInfo track, SafeUri fromUri) { if (track.PrimarySourceId == DbId) { return; } SafeUri new_uri = new SafeUri(GetTrackPath(track, System.IO.Path.GetExtension(fromUri.LocalPath))); // If it already is on the device but it's out of date, remove it //if (File.Exists(new_uri) && File.GetLastWriteTime(track.Uri.LocalPath) > File.GetLastWriteTime(new_uri)) //RemoveTrack(new MassStorageTrackInfo(new SafeUri(new_uri))); if (!File.Exists(new_uri)) { Directory.Create(System.IO.Path.GetDirectoryName(new_uri.LocalPath)); File.Copy(fromUri, new_uri, false); DatabaseTrackInfo copied_track = new DatabaseTrackInfo(track); copied_track.PrimarySource = this; copied_track.Uri = new_uri; // Write the metadata in db to the file on the DAP if it has changed since file was modified // to ensure that when we load it next time, it's data will match what's in the database // and the MetadataHash will actually match. We do this by comparing the time // stamps on files for last update of the db metadata vs the sync to file. // The equals on the inequality below is necessary for podcasts who often have a sync and // update time that are the same to the second, even though the album metadata has changed in the // DB to the feedname instead of what is in the file. It should be noted that writing the metadata // is a small fraction of the total copy time anyway. if (track.LastSyncedStamp >= Hyena.DateTimeUtil.ToDateTime(track.FileModifiedStamp)) { Log.DebugFormat("Copying Metadata to File Since Sync time >= Updated Time"); Banshee.Streaming.StreamTagger.SaveToFile(copied_track); } copied_track.Save(false); } if (CoverArtSize > -1 && !String.IsNullOrEmpty(CoverArtFileType) && !String.IsNullOrEmpty(CoverArtFileName) && (FolderDepth == -1 || FolderDepth > 0)) { SafeUri cover_uri = new SafeUri(System.IO.Path.Combine(System.IO.Path.GetDirectoryName(new_uri.LocalPath), CoverArtFileName)); string coverart_id; if (track.HasAttribute(TrackMediaAttributes.Podcast)) { coverart_id = String.Format("podcast-{0}", Banshee.Base.CoverArtSpec.EscapePart(track.AlbumTitle)); } else { coverart_id = track.ArtworkId; } if (!File.Exists(cover_uri) && CoverArtSpec.CoverExists(coverart_id)) { Gdk.Pixbuf pic = null; if (CoverArtSize == 0) { if (CoverArtFileType == "jpg" || CoverArtFileType == "jpeg") { SafeUri local_cover_uri = new SafeUri(Banshee.Base.CoverArtSpec.GetPath(coverart_id)); Banshee.IO.File.Copy(local_cover_uri, cover_uri, false); } else { pic = artwork_manager.LookupPixbuf(coverart_id); } } else { pic = artwork_manager.LookupScalePixbuf(coverart_id, CoverArtSize); } if (pic != null) { try { byte [] bytes = pic.SaveToBuffer(CoverArtFileType); System.IO.Stream cover_art_file = File.OpenWrite(cover_uri, true); cover_art_file.Write(bytes, 0, bytes.Length); cover_art_file.Close(); } catch (GLib.GException) { Log.DebugFormat("Could not convert cover art to {0}, unsupported filetype?", CoverArtFileType); } finally { Banshee.Collection.Gui.ArtworkManager.DisposePixbuf(pic); } } } } }