Using declarations and other code reformats

This commit is contained in:
Kwoth
2021-12-26 03:22:45 +01:00
parent d18f9429c6
commit b85ba177cd
64 changed files with 2349 additions and 2736 deletions

View File

@@ -61,58 +61,56 @@ public class AnimeSearchService : INService
if (!ok)
{
var config = Configuration.Default.WithDefaultLoader();
using (var document = await BrowsingContext.New(config).OpenAsync(link).ConfigureAwait(false))
using var document = await BrowsingContext.New(config).OpenAsync(link).ConfigureAwait(false);
var imageElem = document.QuerySelector("div.seriesimg > img");
if (imageElem is null)
return null;
var imageUrl = ((IHtmlImageElement)imageElem).Source;
var descElem = document.QuerySelector("div#editdescription > p");
var desc = descElem.InnerHtml;
var genres = document.QuerySelector("div#seriesgenre").Children
.Select(x => x as IHtmlAnchorElement)
.Where(x => x != null)
.Select(x => $"[{x.InnerHtml}]({x.Href})")
.ToArray();
var authors = document
.QuerySelector("div#showauthors")
.Children
.Select(x => x as IHtmlAnchorElement)
.Where(x => x != null)
.Select(x => $"[{x.InnerHtml}]({x.Href})")
.ToArray();
var score = ((IHtmlSpanElement)document
.QuerySelector("h5.seriesother > span.uvotes"))
.InnerHtml;
var status = document
.QuerySelector("div#editstatus")
.InnerHtml;
var title = document
.QuerySelector("div.w-blog-content > div.seriestitlenu")
.InnerHtml;
var obj = new NovelResult()
{
var imageElem = document.QuerySelector("div.seriesimg > img");
if (imageElem is null)
return null;
var imageUrl = ((IHtmlImageElement)imageElem).Source;
Description = desc,
Authors = authors,
Genres = genres,
ImageUrl = imageUrl,
Link = link,
Score = score,
Status = status,
Title = title,
};
var descElem = document.QuerySelector("div#editdescription > p");
var desc = descElem.InnerHtml;
await _cache.SetNovelDataAsync(link,
JsonConvert.SerializeObject(obj)).ConfigureAwait(false);
var genres = document.QuerySelector("div#seriesgenre").Children
.Select(x => x as IHtmlAnchorElement)
.Where(x => x != null)
.Select(x => $"[{x.InnerHtml}]({x.Href})")
.ToArray();
var authors = document
.QuerySelector("div#showauthors")
.Children
.Select(x => x as IHtmlAnchorElement)
.Where(x => x != null)
.Select(x => $"[{x.InnerHtml}]({x.Href})")
.ToArray();
var score = ((IHtmlSpanElement)document
.QuerySelector("h5.seriesother > span.uvotes"))
.InnerHtml;
var status = document
.QuerySelector("div#editstatus")
.InnerHtml;
var title = document
.QuerySelector("div.w-blog-content > div.seriestitlenu")
.InnerHtml;
var obj = new NovelResult()
{
Description = desc,
Authors = authors,
Genres = genres,
ImageUrl = imageUrl,
Link = link,
Score = score,
Status = status,
Title = title,
};
await _cache.SetNovelDataAsync(link,
JsonConvert.SerializeObject(obj)).ConfigureAwait(false);
return obj;
}
return obj;
}
return JsonConvert.DeserializeObject<NovelResult>(data);

View File

