public async Task <List <LivestreamQueryResult> > GetTopStreams(TopStreamQuery topStreamQuery) { if (topStreamQuery == null) { throw new ArgumentNullException(nameof(topStreamQuery)); } var query = new GetStreamsQuery() { First = topStreamQuery.Take }; if (!string.IsNullOrWhiteSpace(topStreamQuery.GameName)) { var gameId = await GetGameIdByName(topStreamQuery.GameName); query.GameIds.Add(gameId); } var topStreams = await twitchTvHelixClient.GetStreams(query); return(topStreams.Select(x => { var channelIdentifier = new ChannelIdentifier(this, x.UserId) { DisplayName = x.UserName }; var queryResult = new LivestreamQueryResult(channelIdentifier); var livestreamModel = new LivestreamModel(x.UserId, channelIdentifier); livestreamModel.PopulateWithStreamDetails(x); queryResult.LivestreamModel = livestreamModel; return queryResult; }).ToList()); }
private async Task <LivestreamQueryResult> QueryChannel(ChannelIdentifier channelIdentifier, CancellationToken cancellationToken) { var queryResult = new LivestreamQueryResult(channelIdentifier); try { var channel = await beamProClient.GetStreamDetails(channelIdentifier.ChannelId, cancellationToken); channelNameIdMap[channel.token] = channel.id; // record the mapping of the channels token/name to its underlying id var livestreamModel = ConvertToLivestreamModel(channel); queryResult.LivestreamModel = livestreamModel; } catch (Exception ex) { queryResult.FailedQueryException = new FailedQueryException(channelIdentifier, ex); } return(queryResult); }
public async Task <List <LivestreamQueryResult> > GetTopStreams(TopStreamQuery topStreamQuery) { if (topStreamQuery == null) { throw new ArgumentNullException(nameof(topStreamQuery)); } var topStreams = await twitchTvClient.GetTopStreams(topStreamQuery); return(topStreams.Select(x => { var channelIdentifier = new ChannelIdentifier(this, x.Channel.Name); var queryResult = new LivestreamQueryResult(channelIdentifier); var livestreamModel = new LivestreamModel(x.Channel?.Name, channelIdentifier); livestreamModel.PopulateWithStreamDetails(x); livestreamModel.PopulateWithChannel(x.Channel); queryResult.LivestreamModel = livestreamModel; return queryResult; }).ToList()); }
private Task <List <LivestreamQueryResult> > QueryChannels( IReadOnlyCollection <ChannelIdentifier> identifiers, CancellationToken cancellationToken) { return(identifiers.ExecuteInParallel( query: async channelIdentifier => { var queryResult = new LivestreamQueryResult(channelIdentifier); try { var livestream = await hitboxClient.GetChannelDetails(channelIdentifier.ChannelId, cancellationToken); queryResult.LivestreamModel = ConvertToLivestreamModel(livestream); } catch (Exception ex) { queryResult.FailedQueryException = new FailedQueryException(channelIdentifier, ex); } return queryResult; }, timeout: Constants.HalfRefreshPollingTime, cancellationToken: cancellationToken)); }
private async Task <List <LivestreamQueryResult> > GetOfflineStreamQueryResults( IEnumerable <ChannelIdentifier> offlineChannels, CancellationToken cancellationToken) { return(await offlineChannels.ExecuteInParallel(async channelIdentifier => { var queryResult = new LivestreamQueryResult(channelIdentifier); try { var channel = await twitchTvClient.GetChannelDetails(channelIdentifier.ChannelId, cancellationToken); queryResult.LivestreamModel = new LivestreamModel(channelIdentifier.ChannelId, channelIdentifier); queryResult.LivestreamModel.PopulateWithChannel(channel); queryResult.LivestreamModel.Offline(); } catch (Exception ex) { queryResult.FailedQueryException = new FailedQueryException(channelIdentifier, ex); } return queryResult; }, Constants.HalfRefreshPollingTime, cancellationToken)); }
public async Task <List <LivestreamQueryResult> > QueryChannels(CancellationToken cancellationToken) { var queryResults = new List <LivestreamQueryResult>(); if (moniteredChannels.Count == 0) { return(queryResults); } // Twitch "get streams" call only returns online streams so to determine if the stream actually exists/is still valid, we must specifically ask for channel details. List <Stream> onlineStreams = new List <Stream>(); int retryCount = 0; bool success = false; while (!success && !cancellationToken.IsCancellationRequested && retryCount < 3) { try { var query = new GetStreamsQuery(); query.UserIds.AddRange(moniteredChannels.Select(x => x.ChannelId)); onlineStreams = await twitchTvHelixClient.GetStreams(query, cancellationToken); success = true; } catch (HttpRequestWithStatusException ex) when(ex.StatusCode == HttpStatusCode.ServiceUnavailable) { await Task.Delay(2000, cancellationToken); retryCount++; } } foreach (var onlineStream in onlineStreams) { if (cancellationToken.IsCancellationRequested) { return(queryResults); } var channelIdentifier = moniteredChannels.First(x => x.ChannelId.IsEqualTo(onlineStream.UserId)); var gameName = await GetGameNameById(onlineStream.GameId); var livestream = new LivestreamModel(onlineStream.UserId, channelIdentifier); livestream.PopulateWithStreamDetails(onlineStream); livestream.Game = gameName; queryResults.Add(new LivestreamQueryResult(channelIdentifier) { LivestreamModel = livestream }); } var offlineStreams = moniteredChannels.Where(x => onlineStreams.All(y => y.UserId != x.ChannelId)).ToList(); foreach (var offlineStream in offlineStreams) { var queryResult = new LivestreamQueryResult(offlineStream) { LivestreamModel = new LivestreamModel(offlineStream.ChannelId, offlineStream) { DisplayName = offlineStream.DisplayName ?? offlineStream.ChannelId } }; queryResults.Add(queryResult); } return(queryResults); }