public async Task RemoveStream(FollowedStream.FollowedStreamType type, [Remainder] string username) { username = username.ToLowerInvariant().Trim(); var fs = new FollowedStream() { ChannelId = Context.Channel.Id, Username = username, Type = type }; bool removed; using (var uow = _db.UnitOfWork) { var config = uow.GuildConfigs.For(Context.Guild.Id, set => set.Include(gc => gc.FollowedStreams)); removed = config.FollowedStreams.Remove(fs); if (removed) { await uow.CompleteAsync().ConfigureAwait(false); } } if (!removed) { await ReplyErrorLocalized("stream_no").ConfigureAwait(false); return; } await ReplyConfirmLocalized("stream_removed", Format.Code(username), type).ConfigureAwait(false); }
public async Task RemoveStream(IUserMessage msg, FollowedStream.FollowedStreamType type, [Remainder] string username) { var channel = (ITextChannel)msg.Channel; username = username.ToLowerInvariant().Trim(); var fs = new FollowedStream() { ChannelId = channel.Id, Username = username, Type = type }; bool removed; using (var uow = DbHandler.UnitOfWork()) { var config = uow.GuildConfigs.For(channel.Guild.Id, set => set.Include(gc => gc.FollowedStreams)); removed = config.FollowedStreams.Remove(fs); if (removed) { await uow.CompleteAsync().ConfigureAwait(false); } } if (!removed) { await channel.SendErrorAsync("No such stream.").ConfigureAwait(false); return; } await channel.SendConfirmAsync($"Removed `{username}`'s stream ({type}) from notifications.").ConfigureAwait(false); }
private async Task TrackStream(ITextChannel channel, string username, FollowedStream.FollowedStreamType type) { username = username.ToLowerInvariant().Trim(); var fs = new FollowedStream { GuildId = channel.Guild.Id, ChannelId = channel.Id, Username = username, Type = type, }; IStreamResponse status; try { status = await _service.GetStreamStatus(fs).ConfigureAwait(false); } catch { await ReplyErrorLocalized("stream_not_exist").ConfigureAwait(false); return; } using (var uow = _db.UnitOfWork) { uow.GuildConfigs.For(channel.Guild.Id, set => set.Include(gc => gc.FollowedStreams)) .FollowedStreams .Add(fs); await uow.CompleteAsync().ConfigureAwait(false); } await channel.EmbedAsync(_service.GetEmbed(fs, status, Context.Guild.Id), GetText("stream_tracked")).ConfigureAwait(false); }
private async Task TrackStream(ITextChannel channel, string username, FollowedStream.FollowedStreamType type) { username = username.ToLowerInvariant().Trim(); var fs = new FollowedStream { GuildId = channel.Guild.Id, ChannelId = channel.Id, Username = username, Type = type, }; StreamStatus status; try { status = await GetStreamStatus(fs).ConfigureAwait(false); } catch { await channel.SendErrorAsync("Stream probably doesn't exist.").ConfigureAwait(false); return; } using (var uow = DbHandler.UnitOfWork()) { uow.GuildConfigs.For(channel.Guild.Id, set => set.Include(gc => gc.FollowedStreams)) .FollowedStreams .Add(fs); await uow.CompleteAsync().ConfigureAwait(false); } await channel.EmbedAsync(fs.GetEmbed(status).Build(), $"🆗 I will notify this channel when status changes.").ConfigureAwait(false); }
private async Task TrackStream(ITextChannel channel, string username, FollowedStream.FollowedStreamType type) { username = username.ToLowerInvariant().Trim(); var stream = new FollowedStream { GuildId = channel.Guild.Id, ChannelId = channel.Id, Username = username, Type = type, }; bool exists; using (var uow = DbHandler.UnitOfWork()) { exists = uow.GuildConfigs.For(channel.Guild.Id).FollowedStreams.Where(fs => fs.ChannelId == channel.Id && fs.Username.ToLowerInvariant().Trim() == username).Any(); } if (exists) { await channel.SendMessageAsync($":anger: I am already following `{username}` ({type}) stream on this channel.").ConfigureAwait(false); return; } StreamStatus data; try { data = await GetStreamStatus(stream).ConfigureAwait(false); } catch { await channel.SendMessageAsync(":anger: Stream probably doesn't exist.").ConfigureAwait(false); return; } var msg = $"Stream is currently **{(data.IsLive ? "ONLINE" : "OFFLINE")}** with **{data.Views}** viewers"; if (data.IsLive) { if (type == FollowedStream.FollowedStreamType.Hitbox) { msg += $"\n`Here is the Link:`【 http://www.hitbox.tv/{stream.Username}/ 】"; } else if (type == FollowedStream.FollowedStreamType.Twitch) { msg += $"\n`Here is the Link:`【 http://www.twitch.tv/{stream.Username}/ 】"; } else if (type == FollowedStream.FollowedStreamType.Beam) { msg += $"\n`Here is the Link:`【 https://beam.pro/{stream.Username}/ 】"; } } using (var uow = DbHandler.UnitOfWork()) { uow.GuildConfigs.For(channel.Guild.Id).FollowedStreams.Add(stream); await uow.CompleteAsync(); } msg = $":ok: I will notify this channel when status changes.\n{msg}"; await channel.SendMessageAsync(msg).ConfigureAwait(false); }
public async Task <IStreamResponse> GetStreamStatus(FollowedStream stream, bool checkCache = true) { string url = string.Empty; Type type = null; switch (stream.Type) { case FollowedStream.FollowedStreamType.Twitch: url = $"https://api.twitch.tv/kraken/streams/{Uri.EscapeUriString(stream.Username.ToLowerInvariant())}?client_id=67w6z9i09xv2uoojdm9l0wsyph4hxo6"; type = typeof(TwitchResponse); break; case FollowedStream.FollowedStreamType.Smashcast: url = $"https://api.smashcast.tv/user/{stream.Username.ToLowerInvariant()}"; type = typeof(SmashcastResponse); break; case FollowedStream.FollowedStreamType.Mixer: url = $"https://mixer.com/api/v1/channels/{stream.Username.ToLowerInvariant()}"; type = typeof(MixerResponse); break; case FollowedStream.FollowedStreamType.Picarto: url = $"https://api.picarto.tv/v1/channel/name/{stream.Username.ToLowerInvariant()}"; type = typeof(PicartoResponse); break; default: break; } if (checkCache && _cachedStatuses.TryGetValue(url, out var result)) { return(result); } var response = await _http.GetAsync(url).ConfigureAwait(false); if (!response.IsSuccessStatusCode) { throw new StreamNotFoundException($"{stream.Username} [{stream.Type}]"); } var responseString = await response.Content.ReadAsStringAsync().ConfigureAwait(false); var data = JsonConvert.DeserializeObject(responseString, type) as IStreamResponse; data.ApiUrl = url; _cachedStatuses.AddOrUpdate(url, data, (key, old) => data); return(data); }
public static string GetLink(this FollowedStream fs) { if (fs.Type == FollowedStream.FollowedStreamType.Hitbox) { return($"http://www.hitbox.tv/{fs.Username}/"); } if (fs.Type == FollowedStream.FollowedStreamType.Twitch) { return($"http://www.twitch.tv/{fs.Username}/"); } if (fs.Type == FollowedStream.FollowedStreamType.Beam) { return($"https://beam.pro/{fs.Username}/"); } return("??"); }
public string GetLink(FollowedStream fs) { if (fs.Type == FollowedStream.FollowedStreamType.Smashcast) { return($"https://www.smashcast.tv/{fs.Username}/"); } if (fs.Type == FollowedStream.FollowedStreamType.Twitch) { return($"https://www.twitch.tv/{fs.Username}/"); } if (fs.Type == FollowedStream.FollowedStreamType.Mixer) { return($"https://www.mixer.com/{fs.Username}/"); } return("??"); }
public EmbedBuilder GetEmbed(FollowedStream fs, IStreamResponse status, ulong guildId) { var embed = new EmbedBuilder() .WithTitle(fs.Username) .WithUrl(GetLink(fs)) .WithDescription(GetLink(fs)) .AddField(efb => efb.WithName(GetText(fs, "status")) .WithValue(status.Live ? "Online" : "Offline") .WithIsInline(true)) .AddField(efb => efb.WithName(GetText(fs, "viewers")) .WithValue(status.Live ? status.Viewers.ToString() : "-") .WithIsInline(true)) .WithColor(status.Live ? NadekoBot.OkColor : NadekoBot.ErrorColor); if (!string.IsNullOrWhiteSpace(status.Title)) { embed.WithAuthor(status.Title); } if (!string.IsNullOrWhiteSpace(status.Game)) { embed.AddField(GetText(fs, "streaming"), status.Game, true); } embed.AddField(GetText(fs, "followers"), status.Followers.ToString(), true); if (!string.IsNullOrWhiteSpace(status.Icon)) { embed.WithThumbnailUrl(status.Icon); } if (!string.IsNullOrWhiteSpace(status.StreamThumbnail)) { embed.WithImageUrl(status.StreamThumbnail); } if (status.AdultStream == true) { embed.WithImageUrl("https://i.imgur.com/IvTOV9v.jpg"); } return(embed); }
public static EmbedBuilder GetEmbed(this FollowedStream fs, Searches.StreamStatus status) { var embed = new EmbedBuilder().WithTitle(fs.Username) .WithUrl(fs.GetLink()) .AddField(efb => efb.WithName("Status") .WithValue(status.IsLive ? "Online" : "Offline") .WithIsInline(true)) .AddField(efb => efb.WithName("Viewers") .WithValue(status.IsLive ? status.Views : "-") .WithIsInline(true)) .AddField(efb => efb.WithName("Platform") .WithValue(fs.Type.ToString()) .WithIsInline(true)) .WithColor(status.IsLive ? NadekoBot.OkColor : NadekoBot.ErrorColor); return(embed); }
public EmbedBuilder GetEmbed(FollowedStream fs, StreamStatus status, ulong guildId) { var embed = new EmbedBuilder().WithTitle(fs.Username) .WithUrl(GetLink(fs)) .AddField(efb => efb.WithName(GetText(fs, "status")) .WithValue(status.IsLive ? "Online" : "Offline") .WithIsInline(true)) .AddField(efb => efb.WithName(GetText(fs, "viewers")) .WithValue(status.IsLive ? status.Views : "-") .WithIsInline(true)) .AddField(efb => efb.WithName(GetText(fs, "platform")) .WithValue(fs.Type.ToString()) .WithIsInline(true)) .WithColor(status.IsLive ? NadekoBot.OkColor : NadekoBot.ErrorColor); return(embed); }
private static async Task <StreamStatus> GetStreamStatus(FollowedStream stream, bool checkCache = true) { string response; StreamStatus result; switch (stream.Type) { case FollowedStream.FollowedStreamType.Hitbox: var hitboxUrl = $"https://api.hitbox.tv/media/status/{stream.Username.ToLowerInvariant()}"; if (checkCache && cachedStatuses.TryGetValue(hitboxUrl, out result)) { return(result); } using (var http = new HttpClient()) { response = await http.GetStringAsync(hitboxUrl).ConfigureAwait(false); } var hbData = JsonConvert.DeserializeObject <HitboxResponse>(response); if (!hbData.Success) { throw new StreamNotFoundException($"{stream.Username} [{stream.Type}]"); } result = new StreamStatus() { IsLive = hbData.IsLive, ApiLink = hitboxUrl, Views = hbData.Views }; cachedStatuses.AddOrUpdate(hitboxUrl, result, (key, old) => result); return(result); case FollowedStream.FollowedStreamType.Twitch: var twitchUrl = $"https://api.twitch.tv/kraken/streams/{Uri.EscapeUriString(stream.Username.ToLowerInvariant())}?client_id=67w6z9i09xv2uoojdm9l0wsyph4hxo6"; if (checkCache && cachedStatuses.TryGetValue(twitchUrl, out result)) { return(result); } using (var http = new HttpClient()) { response = await http.GetStringAsync(twitchUrl).ConfigureAwait(false); } var twData = JsonConvert.DeserializeObject <TwitchResponse>(response); if (twData.Error != null) { throw new StreamNotFoundException($"{stream.Username} [{stream.Type}]"); } result = new StreamStatus() { IsLive = twData.IsLive, ApiLink = twitchUrl, Views = twData.Stream?.Viewers.ToString() ?? "0" }; cachedStatuses.AddOrUpdate(twitchUrl, result, (key, old) => result); return(result); case FollowedStream.FollowedStreamType.Beam: var beamUrl = $"https://beam.pro/api/v1/channels/{stream.Username.ToLowerInvariant()}"; if (checkCache && cachedStatuses.TryGetValue(beamUrl, out result)) { return(result); } using (var http = new HttpClient()) { response = await http.GetStringAsync(beamUrl).ConfigureAwait(false); } var bmData = JsonConvert.DeserializeObject <BeamResponse>(response); if (bmData.Error != null) { throw new StreamNotFoundException($"{stream.Username} [{stream.Type}]"); } result = new StreamStatus() { IsLive = bmData.IsLive, ApiLink = beamUrl, Views = bmData.ViewersCurrent.ToString() }; cachedStatuses.AddOrUpdate(beamUrl, result, (key, old) => result); return(result); default: break; } return(null); }
public static string GetText(this FollowedStream fs, string key, params object[] replacements) => NadekoTopLevelModule.GetTextStatic(key, NadekoBot.Localization.GetCultureInfo((ulong)fs.GuildId), typeof(Searches).Name.ToLowerInvariant(), replacements);
private async Task <StreamStatus> GetStreamStatus(FollowedStream stream, bool checkCache = true) { bool isLive; string response; JObject data; StreamStatus result; switch (stream.Type) { case FollowedStream.FollowedStreamType.Hitbox: var hitboxUrl = $"https://api.hitbox.tv/media/status/{stream.Username}"; if (checkCache && cachedStatuses.TryGetValue(hitboxUrl, out result)) { return(result); } using (var http = new HttpClient()) { response = await http.GetStringAsync(hitboxUrl).ConfigureAwait(false); } data = JObject.Parse(response); isLive = data["media_is_live"].ToString() == "1"; result = new StreamStatus(hitboxUrl, isLive, data["media_views"].ToString()); cachedStatuses.TryAdd(hitboxUrl, result); return(result); case FollowedStream.FollowedStreamType.Twitch: var twitchUrl = $"https://api.twitch.tv/kraken/streams/{Uri.EscapeUriString(stream.Username)}?client_id=67w6z9i09xv2uoojdm9l0wsyph4hxo6"; if (checkCache && cachedStatuses.TryGetValue(twitchUrl, out result)) { return(result); } using (var http = new HttpClient()) { response = await http.GetStringAsync(twitchUrl).ConfigureAwait(false); } data = JObject.Parse(response); isLive = !string.IsNullOrWhiteSpace(data["stream"].ToString()); result = new StreamStatus(twitchUrl, isLive, isLive ? data["stream"]["viewers"].ToString() : "0"); cachedStatuses.TryAdd(twitchUrl, result); return(result); case FollowedStream.FollowedStreamType.Beam: var beamUrl = $"https://beam.pro/api/v1/channels/{stream.Username}"; if (checkCache && cachedStatuses.TryGetValue(beamUrl, out result)) { return(result); } using (var http = new HttpClient()) { response = await http.GetStringAsync(beamUrl).ConfigureAwait(false); } data = JObject.Parse(response); isLive = data["online"].ToObject <bool>() == true; result = new StreamStatus(beamUrl, isLive, data["viewersCurrent"].ToString()); cachedStatuses.TryAdd(beamUrl, result); return(result); default: break; } return(null); }
public async Task <IStreamResponse> GetStreamStatus(FollowedStream stream, bool checkCache = true) { string response; IStreamResponse result; switch (stream.Type) { case FollowedStream.FollowedStreamType.Smashcast: var smashcastUrl = $"https://api.smashcast.tv/user/{stream.Username.ToLowerInvariant()}"; if (checkCache && _cachedStatuses.TryGetValue(smashcastUrl, out result)) { return(result); } response = await _http.GetStringAsync(smashcastUrl).ConfigureAwait(false); var scData = JsonConvert.DeserializeObject <SmashcastResponse>(response); if (!scData.Success) { throw new StreamNotFoundException($"{stream.Username} [{stream.Type}]"); } scData.Url = smashcastUrl; _cachedStatuses.AddOrUpdate(smashcastUrl, scData, (key, old) => scData); return(scData); case FollowedStream.FollowedStreamType.Twitch: var twitchUrl = $"https://api.twitch.tv/kraken/streams/{Uri.EscapeUriString(stream.Username.ToLowerInvariant())}?client_id=67w6z9i09xv2uoojdm9l0wsyph4hxo6"; if (checkCache && _cachedStatuses.TryGetValue(twitchUrl, out result)) { return(result); } response = await _http.GetStringAsync(twitchUrl).ConfigureAwait(false); var twData = JsonConvert.DeserializeObject <TwitchResponse>(response); if (twData.Error != null) { throw new StreamNotFoundException($"{stream.Username} [{stream.Type}]"); } twData.Url = twitchUrl; _cachedStatuses.AddOrUpdate(twitchUrl, twData, (key, old) => twData); return(twData); case FollowedStream.FollowedStreamType.Mixer: var beamUrl = $"https://mixer.com/api/v1/channels/{stream.Username.ToLowerInvariant()}"; if (checkCache && _cachedStatuses.TryGetValue(beamUrl, out result)) { return(result); } response = await _http.GetStringAsync(beamUrl).ConfigureAwait(false); var bmData = JsonConvert.DeserializeObject <MixerResponse>(response); if (bmData.Error != null) { throw new StreamNotFoundException($"{stream.Username} [{stream.Type}]"); } bmData.Url = beamUrl; _cachedStatuses.AddOrUpdate(beamUrl, bmData, (key, old) => bmData); return(bmData); default: break; } return(null); }
public string GetText(FollowedStream fs, string key, params object[] replacements) => _strings.GetText(key, fs.GuildId, "Searches".ToLowerInvariant(), replacements);