@@ -156,15 +156,13 @@ public class FeedsService : INService
public List<FeedSub> GetFeeds(ulong guildId)
{
using (var uow = _db.GetDbContext())
{
return uow.GuildConfigsForId(guildId,
set => set.Include(x => x.FeedSubs)
.ThenInclude(x => x.GuildConfig))
.FeedSubs
.OrderBy(x => x.Id)
.ToList();
}
using var uow = _db.GetDbContext();
return uow.GuildConfigsForId(guildId,
set => set.Include(x => x.FeedSubs)
.ThenInclude(x => x.GuildConfig))
.FeedSubs
.OrderBy(x => x.Id)
.ToList();
}
public bool AddFeed(ulong guildId, ulong channelId, string rssFeed)
@@ -177,32 +175,30 @@ public class FeedsService : INService
Url = rssFeed.Trim(),
};
using (var uow = _db.GetDbContext())
using var uow = _db.GetDbContext();
var gc = uow.GuildConfigsForId(guildId,
set => set.Include(x => x.FeedSubs)
.ThenInclude(x => x.GuildConfig));
if (gc.FeedSubs.Any(x => x.Url.ToLower() == fs.Url.ToLower()))
{
var gc = uow.GuildConfigsForId(guildId,
set => set.Include(x => x.FeedSubs)
.ThenInclude(x => x.GuildConfig));
return false;
}
else if (gc.FeedSubs.Count >= 10)
{
return false;
}
if (gc.FeedSubs.Any(x => x.Url.ToLower() == fs.Url.ToLower()))
gc.FeedSubs.Add(fs);
uow.SaveChanges();
//adding all, in case bot wasn't on this guild when it started
foreach (var feed in gc.FeedSubs)
{
_subs.AddOrUpdate(feed.Url.ToLower(), new HashSet<FeedSub>() {feed}, (k, old) =>
{
return false;
}
else if (gc.FeedSubs.Count >= 10)
{
return false;
}
gc.FeedSubs.Add(fs);
uow.SaveChanges();
//adding all, in case bot wasn't on this guild when it started
foreach (var feed in gc.FeedSubs)
{
_subs.AddOrUpdate(feed.Url.ToLower(), new HashSet<FeedSub>() {feed}, (k, old) =>
{
old.Add(feed);
return old;
});
}
old.Add(feed);
return old;
});
}
return true;
@@ -213,24 +209,22 @@ public class FeedsService : INService
if (index < 0)
return false;
using (var uow = _db.GetDbContext())
{
var items = uow.GuildConfigsForId(guildId, set => set.Include(x => x.FeedSubs))
.FeedSubs
.OrderBy(x => x.Id)
.ToList();
using var uow = _db.GetDbContext();
var items = uow.GuildConfigsForId(guildId, set => set.Include(x => x.FeedSubs))
.FeedSubs
.OrderBy(x => x.Id)
.ToList();
if (items.Count <= index)
return false;
var toRemove = items[index];
_subs.AddOrUpdate(toRemove.Url.ToLower(), new HashSet<FeedSub>(), (key, old) =>
{
old.Remove(toRemove);
return old;
});
uow.Remove(toRemove);
uow.SaveChanges();
}
if (items.Count <= index)
return false;
var toRemove = items[index];
_subs.AddOrUpdate(toRemove.Url.ToLower(), new HashSet<FeedSub>(), (key, old) =>
{
old.Remove(toRemove);
return old;
});
uow.Remove(toRemove);
uow.SaveChanges();
return true;
}

View File

