Commit fdabe628 authored by Robert Rudman's avatar Robert Rudman

When a new post is featured, create a room and get burnaki to track it

parent 74030888
Pipeline #42117501 passed with stages
in 5 minutes and 12 seconds
......@@ -76,7 +76,7 @@ namespace Rodgort.Services
private static readonly Regex _userIdRegex = new Regex(@"\/users\/(\d+)");
private async Task FollowInRoom(int roomId, int followingUserId, DateTime fromTime, string followingTag, DateService dateService, CancellationToken cancellationToken)
public async Task FollowInRoom(int roomId, int followingUserId, DateTime fromTime, string followingTag, DateService dateService, CancellationToken cancellationToken)
{
await RunWithLogging(async () =>
{
......
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Net;
......@@ -12,6 +13,7 @@ using Rodgort.Data.Tables;
using Rodgort.Utilities;
using StackExchangeApi;
using StackExchangeApi.Responses;
using StackExchangeChat;
namespace Rodgort.Services
{
......@@ -23,16 +25,22 @@ namespace Rodgort.Services
private readonly ApiClient _apiClient;
private readonly DateService _dateService;
private readonly ILogger<MetaCrawlerService> _logger;
private readonly NewBurninationService _newBurninationService;
private static readonly object _locker = new object();
private static bool _alreadyProcessing;
public MetaCrawlerService(DbContextOptions<RodgortContext> dbContextOptions, ApiClient apiClient, DateService dateService, ILogger<MetaCrawlerService> logger)
public MetaCrawlerService(DbContextOptions<RodgortContext> dbContextOptions,
ApiClient apiClient,
DateService dateService,
ILogger<MetaCrawlerService> logger,
NewBurninationService newBurninationService)
{
_dbContextOptions = dbContextOptions;
_apiClient = apiClient;
_dateService = dateService;
_logger = logger;
_newBurninationService = newBurninationService;
}
[SuppressMessage("ReSharper", "InconsistentlySynchronizedField", Justification = "Flagged _logger, but in both blocks we're guaranteed to run on a single thread")]
......@@ -67,6 +75,7 @@ namespace Rodgort.Services
var questionLookup = context.MetaQuestions.Where(q => questionIds.Contains(q.Id))
.Include(mq => mq.MetaQuestionMetaTags)
.Include(mq => mq.MetaQuestionTags)
.ToDictionary(q => q.Id, q => q);
var answerIds = metaQuestions.Items.Where(q => q.Answers != null).SelectMany(q => q.Answers.Select(a => a.AnswerId)).Distinct().ToList();
......@@ -81,7 +90,7 @@ namespace Rodgort.Services
if (!questionLookup.ContainsKey(metaQuestion.QuestionId.Value))
{
dbMetaQuestion = new DbMetaQuestion {Id = metaQuestion.QuestionId.Value};
dbMetaQuestion = new DbMetaQuestion {Id = metaQuestion.QuestionId.Value, MetaQuestionTags = new List<DbMetaQuestionTag>()};
context.MetaQuestions.Add(dbMetaQuestion);
questionLookup[dbMetaQuestion.Id] = dbMetaQuestion;
......@@ -107,21 +116,35 @@ namespace Rodgort.Services
if (metaQuestion.ClosedDate.HasValue)
dbMetaQuestion.ClosedDate = Dates.UnixTimeStampToDateTime(metaQuestion.ClosedDate.Value);
var trackedTags = dbMetaQuestion.MetaQuestionTags.Where(mqt => mqt.TrackingStatusId == DbMetaQuestionTagTrackingStatus.TRACKED).ToList();
foreach (var tag in metaQuestion.Tags)
{
if (!dbMetaQuestion.MetaQuestionMetaTags.Any(t => string.Equals(t.TagName, tag, StringComparison.OrdinalIgnoreCase)))
{
context.MetaQuestionMetaTags.Add(new DbMetaQuestionMetaTag { TagName = tag, MetaQuestion = dbMetaQuestion });
if (tag == DbMetaTag.STATUS_FEATURED)
{
dbMetaQuestion.FeaturedStarted = utcNow;
if (!trackedTags.Any())
{
await _newBurninationService.AnnounceNoTrackedTags(metaQuestion.Link);
}
else if (trackedTags.Count > 1)
{
await _newBurninationService.AnnounceMultipleTrackedTags(metaQuestion.Link, trackedTags.Select(t => t.TagName));
}
else
{
await _newBurninationService.CreateRoomForBurn(trackedTags.First().TagName, metaQuestion.Link);
}
}
if (tag == DbMetaTag.STATUS_PLANNED)
dbMetaQuestion.BurnStarted = utcNow;
}
}
foreach (var dbTag in dbMetaQuestion.MetaQuestionMetaTags.ToList())
var metaQuestionList = dbMetaQuestion.MetaQuestionMetaTags.ToList();
foreach (var dbTag in metaQuestionList)
{
if (!metaQuestion.Tags.Any(t => string.Equals(t, dbTag.TagName, StringComparison.OrdinalIgnoreCase)))
{
......@@ -130,7 +153,11 @@ namespace Rodgort.Services
if (dbTag.TagName == DbMetaTag.STATUS_FEATURED)
dbMetaQuestion.FeaturedEnded = utcNow;
if (dbTag.TagName == DbMetaTag.STATUS_PLANNED)
{
dbMetaQuestion.BurnEnded = utcNow;
foreach (var trackedTag in trackedTags)
await _newBurninationService.StopBurn(trackedTag.TagName);
}
}
}
......
using System.Threading.Tasks;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore.Metadata.Internal;
using Rodgort.Data;
using Rodgort.Data.Tables;
using Rodgort.Utilities;
using StackExchangeChat;
......@@ -7,24 +13,91 @@ namespace Rodgort.Services
public class NewBurninationService
{
private readonly ChatClient _chatClient;
public NewBurninationService(ChatClient chatClient)
private readonly RodgortContext _rodgortContext;
private readonly DateService _dateService;
private readonly BurnakiFollowService _burnakiFollowService;
private readonly bool Enabled;
public NewBurninationService(ChatClient chatClient, RodgortContext rodgortContext, DateService dateService, BurnakiFollowService burnakiFollowService, IChatCredentials chatCredentials)
{
_chatClient = chatClient;
_rodgortContext = rodgortContext;
_dateService = dateService;
_burnakiFollowService = burnakiFollowService;
var hasCookies = !string.IsNullOrWhiteSpace(chatCredentials.AcctCookie);
var hasCredentials = !string.IsNullOrWhiteSpace(chatCredentials.AcctCookie) && !string.IsNullOrWhiteSpace(chatCredentials.Password);
Enabled = hasCookies || hasCredentials;
}
public async Task AnnounceMultipleTrackedTags(string metaPostUrl, IEnumerable<string> trackedTags)
{
if (!Enabled)
return;
await _chatClient.SendMessage(ChatSite.StackOverflow, ChatRooms.SO_BOTICS_WORKSHOP, $"Discussion for the burnination of {metaPostUrl} started, but there are multiple tracked tags: {string.Join(", ", trackedTags)}");
}
public async Task AnnounceNoTrackedTags(string metaPostUrl)
{
if (!Enabled)
return;
await _chatClient.SendMessage(ChatSite.StackOverflow, ChatRooms.SO_BOTICS_WORKSHOP, $"Discussion for the burnination of {metaPostUrl} started, but there are no tracked tags");
}
public async Task CreateRoomForBurn(ChatSite chatSite, int currentRoomId, string tag, string metaPostUrl)
public async Task StopBurn(string tag)
{
if (!Enabled)
return;
await _chatClient.SendMessage(ChatSite.StackOverflow, ChatRooms.SO_BOTICS_WORKSHOP, $"@Gemmy stop tag {tag}");
await _chatClient.SendMessage(ChatSite.StackOverflow, ChatRooms.SO_BOTICS_WORKSHOP, $"The burnination of [tag:{tag}] has finished!");
var follows = _rodgortContext.BurnakiFollows.Where(bf => bf.BurnakiId == 8300708 && bf.Tag == tag).ToList();
foreach (var follow in follows)
{
follow.FollowEnded = _dateService.UtcNow;
}
_rodgortContext.SaveChanges();
}
public async Task CreateRoomForBurn(string tag, string metaPostUrl)
{
var roomName = $"Observation room for [{tag}] burnination";
var roomId = await _chatClient.CreateRoom(chatSite, currentRoomId, roomName, string.Empty);
var roomId = await _chatClient.CreateRoom(ChatSite.StackOverflow, ChatRooms.SO_BOTICS_WORKSHOP, roomName, string.Empty);
var gemmyMessage = $"@Gemmy start tag [{tag}] {roomId} https://chat.stackoverflow.com/rooms/{roomId}";
await _chatClient.SendMessage(ChatSite.StackOverflow, ChatRooms.SO_BOTICS_WORKSHOP, gemmyMessage);
var burninationMessage = $"The burnination of [tag:{tag}] has begun! {metaPostUrl}";
var burninationMessage = $"The burnination of [tag:{tag}] is now being discussed {metaPostUrl}";
var burninationMessageId = await _chatClient.SendMessage(ChatSite.StackOverflow, ChatRooms.SO_BOTICS_WORKSHOP, burninationMessage);
await _chatClient.PinMessage(ChatSite.StackOverflow, ChatRooms.SO_BOTICS_WORKSHOP, burninationMessageId);
var burnakiFollow = new DbBurnakiFollow
{
BurnakiId = 8300708,
FollowStarted = _dateService.UtcNow,
RoomId = roomId,
Tag = tag
};
_rodgortContext.BurnakiFollows.Add(burnakiFollow);
_rodgortContext.SaveChanges();
await _burnakiFollowService.FollowInRoom(
burnakiFollow.RoomId,
burnakiFollow.BurnakiId,
burnakiFollow.FollowStarted,
burnakiFollow.Tag,
_dateService,
CancellationToken.None
);
}
}
}
......@@ -89,7 +89,8 @@ namespace Rodgort
services.AddScoped<SiteAuthenticator>();
services.AddScoped<ChatClient>();
services.AddScoped<NewBurninationService>();
services.AddHostedService<BurnakiFollowService>();
}
......
......@@ -52,7 +52,7 @@ namespace StackExchangeChat.Console
var newBurninationService = serviceProvider.GetService<NewBurninationService>();
newBurninationService.CreateRoomForBurn(ChatSite.StackOverflow, ChatRooms.SO_BOTICS_WORKSHOP, "priority", "https://meta.stackoverflow.com/questions/285084/should-we-burninate-the-priority-tag").GetAwaiter().GetResult();
// newBurninationService.CreateRoomForBurn(ChatSite.StackOverflow, ChatRooms.SO_BOTICS_WORKSHOP, "priority", "https://meta.stackoverflow.com/questions/285084/should-we-burninate-the-priority-tag").GetAwaiter().GetResult();
// var roomId = chatClient.CreateRoom(ChatSite.StackOverflow, 167908, "This is a testing room", "This is a testing description").GetAwaiter().GetResult();
//var events = chatClient.SubscribeToEvents(ChatSite.StackExchange, 86421);
//events.Subscribe(System.Console.WriteLine);
......
......@@ -28,7 +28,7 @@ namespace StackExchangeChat
public async Task<int> SendMessage(ChatSite chatSite, int roomId, string message)
{
return await ThrottlingUtils.Throttle<int>(ChatThrottleGroups.WebRequestThrottle, async () =>
return await ThrottlingUtils.Throttle(ChatThrottleGroups.WebRequestThrottle, async () =>
{
var fkey = (await _siteAuthenticator.GetRoomDetails(chatSite, roomId)).FKey;
await _siteAuthenticator.AuthenticateClient(_httpClient, chatSite);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment