Skip to content

Commit

Permalink
When a new post is featured, create a room and get burnaki to track it
Browse files Browse the repository at this point in the history
  • Loading branch information
rjrudman committed Jan 4, 2019
1 parent 7403088 commit fdabe62
Show file tree
Hide file tree
Showing 6 changed files with 116 additions and 15 deletions.
2 changes: 1 addition & 1 deletion Rodgort/Services/BurnakiFollowService.cs
Expand Up @@ -76,7 +76,7 @@ await events

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 () =>
{
Expand Down
39 changes: 33 additions & 6 deletions Rodgort/Services/MetaCrawlerService.cs
@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Net;
Expand All @@ -12,6 +13,7 @@
using Rodgort.Utilities;
using StackExchangeApi;
using StackExchangeApi.Responses;
using StackExchangeChat;

namespace Rodgort.Services
{
Expand All @@ -23,16 +25,22 @@ public class MetaCrawlerService
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")]
Expand Down Expand Up @@ -67,6 +75,7 @@ public async Task CrawlMeta()

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();
Expand All @@ -81,7 +90,7 @@ public async Task CrawlMeta()

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;
Expand All @@ -107,21 +116,35 @@ public async Task CrawlMeta()
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)))
{
Expand All @@ -130,7 +153,11 @@ public async Task CrawlMeta()
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);
}
}
}

Expand Down
83 changes: 78 additions & 5 deletions Rodgort/Services/NewBurninationService.cs
@@ -1,4 +1,10 @@
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;

Expand All @@ -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
);
}
}
}
3 changes: 2 additions & 1 deletion Rodgort/Startup.cs
Expand Up @@ -89,7 +89,8 @@ public void ConfigureServices(IServiceCollection services)

services.AddScoped<SiteAuthenticator>();
services.AddScoped<ChatClient>();

services.AddScoped<NewBurninationService>();

services.AddHostedService<BurnakiFollowService>();
}

Expand Down
2 changes: 1 addition & 1 deletion StackExchangeChat.Console/Program.cs
Expand Up @@ -52,7 +52,7 @@ public static void Main(string[] args)

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);
Expand Down
2 changes: 1 addition & 1 deletion StackExchangeChat/ChatClient.cs
Expand Up @@ -28,7 +28,7 @@ public ChatClient(SiteAuthenticator siteAuthenticator, HttpClientWithHandler htt

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);
Expand Down

0 comments on commit fdabe62

Please sign in to comment.