Exemplo n.º 1
0
        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);
                }
            }
        }
Exemplo n.º 2
0
        /// <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);
                }
            }
                );
        }