Files
2017-03-25 15:29:51 +11:00

129 lines
5.1 KiB
C#

using Disco.Data.Repository;
using Disco.Models.Repository;
using Disco.Services.Tasks;
using Quartz;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
namespace Disco.Services.Documents.AttachmentImport
{
public class ThumbnailUpdateTask : ScheduledTask
{
public override string TaskName { get { return "Migration: PDF Attachment Thumbnail Update"; } }
public override bool SingleInstanceTask { get { return true; } }
public override bool CancelInitiallySupported { get { return false; } }
#region Required Helpers
private static string RequiredFilePath(DiscoDataContext Database)
{
if (Database.DiscoConfiguration.DataStoreLocation != null)
return Path.Combine(Database.DiscoConfiguration.DataStoreLocation, "_ThumbnailUpdateRequired.txt");
else
return null;
}
public static bool IsRequired(DiscoDataContext Database)
{
var requiredFilePath = RequiredFilePath(Database);
if (requiredFilePath == null)
return false;
else
return File.Exists(requiredFilePath);
}
public static void SetRequired(DiscoDataContext Database)
{
var requiredFilePath = RequiredFilePath(Database);
if (requiredFilePath != null)
{
File.WriteAllText(requiredFilePath, "This file exists to indicate a Thumbnail Update is required. It will automatically be deleted when the update completes.");
File.SetAttributes(requiredFilePath, FileAttributes.Hidden);
}
}
#endregion
public override void InitalizeScheduledTask(DiscoDataContext Database)
{
if (IsRequired(Database))
{
// Schedule in 5mins
var trigger = TriggerBuilder.Create()
.StartAt(DateTimeOffset.Now.AddMinutes(5));
ScheduleTask(trigger);
}
}
public static ScheduledTaskStatus ScheduleImmediately()
{
var existingTask = ScheduledTasks.GetTaskStatuses(typeof(ThumbnailUpdateTask)).Where(s => s.IsRunning).FirstOrDefault();
if (existingTask != null)
return existingTask;
var instance = new ThumbnailUpdateTask();
return instance.ScheduleTask();
}
protected override void ExecuteTask()
{
using (DiscoDataContext database = new DiscoDataContext())
{
Status.UpdateStatus(0, "Updating Attachment PDF Thumbnails", "Reading Attachments");
// Attachments
List<IAttachment> attachments = database
.DeviceAttachments.Where(da => da.MimeType == "application/pdf").ToList().Cast<IAttachment>()
.Concat(database.UserAttachments.Where(da => da.MimeType == "application/pdf").ToList().Cast<IAttachment>())
.Concat(database.JobAttachments.Where(da => da.MimeType == "application/pdf").ToList().Cast<IAttachment>())
.ToList();
int failedTotal = 0;
int notFoundTotal = 0;
int completedTotal = 0;
attachments.AsParallel().ForAll(a =>
{
var completed = Interlocked.Increment(ref completedTotal);
if ((completed % 10) == 0)
{
Status.UpdateStatus((100D / attachments.Count) * completed, $"Processing: {a.AttachmentType} Attachment, Id: {a.Id}");
}
try
{
var fileName = a.RepositoryFilename(database);
if (!File.Exists(fileName))
{
Interlocked.Increment(ref notFoundTotal);
Status.LogWarning($"Attachment not found in the Data Store. [{a.AttachmentType} Attachment, Id {a.Id}] expected at: '{fileName}'");
}
else
{
a.GenerateThumbnail(database);
}
}
catch (Exception ex)
{
Interlocked.Increment(ref failedTotal);
Status.LogWarning($"Error when generating thumbnail for [{a.AttachmentType} Attachment, Id {a.Id}]: [{ex.GetType().Name}] {ex.Message}");
}
});
// Finished - Remove Placeholder File
var requiredFilePath = RequiredFilePath(database);
if (requiredFilePath != null && File.Exists(requiredFilePath))
File.Delete(requiredFilePath);
Status.SetFinishedMessage($"Finished updating thumbnails for {attachments.Count:N0}. {notFoundTotal:N0} were not found. {failedTotal:N0} failed.");
Status.LogInformation(Status.FinishedMessage);
Status.Finished();
}
}
}
}