MapResult Map(ReportingTask<MapResult> taskContext, MapState state) { // Locally register all tracks from iTunes taskContext.Description = "Fetching iTunes library playlist"; var iTunesTracks = iTunes.LibraryPlaylist.Tracks; var trackCount = iTunesTracks.Count; taskContext.TotalItems = trackCount + state.Scrobbles.Count(); // No concurrent dictionaries in this CTP, so this has to be sequential... for (int i = 1; i <= trackCount; i++) { if (taskContext.Task.IsCanceled) return null; var track = new ItunesLibraryTrack(iTunesTracks.get_ItemByPlayOrder(i)); taskContext.Description = "Registering iTunes track '" + track.Artist + " - " + track.Title + "'"; RegisterLibraryTrack(track, state); taskContext.ReportItemCompleted(); } // Find and update tracks FindAndUpdateTracks(taskContext, state); // "Early" out if (taskContext.Task.IsCanceled) return null; // Compose and return return new MapResult(state.FuzzyMatches.ToArray(), state.Updated, state.AlreadyUpToDate, state.NotFound, state.UpdateFailed, state.Errors.ToArray()); }
/// <summary> /// Starts the asynchronous reporting task for choosing fuzzy matches /// </summary> /// <param name="host">The parent form</param> /// <param name="fuzzyMatches">The fuzzy matches to evaluate</param> /// <returns>The associated task</returns> public IReportingTask <ChooseFuzzyMatchesResult> ChooseFuzzyMatchesAsync(Form host, IEnumerable <FuzzyMatch> fuzzyMatches) { var context = new ReportingTask <ChooseFuzzyMatchesResult>(); context.Task = Task.Factory.StartNew(() => ChooseFuzzyMatches(context, new ChooseFuzzyMatchesState(fuzzyMatches, host)), context.CancellationTokenSource.Token); return(context); }
/// <summary> /// Starts the asynchronous reporting task for library mapping /// </summary> /// <param name="scrobbles">The fetched scrobbles</param> /// <returns>The associated task</returns> public override IReportingTask <MapResult> MapAsync(IEnumerable <ScrobbledTrack> scrobbles) { var context = new ReportingTask <MapResult>(); context.Task = Task.Factory.StartNew(() => Map(context, new MapState(scrobbles)), context.CancellationTokenSource.Token); return(context); }
/// <summary> /// Starts the asynchronous reporting task for scrobble fetching /// </summary> /// <param name="user">The user to query</param> /// <param name="fromWeek">The first week to query</param> /// <returns>The associated task</returns> public IReportingTask <FetchResult> FetchAsync(string user, DateTime fromWeek) { var context = new ReportingTask <FetchResult>(); context.Task = Task.Factory.StartNew(() => Fetch(context, new FetchState(user, fromWeek)), context.CancellationTokenSource.Token); return(context); }
FetchResult Fetch(ReportingTask<FetchResult> taskContext, FetchState state) { // Get the charts taskContext.Description = "Fetching weekly charts list"; var chartsResponse = client.UserGetWeeklyChartList(state.User); if (chartsResponse.StatusCode == StatusCode.Failed) throw new InvalidOperationException("This user does not exist, or it doesn't have any weekly chart generated yet ('" + chartsResponse.Error.Message + "')"); // Get the tracks... taskContext.TotalItems = chartsResponse.Content.Charts.Length; // ...in parallel! Parallel.ForEach(chartsResponse.Content.Charts, () => { var thisWeek = new List<ScrobbledTrack>(); state.WeeklyTracks.Enqueue(thisWeek); return thisWeek; }, (range, index, parallelState) => { if (taskContext.Task.IsCanceled) // Allow mid-operation canceling parallelState.Stop(); taskContext.Description = "Fetching weekly chart starting " + range.From.ToShortDateString(); var tracksResponse = client.UserGetWeeklyTrackChart(state.User, range.From, range.To); if (tracksResponse.StatusCode == StatusCode.Failed) state.Errors.Enqueue(new QualifiedError(range.From.ToShortDateString() + " to " + range.To.ToShortDateString(), "'" + tracksResponse.Error.Message + "' (scrobbles from that week were ignored)")); else if (tracksResponse.Content.Tracks != null) // This does happen sometimes parallelState.ThreadLocalState.AddRange(from track in tracksResponse.Content.Tracks select new ScrobbledTrack(track.Artist.Name, track.Title, track.PlayCount, range.To)); taskContext.ReportItemCompleted(); }); // Early out if (taskContext.Task.IsCanceled) return null; // Compose results taskContext.Description = "Assembling charts"; var trackSet = new Dictionary<string, ScrobbledTrack>(); foreach (var track in state.WeeklyTracks.SelectMany(x => x)) { ScrobbledTrack contained; string key = track.Artist + track.Title; if (trackSet.TryGetValue(key, out contained)) { contained.PlayCount += track.PlayCount; if (track.WeekLastPlayed > contained.WeekLastPlayed) contained.WeekLastPlayed = track.WeekLastPlayed; } else trackSet.Add(key, track); } return new FetchResult(trackSet.Values.ToArray(), state.Errors.ToArray()); }
/// <summary> /// Starts the asynchronous reporting task for library mapping /// </summary> /// <param name="scrobbles">The fetched scrobbles</param> /// <returns>The associated task</returns> public override IReportingTask<MapResult> MapAsync(IEnumerable<ScrobbledTrack> scrobbles) { var context = new ReportingTask<MapResult>(); var future = Future.Create(() => Map(context, new MapState(scrobbles))); context.Task = future; return context; }
public void Start() { extent = ReportManager.GetInstance; if (_reportingTasks == null) { _reportingTasks = new ReportingTask(extent); _reportingTasks.SetupReporting(); } if (driver == null) { driver = new ChromeDriver("E:\\AlphaAutomation\\AlphaTestSuite\\AlphaTestReport"); driver.Manage().Window.Maximize(); } }
MapResult Map(ReportingTask <MapResult> taskContext, MapState state) { // Locally register all tracks from WMP var library = (IWMPMediaCollection2)WindowsMediaPlayer.mediaCollection; taskContext.Description = "Fetching WMP library items"; var wmpTracks = library.getByAttribute(MediaTypeAttribute, AudioMediaType); var itemCount = wmpTracks.count; taskContext.TotalItems = itemCount + state.Scrobbles.Count(); for (int i = 0; i < itemCount; i++) { if (taskContext.CancellationTokenSource.Token.IsCancellationRequested) { taskContext.CancellationTokenSource.Token.ThrowIfCancellationRequested(); } var track = new WmpLibraryTrack(wmpTracks.get_Item(i)); taskContext.Description = "Registering WMP track '" + track.Artist + " - " + track.Title + "'"; RegisterLibraryTrack(track, state); taskContext.ReportItemCompleted(); } // Find and update tracks FindAndUpdateTracks(taskContext, state); // "Early" out if (taskContext.CancellationTokenSource.Token.IsCancellationRequested) { taskContext.CancellationTokenSource.Token.ThrowIfCancellationRequested(); } // Compose and return return(new MapResult(state.FuzzyMatches.ToArray(), state.Updated, state.AlreadyUpToDate, state.NotFound, state.UpdateFailed, state.Errors.ToArray())); }
/// <summary> /// Finds matches to all scrobbles and updates where needed and possible /// </summary> /// <param name="taskContext">The current task's context</param> /// <param name="state">The current task's state</param> protected void FindAndUpdateTracks(ReportingTask <MapResult> taskContext, MapState state) { foreach (var scrobble in state.Scrobbles) { if (taskContext.CancellationTokenSource.Token.IsCancellationRequested) { break; } taskContext.Description = "Matching scrobble '" + scrobble.Artist + " - " + scrobble.Title + "'"; // Only exact matches are updated immediately var media = Find(scrobble, state); if (media != null) { try { if (media.TryUpdate(scrobble)) { state.Updated++; } else { state.AlreadyUpToDate++; } } catch (COMException e) { // Log errors to a list var error = new QualifiedError(media.ToString(), InterpretErrorCode(e.ErrorCode)); state.Errors.Add(error); state.UpdateFailed++; } } taskContext.ReportItemCompleted(); } }
private List <JobResult> GetResults(Guid taskId, bool readfileData = false) { var results = new List <JobResult>(); try { logger.Debug($"Get the results of the Task {taskId}."); var taskFolder = Path.Combine(Options.TempFolder, taskId.ToString()); logger.Trace($"Job result \"{taskFolder}\"."); var para = GetJobParameter(taskFolder); results.AddRange(ReportingTask.GetAllResultsFromJob(para)); if (readfileData) { foreach (var result in results) { foreach (var report in result.Reports) { foreach (var path in report.Paths) { report.Data.Add(new ReportData() { Filename = Path.GetFileName(path), DownloadData = File.ReadAllBytes(path) }); } } } } return(results); } catch (Exception ex) { logger.Error(ex, "The task result could not found."); return(results); } }
MapResult Map(ReportingTask <MapResult> taskContext, MapState state) { // Locally register all tracks from iTunes taskContext.Description = "Fetching iTunes library playlist"; var iTunesTracks = iTunes.LibraryPlaylist.Tracks; var trackCount = iTunesTracks.Count; taskContext.TotalItems = trackCount + state.Scrobbles.Count(); for (int i = 1; i <= trackCount; i++) { if (taskContext.CancellationTokenSource.Token.IsCancellationRequested) { taskContext.CancellationTokenSource.Token.ThrowIfCancellationRequested(); } var track = new ItunesLibraryTrack(iTunesTracks.get_ItemByPlayOrder(i)); taskContext.Description = "Registering iTunes track '" + track.Artist + " - " + track.Title + "'"; RegisterLibraryTrack(track, state); taskContext.ReportItemCompleted(); } // Find and update tracks FindAndUpdateTracks(taskContext, state); // "Early" out if (taskContext.CancellationTokenSource.Token.IsCancellationRequested) { taskContext.CancellationTokenSource.Token.ThrowIfCancellationRequested(); } // Compose and return return(new MapResult(state.FuzzyMatches.ToArray(), state.Updated, state.AlreadyUpToDate, state.NotFound, state.UpdateFailed, state.Errors.ToArray())); }
MapResult Map(ReportingTask<MapResult> taskContext, MapState state) { // Locally register all tracks from WMP var library = (IWMPMediaCollection2) WindowsMediaPlayer.mediaCollection; taskContext.Description = "Fetching WMP library playlist"; var wmpTracks = library.getAll(); var trackCount = wmpTracks.count; taskContext.TotalItems = trackCount + state.Scrobbles.Count(); // No concurrent dictionaries in this CTP, so this has to be sequential... for (int i = 0; i < trackCount; i++) { if (taskContext.Task.IsCanceled) return null; var track = new WmpLibraryTrack(wmpTracks.get_Item(i)); taskContext.Description = "Registering WMP track '" + track.Artist + " - " + track.Title + "'"; RegisterLibraryTrack(track, state); taskContext.ReportItemCompleted(); } // Find and update tracks FindAndUpdateTracks(taskContext, state); // "Early" out if (taskContext.Task.IsCanceled) return null; // Compose and return return new MapResult(state.FuzzyMatches.ToArray(), state.Updated, state.AlreadyUpToDate, state.NotFound, state.UpdateFailed, state.Errors.ToArray()); }
/// <summary> /// Starts the asynchronous reporting task for scrobble fetching /// </summary> /// <param name="user">The user to query</param> /// <returns>The associated task</returns> public IReportingTask<FetchResult> FetchAsync(string user) { var context = new ReportingTask<FetchResult>(); context.Task = Future.Create(() => Fetch(context, new FetchState(user))); return context; }
/// <summary> /// Starts the asynchronous reporting task for choosing fuzzy matches /// </summary> /// <param name="host">The parent form</param> /// <param name="fuzzyMatches">The fuzzy matches to evaluate</param> /// <returns>The associated task</returns> public IReportingTask<ChooseFuzzyMatchesResult> ChooseFuzzyMatchesAsync(Form host, IEnumerable<FuzzyMatch> fuzzyMatches) { var context = new ReportingTask<ChooseFuzzyMatchesResult>(); context.Task = Future.Create(() => ChooseFuzzyMatches(context, new ChooseFuzzyMatchesState(fuzzyMatches, host))); return context; }
/// <summary> /// Finds matches to all scrobbles and updates where needed and possible /// </summary> /// <param name="taskContext">The current task's context</param> /// <param name="state">The current task's state</param> protected void FindAndUpdateTracks(ReportingTask<MapResult> taskContext, MapState state) { Parallel.ForEach(state.Scrobbles, (scrobble, parallelState) => { if (taskContext.Task.IsCanceled) // Allow mid-task canceling parallelState.Stop(); taskContext.Description = "Matching scrobble '" + scrobble.Artist + " - " + scrobble.Title + "'"; // Only exact matches are updated immediately var media = Find(scrobble, state); if (media != null) { try { if (media.TryUpdate(scrobble)) Interlocked.Increment(ref state.Updated); else Interlocked.Increment(ref state.AlreadyUpToDate); } catch (COMException e) { // Log errors to a list state.Errors.Enqueue(new QualifiedError(media.ToString(), InterpretErrorCode(e.ErrorCode))); Interlocked.Increment(ref state.UpdateFailed); } } taskContext.ReportItemCompleted(); }); }
FetchResult Fetch(ReportingTask <FetchResult> taskContext, FetchState state) { // Get the charts taskContext.Description = "Fetching weekly charts list"; var chartsResponse = client.UserGetWeeklyChartList(state.User); if (chartsResponse.StatusCode == StatusCode.Failed) { throw new InvalidOperationException("This user does not exist, or it doesn't have any weekly chart generated yet ('" + chartsResponse.Error.Message + "')"); } var lastWeekFetched = chartsResponse.Content.Charts.Max(x => x.From); // Get the tracks... taskContext.TotalItems = chartsResponse.Content.Charts.Length; // ...in parallel! Parallel.ForEach(chartsResponse.Content.Charts, () => { var thisWeek = new List <ScrobbledTrack>(); state.WeeklyTracks.Enqueue(thisWeek); return(thisWeek); }, (range, parallelState, output) => { // Allow mid-operation canceling if (taskContext.CancellationTokenSource.Token.IsCancellationRequested) { parallelState.Stop(); } // Skip weeks that have already been imported or fetched if (range.From > state.FirstWeek) { taskContext.Description = "Fetching weekly chart starting " + range.From.ToShortDateString(); var tracksResponse = client.UserGetWeeklyTrackChart(state.User, range.From, range.To); if (tracksResponse.StatusCode == StatusCode.Failed) { state.Errors.Enqueue(new QualifiedError(range.From.ToShortDateString() + " to " + range.To.ToShortDateString(), "'" + tracksResponse.Error.Message + "' (scrobbles from that week were ignored)")); } else if (tracksResponse.Content.Tracks != null) // This does happen sometimes { output.AddRange(from track in tracksResponse.Content.Tracks select new ScrobbledTrack(track.Artist, track.Title, track.PlayCount, range.To)); } } taskContext.ReportItemCompleted(); return(output); }, ActionUtil.NullAction); // Early out if (taskContext.CancellationTokenSource.Token.IsCancellationRequested) { taskContext.CancellationTokenSource.Token.ThrowIfCancellationRequested(); } // Compose results taskContext.Description = "Assembling charts"; var trackSet = new Dictionary <ScrobbledTrack, ScrobbledTrack>(); foreach (var track in state.WeeklyTracks.SelectMany(x => x)) { ScrobbledTrack contained; if (trackSet.TryGetValue(track, out contained)) { contained.PlayCount += track.PlayCount; if (track.WeekLastPlayed > contained.WeekLastPlayed) { contained.WeekLastPlayed = track.WeekLastPlayed; } } else { trackSet.Add(track, track); } } return(new FetchResult(trackSet.Values.ToList(), state.Errors.ToArray(), lastWeekFetched)); }