Viewer to Server
This commit is contained in:
30
Server/Controllers/ErrorHandlerController.cs
Normal file
30
Server/Controllers/ErrorHandlerController.cs
Normal file
@ -0,0 +1,30 @@
|
||||
using Microsoft.AspNetCore.Diagnostics;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace OI.Metrology.Server.Controllers;
|
||||
|
||||
[Route("/error")]
|
||||
public class ErrorHandlerController : Controller
|
||||
{
|
||||
private readonly ILogger _Logger;
|
||||
|
||||
public ErrorHandlerController(ILogger<ErrorHandlerController> logger) => _Logger = logger;
|
||||
|
||||
public IActionResult Index()
|
||||
{
|
||||
IExceptionHandlerFeature? error = HttpContext.Features.Get<IExceptionHandlerFeature>();
|
||||
if (error is null)
|
||||
{
|
||||
return Redirect("~/");
|
||||
}
|
||||
else
|
||||
{
|
||||
_Logger.LogError("Unhandled exception: " + error.Error.ToString());
|
||||
dynamic r = new
|
||||
{
|
||||
Message = error.Error is null ? "Error" : error.Error.Message
|
||||
};
|
||||
return StatusCode(StatusCodes.Status500InternalServerError, r);
|
||||
}
|
||||
}
|
||||
}
|
160
Server/Controllers/ExportController.cs
Normal file
160
Server/Controllers/ExportController.cs
Normal file
@ -0,0 +1,160 @@
|
||||
using Infineon.Monitoring.MonA;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
using OI.Metrology.Server.Models;
|
||||
using OI.Metrology.Shared.DataModels;
|
||||
using OI.Metrology.Shared.Models.Stateless;
|
||||
using OI.Metrology.Shared.ViewModels;
|
||||
using System.Text;
|
||||
|
||||
namespace OI.Metrology.Server.Controllers;
|
||||
|
||||
public class ExportController : Controller
|
||||
{
|
||||
|
||||
private readonly string _ApiUrl;
|
||||
private readonly ILogger _Logger;
|
||||
private readonly bool _IsTestDatabase;
|
||||
private readonly AppSettings _AppSettings;
|
||||
private readonly IMetrologyRepository _MetrologyRepository;
|
||||
|
||||
public ExportController(AppSettings appSettings, ILogger<ExportController> logger, IMetrologyRepository metrologyRepository)
|
||||
{
|
||||
_Logger = logger;
|
||||
_AppSettings = appSettings;
|
||||
_MetrologyRepository = metrologyRepository;
|
||||
_IsTestDatabase = appSettings.ConnectionString.Contains("test", StringComparison.InvariantCultureIgnoreCase);
|
||||
_ApiUrl = string.IsNullOrEmpty(appSettings.ApiUrl) ? Url.Content("~/") : appSettings.ApiUrl[0] == '~' ? Url.Content(appSettings.ApiUrl) : appSettings.ApiUrl;
|
||||
}
|
||||
|
||||
public override void OnActionExecuted(ActionExecutedContext context)
|
||||
{
|
||||
base.OnActionExecuted(context);
|
||||
ViewBag.IsTestDatabase = _IsTestDatabase;
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
[Route("/Export")]
|
||||
public ActionResult Index()
|
||||
{
|
||||
Export model = new()
|
||||
{
|
||||
StartTime = DateTime.Now.AddMonths(-1),
|
||||
EndTime = DateTime.Now
|
||||
};
|
||||
MonIn monIn = MonIn.GetInstance();
|
||||
_ = monIn.SendStatus(_AppSettings.MonASite, _AppSettings.MonAResource, "Heartbeat", State.Up);
|
||||
ViewBag.ApiUrl = _ApiUrl;
|
||||
return View(model);
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[Route("/ExportData")]
|
||||
public ActionResult ExportData(Export model)
|
||||
{
|
||||
ToolType? toolType = null;
|
||||
if (string.IsNullOrEmpty(model.ToolType))
|
||||
ModelState.AddModelError("Exception", "Invalid selection");
|
||||
else
|
||||
{
|
||||
if (model.StartTime > model.EndTime)
|
||||
ModelState.AddModelError("EndTime", "End time must be after start time");
|
||||
IEnumerable<ToolType> toolTypes = _MetrologyRepository.GetToolTypes();
|
||||
toolType = toolTypes.Where(tt => tt.ID.ToString() == model.ToolType).SingleOrDefault();
|
||||
if (toolType is null)
|
||||
ModelState.AddModelError("ToolType", "Invalid selection");
|
||||
else if (string.IsNullOrWhiteSpace(toolType.ExportSPName))
|
||||
ModelState.AddModelError("ToolType", "Tool type is not exportable");
|
||||
}
|
||||
if (ModelState.IsValid)
|
||||
{
|
||||
try
|
||||
{
|
||||
DateTime startDT = model.StartDate.Date.Add(model.StartTime.TimeOfDay);
|
||||
DateTime endDT = model.EndDate.Date.Add(model.EndTime.TimeOfDay);
|
||||
|
||||
return DoCSVExport(toolType?.ToolTypeName, toolType?.ExportSPName, startDT, endDT);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ModelState.AddModelError("Exception", "Error exporting data");
|
||||
ModelState.AddModelError("Exception", ex.Message);
|
||||
string errorMessage = $"Error exporting: {ex}";
|
||||
_Logger.LogError(message: errorMessage);
|
||||
MonIn monIn = MonIn.GetInstance();
|
||||
_ = monIn.SendStatus(_AppSettings.MonASite, _AppSettings.MonAResource, "Heartbeat", State.Warning);
|
||||
}
|
||||
}
|
||||
ViewBag.ApiUrl = _ApiUrl;
|
||||
return View("Index", model);
|
||||
}
|
||||
|
||||
protected ActionResult DoCSVExport(string? toolTypeName, string? spName, DateTime startTime, DateTime endTime)
|
||||
{
|
||||
string fileName = string.Format("Export_{0}_{1:yyyyMMddHHmm}_to_{2:yyyyMMddHHmm}.csv", toolTypeName, startTime, endTime);
|
||||
StringBuilder sb = new();
|
||||
if (spName is null)
|
||||
throw new NullReferenceException(nameof(spName));
|
||||
System.Data.DataTable dt = _MetrologyRepository.ExportData(spName, startTime, endTime);
|
||||
_ = sb.AppendLine(GetColumnHeaders(dt));
|
||||
foreach (System.Data.DataRow dr in dt.Rows)
|
||||
_ = sb.AppendLine(GetRowData(dr));
|
||||
byte[] contents = Encoding.UTF8.GetBytes(sb.ToString());
|
||||
return File(contents, "application/octet-stream", fileName);
|
||||
}
|
||||
|
||||
protected static string GetRowData(System.Data.DataRow dr)
|
||||
{
|
||||
StringBuilder r = new();
|
||||
for (int i = 0; i < dr.Table.Columns.Count; i++)
|
||||
{
|
||||
if (i > 0)
|
||||
_ = r.Append(',');
|
||||
object v = dr[i];
|
||||
if (!Convert.IsDBNull(v))
|
||||
{
|
||||
string? c = Convert.ToString(v);
|
||||
if (c is not null)
|
||||
_ = r.Append(FormatForCSV(c));
|
||||
}
|
||||
}
|
||||
return r.ToString();
|
||||
}
|
||||
|
||||
protected static string GetColumnHeaders(System.Data.DataTable dt)
|
||||
{
|
||||
StringBuilder r = new();
|
||||
for (int i = 0; i < dt.Columns.Count; i++)
|
||||
{
|
||||
if (i > 0)
|
||||
_ = r.Append(',');
|
||||
|
||||
_ = r.Append(FormatForCSV(dt.Columns[i].ColumnName.TrimEnd('_')));
|
||||
}
|
||||
return r.ToString();
|
||||
}
|
||||
|
||||
protected static string FormatForCSV(string v)
|
||||
{
|
||||
bool doubleQuoted = false;
|
||||
StringBuilder r = new(v.Length + 2);
|
||||
if (v.StartsWith(' ') || v.EndsWith(' ') || v.Contains(',') || v.Contains('"'))
|
||||
{
|
||||
_ = r.Append('"');
|
||||
doubleQuoted = true;
|
||||
}
|
||||
foreach (char c in v)
|
||||
{
|
||||
_ = c switch
|
||||
{
|
||||
'\r' or '\n' => r.Append(' '),
|
||||
'"' => r.Append("\"\""),
|
||||
_ => r.Append(c),
|
||||
};
|
||||
}
|
||||
if (doubleQuoted)
|
||||
_ = r.Append('"');
|
||||
return r.ToString();
|
||||
}
|
||||
|
||||
}
|
77
Server/Controllers/PagesController.cs
Normal file
77
Server/Controllers/PagesController.cs
Normal file
@ -0,0 +1,77 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
using OI.Metrology.Server.Models;
|
||||
using OI.Metrology.Shared.Models.Stateless;
|
||||
using OI.Metrology.Shared.ViewModels;
|
||||
|
||||
namespace OI.Metrology.Server.Controllers;
|
||||
|
||||
public class PagesController : Controller
|
||||
{
|
||||
|
||||
private readonly string _ApiUrl;
|
||||
private readonly bool _IsTestDatabase;
|
||||
private readonly IMetrologyRepository _MetrologyRepository;
|
||||
|
||||
public PagesController(AppSettings appSettings, IMetrologyRepository metrologyRepository)
|
||||
{
|
||||
_MetrologyRepository = metrologyRepository;
|
||||
_IsTestDatabase = appSettings.ConnectionString.Contains("test", StringComparison.InvariantCultureIgnoreCase);
|
||||
_ApiUrl = string.IsNullOrEmpty(appSettings.ApiUrl) ? Url.Content("~/") : appSettings.ApiUrl[0] == '~' ? Url.Content(appSettings.ApiUrl) : appSettings.ApiUrl;
|
||||
}
|
||||
|
||||
public override void OnActionExecuted(ActionExecutedContext context)
|
||||
{
|
||||
base.OnActionExecuted(context);
|
||||
ViewBag.IsTestDatabase = _IsTestDatabase;
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
[Route("/")]
|
||||
public IActionResult Index()
|
||||
{
|
||||
ViewBag.ApiUrl = _ApiUrl;
|
||||
return View("AwaitingDispo");
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
[Route("/AwaitingDispo")]
|
||||
[Route("/Metrology/AwaitingDispo")]
|
||||
public IActionResult AwaitingDispo()
|
||||
{
|
||||
ViewBag.ApiUrl = _ApiUrl;
|
||||
return View();
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
[Route("/RunInfo")]
|
||||
[Route("/Metrology/RunInfo")]
|
||||
public IActionResult RunInfo([FromQuery] int tooltypeid = 1, [FromQuery] int headerid = 0)
|
||||
{
|
||||
RunInfo m = new()
|
||||
{
|
||||
ToolTypeID = tooltypeid,
|
||||
HeaderID = headerid,
|
||||
HeaderAttachmentID = Guid.Empty,
|
||||
};
|
||||
if (headerid > 0)
|
||||
{
|
||||
m.HeaderAttachmentID = _MetrologyRepository.GetHeaderAttachmentID(tooltypeid, headerid);
|
||||
}
|
||||
ViewBag.ApiUrl = _ApiUrl;
|
||||
return View(m);
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
[Route("/RunHeaders")]
|
||||
[Route("/Metrology/RunHeaders")]
|
||||
public IActionResult RunHeaders()
|
||||
{
|
||||
ViewBag.ApiUrl = _ApiUrl;
|
||||
return View();
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
[Route("/Crash")]
|
||||
public IActionResult Crash() => throw new Exception("Test unhandled exception");
|
||||
}
|
Reference in New Issue
Block a user