protected void AssertTitleSort(string title, string title_sort, byte[] expected) { DatabaseTrackInfo info = new DatabaseTrackInfo (); info.TrackTitle = title; info.TrackTitleSort = title_sort; Assert.AreEqual (expected, info.TrackTitleSortKey); }
protected static PrimarySource DefaultTrackPrimarySourceChooser (DatabaseTrackInfo track) { if ((track.MediaAttributes & TrackMediaAttributes.VideoStream) != 0) { return ServiceManager.SourceManager.VideoLibrary; } else { return ServiceManager.SourceManager.MusicLibrary; } }
public override void CopyTrackTo (DatabaseTrackInfo track, SafeUri uri, BatchUserJob job) { if (track.PrimarySource == this && track.Uri.Scheme.StartsWith ("http")) { foreach (double percent in database.DownloadTrack ((int)track.ExternalId, track.MimeType, uri.AbsolutePath)) { job.DetailedProgress = percent; } } }
public Bookmark(DatabaseTrackInfo track, int position_ms, string type) { Track = track; Position = TimeSpan.FromMilliseconds (position_ms); CreatedAt = DateTime.Now; Type = type; Save (); }
private void DownloadLyrics(DatabaseTrackInfo track) { string lyrics = null; try { lyrics = LyricsManager.Instance.DownloadLyrics (track); } catch (Exception e) { Log.Warning (e); return; } LyricsManager.Instance.SaveLyrics (track, lyrics, true); }
public PodcastPropertiesDialog (DatabaseTrackInfo track) { PodcastTrackInfo pi = PodcastTrackInfo.From (track); if (pi == null) { throw new ArgumentNullException ("pi"); } this.pi = pi; Title = track.TrackTitle; BuildWindow (); //IconThemeUtils.SetWindowIcon (this); }
public ContactTrackInfo(DatabaseTrackInfo track, ContactSource source) : this() { if (track == null) { throw new ArgumentNullException ("track"); } else if (source == null) { throw new ArgumentNullException ("source"); } this.TrackId = track.TrackId; this.ExternalId = track.ExternalId; this.AlbumTitle = track.AlbumTitle; this.ArtistName = track.ArtistName; this.TrackNumber = track.TrackNumber; this.TrackTitle = track.TrackTitle; this.Uri = track.Uri; PrimarySource = source; }
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"); bool write_metadata = Metadata.SaveTrackMetadataService.WriteMetadataEnabled.Value; bool write_ratings_and_playcounts = Metadata.SaveTrackMetadataService.WriteRatingsAndPlayCountsEnabled.Value; Banshee.Streaming.StreamTagger.SaveToFile (copied_track, write_metadata, write_ratings_and_playcounts); } 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 = 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); } } } } }
public override void CopyTrackTo (DatabaseTrackInfo track, SafeUri uri, BatchUserJob job) { if (track.PrimarySourceId == DbId) { Banshee.IO.File.Copy (track.Uri, uri, false); } }
public DatabaseTrackInfo ImportTrack(SafeUri uri) { if (!IsWhiteListedFile(uri.AbsoluteUri)) { return(null); } if (DatabaseTrackInfo.ContainsUri(uri, PrimarySourceIds)) { // TODO add DatabaseTrackInfo.SyncedStamp property, and if the file has been // updated since the last sync, fetch its metadata into the db. return(null); } if (Banshee.IO.File.GetSize(uri) == 0) { throw new InvalidFileException(String.Format( Catalog.GetString("File is empty so it could not be imported: {0}"), Path.GetFileName(uri.LocalPath))); } DatabaseTrackInfo track = new DatabaseTrackInfo() { Uri = uri }; using (var file = StreamTagger.ProcessUri(uri)) { StreamTagger.TrackInfoMerge(track, file, false, true, true); } track.Uri = uri; if (FindOutdatedDupe(track)) { return(null); } track.PrimarySource = trackPrimarySourceChooser(track); // TODO note, there is deadlock potential here b/c of locking of shared commands and blocking // because of transactions. Needs to be fixed in HyenaDatabaseConnection. ServiceManager.DbConnection.BeginTransaction(); try { bool save_track = true; if (track.PrimarySource is Banshee.Library.LibrarySource) { save_track = track.CopyToLibraryIfAppropriate(force_copy); } if (save_track) { track.Save(false); } ServiceManager.DbConnection.CommitTransaction(); } catch (Exception) { ServiceManager.DbConnection.RollbackTransaction(); throw; } counts[track.PrimarySourceId] = counts.ContainsKey(track.PrimarySourceId) ? counts[track.PrimarySourceId] + 1 : 1; // Reload every 20% or every 250 tracks, whatever is more (eg at most reload 5 times during an import) if (counts[track.PrimarySourceId] >= Math.Max(TotalCount / 5, 250)) { counts[track.PrimarySourceId] = 0; track.PrimarySource.NotifyTracksAdded(); } return(track); }
protected override bool DeleteTrack (DatabaseTrackInfo track) { lock (mtp_device) { Track mtp_track = track_map [track.TrackId]; track_map.Remove (track.TrackId); // Remove from device mtp_device.Remove (mtp_track); // Remove track from album, and remove album from device if it no longer has tracks string key = MakeAlbumKey (track.ArtistName, track.AlbumTitle); if (album_cache.ContainsKey (key)) { Album album = album_cache[key]; album.RemoveTrack (mtp_track); if (album.Count == 0) { album.Remove (); album_cache.Remove (key); } } return true; } }
public override void CopyTrackTo (DatabaseTrackInfo track, SafeUri uri, BatchUserJob job) { if (track_map.ContainsKey (track.TrackId)) { track_map[track.TrackId].Download (uri.LocalPath, delegate (ulong current, ulong total, IntPtr data) { job.DetailedProgress = (double) current / total; return 0; }); } else { throw new Exception ("Error copying track from MTP device"); } }
private bool RenameFile (DatabaseTrackInfo track) { SafeUri old_uri = track.Uri; bool in_library = old_uri.AbsolutePath.StartsWith (musicLibrarySource.BaseDirectoryWithSeparator); if (!in_library) { return false; } string new_filename = track.PathPattern.BuildFull (musicLibrarySource.BaseDirectory, track, System.IO.Path.GetExtension (old_uri.ToString ())); SafeUri new_uri = new SafeUri (new_filename); if (!new_uri.Equals (old_uri) && !Banshee.IO.File.Exists (new_uri)) { Banshee.IO.File.Move (old_uri, new_uri); Banshee.IO.Utilities.TrimEmptyDirectories (old_uri); track.Uri = new_uri; return true; } return false; }
private void EditStation (DatabaseTrackInfo track) { StationEditor editor = new StationEditor (track); editor.Response += OnStationEditorResponse; editor.Show (); }
protected virtual bool DeleteTrack (DatabaseTrackInfo track) { if (!track.Uri.IsLocalPath) throw new Exception ("Cannot delete a non-local resource: " + track.Uri.Scheme); try { Banshee.IO.Utilities.DeleteFileTrimmingParentDirectories (track.Uri); } catch (System.IO.FileNotFoundException) { } catch (System.IO.DirectoryNotFoundException) { } return true; }
public virtual void UpdateMetadata (DatabaseTrackInfo track) { }
protected override bool DeleteTrack (DatabaseTrackInfo track) { try { if (ms_device != null && !ms_device.DeleteTrackHook (track)) { return false; } string track_file = System.IO.Path.GetFileName (track.Uri.LocalPath); string track_dir = System.IO.Path.GetDirectoryName (track.Uri.LocalPath); int files = 0; // Count how many files remain in the track's directory, // excluding self or cover art foreach (string file in System.IO.Directory.GetFiles (track_dir)) { string relative = System.IO.Path.GetFileName (file); if (relative != track_file && relative != CoverArtFileName) { files++; } } // If we are the last track, go ahead and delete the artwork // to ensure that the directory tree can get trimmed away too if (files == 0 && CoverArtFileName != null) { System.IO.File.Delete (Paths.Combine (track_dir, CoverArtFileName)); } Banshee.IO.Utilities.DeleteFileTrimmingParentDirectories (track.Uri); } catch (System.IO.FileNotFoundException) { } catch (System.IO.DirectoryNotFoundException) { } return true; }
public static bool TrackEqual(DatabaseTrackInfo a, DatabaseTrackInfo b) { return(a != null && b != null && a.TrackId == b.TrackId); }
public DatabaseTrackInfo(DatabaseTrackInfo original) : base() { Provider.Copy(original, this); }
private void FetchForTrack(DatabaseTrackInfo track) { bool save = true; try { if (String.IsNullOrEmpty (track.AlbumTitle) || String.IsNullOrEmpty (track.ArtistName)) { // Do not try to fetch album art for these } else { IMetadataLookupJob job = MetadataService.Instance.CreateJob (track); job.Run (); } } catch (System.Threading.ThreadAbortException) { save = false; throw; } catch (Exception e) { Log.Exception (e); } finally { if (save) { bool have_cover_art = CoverArtSpec.CoverExists (track.ArtistName, track.AlbumTitle); ServiceManager.DbConnection.Execute ( "INSERT OR REPLACE INTO CoverArtDownloads (AlbumID, Downloaded, LastAttempt) VALUES (?, ?, ?)", track.AlbumId, have_cover_art, DateTime.Now); } } }
public override bool DeleteTrackHook (DatabaseTrackInfo track) { // Do not allow removing purchased tracks if not in the // Amazon Purchased Music source; this should prevent // accidental deletion of purchased music that may not // have been copied from the device yet. // // TODO: Provide some feedback when a purchased track is // skipped from deletion // // FIXME: unfortunately this does not work due to // the cache models being potentially different // even though they will always reference the same tracks // amazon_source.TrackModel.IndexOf (track) >= 0 if (!amazon_source.Active && amazon_source.Count > 0 && track.Uri.LocalPath.StartsWith (amazon_base_dir)) { return false; } return true; }
public virtual void CopyTrackTo (DatabaseTrackInfo track, SafeUri uri, BatchUserJob job) { Log.WarningFormat ("CopyTrackTo not implemented for source {0}", this); }
protected override void AddTrack(DatabaseTrackInfo track) { AddTrack (track.TrackId); }
protected virtual void AddTrackAndIncrementCount (DatabaseTrackInfo track) { AddTrackJob.Status = String.Format ("{0} - {1}", track.ArtistName, track.TrackTitle); AddTrack (track); IncrementAddedTracks (); }
/*public override void CopyTrackTo (DatabaseTrackInfo track, SafeUri uri, UserJob job) { Banshee.IO.File.Copy (track.Uri, uri, false); }*/ protected override void AddTrack (DatabaseTrackInfo track) { // Ignore if already have it if (track.PrimarySourceId == DbId) return; PrimarySource source = track.PrimarySource; // If it's from a local primary source, change its PrimarySource if (source.IsLocal || source is LibrarySource) { track.PrimarySource = this; if (!(source is LibrarySource)) { track.CopyToLibraryIfAppropriate (false); } track.Save (false); // TODO optimize, remove this? I think it makes moving items // between local libraries very slow. //source.NotifyTracksChanged (); } else { // Figure out where we should put it if were to copy it var pattern = this.PathPattern ?? MusicLibrarySource.MusicFileNamePattern; string path = pattern.BuildFull (BaseDirectory, track); SafeUri uri = new SafeUri (path); // Make sure it's not already in the library // TODO optimize - no need to recreate this int [] every time if (DatabaseTrackInfo.ContainsUri (uri, new int [] {DbId})) { return; } // Since it's not, copy it and create a new TrackInfo object track.PrimarySource.CopyTrackTo (track, uri, AddTrackJob); // Create a new entry in CoreTracks for the copied file DatabaseTrackInfo new_track = new DatabaseTrackInfo (track); new_track.Uri = uri; new_track.PrimarySource = this; new_track.Save (false); } }
/// <summary> /// Adds the currently selected item(s) of the active source to the internet radio source /// as new stations. Any session data (as in live365 with activated user login) will previously /// be cleared. /// </summary> /// <param name="o"> /// A <see cref="System.Object"/> -- not used /// </param> /// <param name="e"> /// A <see cref="EventArgs"/> -- not used /// </param> protected void OnAddToInternetRadio(object o, EventArgs e) { PrimarySource internet_radio_source = GetInternetRadioSource (); PrimarySource current_source = ServiceManager.SourceManager.ActiveSource as PrimarySource; if (current_source == null) { Log.Debug ("[LiveRadioSource]<OnAddToInternetRadio> ActiveSource not Primary"); return; } if (internet_radio_source == null) { Log.Debug ("[LiveRadioSource]<OnAddToInternetRadio> Internet Radio not found"); return; } ITrackModelSource active_track_model_source = (ITrackModelSource) current_source; if (active_track_model_source.TrackModel.SelectedItems == null || active_track_model_source.TrackModel.SelectedItems.Count <= 0) { return; } ILiveRadioPlugin current_plugin = null; foreach (ILiveRadioPlugin plugin in plugins) { if (plugin.PluginSource != null && plugin.PluginSource.Equals (current_source)) { current_plugin = plugin; } } foreach (TrackInfo track in active_track_model_source.TrackModel.SelectedItems) { DatabaseTrackInfo station_track = new DatabaseTrackInfo (track as DatabaseTrackInfo); if (station_track != null) { station_track.PrimarySource = internet_radio_source; if (current_plugin != null) station_track.Uri = current_plugin.CleanUpUrl (station_track.Uri); station_track.Save (); } } }
protected virtual void OnImportResult (DatabaseTrackInfo track, string path, Exception error) { DatabaseImportResultHandler handler = ImportResult; if (handler != null) { handler (this, new DatabaseImportResultArgs (track, path, error)); } }
public virtual bool DeleteTrackHook (DatabaseTrackInfo track) { return true; }
public DatabaseTrackInfo ImportTrack (SafeUri uri) { if (!IsWhiteListedFile (uri.AbsoluteUri)) { return null; } if (DatabaseTrackInfo.ContainsUri (uri, PrimarySourceIds)) { // TODO add DatabaseTrackInfo.SyncedStamp property, and if the file has been // updated since the last sync, fetch its metadata into the db. return null; } if (Banshee.IO.File.GetSize (uri) == 0) { throw new InvalidFileException (String.Format ( Catalog.GetString ("File is empty so it could not be imported: {0}"), Path.GetFileName (uri.LocalPath))); } DatabaseTrackInfo track = new DatabaseTrackInfo () { Uri = uri }; using (var file = StreamTagger.ProcessUri (uri)) { StreamTagger.TrackInfoMerge (track, file, false, true, true); } track.Uri = uri; if (FindOutdatedDupe (track)) { return null; } track.PrimarySource = trackPrimarySourceChooser (track); // TODO note, there is deadlock potential here b/c of locking of shared commands and blocking // because of transactions. Needs to be fixed in HyenaDatabaseConnection. ServiceManager.DbConnection.BeginTransaction (); try { bool save_track = true; if (track.PrimarySource is Banshee.Library.LibrarySource) { save_track = track.CopyToLibraryIfAppropriate (force_copy); } if (save_track) { track.Save (false); } ServiceManager.DbConnection.CommitTransaction (); } catch (Exception) { ServiceManager.DbConnection.RollbackTransaction (); throw; } counts[track.PrimarySourceId] = counts.ContainsKey (track.PrimarySourceId) ? counts[track.PrimarySourceId] + 1 : 1; // Reload every 20% or every 250 tracks, whatever is more (eg at most reload 5 times during an import) if (counts[track.PrimarySourceId] >= Math.Max (TotalCount/5, 250)) { counts[track.PrimarySourceId] = 0; track.PrimarySource.NotifyTracksAdded (); } return 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); 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)) { // 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) { 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; } }
private bool FindOutdatedDupe (DatabaseTrackInfo track) { if (DatabaseTrackInfo.MetadataHashCount (track.MetadataHash, PrimarySourceIds) != 1) { return false; } var track_to_update = DatabaseTrackInfo.GetTrackForMetadataHash (track.MetadataHash, PrimarySourceIds); if (track_to_update == null || Banshee.IO.File.Exists (track_to_update.Uri)) { return false; } track_to_update.Uri = track.Uri; track_to_update.Save (); return true; }
public void Add(DatabaseTrackInfo track) { AddTrack(track); }
public bool Contains(DatabaseTrackInfo track) { return track != null && connection.Query<bool> ( String.Format ("SELECT COUNT(*) > 0 {0} AND CoreTracks.TrackID = ? LIMIT 1", UnfilteredQuery), track.TrackId ); }