protected override async Task ExecuteAsync(CancellationToken stoppingToken) { // read all channel ids //var channels = await _channelRepository.GetAllChannelIdAndTitle(); var channels = new List <Channel> { new Channel() with { Id = "UCBo9TLJiZ5HI5CXFsCxOhmA" } }; _logger.LogInformation( $"{channels.Count} channels will be inspected for publish schedules" ); foreach (var channel in channels) { try { _logger.LogInformation(channel.Id); // aggregate the channel video views of this channel per // timeframes (day of week, hour of day) var result = await _aggregateVideoPublishTimesUseCase.Handle( new AggregateVideoPublishTimesRequest( channel.Id ) ); var items = new List <VideoPublishAggregationItem>(); foreach (var daysOfWeek in result.Aggregation) { foreach (var hourOfDay in daysOfWeek.Value) { var item = new VideoPublishAggregationItem() { DayOfTheWeek = (int)daysOfWeek.Key, HourOfTheDay = hourOfDay.Key, PublishedVideos = hourOfDay.Value }; items.Add(item); } } if (items.Count == 0) { _logger.LogInformation($"No uploads for channel {channel.Id} within the last 4 month"); continue; } var average = items.Sum(i => i.PublishedVideos) / items.Count; var sortedByDeviation = items .Select(item => new PublishSchedulePrediction( item, item.PublishedVideos / average)) .OrderByDescending(item => item.DeviationFromAverage) .Where(i => i.DeviationFromAverage > average) .Take(5) .ToList(); var mergedNeighbors = MergeNeighbors(sortedByDeviation); var gradient = 1 - average / mergedNeighbors.First().DeviationFromAverage; var channelResult = new ChannelPublishPrediction( channel.Id, channel.Title, average, mergedNeighbors, gradient); var updatePredictionSuccessful = await _channelPublishPredictionRepository.UpdatePrediction(channelResult); if (!updatePredictionSuccessful) { _logger.LogWarning($"Updating publish prediction for channel {channel.Id} was not successful"); } } catch (Exception e) { _logger.LogError(e.ToString(), e.InnerException); } } }
/// <summary> /// Resolves all queries on guest accesses /// </summary> /// <param name="graphQlQuery"></param> public void ResolveQuery(GraphQlQuery graphQlQuery) { // LATEST VIDEO: returns the latest video of a channel graphQlQuery.FieldAsync <VideoType>( "latestVideo", arguments: new QueryArguments( new QueryArgument <NonNullGraphType <IdGraphType> > { Name = "channelId" } ), resolve: async(context) => { var channelId = context.GetArgument <string>("channelId"); var video = await _videoRepository.GetLatest(channelId); var channel = await _channelRepository.Get(channelId); var enrichedVideo = video with { Channel = channel }; // map entity to model return(_mapper.Map <VideoModel>(enrichedVideo)); } ); // VIDEOS: returns all videos of a certain channel graphQlQuery.FieldAsync <ListGraphType <VideoType> >( "videos", arguments: new QueryArguments( new QueryArgument <NonNullGraphType <IdGraphType> > { Name = "channelId" }, new QueryArgument <NonNullGraphType <IntGraphType> > { Name = "skip" }, new QueryArgument <NonNullGraphType <IntGraphType> > { Name = "take" } ), resolve: async(context) => { var channelId = context.GetArgument <string>("channelId"); var channel = await _channelRepository.Get(channelId); var videos = await _videoRepository.GetByChannel( channelId, context.GetArgument <int>("skip"), context.GetArgument <int>("take") ); var enrichedVideos = EnrichVideosWithChannel(videos, channel); // map entity to model return(_mapper.Map <List <VideoModel> >(enrichedVideos)); } ); // VIDEOS: returns all videos of a certain channel graphQlQuery.FieldAsync <IntGraphType>( "videoCount", arguments: new QueryArguments( new QueryArgument <NonNullGraphType <IdGraphType> > { Name = "channelId" } ), resolve: async(context) => { var videoCount = await _videoRepository.CountByChannel( context.GetArgument <string>("channelId") ); // map entity to model return(videoCount); } ); // VIDEO COUNT TOTAL graphQlQuery.FieldAsync <IntGraphType>( "videoCountTotal", resolve: async(context) => { var videoCount = await _videoRepository.Count(); // map entity to model return(videoCount); } ); // VIDEO PUBLISH DISTRIBUTION graphQlQuery.FieldAsync <ListGraphType <VideoPublishAggregationItemType> >( "videoPublishDistribution", arguments: new QueryArguments( new QueryArgument <NonNullGraphType <IdGraphType> > { Name = "channelId" } ), resolve: async(context) => { try { var result = await _aggregateVideoPublishTimesUseCase.Handle( new AggregateVideoPublishTimesRequest( context.GetArgument <string>("channelId") ) ); var aggregationModels = new List <VideoPublishAggregationItemModel>(); foreach (var daysOfWeek in result.Aggregation) { foreach (var hourOfDay in daysOfWeek.Value) { aggregationModels.Add(new VideoPublishAggregationItemModel() { DayOfTheWeek = (int)daysOfWeek.Key, HourOfTheDay = hourOfDay.Key, PublishedVideos = hourOfDay.Value }); } } // map entity to model return(aggregationModels); } catch { return(null); } } ); }