2020-05-13 21:52:34 +00:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Net;
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
using Microsoft.AspNetCore.Mvc;
|
|
|
|
|
using Microsoft.Extensions.Logging;
|
|
|
|
|
using Nettle;
|
|
|
|
|
using Wabbajack.Common;
|
2020-06-03 21:04:18 +00:00
|
|
|
|
using Wabbajack.Common.Serialization.Json;
|
2020-07-16 12:28:05 +00:00
|
|
|
|
using Wabbajack.Lib;
|
2020-05-13 21:52:34 +00:00
|
|
|
|
using Wabbajack.Lib.ModListRegistry;
|
2020-07-07 12:29:05 +00:00
|
|
|
|
using Wabbajack.Server;
|
2020-05-13 21:52:34 +00:00
|
|
|
|
using Wabbajack.Server.DataLayer;
|
|
|
|
|
using Wabbajack.Server.DTOs;
|
|
|
|
|
using Wabbajack.Server.Services;
|
|
|
|
|
|
|
|
|
|
namespace Wabbajack.BuildServer.Controllers
|
|
|
|
|
{
|
|
|
|
|
[ApiController]
|
|
|
|
|
[Route("/lists")]
|
|
|
|
|
public class ListsStatus : ControllerBase
|
|
|
|
|
{
|
|
|
|
|
private ILogger<ListsStatus> _logger;
|
|
|
|
|
private ListValidator _validator;
|
|
|
|
|
|
|
|
|
|
public ListsStatus(ILogger<ListsStatus> logger, ListValidator validator)
|
|
|
|
|
{
|
|
|
|
|
_logger = logger;
|
|
|
|
|
_validator = validator;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[HttpGet]
|
|
|
|
|
[Route("status.json")]
|
|
|
|
|
public async Task<IEnumerable<ModListSummary>> HandleGetLists()
|
|
|
|
|
{
|
|
|
|
|
return (_validator.Summaries).Select(d => d.Summary);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private static readonly Func<object, string> HandleGetRssFeedTemplate = NettleEngine.GetCompiler().Compile(@"
|
|
|
|
|
<?xml version=""1.0""?>
|
|
|
|
|
<rss version=""2.0"">
|
|
|
|
|
<channel>
|
|
|
|
|
<title>{{lst.Name}} - Broken Mods</title>
|
|
|
|
|
<link>http://build.wabbajack.org/status/{{lst.Name}}.html</link>
|
|
|
|
|
<description>These are mods that are broken and need updating</description>
|
|
|
|
|
{{ each $.failed }}
|
|
|
|
|
<item>
|
|
|
|
|
<title>{{$.Archive.Name}} {{$.Archive.Hash}} {{$.Archive.State.PrimaryKeyString}}</title>
|
|
|
|
|
<link>{{$.Archive.Name}}</link>
|
|
|
|
|
</item>
|
|
|
|
|
{{/each}}
|
|
|
|
|
</channel>
|
|
|
|
|
</rss>
|
|
|
|
|
");
|
|
|
|
|
|
|
|
|
|
[HttpGet]
|
|
|
|
|
[Route("status/{Name}/broken.rss")]
|
|
|
|
|
public async Task<ContentResult> HandleGetRSSFeed(string Name)
|
|
|
|
|
{
|
|
|
|
|
var lst = await DetailedStatus(Name);
|
|
|
|
|
var response = HandleGetRssFeedTemplate(new
|
|
|
|
|
{
|
|
|
|
|
lst,
|
|
|
|
|
failed = lst.Archives.Where(a => a.IsFailing).ToList(),
|
|
|
|
|
passed = lst.Archives.Where(a => !a.IsFailing).ToList()
|
|
|
|
|
});
|
|
|
|
|
return new ContentResult
|
|
|
|
|
{
|
|
|
|
|
ContentType = "application/rss+xml",
|
|
|
|
|
StatusCode = (int) HttpStatusCode.OK,
|
|
|
|
|
Content = response
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static readonly Func<object, string> HandleGetListTemplate = NettleEngine.GetCompiler().Compile(@"
|
|
|
|
|
<html><body>
|
|
|
|
|
<h2>{{lst.Name}} - {{lst.Checked}} - {{ago}}min ago</h2>
|
2020-07-16 12:28:05 +00:00
|
|
|
|
|
2020-05-13 21:52:34 +00:00
|
|
|
|
<h3>Failed ({{failed.Count}}):</h3>
|
|
|
|
|
<ul>
|
|
|
|
|
{{each $.failed }}
|
2020-07-16 12:28:05 +00:00
|
|
|
|
{{if $.HasUrl}}
|
2020-07-16 21:17:37 +00:00
|
|
|
|
<li><a href='{{$.Url}}'>{{$.Name}}</a></li>
|
2020-07-16 12:28:05 +00:00
|
|
|
|
{{else}}
|
|
|
|
|
<li>{{$.Name}}</li>
|
|
|
|
|
{{/if}}
|
2020-05-13 21:52:34 +00:00
|
|
|
|
{{/each}}
|
|
|
|
|
</ul>
|
2020-07-16 12:28:05 +00:00
|
|
|
|
|
|
|
|
|
|
2020-06-14 13:13:29 +00:00
|
|
|
|
<h3>Updated ({{updated.Count}}):</h3>
|
|
|
|
|
<ul>
|
|
|
|
|
{{each $.updated }}
|
2020-07-16 12:28:05 +00:00
|
|
|
|
{{if $.HasUrl}}
|
2020-07-16 21:17:37 +00:00
|
|
|
|
<li><a href='{{$.Url}}'>{{$.Name}}</a></li>
|
2020-07-16 12:28:05 +00:00
|
|
|
|
{{else}}
|
|
|
|
|
<li>{{$.Name}}</li>
|
|
|
|
|
{{/if}}
|
|
|
|
|
|
2020-06-14 13:13:29 +00:00
|
|
|
|
{{/each}}
|
|
|
|
|
</ul>
|
2020-07-16 12:28:05 +00:00
|
|
|
|
|
2020-08-08 20:20:15 +00:00
|
|
|
|
<h3>Mirrored ({{mirrored.Count}}):</h3>
|
|
|
|
|
<ul>
|
|
|
|
|
{{each $.mirrored }}
|
|
|
|
|
{{if $.HasUrl}}
|
|
|
|
|
<li><a href='{{$.Url}}'>{{$.Name}}</a></li>
|
|
|
|
|
{{else}}
|
|
|
|
|
<li>{{$.Name}}</li>
|
|
|
|
|
{{/if}}
|
|
|
|
|
|
|
|
|
|
{{/each}}
|
|
|
|
|
</ul>
|
|
|
|
|
|
2020-06-14 13:13:29 +00:00
|
|
|
|
<h3>Updating ({{updating.Count}}):</h3>
|
|
|
|
|
<ul>
|
|
|
|
|
{{each $.updating }}
|
2020-07-16 12:28:05 +00:00
|
|
|
|
{{if $.HasUrl}}
|
2020-07-16 21:17:37 +00:00
|
|
|
|
<li><a href='{{$.Url}}'>{{$.Name}}</a></li>
|
2020-07-16 12:28:05 +00:00
|
|
|
|
{{else}}
|
|
|
|
|
<li>{{$.Name}}</li>
|
|
|
|
|
{{/if}}
|
2020-06-14 13:13:29 +00:00
|
|
|
|
{{/each}}
|
|
|
|
|
</ul>
|
2020-07-16 12:28:05 +00:00
|
|
|
|
|
2020-05-13 21:52:34 +00:00
|
|
|
|
<h3>Passed ({{passed.Count}}):</h3>
|
|
|
|
|
<ul>
|
|
|
|
|
{{each $.passed }}
|
2020-07-16 12:28:05 +00:00
|
|
|
|
{{if $.HasUrl}}
|
2020-07-16 21:17:37 +00:00
|
|
|
|
<li><a href='{{$.Url}}'>{{$.Name}}</a></li>
|
2020-07-16 12:28:05 +00:00
|
|
|
|
{{else}}
|
|
|
|
|
<li>{{$.Name}}</li>
|
|
|
|
|
{{/if}}
|
2020-05-13 21:52:34 +00:00
|
|
|
|
{{/each}}
|
|
|
|
|
</ul>
|
|
|
|
|
</body></html>
|
|
|
|
|
");
|
|
|
|
|
|
|
|
|
|
[HttpGet]
|
|
|
|
|
[Route("status/{Name}.html")]
|
|
|
|
|
public async Task<ContentResult> HandleGetListHtml(string Name)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
var lst = await DetailedStatus(Name);
|
2020-07-16 12:28:05 +00:00
|
|
|
|
|
2020-05-13 21:52:34 +00:00
|
|
|
|
var response = HandleGetListTemplate(new
|
|
|
|
|
{
|
|
|
|
|
lst,
|
|
|
|
|
ago = (DateTime.UtcNow - lst.Checked).TotalMinutes,
|
|
|
|
|
failed = lst.Archives.Where(a => a.IsFailing).ToList(),
|
2020-06-14 13:13:29 +00:00
|
|
|
|
passed = lst.Archives.Where(a => !a.IsFailing).ToList(),
|
|
|
|
|
updated = lst.Archives.Where(a => a.ArchiveStatus == ArchiveStatus.Updated).ToList(),
|
|
|
|
|
updating = lst.Archives.Where(a => a.ArchiveStatus == ArchiveStatus.Updating).ToList(),
|
2020-08-08 20:20:15 +00:00
|
|
|
|
mirrored = lst.Archives.Where(a => a.ArchiveStatus == ArchiveStatus.Mirrored).ToList()
|
2020-05-13 21:52:34 +00:00
|
|
|
|
});
|
|
|
|
|
return new ContentResult
|
|
|
|
|
{
|
|
|
|
|
ContentType = "text/html",
|
|
|
|
|
StatusCode = (int) HttpStatusCode.OK,
|
|
|
|
|
Content = response
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[HttpGet]
|
|
|
|
|
[Route("status/{Name}.json")]
|
2020-08-26 04:03:43 +00:00
|
|
|
|
[ResponseCache(Duration = 60 * 5)]
|
2020-05-13 21:52:34 +00:00
|
|
|
|
public async Task<IActionResult> HandleGetListJson(string Name)
|
|
|
|
|
{
|
|
|
|
|
return Ok((await DetailedStatus(Name)).ToJson());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private async Task<DetailedStatus> DetailedStatus(string Name)
|
|
|
|
|
{
|
2020-07-16 12:28:05 +00:00
|
|
|
|
var results = _validator.Summaries
|
2020-05-13 21:52:34 +00:00
|
|
|
|
.Select(d => d.Detailed)
|
|
|
|
|
.FirstOrDefault(d => d.MachineName == Name);
|
2020-07-16 12:28:05 +00:00
|
|
|
|
results!.Archives.Do(itm =>
|
|
|
|
|
{
|
|
|
|
|
if (string.IsNullOrWhiteSpace(itm.Archive.Name))
|
|
|
|
|
itm.Archive.Name = itm.Archive.State.PrimaryKeyString;
|
|
|
|
|
});
|
2020-07-19 23:09:59 +00:00
|
|
|
|
results.Archives = results.Archives.OrderBy(a => a.Name).ToList();
|
2020-07-16 12:28:05 +00:00
|
|
|
|
return results;
|
2020-05-13 21:52:34 +00:00
|
|
|
|
}
|
|
|
|
|
|
2020-06-03 14:48:49 +00:00
|
|
|
|
[HttpGet]
|
|
|
|
|
[Route("status/badge.json")]
|
|
|
|
|
public async Task<IActionResult> HandleGitHubBadge()
|
|
|
|
|
{
|
|
|
|
|
//var failing = _validator.Summaries.Select(x => x.Summary.Failed).Aggregate((x, y) => x + y);
|
|
|
|
|
var succeeding = _validator.Summaries.Select(x => x.Summary.Passed).Aggregate((x, y) => x + y);
|
|
|
|
|
var total = _validator.Summaries.Count();
|
|
|
|
|
double ration = total / (double)succeeding * 100.0;
|
|
|
|
|
string color;
|
|
|
|
|
if (ration >= 95)
|
|
|
|
|
color = "brightgreen";
|
|
|
|
|
else if (ration >= 80)
|
|
|
|
|
color = "green";
|
|
|
|
|
else if (ration >= 50)
|
|
|
|
|
color = "yellowgreen";
|
|
|
|
|
else if (ration >= 20)
|
|
|
|
|
color = "orange";
|
|
|
|
|
else
|
|
|
|
|
color = "red";
|
|
|
|
|
|
2020-06-03 21:23:22 +00:00
|
|
|
|
Response.ContentType = "application/json";
|
|
|
|
|
return Ok(new Badge("Modlist Availability", $"{ration}%"){color = color});
|
2020-06-03 14:48:49 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[HttpGet]
|
|
|
|
|
[Route("status/{Name}/badge.json")]
|
|
|
|
|
public async Task<IActionResult> HandleNamedGitHubBadge(string Name)
|
|
|
|
|
{
|
|
|
|
|
var info = _validator.Summaries.Select(x => x.Summary)
|
|
|
|
|
.FirstOrDefault(x => x.MachineURL == Name);
|
|
|
|
|
|
|
|
|
|
if (info == null)
|
|
|
|
|
return new NotFoundObjectResult("Not Found!");
|
|
|
|
|
|
|
|
|
|
var failing = info.HasFailures;
|
|
|
|
|
|
2020-06-03 21:23:22 +00:00
|
|
|
|
Response.ContentType = "application/json";
|
|
|
|
|
return Ok(new Badge(info.Name, failing ? "Failing" : "Succeeding"){color = failing ? "red" : "green"});
|
2020-06-03 14:48:49 +00:00
|
|
|
|
}
|
2020-05-13 21:52:34 +00:00
|
|
|
|
}
|
|
|
|
|
}
|