2017-04-17 14:39:29 +02:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Threading.Tasks;
|
2017-04-17 21:56:53 +02:00
|
|
|
|
using Discord;
|
2017-09-25 19:50:59 +02:00
|
|
|
|
using Discord.WebSocket;
|
2017-04-17 14:39:29 +02:00
|
|
|
|
|
2017-10-04 11:27:01 +02:00
|
|
|
|
namespace DML.Core.Classes
|
2017-04-17 14:39:29 +02:00
|
|
|
|
{
|
|
|
|
|
public class Job
|
|
|
|
|
{
|
|
|
|
|
public int Id { get; set; }
|
|
|
|
|
public ulong GuildId { get; set; }
|
|
|
|
|
public ulong ChannelId { get; set; }
|
2017-04-17 21:56:53 +02:00
|
|
|
|
public double KnownTimestamp { get; set; } = 0;
|
|
|
|
|
private double StopTimestamp { get; set; } = 0;
|
2017-04-30 11:06:10 +02:00
|
|
|
|
private bool IsValid { get; set; } = true;
|
2017-04-17 14:39:29 +02:00
|
|
|
|
|
|
|
|
|
internal void Store()
|
|
|
|
|
{
|
|
|
|
|
Debug("Storing job to database...");
|
|
|
|
|
Trace("Getting jobs collection...");
|
2017-10-04 11:27:01 +02:00
|
|
|
|
var jobDb = DML.Core.Core.Database.GetCollection<Job>("jobs");
|
2017-04-17 14:39:29 +02:00
|
|
|
|
|
|
|
|
|
Trace("Adding new value...");
|
2017-04-17 21:56:53 +02:00
|
|
|
|
|
|
|
|
|
if (jobDb.Find(x => x.ChannelId == ChannelId && x.GuildId == GuildId).Any())
|
|
|
|
|
{
|
|
|
|
|
jobDb.Update(this);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
jobDb.Insert(this);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-04-17 23:02:57 +02:00
|
|
|
|
internal void Delete()
|
|
|
|
|
{
|
|
|
|
|
Debug("Deleting job from database...");
|
|
|
|
|
Trace("Getting jobs collection...");
|
2017-10-04 11:27:01 +02:00
|
|
|
|
var jobDb = DML.Core.Core.Database.GetCollection<Job>("jobs");
|
2017-04-17 23:02:57 +02:00
|
|
|
|
|
|
|
|
|
Trace("Deleting value...");
|
|
|
|
|
jobDb.Delete(Id);
|
|
|
|
|
}
|
|
|
|
|
|
2017-09-25 19:50:59 +02:00
|
|
|
|
private SocketGuild FindServerById(ulong id)
|
2017-04-17 21:56:53 +02:00
|
|
|
|
{
|
|
|
|
|
Trace($"Trying to find server by Id: {id}");
|
2017-10-04 11:27:01 +02:00
|
|
|
|
return (from s in DML.Core.Core.Client.Guilds where s.Id == id select s).FirstOrDefault();
|
2017-04-17 21:56:53 +02:00
|
|
|
|
}
|
|
|
|
|
|
2017-09-25 19:50:59 +02:00
|
|
|
|
private SocketTextChannel FindChannelById(SocketGuild server, ulong id)
|
2017-04-17 21:56:53 +02:00
|
|
|
|
{
|
|
|
|
|
Trace($"Trying to find channel in {server} by id: {id}");
|
|
|
|
|
return (from c in server.TextChannels where c.Id == id select c).FirstOrDefault();
|
|
|
|
|
}
|
|
|
|
|
|
2017-09-25 19:50:59 +02:00
|
|
|
|
internal async Task<List<SocketMessage>> Scan()
|
2017-04-17 21:56:53 +02:00
|
|
|
|
{
|
|
|
|
|
Debug($"Starting scan of guild {GuildId} channel {ChannelId}...");
|
2017-09-25 19:50:59 +02:00
|
|
|
|
var result = new List<SocketMessage>();
|
2017-04-17 21:56:53 +02:00
|
|
|
|
|
|
|
|
|
var limit = 100;
|
|
|
|
|
var lastId = ulong.MaxValue;
|
|
|
|
|
var isFirst = true;
|
|
|
|
|
var finished = false;
|
|
|
|
|
|
|
|
|
|
var guild = FindServerById(GuildId);
|
|
|
|
|
var channel = FindChannelById(guild, ChannelId);
|
|
|
|
|
|
|
|
|
|
if (Math.Abs(StopTimestamp) < 0.4)
|
|
|
|
|
StopTimestamp = KnownTimestamp;
|
|
|
|
|
Trace("Initialized scanning parameters.");
|
|
|
|
|
|
|
|
|
|
while (!finished)
|
|
|
|
|
{
|
|
|
|
|
Trace("Entering scanning loop...");
|
2017-09-25 19:50:59 +02:00
|
|
|
|
SocketMessage[] messages;
|
2017-04-17 21:56:53 +02:00
|
|
|
|
|
|
|
|
|
Trace($"Downloading next {limit} messages...");
|
|
|
|
|
if (isFirst)
|
|
|
|
|
{
|
2017-09-25 19:50:59 +02:00
|
|
|
|
messages = await channel.GetMessagesAsync(limit).ToArray() as SocketMessage[];
|
2017-04-17 21:56:53 +02:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2017-09-25 19:50:59 +02:00
|
|
|
|
messages = await channel.GetMessagesAsync(lastId, Direction.Before, limit).ToArray() as SocketMessage[];
|
2017-04-17 21:56:53 +02:00
|
|
|
|
}
|
|
|
|
|
Trace($"Downloaded {messages.Length} messages.");
|
|
|
|
|
|
|
|
|
|
isFirst = false;
|
|
|
|
|
|
|
|
|
|
foreach (var m in messages)
|
|
|
|
|
{
|
2017-04-30 11:06:10 +02:00
|
|
|
|
if (!IsValid)
|
|
|
|
|
return null;
|
|
|
|
|
|
2017-04-17 21:56:53 +02:00
|
|
|
|
Debug($"Processing message {m.Id}");
|
|
|
|
|
if (m.Id < lastId)
|
|
|
|
|
{
|
|
|
|
|
Trace($"Updating lastId ({lastId}) to {m.Id}");
|
|
|
|
|
lastId = m.Id;
|
|
|
|
|
}
|
|
|
|
|
|
2017-09-25 19:50:59 +02:00
|
|
|
|
if (SweetUtils.DateTimeToUnixTimeStamp(m.CreatedAt.UtcDateTime) <= StopTimestamp)
|
2017-04-17 21:56:53 +02:00
|
|
|
|
{
|
|
|
|
|
Debug("Found a message with a known timestamp...Stopping scan.");
|
|
|
|
|
finished = true;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
2017-09-25 19:50:59 +02:00
|
|
|
|
Trace($"Message {m.Id} has {m.Attachments.Count} attachments.");
|
|
|
|
|
if (m.Attachments.Count > 0)
|
2017-04-17 21:56:53 +02:00
|
|
|
|
{
|
|
|
|
|
result.Add(m);
|
2017-10-04 11:27:01 +02:00
|
|
|
|
DML.Core.Core.Scheduler.TotalAttachments++;
|
2017-04-17 21:56:53 +02:00
|
|
|
|
Trace($"Added message {m.Id}");
|
|
|
|
|
}
|
|
|
|
|
Debug($"Finished message {m.Id}");
|
2017-04-17 23:02:57 +02:00
|
|
|
|
|
2017-10-04 11:27:01 +02:00
|
|
|
|
DML.Core.Core.Scheduler.MessagesScanned++;
|
2017-04-17 21:56:53 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
finished = finished || messages.Length < limit;
|
|
|
|
|
}
|
|
|
|
|
Trace($"Downloaded all messages for guild {GuildId} channel {ChannelId}.");
|
|
|
|
|
|
|
|
|
|
Trace("Sorting messages...");
|
2017-09-25 19:50:59 +02:00
|
|
|
|
result.Sort((a, b) => DateTime.Compare(a.CreatedAt.UtcDateTime, b.CreatedAt.UtcDateTime));
|
2017-04-17 21:56:53 +02:00
|
|
|
|
|
2017-04-30 11:06:10 +02:00
|
|
|
|
if (result.Count > 0)
|
|
|
|
|
{
|
|
|
|
|
Trace("Updating StopTimestamp for next scan...");
|
2017-09-25 19:50:59 +02:00
|
|
|
|
StopTimestamp = SweetUtils.DateTimeToUnixTimeStamp(result[result.Count - 1].CreatedAt.UtcDateTime);
|
2017-04-30 11:06:10 +02:00
|
|
|
|
}
|
2017-04-17 21:56:53 +02:00
|
|
|
|
|
|
|
|
|
Debug($"Fisnished scan of guild {GuildId} channel {ChannelId}.");
|
|
|
|
|
|
|
|
|
|
return result;
|
2017-04-17 14:39:29 +02:00
|
|
|
|
}
|
|
|
|
|
|
2017-04-30 11:06:10 +02:00
|
|
|
|
internal void Stop()
|
|
|
|
|
{
|
|
|
|
|
IsValid = false;
|
|
|
|
|
}
|
|
|
|
|
|
2017-04-17 14:39:29 +02:00
|
|
|
|
internal static IEnumerable<Job> RestoreJobs()
|
|
|
|
|
{
|
|
|
|
|
Debug("Restoring jobs...");
|
|
|
|
|
Trace("Getting jobs collection...");
|
2017-10-04 11:27:01 +02:00
|
|
|
|
var jobDb = DML.Core.Core.Database.GetCollection<Job>("jobs");
|
2017-04-17 14:39:29 +02:00
|
|
|
|
|
|
|
|
|
Trace("Creating new empty job list");
|
|
|
|
|
return jobDb.FindAll();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|