aspnetcore/tools/ProjectKClone/MyService.cs

130 lines
4.8 KiB
C#

using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.ServiceProcess;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.VisualBasic.Logging;
using NuGet;
namespace NuGetClone
{
public class MyService : ServiceBase
{
private static readonly Uri DeveloperFeed = new Uri("https://www.myget.org/F/aspnetvnext/api/v2");
private static readonly ICredentials _credentials = new NetworkCredential("aspnetreadonly", "4d8a2d9c-7b80-4162-9978-47e918c9658c");
private Timer _timer;
private string _targetDirectory;
protected override void OnStart(string[] args)
{
base.OnStart(args);
Init();
_timer = new Timer(Run, null, TimeSpan.FromSeconds(1), TimeSpan.FromMinutes(2));
}
public void Init()
{
_targetDirectory = Environment.GetEnvironmentVariable("PROJECTK_PACKAGE_CACHE");
if (string.IsNullOrEmpty(_targetDirectory))
{
_targetDirectory = @"c:\projectk-cache";
}
var fileTraceListener = new FileLogTraceListener
{
AutoFlush = true,
Location = LogFileLocation.Custom,
CustomLocation = _targetDirectory,
BaseFileName = "ProjectKClone",
TraceOutputOptions = TraceOptions.DateTime,
LogFileCreationSchedule = LogFileCreationScheduleOption.Weekly
};
Trace.Listeners.Add(fileTraceListener);
}
public void Run(object state)
{
try
{
RunFromGallery();
}
catch (Exception ex)
{
Trace.WriteLine(String.Format("{0}: ERROR {1}", DateTime.Now, ex));
}
}
public void RunFromGallery()
{
Directory.CreateDirectory(_targetDirectory);
var client = new HttpClient(DeveloperFeed);
client.SendingRequest += (sender, e) =>
{
e.Request.Credentials = _credentials;
e.Request.PreAuthenticate = true;
};
var remoteRepo = new DataServicePackageRepository(client);
var targetRepo = new LocalPackageRepository(_targetDirectory);
var packages = remoteRepo.GetPackages()
.Where(p => p.IsAbsoluteLatestVersion)
.ToList();
Parallel.ForEach(packages,
new ParallelOptions { MaxDegreeOfParallelism = 4 },
package =>
{
// Some packages are updated without revving the version. We'll only opt not to re-download
// a package if an identical version does not exist on disk.
var existingPackage = targetRepo.FindPackage(package.Id, package.Version);
var dataServicePackage = (DataServicePackage)package;
if (existingPackage == null ||
!existingPackage.GetHash(dataServicePackage.PackageHashAlgorithm).Equals(dataServicePackage.PackageHash, StringComparison.Ordinal))
{
Trace.WriteLine(string.Format("{0}: Adding package {1}", DateTime.Now, package.GetFullName()));
var packagePath = GetPackagePath(package);
using (var input = package.GetStream())
using (var output = File.Create(packagePath))
{
input.CopyTo(output);
}
PurgeOldVersions(targetRepo, package);
}
});
}
private string GetPackagePath(IPackage package)
{
return Path.Combine(_targetDirectory, package.Id + "." + package.Version + ".nupkg");
}
private void PurgeOldVersions(LocalPackageRepository targetRepo, IPackage package)
{
foreach (var oldPackage in targetRepo.FindPackagesById(package.Id).Where(p => p.Version < package.Version))
{
try
{
var path = GetPackagePath(oldPackage);
Trace.WriteLine(string.Format("Deleting package {0}", oldPackage.GetFullName()));
File.Delete(path);
}
catch
{
// Ignore
}
}
}
protected override void OnStop()
{
base.OnStop();
}
}
}