Skip to content

Commit

Permalink
Added daily reminder
Browse files Browse the repository at this point in the history
  • Loading branch information
chamik committed Feb 4, 2021
1 parent afae67a commit a6bfc1b
Show file tree
Hide file tree
Showing 9 changed files with 544 additions and 0 deletions.
368 changes: 368 additions & 0 deletions thorn/Config/daily.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions thorn/Config/pairs.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"WELCOME_CHANNEL_ID": "666672988883779585",
"NEWS_CHANNEL_ID": "537063810121334784",
"LOGGING_CHANNEL_ID": "661982623085625364",
"GENERAL_CHANNEL_ID": "640917453169229856",

"CLASS_C_ROLE_ID": "537322727225163776",
"INT_ROLE_ID": "537023765163409439",
Expand Down
13 changes: 13 additions & 0 deletions thorn/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,12 @@
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Quartz;
using Quartz.Impl;
using Quartz.Spi;
using Serilog;
using Serilog.Events;
using thorn.Reminder;
using thorn.Services;

namespace thorn
Expand Down Expand Up @@ -50,10 +54,19 @@ private static async Task Main()
{
collection.AddHostedService<CommandHandler>();
collection.AddHostedService<ReactionHandler>();
collection.AddHostedService<QuartzHostedService>();

collection.AddSingleton<PairsService>();
collection.AddSingleton<DataStorageService>();
collection.AddSingleton<UserAccountsService>();

// Quartz
collection.AddSingleton<IJobFactory, SingletonJobFactory>();
collection.AddSingleton<ISchedulerFactory, StdSchedulerFactory>();
collection.AddSingleton<ReminderJob>();
collection.AddSingleton(new JobSchedule(
typeof(ReminderJob),
"0 0 0 * * ?")); // Every day at midnight
});

await hostBuilder.RunConsoleAsync();
Expand Down
16 changes: 16 additions & 0 deletions thorn/Reminder/JobSchedule.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using System;

namespace thorn.Reminder
{
public class JobSchedule
{
public JobSchedule(Type jobType, string cronExpression)
{
JobType = jobType;
CronExpression = cronExpression;
}

public Type JobType { get; }
public string CronExpression { get; }
}
}
68 changes: 68 additions & 0 deletions thorn/Reminder/QuartzHostedService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Hosting;
using Quartz;
using Quartz.Spi;

namespace thorn.Reminder
{
public class QuartzHostedService : IHostedService
{
private readonly ISchedulerFactory _schedulerFactory;
private readonly IJobFactory _jobFactory;
private readonly IEnumerable<JobSchedule> _jobSchedules;

public QuartzHostedService(
ISchedulerFactory schedulerFactory,
IJobFactory jobFactory,
IEnumerable<JobSchedule> jobSchedules)
{
_schedulerFactory = schedulerFactory;
_jobSchedules = jobSchedules;
_jobFactory = jobFactory;
}
public IScheduler Scheduler { get; set; }

public async Task StartAsync(CancellationToken cancellationToken)
{
Scheduler = await _schedulerFactory.GetScheduler(cancellationToken);
Scheduler.JobFactory = _jobFactory;

foreach (var jobSchedule in _jobSchedules)
{
var job = CreateJob(jobSchedule);
var trigger = CreateTrigger(jobSchedule);

await Scheduler.ScheduleJob(job, trigger, cancellationToken);
}

await Scheduler.Start(cancellationToken);
}

public async Task StopAsync(CancellationToken cancellationToken)
{
await Scheduler?.Shutdown(cancellationToken);
}

private static IJobDetail CreateJob(JobSchedule schedule)
{
var jobType = schedule.JobType;
return JobBuilder
.Create(jobType)
.WithIdentity(jobType.FullName ?? string.Empty)
.WithDescription(jobType.Name)
.Build();
}

private static ITrigger CreateTrigger(JobSchedule schedule)
{
return TriggerBuilder
.Create()
.WithIdentity($"{schedule.JobType.FullName}.trigger")
.WithCronSchedule(schedule.CronExpression)
.WithDescription(schedule.CronExpression)
.Build();
}
}
}
49 changes: 49 additions & 0 deletions thorn/Reminder/ReminderJob.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using Discord;
using Discord.WebSocket;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Quartz;
using thorn.Services;

namespace thorn.Reminder
{
public class ReminderJob : IJob
{
private readonly ILogger<ReminderJob> _logger;
private readonly SocketTextChannel _channel;
private readonly PairsService _pairs;

private readonly Dictionary<string, string> _daily;

public ReminderJob(ILogger<ReminderJob> logger, DiscordSocketClient client, PairsService pairs, DataStorageService data)
{
_logger = logger;
_pairs = pairs;

_channel = client.GetChannel(ulong.Parse(pairs.GetString("GENERAL_CHANNEL_ID"))) as SocketTextChannel;
_daily = DataStorageService.GetDictionary<string>("Config/daily.json");
}

public async Task Execute(IJobExecutionContext context)
{
var day = DateTime.Now;
var description = _daily[day.ToString("dd MM")] +
$"\n\nPřeji krásný den {_pairs.GetString("AGRLOVE_EMOTE")}";

var embed = new EmbedBuilder
{
Title = "Krásné dobré ráno!",
Description = description,
ThumbnailUrl = "https://cdn.discordapp.com/attachments/537064369725636611/733080455217283131/calendar-flat.png",
Color = Color.Green
}.Build();

await _channel.SendMessageAsync(embed: embed);
_logger.LogInformation("Sent daily reminder for {Day}", day.Date);
}
}
}
23 changes: 23 additions & 0 deletions thorn/Reminder/SingletonJobFactory.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using System;
using Microsoft.Extensions.DependencyInjection;
using Quartz;
using Quartz.Spi;

namespace thorn.Reminder
{
public class SingletonJobFactory : IJobFactory
{
private readonly IServiceProvider _serviceProvider;
public SingletonJobFactory(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}

public IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler)
{
return _serviceProvider.GetRequiredService(bundle.JobDetail.JobType) as IJob;
}

public void ReturnJob(IJob job) { }
}
}
3 changes: 3 additions & 0 deletions thorn/Services/DataStorageService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ public Task SaveAllUserAccounts(IEnumerable<UserAccount> accounts, string filePa
return Task.CompletedTask;
}

public static Dictionary<string, T> GetDictionary<T>(string path) =>
JsonConvert.DeserializeObject<Dictionary<string, T>>(File.ReadAllText(path));

public static List<UserAccount> LoadUserAccounts(string filePath)
{
if (!File.Exists(filePath))
Expand Down
3 changes: 3 additions & 0 deletions thorn/thorn.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@
<None Update="Config\config.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Config\daily.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>

<ItemGroup>
Expand Down

0 comments on commit a6bfc1b

Please sign in to comment.