@@ -85,55 +85,49 @@ public class SearchesService : INService
public async Task<byte[]> GetRipPictureFactory((string text, Uri avatarUrl) arg)
{
var (text, avatarUrl) = arg;
using (var bg = Image.Load<Rgba32>(_imgs.Rip.ToArray()))
using var bg = Image.Load<Rgba32>(_imgs.Rip.ToArray());
var (succ, data) = (false, (byte[])null); //await _cache.TryGetImageDataAsync(avatarUrl);
if (!succ)
{
var (succ, data) = (false, (byte[])null); //await _cache.TryGetImageDataAsync(avatarUrl);
if (!succ)
using var http = _httpFactory.CreateClient();
data = await http.GetByteArrayAsync(avatarUrl);
using (var avatarImg = Image.Load<Rgba32>(data))
{
using (var http = _httpFactory.CreateClient())
{
data = await http.GetByteArrayAsync(avatarUrl);
using (var avatarImg = Image.Load<Rgba32>(data))
{
avatarImg.Mutate(x => x
.Resize(85, 85)
.ApplyRoundedCorners(42));
data = avatarImg.ToStream().ToArray();
DrawAvatar(bg, avatarImg);
}
await _cache.SetImageDataAsync(avatarUrl, data);
}
avatarImg.Mutate(x => x
.Resize(85, 85)
.ApplyRoundedCorners(42));
data = avatarImg.ToStream().ToArray();
DrawAvatar(bg, avatarImg);
}
else
{
using (var avatarImg = Image.Load<Rgba32>(data))
{
DrawAvatar(bg, avatarImg);
}
}
bg.Mutate(x => x.DrawText(
new()
{
TextOptions = new TextOptions
{
HorizontalAlignment = HorizontalAlignment.Center,
WrapTextWidth = 190,
}.WithFallbackFonts(_fonts.FallBackFonts)
},
text,
_fonts.RipFont,
SixLabors.ImageSharp.Color.Black,
new(25, 225)));
//flowa
using (var flowers = Image.Load(_imgs.RipOverlay.ToArray()))
{
bg.Mutate(x => x.DrawImage(flowers, new(0, 0), new GraphicsOptions()));
}
return bg.ToStream().ToArray();
await _cache.SetImageDataAsync(avatarUrl, data);
}
else
{
using var avatarImg = Image.Load<Rgba32>(data);
DrawAvatar(bg, avatarImg);
}
bg.Mutate(x => x.DrawText(
new()
{
TextOptions = new TextOptions
{
HorizontalAlignment = HorizontalAlignment.Center,
WrapTextWidth = 190,
}.WithFallbackFonts(_fonts.FallBackFonts)
},
text,
_fonts.RipFont,
SixLabors.ImageSharp.Color.Black,
new(25, 225)));
//flowa
using (var flowers = Image.Load(_imgs.RipOverlay.ToArray()))
{
bg.Mutate(x => x.DrawImage(flowers, new(0, 0), new GraphicsOptions()));
}
return bg.ToStream().ToArray();
}
public Task<WeatherData> GetWeatherDataAsync(string query)
@@ -148,25 +142,23 @@ public class SearchesService : INService
private async Task<WeatherData> GetWeatherDataFactory(string query)
{
using (var http = _httpFactory.CreateClient())
using var http = _httpFactory.CreateClient();
try
{
try
{
var data = await http.GetStringAsync($"http://api.openweathermap.org/data/2.5/weather?" +
$"q={query}&" +
$"appid=42cd627dd60debf25a5739e50a217d74&" +
$"units=metric").ConfigureAwait(false);
var data = await http.GetStringAsync($"http://api.openweathermap.org/data/2.5/weather?" +
$"q={query}&" +
$"appid=42cd627dd60debf25a5739e50a217d74&" +
$"units=metric").ConfigureAwait(false);
if (data is null)
return null;
return JsonConvert.DeserializeObject<WeatherData>(data);
}
catch (Exception ex)
{
Log.Warning(ex.Message);
if (data is null)
return null;
}
return JsonConvert.DeserializeObject<WeatherData>(data);
}
catch (Exception ex)
{
Log.Warning(ex.Message);
return null;
}
}
@@ -195,49 +187,42 @@ public class SearchesService : INService
try
{
using (var _http = _httpFactory.CreateClient())
using var _http = _httpFactory.CreateClient();
var res = await _cache.GetOrAddCachedDataAsync($"geo_{query}", _ =>
{
var res = await _cache.GetOrAddCachedDataAsync($"geo_{query}", _ =>
{
var url = "https://eu1.locationiq.com/v1/search.php?" +
(string.IsNullOrWhiteSpace(_creds.LocationIqApiKey) ? "key=" : $"key={_creds.LocationIqApiKey}&") +
$"q={Uri.EscapeDataString(query)}&" +
$"format=json";
var url = "https://eu1.locationiq.com/v1/search.php?" +
(string.IsNullOrWhiteSpace(_creds.LocationIqApiKey) ? "key=" : $"key={_creds.LocationIqApiKey}&") +
$"q={Uri.EscapeDataString(query)}&" +
$"format=json";
var res = _http.GetStringAsync(url);
return res;
}, "", TimeSpan.FromHours(1));
var res = _http.GetStringAsync(url);
return res;
}, "", TimeSpan.FromHours(1));
var responses = JsonConvert.DeserializeObject<LocationIqResponse[]>(res);
if (responses is null || responses.Length == 0)
{
Log.Warning("Geocode lookup failed for: {Query}", query);
return (default, TimeErrors.NotFound);
}
var geoData = responses[0];
using (var req = new HttpRequestMessage(HttpMethod.Get, "http://api.timezonedb.com/v2.1/get-time-zone?" +
$"key={_creds.TimezoneDbApiKey}&format=json&" +
"by=position&" +
$"lat={geoData.Lat}&lng={geoData.Lon}"))
{
using (var geoRes = await _http.SendAsync(req))
{
var resString = await geoRes.Content.ReadAsStringAsync();
var timeObj = JsonConvert.DeserializeObject<TimeZoneResult>(resString);
var time = new DateTime(1970, 1, 1, 0, 0, 0, System.DateTimeKind.Utc).AddSeconds(timeObj.Timestamp);
return ((
Address: responses[0].DisplayName,
Time: time,
TimeZoneName: timeObj.TimezoneName
), default);
}
}
var responses = JsonConvert.DeserializeObject<LocationIqResponse[]>(res);
if (responses is null || responses.Length == 0)
{
Log.Warning("Geocode lookup failed for: {Query}", query);
return (default, TimeErrors.NotFound);
}
var geoData = responses[0];
using var req = new HttpRequestMessage(HttpMethod.Get, "http://api.timezonedb.com/v2.1/get-time-zone?" +
$"key={_creds.TimezoneDbApiKey}&format=json&" +
"by=position&" +
$"lat={geoData.Lat}&lng={geoData.Lon}");
using var geoRes = await _http.SendAsync(req);
var resString = await geoRes.Content.ReadAsStringAsync();
var timeObj = JsonConvert.DeserializeObject<TimeZoneResult>(resString);
var time = new DateTime(1970, 1, 1, 0, 0, 0, System.DateTimeKind.Utc).AddSeconds(timeObj.Timestamp);
return ((
Address: responses[0].DisplayName,
Time: time,
TimeZoneName: timeObj.TimezoneName
), default);
}
catch (Exception ex)
{
@@ -310,21 +295,17 @@ public class SearchesService : INService
public async Task<(string Setup, string Punchline)> GetRandomJoke()
{
using (var http = _httpFactory.CreateClient())
{
var res = await http.GetStringAsync("https://official-joke-api.appspot.com/random_joke");
var resObj = JsonConvert.DeserializeAnonymousType(res, new {setup = "", punchline = ""});
return (resObj.setup, resObj.punchline);
}
using var http = _httpFactory.CreateClient();
var res = await http.GetStringAsync("https://official-joke-api.appspot.com/random_joke");
var resObj = JsonConvert.DeserializeAnonymousType(res, new {setup = "", punchline = ""});
return (resObj.setup, resObj.punchline);
}
public async Task<string> GetChuckNorrisJoke()
{
using (var http = _httpFactory.CreateClient())
{
var response = await http.GetStringAsync(new Uri("http://api.icndb.com/jokes/random/")).ConfigureAwait(false);
return JObject.Parse(response)["value"]["joke"].ToString() + " 😆";
}
using var http = _httpFactory.CreateClient();
var response = await http.GetStringAsync(new Uri("http://api.icndb.com/jokes/random/")).ConfigureAwait(false);
return JObject.Parse(response)["value"]["joke"].ToString() + " 😆";
}
public async Task<MtgData> GetMtgCardAsync(string search)
@@ -367,30 +348,28 @@ public class SearchesService : INService
};
}
using (var http = _httpFactory.CreateClient())
using var http = _httpFactory.CreateClient();
http.DefaultRequestHeaders.Clear();
var response = await http.GetStringAsync($"https://api.magicthegathering.io/v1/cards?name={Uri.EscapeDataString(search)}")
.ConfigureAwait(false);
var responseObject = JsonConvert.DeserializeObject<MtgResponse>(response);
if (responseObject is null)
return new MtgData[0];
var cards = responseObject.Cards.Take(5).ToArray();
if (cards.Length == 0)
return new MtgData[0];
var tasks = new List<Task<MtgData>>(cards.Length);
for (var i = 0; i < cards.Length; i++)
{
http.DefaultRequestHeaders.Clear();
var response = await http.GetStringAsync($"https://api.magicthegathering.io/v1/cards?name={Uri.EscapeDataString(search)}")
.ConfigureAwait(false);
var card = cards[i];
var responseObject = JsonConvert.DeserializeObject<MtgResponse>(response);
if (responseObject is null)
return new MtgData[0];
var cards = responseObject.Cards.Take(5).ToArray();
if (cards.Length == 0)
return new MtgData[0];
var tasks = new List<Task<MtgData>>(cards.Length);
for (var i = 0; i < cards.Length; i++)
{
var card = cards[i];
tasks.Add(GetMtgDataAsync(card));
}
return await Task.WhenAll(tasks).ConfigureAwait(false);
tasks.Add(GetMtgDataAsync(card));
}
return await Task.WhenAll(tasks).ConfigureAwait(false);
}
public Task<HearthstoneCardData> GetHearthstoneCardDataAsync(string name)
@@ -404,38 +383,36 @@ public class SearchesService : INService
private async Task<HearthstoneCardData> HearthstoneCardDataFactory(string name)
{
using (var http = _httpFactory.CreateClient())
using var http = _httpFactory.CreateClient();
http.DefaultRequestHeaders.Clear();
http.DefaultRequestHeaders.Add("x-rapidapi-key", _creds.RapidApiKey);
try
{
http.DefaultRequestHeaders.Clear();
http.DefaultRequestHeaders.Add("x-rapidapi-key", _creds.RapidApiKey);
try
{
var response = await http.GetStringAsync($"https://omgvamp-hearthstone-v1.p.rapidapi.com/" +
$"cards/search/{Uri.EscapeDataString(name)}").ConfigureAwait(false);
var objs = JsonConvert.DeserializeObject<HearthstoneCardData[]>(response);
if (objs is null || objs.Length == 0)
return null;
var data = objs.FirstOrDefault(x => x.Collectible)
?? objs.FirstOrDefault(x => !string.IsNullOrEmpty(x.PlayerClass))
?? objs.FirstOrDefault();
if (data is null)
return null;
if (!string.IsNullOrWhiteSpace(data.Img))
{
data.Img = await _google.ShortenUrl(data.Img).ConfigureAwait(false);
}
if (!string.IsNullOrWhiteSpace(data.Text))
{
var converter = new Html2Markdown.Converter();
data.Text = converter.Convert(data.Text);
}
return data;
}
catch (Exception ex)
{
Log.Error(ex.Message);
var response = await http.GetStringAsync($"https://omgvamp-hearthstone-v1.p.rapidapi.com/" +
$"cards/search/{Uri.EscapeDataString(name)}").ConfigureAwait(false);
var objs = JsonConvert.DeserializeObject<HearthstoneCardData[]>(response);
if (objs is null || objs.Length == 0)
return null;
var data = objs.FirstOrDefault(x => x.Collectible)
?? objs.FirstOrDefault(x => !string.IsNullOrEmpty(x.PlayerClass))
?? objs.FirstOrDefault();
if (data is null)
return null;
if (!string.IsNullOrWhiteSpace(data.Img))
{
data.Img = await _google.ShortenUrl(data.Img).ConfigureAwait(false);
}
if (!string.IsNullOrWhiteSpace(data.Text))
{
var converter = new Html2Markdown.Converter();
data.Text = converter.Convert(data.Text);
}
return data;
}
catch (Exception ex)
{
Log.Error(ex.Message);
return null;
}
}
@@ -450,16 +427,14 @@ public class SearchesService : INService
private async Task<OmdbMovie> GetMovieDataFactory(string name)
{
using (var http = _httpFactory.CreateClient())
{
var res = await http.GetStringAsync(string.Format("https://omdbapi.nadeko.bot/?t={0}&y=&plot=full&r=json",
name.Trim().Replace(' ', '+'))).ConfigureAwait(false);
var movie = JsonConvert.DeserializeObject<OmdbMovie>(res);
if (movie?.Title is null)
return null;
movie.Poster = await _google.ShortenUrl(movie.Poster).ConfigureAwait(false);
return movie;
}
using var http = _httpFactory.CreateClient();
var res = await http.GetStringAsync(string.Format("https://omdbapi.nadeko.bot/?t={0}&y=&plot=full&r=json",
name.Trim().Replace(' ', '+'))).ConfigureAwait(false);
var movie = JsonConvert.DeserializeObject<OmdbMovie>(res);
if (movie?.Title is null)
return null;
movie.Poster = await _google.ShortenUrl(movie.Poster).ConfigureAwait(false);
return movie;
}
public async Task<int> GetSteamAppIdByName(string query)
@@ -486,20 +461,18 @@ public class SearchesService : INService
var gamesMap = await _cache.GetOrAddCachedDataAsync(STEAM_GAME_IDS_KEY, async _ =>
{
using (var http = _httpFactory.CreateClient())
{
// https://api.steampowered.com/ISteamApps/GetAppList/v2/
var gamesStr = await http.GetStringAsync("https://api.steampowered.com/ISteamApps/GetAppList/v2/").ConfigureAwait(false);
var apps = JsonConvert.DeserializeAnonymousType(gamesStr, new { applist = new { apps = new List<SteamGameId>() } }).applist.apps;
using var http = _httpFactory.CreateClient();
// https://api.steampowered.com/ISteamApps/GetAppList/v2/
var gamesStr = await http.GetStringAsync("https://api.steampowered.com/ISteamApps/GetAppList/v2/").ConfigureAwait(false);
var apps = JsonConvert.DeserializeAnonymousType(gamesStr, new { applist = new { apps = new List<SteamGameId>() } }).applist.apps;
return apps
.OrderBy(x => x.Name, StringComparer.OrdinalIgnoreCase)
.GroupBy(x => x.Name)
.ToDictionary(x => x.Key, x => x.First().AppId);
//await db.HashSetAsync("steam_game_ids", apps.Select(app => new HashEntry(app.Name.Trim().ToLowerInvariant(), app.AppId)).ToArray()).ConfigureAwait(false);
//await db.StringSetAsync("steam_game_ids", gamesStr, TimeSpan.FromHours(24));
//await db.KeyExpireAsync("steam_game_ids", TimeSpan.FromHours(24), CommandFlags.FireAndForget).ConfigureAwait(false);
}
return apps
.OrderBy(x => x.Name, StringComparer.OrdinalIgnoreCase)
.GroupBy(x => x.Name)
.ToDictionary(x => x.Key, x => x.First().AppId);
//await db.HashSetAsync("steam_game_ids", apps.Select(app => new HashEntry(app.Name.Trim().ToLowerInvariant(), app.AppId)).ToArray()).ConfigureAwait(false);
//await db.StringSetAsync("steam_game_ids", gamesStr, TimeSpan.FromHours(24));
//await db.KeyExpireAsync("steam_game_ids", TimeSpan.FromHours(24), CommandFlags.FireAndForget).ConfigureAwait(false);
}, default(string), TimeSpan.FromHours(24));
if (gamesMap is null)

View File

@@ -130,24 +130,22 @@ public sealed class StreamNotificationService : INService
var deleteGroups = failingStreams.GroupBy(x => x.Type)
.ToDictionary(x => x.Key, x => x.Select(x => x.Name).ToList());
using (var uow = _db.GetDbContext())
using var uow = _db.GetDbContext();
foreach (var kvp in deleteGroups)
{
foreach (var kvp in deleteGroups)
{
Log.Information($"Deleting {kvp.Value.Count} {kvp.Key} streams because " +
$"they've been erroring for more than {errorLimit}: {string.Join(", ", kvp.Value)}");
Log.Information($"Deleting {kvp.Value.Count} {kvp.Key} streams because " +
$"they've been erroring for more than {errorLimit}: {string.Join(", ", kvp.Value)}");
var toDelete = uow.Set<FollowedStream>()
.AsQueryable()
.Where(x => x.Type == kvp.Key && kvp.Value.Contains(x.Username))
.ToList();
var toDelete = uow.Set<FollowedStream>()
.AsQueryable()
.Where(x => x.Type == kvp.Key && kvp.Value.Contains(x.Username))
.ToList();
uow.RemoveRange(toDelete);
uow.SaveChanges();
uow.RemoveRange(toDelete);
uow.SaveChanges();
foreach(var loginToDelete in kvp.Value)
_streamTracker.UntrackStreamByKey(new(kvp.Key, loginToDelete));
}
foreach(var loginToDelete in kvp.Value)
_streamTracker.UntrackStreamByKey(new(kvp.Key, loginToDelete));
}
}
catch (Exception ex)
@@ -461,20 +459,18 @@ public sealed class StreamNotificationService : INService
public bool ToggleStreamOffline(ulong guildId)
{
bool newValue;
using (var uow = _db.GetDbContext())
{
var gc = uow.GuildConfigsForId(guildId, set => set);
newValue = gc.NotifyStreamOffline = !gc.NotifyStreamOffline;
uow.SaveChanges();
using var uow = _db.GetDbContext();
var gc = uow.GuildConfigsForId(guildId, set => set);
newValue = gc.NotifyStreamOffline = !gc.NotifyStreamOffline;
uow.SaveChanges();
if (newValue)
{
_offlineNotificationServers.Add(guildId);
}
else
{
_offlineNotificationServers.TryRemove(guildId);
}
if (newValue)
{
_offlineNotificationServers.Add(guildId);
}
else
{
_offlineNotificationServers.TryRemove(guildId);
}
return newValue;
@@ -510,35 +506,33 @@ public sealed class StreamNotificationService : INService
public bool SetStreamMessage(ulong guildId, int index, string message, out FollowedStream fs)
{
using (var uow = _db.GetDbContext())
using var uow = _db.GetDbContext();
var fss = uow.Set<FollowedStream>()
.AsQueryable()
.Where(x => x.GuildId == guildId)
.OrderBy(x => x.Id)
.ToList();
if (fss.Count <= index)
{
var fss = uow.Set<FollowedStream>()
.AsQueryable()
.Where(x => x.GuildId == guildId)
.OrderBy(x => x.Id)
.ToList();
if (fss.Count <= index)
{
fs = null;
return false;
}
fs = fss[index];
fs.Message = message;
lock (_shardLock)
{
var streams = GetLocalGuildStreams(fs.CreateKey(), guildId);
// message doesn't participate in equality checking
// removing and adding = update
streams.Remove(fs);
streams.Add(fs);
}
uow.SaveChanges();
fs = null;
return false;
}
fs = fss[index];
fs.Message = message;
lock (_shardLock)
{
var streams = GetLocalGuildStreams(fs.CreateKey(), guildId);
// message doesn't participate in equality checking
// removing and adding = update
streams.Remove(fs);
streams.Add(fs);
}
uow.SaveChanges();
return true;
}