/// <summary> /// Returns the viewing statistics for all movies. /// ● The movies are ordered by most watched, then by release year with newer releases /// being considered more important. /// ● The data returned only needs to contain information from the supplied csv documents /// and does not need to return data provided by the POST metadata endpoint. /// </summary> /// <returns></returns> public async Task <string> GetStats() { if (_movies == null) { await LoadData(); } var movieWatchDurations = await LoadStats(); var moviesStat = new List <MovieStat>(); foreach (var kv in movieWatchDurations.OrderByDescending(x => x.Value.Count)) { var moviesById = await GetMovieById(kv.Key); if (moviesById.Count == 0) { continue; } foreach (var movieDetails in moviesById) { var averageWatchDurationS = (int)(kv.Value.Sum() / (1000.0 * kv.Value.Count)); var movieStat = new MovieStat { MoveId = movieDetails.MoveId, Title = movieDetails.Title, ReleaseYear = movieDetails.ReleaseYear, Watches = kv.Value.Count, AverageWatchDurationS = averageWatchDurationS }; moviesStat.Add(movieStat); } } return(JsonSerializer.Serialize <List <MovieStat> >(moviesStat)); }
//private List<MovieStat> getStatsFromString() private void populateMovieLists() { List <string> statsStrings = Retrieve.RetrieveData(statsFileLocation); List <string> metaStrings = Retrieve.RetrieveData(metaFileLocation); statsStrings.Sort(); // Sort the list so all ids are together // metaStrings are already sorted by id and MovieID int currentID = -1; int numOfEntries = 0; double sumOfMs = 0; foreach (string statString in statsStrings) { int newID = 0; bool ret_val = Int32.TryParse((statString.Split(','))[0], out newID); if (ret_val) // We have valid values { double currentMs = Convert.ToDouble((statString.Split(','))[1]); if ((newID != currentID) && (numOfEntries > 0)) // a) we can't divide by zero b) we only want to add a stat after we got an entry { // Argument is int, as the average watch time, shouldn't be more than the movies duration MovieStat aStat = new MovieStat(currentID, (int)(sumOfMs / numOfEntries), numOfEntries); moviesWithStat.Add(aStat); numOfEntries = 0; sumOfMs = currentMs; } else { sumOfMs += currentMs; // Add entry to the sum of stats numOfEntries++; } currentID = newID; // Set the id of the new statString element } // Else this line has headers or invalid text } // There should be one last item we haven't inserted to the list if (numOfEntries != 0) { // Argument is int, as the average watch time, shouldn't be more than the movies duration MovieStat aStat = new MovieStat(currentID, (int)(sumOfMs / numOfEntries), numOfEntries); moviesWithStat.Add(aStat); } MovieMeta previousMeta = new MovieMeta(); // Now we have to retrieve the metaData and use them to populate the missing // data in the statsList foreach (string meta in metaStrings) { string[] metaArray = meta.Split(','); // We will not consider metadata with missing values int newID, tempYear = 0; bool ret_id = Int32.TryParse(metaArray[0], out newID); // every valid data line, should start with an id bool ret_year = Int32.TryParse(metaArray[5], out tempYear); // every valid data line, should start with an id if (ret_id && ret_year) { if (metaArray.Length > 5) { // MetaArray[0] should be the file id MovieMeta metaItem = new MovieMeta(Convert.ToInt32(metaArray[1]), metaArray[2], metaArray[3], metaArray[4], metaArray[5]); // The first item as the previous and the current one if (previousMeta == null) { previousMeta = metaItem; } else // Make sure there are no empty values if (metaItem.movieId != 0 && metaItem.title != "" && metaItem.language != "" && metaItem.duration != "" && metaItem.releaseYear != 0) { // We have to take only the latest (higher ID number) of the same metadata // as "same", we consider metadata that have the same movieID and Language parameters if ((metaItem.movieId != previousMeta.movieId) || (metaItem.language != previousMeta.language)) {// We have a new meta data that needs to be stored, // previousMeta, have the latest values of similar metas, since the list ordered by id and movieID moviesWithMeta.Add(metaItem); previousMeta = metaItem; // Update the previous meta as we have added it to the list // Add the missing data in the stats list objects var obj = moviesWithStat.FirstOrDefault(statList => statList.movieId == metaItem.movieId); // obj is a reference type like the MovieStat inside the list so, the above assignment is a reference copy // thus, any change in the obj values, will be a change of the values inside the list... if (obj != null) // There might extra movieIDs that do not exist in the metadata file { obj.title = metaItem.title; obj.releaseYear = metaItem.releaseYear; } } } } } // Else, this line had no valid data, skip... } }