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());
        }
예제 #2
0
        /// <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);
        }
예제 #3
0
        /// <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);
        }
예제 #4
0
        /// <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;
        }
예제 #7
0
 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();
     }
 }
예제 #8
0
        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()));
        }
예제 #9
0
        /// <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();
            }
        }
예제 #10
0
        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);
            }
        }
예제 #11
0
        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();
            });
        }
예제 #16
0
        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));
        }