AirScout/ScoutBase/ScoutBase.CAT/CATUpdater.cs

204 wiersze
8.2 KiB
C#

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data.OleDb;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using ScoutBase.Core;
using System.Data.SQLite;
namespace ScoutBase.CAT
{
public class CATUpdaterStartOptions
{
public string Name;
public BACKGROUNDUPDATERSTARTOPTIONS Options;
}
// Background worker for rig definitions update
[DefaultPropertyAttribute("Name")]
public class CATUpdater : BackgroundWorker
{
CATUpdaterStartOptions StartOptions;
// Temp directory to save downloaded files
string TmpDirectory = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), Application.CompanyName, Application.ProductName, "Tmp", "RigData").TrimEnd(Path.DirectorySeparatorChar);
// File extension
string FileExtension = ".ini";
public CATUpdater() : base()
{
this.WorkerReportsProgress = true;
this.WorkerSupportsCancellation = true;
// create temp directory if not exists
if (!Directory.Exists(TmpDirectory))
Directory.CreateDirectory(TmpDirectory);
}
private DOWNLOADFILESTATUS GetUpdateFromURL(string url, string zipfilename)
{
AutoDecompressionWebClient cl = new AutoDecompressionWebClient();
DOWNLOADFILESTATUS status = cl.DownloadFileIfNewer(url, zipfilename, true, true);
return status;
}
private bool ReadRigsFromURL(string url, string zipfilename)
{
try
{
DOWNLOADFILESTATUS status = GetUpdateFromURL(url, zipfilename);
if (((status & DOWNLOADFILESTATUS.ERROR) > 0) && ((status & DOWNLOADFILESTATUS.NOTFOUND) > 0))
{
this.ReportProgress(-1, "Error while downloading and extracting " + zipfilename);
return false;
}
else if (((status & DOWNLOADFILESTATUS.NEWER) > 0) || ((status & DOWNLOADFILESTATUS.NOTNEWER) > 0))
{
var dir = new DirectoryInfo(TmpDirectory);
FileInfo[] files = dir.GetFiles("*" + FileExtension);
foreach (FileInfo file in files)
{
string oldfilename = Path.Combine(RigData.Database.DefaultDatabaseDirectory(), file.Name);
try
{
if (!File.Exists(oldfilename))
{
// file does not exist --> simply copy over
File.Copy(file.FullName, oldfilename);
}
else if (new FileInfo(oldfilename).LastWriteTimeUtc < file.LastWriteTimeUtc)
{
// file exists but is older --> delete old file and copy over
File.Delete(oldfilename);
File.Copy(file.FullName, oldfilename);
}
if (this.CancellationPending)
return false;
// reduce CPU load
Thread.Sleep(1);
}
catch (Exception ex)
{
this.ReportProgress(-1, "Error while checking " + oldfilename);
return false;
}
}
return true;
}
}
catch (Exception ex)
{
// Error loading database
this.ReportProgress(-1, "[" + url + "]: " + ex.ToString());
}
return false;
}
protected override void OnDoWork(DoWorkEventArgs e)
{
StartOptions = (CATUpdaterStartOptions)e.Argument;
this.ReportProgress(0, StartOptions.Name + " started.");
// name the thread for debugging
if (String.IsNullOrEmpty(Thread.CurrentThread.Name))
Thread.CurrentThread.Name = nameof(CATUpdater);
// create directories if not exist
try
{
if (!Directory.Exists(TmpDirectory))
Directory.CreateDirectory(TmpDirectory);
if (!Directory.Exists(RigData.Database.DefaultDatabaseDirectory()))
Directory.CreateDirectory(RigData.Database.DefaultDatabaseDirectory());
}
catch (Exception ex)
{
this.ReportProgress(-1, "Error while creating directories: " + ex.ToString());
}
this.ReportProgress(0, "Updating rig definitions...");
// get update interval
int interval = (int)Properties.Settings.Default.Database_BackgroundUpdate_Period * 60;
do
{
try
{
// check if any kind of update is enabled
if ((StartOptions.Options == BACKGROUNDUPDATERSTARTOPTIONS.RUNONCE) || (StartOptions.Options == BACKGROUNDUPDATERSTARTOPTIONS.RUNPERIODICALLY))
{
// reset database status
this.ReportProgress(1, System.Data.SQLite.DATABASESTATUS.UNDEFINED);
Stopwatch st = new Stopwatch();
st.Start();
// clear temporary files
try
{
SupportFunctions.DeleteFilesFromDirectory(TmpDirectory, new string[] { "*.tmp", "*.PendingOverwrite" });
}
catch (Exception ex)
{
this.ReportProgress(-1, ex.ToString());
}
// update rig database
this.ReportProgress(1, System.Data.SQLite.DATABASESTATUS.UPDATING);
this.ReportProgress(0, "Updating rig definitions from web database...");
// get update from url
if (ReadRigsFromURL(Properties.Settings.Default.Rigs_UpdateURL + "rigs.zip", Path.Combine(TmpDirectory, "rigs.zip")))
{
st.Stop();
this.ReportProgress(1, System.Data.SQLite.DATABASESTATUS.UPTODATE);
this.ReportProgress(0, " Rig database update completed: " + st.Elapsed.ToString(@"hh\:mm\:ss"));
}
else
{
st.Stop();
this.ReportProgress(1, System.Data.SQLite.DATABASESTATUS.ERROR);
this.ReportProgress(0, " Rig database update completed with errors: " + st.Elapsed.ToString(@"hh\:mm\:ss"));
}
if (this.CancellationPending)
break;
// sleep once to get all messages to main thread
Thread.Sleep(1000);
// sleep when running periodically
if (StartOptions.Options == BACKGROUNDUPDATERSTARTOPTIONS.RUNPERIODICALLY)
{
int i = 0;
while (!this.CancellationPending && (i < interval))
{
Thread.Sleep(1000);
i++;
}
}
}
}
catch (Exception ex)
{
this.ReportProgress(-1, ex.ToString());
}
}
while (!this.CancellationPending && (StartOptions.Options == BACKGROUNDUPDATERSTARTOPTIONS.RUNPERIODICALLY));
if (this.CancellationPending)
this.ReportProgress(0, "Cancelled.");
else
this.ReportProgress(0, "Finished.");
}
}
}