234 lines
6.8 KiB
C#
234 lines
6.8 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Runtime.InteropServices;
|
|
using MusicMetaTagger.Core.Utility;
|
|
using iTunesLib;
|
|
|
|
namespace MusicMetaTagger.UI
|
|
{
|
|
public class ItunesLibraryInterface : IMusicLibraryInterface, IDisposable
|
|
{
|
|
private iTunesApp _iTunesApp;
|
|
|
|
private Dictionary<TrackQueryStatus, IITTrack> _trackQueryTracks;
|
|
|
|
/// <summary>
|
|
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
|
|
/// </summary>
|
|
public void Dispose()
|
|
{
|
|
Marshal.ReleaseComObject(_iTunesApp);
|
|
_iTunesApp = null;
|
|
GC.Collect();
|
|
}
|
|
|
|
#region IMusicLibraryInterface Members
|
|
|
|
/// <summary>
|
|
/// Gets the track queries.
|
|
/// </summary>
|
|
/// <param name = "libraryQuery">The library query.</param>
|
|
/// <param name = "callback">The callback.</param>
|
|
/// <returns></returns>
|
|
public List<TrackQueryStatus> GetTrackQueries(LibraryQuery libraryQuery, IProgressCallback callback)
|
|
{
|
|
if (_trackQueryTracks == null)
|
|
_trackQueryTracks = new Dictionary<TrackQueryStatus, IITTrack>();
|
|
var trackQueries = new List<TrackQueryStatus>();
|
|
|
|
callback.SetText("Opening iTunes Library");
|
|
if (_iTunesApp == null)
|
|
_iTunesApp = new iTunesApp();
|
|
|
|
callback.SetText("Getting tracks");
|
|
var tracks = _iTunesApp.LibraryPlaylist.Tracks;
|
|
|
|
var trackCount = libraryQuery.ScanLimit <= 0 ? tracks.Count : Math.Min(tracks.Count, libraryQuery.ScanLimit);
|
|
|
|
callback.SetRange(0, trackCount);
|
|
|
|
for (var i = 1; i <= trackCount; i++)
|
|
{
|
|
callback.Increment(1);
|
|
if (i%5 == 0 || i == trackCount)
|
|
callback.SetText(string.Format("Scanning iTunes track# {0} / {1}, Found {2} matches", i, trackCount,
|
|
trackQueries.Count));
|
|
|
|
if (callback.IsAborting)
|
|
break;
|
|
|
|
var track = tracks[i];
|
|
|
|
var trackQuery = new TrackQueryStatus
|
|
{
|
|
TrackTitle = track.Name,
|
|
AlbumTitle = track.Album,
|
|
ArtistName = track.Artist,
|
|
TrackNumber = track.TrackNumber,
|
|
TrackLength = StringUtility.ConvertTimeSpan(track.Time),
|
|
AlbumYear = track.Year,
|
|
AlbumPartOfCompilation = track.Compilation,
|
|
AlbumGenre = track.Genre//,
|
|
//AlbumArtistName = track.AlbumArtist
|
|
};
|
|
|
|
|
|
if (libraryQuery.AddedAfter > track.DateAdded)
|
|
continue;
|
|
|
|
if (libraryQuery.BlankGenre && !string.IsNullOrEmpty(track.Genre))
|
|
continue;
|
|
|
|
if (libraryQuery.BlankRating && track.Rating > 0)
|
|
continue;
|
|
|
|
if (libraryQuery.BlankYear && track.Year > 0)
|
|
continue;
|
|
|
|
if (!libraryQuery.MatchTrackQuery(trackQuery))
|
|
continue;
|
|
|
|
// skip pod casts
|
|
if (track.Genre == "Podcast" || track.Genre == "Voice Memo" ) // || track.VideoKind != 0 || track.Podcast)
|
|
continue;
|
|
|
|
trackQueries.Add(trackQuery);
|
|
_trackQueryTracks.Add(trackQuery, track);
|
|
}
|
|
|
|
return trackQueries;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Updates the album art.
|
|
/// </summary>
|
|
/// <param name = "trackQuery">The track query.</param>
|
|
/// <param name = "albumArt">The album art file info.</param>
|
|
/// <param name = "overwrite">if set to <c>true</c> [overwrite].</param>
|
|
/// <returns>True if update was successful, false otherwise</returns>
|
|
public bool UpdateAlbumArt(TrackQueryStatus trackQuery, FileInfo albumArt, bool overwrite)
|
|
{
|
|
var iTrack = GetTrack(trackQuery);
|
|
if (albumArt == null)
|
|
return false;
|
|
if (iTrack.Artwork.Count == 0 || overwrite)
|
|
{
|
|
if (overwrite && iTrack.Artwork.Count > 0)
|
|
{
|
|
while (iTrack.Artwork.Count > 0)
|
|
iTrack.Artwork[1].Delete();
|
|
}
|
|
iTrack.AddArtworkFromFile(albumArt.FullName);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Tries to update the genre.
|
|
/// </summary>
|
|
/// <param name = "trackQuery">The track query.</param>
|
|
/// <param name = "genre">The genre.</param>
|
|
/// <param name = "overwrite">if set to <c>true</c> [overwrite].</param>
|
|
/// <returns>True if update was successful, false otherwise</returns>
|
|
public bool UpdateGenre(TrackQueryStatus trackQuery, string genre, bool overwrite)
|
|
{
|
|
var iTrack = GetTrack(trackQuery);
|
|
if (string.IsNullOrEmpty(iTrack.Genre) || overwrite)
|
|
{
|
|
try
|
|
{
|
|
iTrack.Genre = genre;
|
|
return true;
|
|
}
|
|
catch
|
|
{
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Updates the year.
|
|
/// </summary>
|
|
/// <param name = "trackQuery">The track query.</param>
|
|
/// <param name = "year">The year.</param>
|
|
/// <param name = "overwrite">if set to <c>true</c> [overwrite].</param>
|
|
/// <returns>True if update was successful, false otherwise</returns>
|
|
public bool UpdateYear(TrackQueryStatus trackQuery, int year, bool overwrite)
|
|
{
|
|
var iTrack = GetTrack(trackQuery);
|
|
if (iTrack.Year == 0 || overwrite)
|
|
{
|
|
iTrack.Year = year;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Updates the rating.
|
|
/// </summary>
|
|
/// <param name = "trackQuery">The track query.</param>
|
|
/// <param name = "rating">The rating from 0 to 100.</param>
|
|
/// <param name = "overwrite">if set to <c>true</c> overwrite existing value.</param>
|
|
/// <returns>True if update was successful, false otherwise</returns>
|
|
public bool UpdateRating(TrackQueryStatus trackQuery, int rating, bool overwrite)
|
|
{
|
|
var iTrack = GetTrack(trackQuery);
|
|
if (iTrack.Rating == 0 || overwrite)
|
|
{
|
|
iTrack.Rating = rating;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public bool AddComment(TrackQueryStatus trackQuery, string comment)
|
|
{
|
|
var iTrack = GetTrack(trackQuery);
|
|
if (iTrack.Comment == null)
|
|
{
|
|
iTrack.Comment = comment;
|
|
return true;
|
|
}
|
|
if (!iTrack.Comment.Contains(comment))
|
|
{
|
|
iTrack.Comment += comment;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns true if the trackQuery represents an Mp3.
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public bool IsMp3(TrackQueryStatus trackQuery)
|
|
{
|
|
var iTrack = GetTrack(trackQuery);
|
|
return iTrack.KindAsString == "MPEG audio file";
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns the Mp3 represented by this trackQuery
|
|
/// </summary>
|
|
/// <param name = "trackQuery"></param>
|
|
/// <returns></returns>
|
|
public FileInfo GetMp3FileInfo(TrackQueryStatus trackQuery)
|
|
{
|
|
var file = (IITFileOrCDTrack) GetTrack(trackQuery);
|
|
return file.Location != null ? new FileInfo(file.Location) : null;
|
|
}
|
|
|
|
#endregion
|
|
|
|
private IITTrack GetTrack(TrackQueryStatus trackQueryStatus)
|
|
{
|
|
if (!_trackQueryTracks.ContainsKey(trackQueryStatus))
|
|
throw new ApplicationException("Doesn't contain track" + trackQueryStatus.TrackTitle);
|
|
return _trackQueryTracks[trackQueryStatus];
|
|
}
|
|
}
|
|
} |