Compare commits
28 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
79633dbe1d | ||
|
|
f325306e20 | ||
|
|
4778656063 | ||
|
|
f7e00523c2 | ||
|
|
bf3df7230b | ||
|
|
c5182e0ed6 | ||
|
|
4081438cba | ||
|
|
b72fe2bf37 | ||
|
|
4d9c687709 | ||
|
|
792f295c45 | ||
|
|
af28753558 | ||
|
|
24fb663599 | ||
|
|
140506c9c3 | ||
|
|
519f159c8c | ||
|
|
bb019cbcd9 | ||
|
|
84219627ff | ||
|
|
f218e878c6 | ||
|
|
520f47955b | ||
|
|
8110ee18f1 | ||
|
|
55bf817310 | ||
|
|
f2f55f8118 | ||
|
|
f48e7cd0d4 | ||
|
|
c82e0c8b9b | ||
|
|
c72877e16b | ||
|
|
ccc9076397 | ||
|
|
1c716ecf4a | ||
|
|
2cc471b944 | ||
|
|
a6c450109a |
11
.gitignore
vendored
11
.gitignore
vendored
@@ -1,15 +1,6 @@
|
||||
.vs/
|
||||
bin/
|
||||
obj/
|
||||
wwwroot/images/
|
||||
cartracker.db
|
||||
data/cartracker.db
|
||||
wwwroot/documents/
|
||||
wwwroot/temp/
|
||||
wwwroot/imports/
|
||||
wwwroot/translations/
|
||||
config/userConfig.json
|
||||
data/
|
||||
CarCareTracker.csproj.user
|
||||
Properties/launchSettings.json
|
||||
data/cartracker-log.db
|
||||
data/widgets.html
|
||||
|
||||
@@ -34,6 +34,7 @@ namespace CarCareTracker.Controllers
|
||||
private readonly IFileHelper _fileHelper;
|
||||
private readonly IMailHelper _mailHelper;
|
||||
private readonly IConfigHelper _config;
|
||||
private readonly IWebHostEnvironment _webEnv;
|
||||
public APIController(IVehicleDataAccess dataAccess,
|
||||
IGasHelper gasHelper,
|
||||
IReminderHelper reminderHelper,
|
||||
@@ -55,7 +56,8 @@ namespace CarCareTracker.Controllers
|
||||
IConfigHelper config,
|
||||
IUserLogic userLogic,
|
||||
IVehicleLogic vehicleLogic,
|
||||
IOdometerLogic odometerLogic)
|
||||
IOdometerLogic odometerLogic,
|
||||
IWebHostEnvironment webEnv)
|
||||
{
|
||||
_dataAccess = dataAccess;
|
||||
_noteDataAccess = noteDataAccess;
|
||||
@@ -79,6 +81,7 @@ namespace CarCareTracker.Controllers
|
||||
_vehicleLogic = vehicleLogic;
|
||||
_fileHelper = fileHelper;
|
||||
_config = config;
|
||||
_webEnv = webEnv;
|
||||
}
|
||||
public IActionResult Index()
|
||||
{
|
||||
@@ -163,7 +166,7 @@ namespace CarCareTracker.Controllers
|
||||
return Json(response);
|
||||
}
|
||||
var vehicleRecords = _serviceRecordDataAccess.GetServiceRecordsByVehicleId(vehicleId);
|
||||
var result = vehicleRecords.Select(x => new GenericRecordExportModel { Id = x.Id.ToString(), Date = x.Date.ToShortDateString(), Description = x.Description, Cost = x.Cost.ToString(), Notes = x.Notes, Odometer = x.Mileage.ToString(), ExtraFields = x.ExtraFields, Tags = string.Join(' ', x.Tags) });
|
||||
var result = vehicleRecords.Select(x => new GenericRecordExportModel { Id = x.Id.ToString(), Date = x.Date.ToShortDateString(), Description = x.Description, Cost = x.Cost.ToString(), Notes = x.Notes, Odometer = x.Mileage.ToString(), ExtraFields = x.ExtraFields, Files = x.Files, Tags = string.Join(' ', x.Tags) });
|
||||
if (_config.GetInvariantApi() || Request.Headers.ContainsKey("culture-invariant"))
|
||||
{
|
||||
return Json(result, StaticHelper.GetInvariantOption());
|
||||
@@ -206,6 +209,7 @@ namespace CarCareTracker.Controllers
|
||||
Notes = string.IsNullOrWhiteSpace(input.Notes) ? "" : input.Notes,
|
||||
Cost = decimal.Parse(input.Cost),
|
||||
ExtraFields = input.ExtraFields,
|
||||
Files = input.Files,
|
||||
Tags = string.IsNullOrWhiteSpace(input.Tags) ? new List<string>() : input.Tags.Split(' ').Distinct().ToList()
|
||||
};
|
||||
_serviceRecordDataAccess.SaveServiceRecordToVehicle(serviceRecord);
|
||||
@@ -291,6 +295,7 @@ namespace CarCareTracker.Controllers
|
||||
existingRecord.Description = input.Description;
|
||||
existingRecord.Notes = string.IsNullOrWhiteSpace(input.Notes) ? "" : input.Notes;
|
||||
existingRecord.Cost = decimal.Parse(input.Cost);
|
||||
existingRecord.Files = input.Files;
|
||||
existingRecord.ExtraFields = input.ExtraFields;
|
||||
existingRecord.Tags = string.IsNullOrWhiteSpace(input.Tags) ? new List<string>() : input.Tags.Split(' ').Distinct().ToList();
|
||||
_serviceRecordDataAccess.SaveServiceRecordToVehicle(existingRecord);
|
||||
@@ -322,7 +327,7 @@ namespace CarCareTracker.Controllers
|
||||
return Json(response);
|
||||
}
|
||||
var vehicleRecords = _collisionRecordDataAccess.GetCollisionRecordsByVehicleId(vehicleId);
|
||||
var result = vehicleRecords.Select(x => new GenericRecordExportModel { Id = x.Id.ToString(), Date = x.Date.ToShortDateString(), Description = x.Description, Cost = x.Cost.ToString(), Notes = x.Notes, Odometer = x.Mileage.ToString(), ExtraFields = x.ExtraFields, Tags = string.Join(' ', x.Tags) });
|
||||
var result = vehicleRecords.Select(x => new GenericRecordExportModel { Id = x.Id.ToString(), Date = x.Date.ToShortDateString(), Description = x.Description, Cost = x.Cost.ToString(), Notes = x.Notes, Odometer = x.Mileage.ToString(), ExtraFields = x.ExtraFields, Files = x.Files, Tags = string.Join(' ', x.Tags) });
|
||||
if (_config.GetInvariantApi() || Request.Headers.ContainsKey("culture-invariant"))
|
||||
{
|
||||
return Json(result, StaticHelper.GetInvariantOption());
|
||||
@@ -366,6 +371,7 @@ namespace CarCareTracker.Controllers
|
||||
Notes = string.IsNullOrWhiteSpace(input.Notes) ? "" : input.Notes,
|
||||
Cost = decimal.Parse(input.Cost),
|
||||
ExtraFields = input.ExtraFields,
|
||||
Files = input.Files,
|
||||
Tags = string.IsNullOrWhiteSpace(input.Tags) ? new List<string>() : input.Tags.Split(' ').Distinct().ToList()
|
||||
};
|
||||
_collisionRecordDataAccess.SaveCollisionRecordToVehicle(repairRecord);
|
||||
@@ -453,6 +459,7 @@ namespace CarCareTracker.Controllers
|
||||
existingRecord.Notes = string.IsNullOrWhiteSpace(input.Notes) ? "" : input.Notes;
|
||||
existingRecord.Cost = decimal.Parse(input.Cost);
|
||||
existingRecord.ExtraFields = input.ExtraFields;
|
||||
existingRecord.Files = input.Files;
|
||||
existingRecord.Tags = string.IsNullOrWhiteSpace(input.Tags) ? new List<string>() : input.Tags.Split(' ').Distinct().ToList();
|
||||
_collisionRecordDataAccess.SaveCollisionRecordToVehicle(existingRecord);
|
||||
StaticHelper.NotifyAsync(_config.GetWebHookUrl(), WebHookPayload.FromGenericRecord(existingRecord, "repairrecord.update.api", User.Identity.Name));
|
||||
@@ -484,7 +491,7 @@ namespace CarCareTracker.Controllers
|
||||
return Json(response);
|
||||
}
|
||||
var vehicleRecords = _upgradeRecordDataAccess.GetUpgradeRecordsByVehicleId(vehicleId);
|
||||
var result = vehicleRecords.Select(x => new GenericRecordExportModel { Id = x.Id.ToString(), Date = x.Date.ToShortDateString(), Description = x.Description, Cost = x.Cost.ToString(), Notes = x.Notes, Odometer = x.Mileage.ToString(), ExtraFields = x.ExtraFields, Tags = string.Join(' ', x.Tags) });
|
||||
var result = vehicleRecords.Select(x => new GenericRecordExportModel { Id = x.Id.ToString(), Date = x.Date.ToShortDateString(), Description = x.Description, Cost = x.Cost.ToString(), Notes = x.Notes, Odometer = x.Mileage.ToString(), ExtraFields = x.ExtraFields, Files = x.Files, Tags = string.Join(' ', x.Tags) });
|
||||
if (_config.GetInvariantApi() || Request.Headers.ContainsKey("culture-invariant"))
|
||||
{
|
||||
return Json(result, StaticHelper.GetInvariantOption());
|
||||
@@ -528,6 +535,7 @@ namespace CarCareTracker.Controllers
|
||||
Notes = string.IsNullOrWhiteSpace(input.Notes) ? "" : input.Notes,
|
||||
Cost = decimal.Parse(input.Cost),
|
||||
ExtraFields = input.ExtraFields,
|
||||
Files = input.Files,
|
||||
Tags = string.IsNullOrWhiteSpace(input.Tags) ? new List<string>() : input.Tags.Split(' ').Distinct().ToList()
|
||||
};
|
||||
_upgradeRecordDataAccess.SaveUpgradeRecordToVehicle(upgradeRecord);
|
||||
@@ -614,6 +622,7 @@ namespace CarCareTracker.Controllers
|
||||
existingRecord.Notes = string.IsNullOrWhiteSpace(input.Notes) ? "" : input.Notes;
|
||||
existingRecord.Cost = decimal.Parse(input.Cost);
|
||||
existingRecord.ExtraFields = input.ExtraFields;
|
||||
existingRecord.Files = input.Files;
|
||||
existingRecord.Tags = string.IsNullOrWhiteSpace(input.Tags) ? new List<string>() : input.Tags.Split(' ').Distinct().ToList();
|
||||
_upgradeRecordDataAccess.SaveUpgradeRecordToVehicle(existingRecord);
|
||||
StaticHelper.NotifyAsync(_config.GetWebHookUrl(), WebHookPayload.FromGenericRecord(existingRecord, "upgraderecord.update.api", User.Identity.Name));
|
||||
@@ -644,7 +653,7 @@ namespace CarCareTracker.Controllers
|
||||
Response.StatusCode = 400;
|
||||
return Json(response);
|
||||
}
|
||||
var result = _taxRecordDataAccess.GetTaxRecordsByVehicleId(vehicleId).Select(x => new TaxRecordExportModel { Id = x.Id.ToString(), Date = x.Date.ToShortDateString(), Description = x.Description, Cost = x.Cost.ToString(), Notes = x.Notes, ExtraFields = x.ExtraFields, Tags = string.Join(' ', x.Tags) });
|
||||
var result = _taxRecordDataAccess.GetTaxRecordsByVehicleId(vehicleId).Select(x => new TaxRecordExportModel { Id = x.Id.ToString(), Date = x.Date.ToShortDateString(), Description = x.Description, Cost = x.Cost.ToString(), Notes = x.Notes, ExtraFields = x.ExtraFields, Files = x.Files, Tags = string.Join(' ', x.Tags) });
|
||||
if (_config.GetInvariantApi() || Request.Headers.ContainsKey("culture-invariant"))
|
||||
{
|
||||
return Json(result, StaticHelper.GetInvariantOption());
|
||||
@@ -721,6 +730,7 @@ namespace CarCareTracker.Controllers
|
||||
Notes = string.IsNullOrWhiteSpace(input.Notes) ? "" : input.Notes,
|
||||
Cost = decimal.Parse(input.Cost),
|
||||
ExtraFields = input.ExtraFields,
|
||||
Files = input.Files,
|
||||
Tags = string.IsNullOrWhiteSpace(input.Tags) ? new List<string>() : input.Tags.Split(' ').Distinct().ToList()
|
||||
};
|
||||
_taxRecordDataAccess.SaveTaxRecordToVehicle(taxRecord);
|
||||
@@ -790,6 +800,7 @@ namespace CarCareTracker.Controllers
|
||||
existingRecord.Notes = string.IsNullOrWhiteSpace(input.Notes) ? "" : input.Notes;
|
||||
existingRecord.Cost = decimal.Parse(input.Cost);
|
||||
existingRecord.ExtraFields = input.ExtraFields;
|
||||
existingRecord.Files = input.Files;
|
||||
existingRecord.Tags = string.IsNullOrWhiteSpace(input.Tags) ? new List<string>() : input.Tags.Split(' ').Distinct().ToList();
|
||||
_taxRecordDataAccess.SaveTaxRecordToVehicle(existingRecord);
|
||||
StaticHelper.NotifyAsync(_config.GetWebHookUrl(), WebHookPayload.FromTaxRecord(existingRecord, "taxrecord.update.api", User.Identity.Name));
|
||||
@@ -840,7 +851,7 @@ namespace CarCareTracker.Controllers
|
||||
{
|
||||
vehicleRecords = _odometerLogic.AutoConvertOdometerRecord(vehicleRecords);
|
||||
}
|
||||
var result = vehicleRecords.Select(x => new OdometerRecordExportModel { Id = x.Id.ToString(), Date = x.Date.ToShortDateString(), InitialOdometer = x.InitialMileage.ToString(), Odometer = x.Mileage.ToString(), Notes = x.Notes, ExtraFields = x.ExtraFields, Tags = string.Join(' ', x.Tags) });
|
||||
var result = vehicleRecords.Select(x => new OdometerRecordExportModel { Id = x.Id.ToString(), Date = x.Date.ToShortDateString(), InitialOdometer = x.InitialMileage.ToString(), Odometer = x.Mileage.ToString(), Notes = x.Notes, ExtraFields = x.ExtraFields, Files = x.Files, Tags = string.Join(' ', x.Tags) });
|
||||
if (_config.GetInvariantApi() || Request.Headers.ContainsKey("culture-invariant"))
|
||||
{
|
||||
return Json(result, StaticHelper.GetInvariantOption());
|
||||
@@ -881,6 +892,7 @@ namespace CarCareTracker.Controllers
|
||||
InitialMileage = (string.IsNullOrWhiteSpace(input.InitialOdometer) || int.Parse(input.InitialOdometer) == default) ? _odometerLogic.GetLastOdometerRecordMileage(vehicleId, new List<OdometerRecord>()) : int.Parse(input.InitialOdometer),
|
||||
Mileage = int.Parse(input.Odometer),
|
||||
ExtraFields = input.ExtraFields,
|
||||
Files = input.Files,
|
||||
Tags = string.IsNullOrWhiteSpace(input.Tags) ? new List<string>() : input.Tags.Split(' ').Distinct().ToList()
|
||||
};
|
||||
_odometerRecordDataAccess.SaveOdometerRecordToVehicle(odometerRecord);
|
||||
@@ -948,6 +960,7 @@ namespace CarCareTracker.Controllers
|
||||
existingRecord.InitialMileage = int.Parse(input.InitialOdometer);
|
||||
existingRecord.Notes = string.IsNullOrWhiteSpace(input.Notes) ? "" : input.Notes;
|
||||
existingRecord.ExtraFields = input.ExtraFields;
|
||||
existingRecord.Files = input.Files;
|
||||
existingRecord.Tags = string.IsNullOrWhiteSpace(input.Tags) ? new List<string>() : input.Tags.Split(' ').Distinct().ToList();
|
||||
_odometerRecordDataAccess.SaveOdometerRecordToVehicle(existingRecord);
|
||||
StaticHelper.NotifyAsync(_config.GetWebHookUrl(), WebHookPayload.FromOdometerRecord(existingRecord, "odometerrecord.update.api", User.Identity.Name));
|
||||
@@ -991,6 +1004,7 @@ namespace CarCareTracker.Controllers
|
||||
MissedFuelUp = x.MissedFuelUp.ToString(),
|
||||
Notes = x.Notes,
|
||||
ExtraFields = x.ExtraFields,
|
||||
Files = x.Files,
|
||||
Tags = string.Join(' ', x.Tags)
|
||||
});
|
||||
if (_config.GetInvariantApi() || Request.Headers.ContainsKey("culture-invariant"))
|
||||
@@ -1041,6 +1055,7 @@ namespace CarCareTracker.Controllers
|
||||
Notes = string.IsNullOrWhiteSpace(input.Notes) ? "" : input.Notes,
|
||||
Cost = decimal.Parse(input.Cost),
|
||||
ExtraFields = input.ExtraFields,
|
||||
Files = input.Files,
|
||||
Tags = string.IsNullOrWhiteSpace(input.Tags) ? new List<string>() : input.Tags.Split(' ').Distinct().ToList()
|
||||
};
|
||||
_gasRecordDataAccess.SaveGasRecordToVehicle(gasRecord);
|
||||
@@ -1085,7 +1100,7 @@ namespace CarCareTracker.Controllers
|
||||
{
|
||||
StaticHelper.NotifyAsync(_config.GetWebHookUrl(), WebHookPayload.FromGasRecord(existingRecord, "gasrecord.delete.api", User.Identity.Name));
|
||||
}
|
||||
return Json(OperationResponse.Conditional(result, "Odometer Record Deleted"));
|
||||
return Json(OperationResponse.Conditional(result, "Gas Record Deleted"));
|
||||
}
|
||||
[HttpPut]
|
||||
[Route("/api/vehicle/gasrecords/update")]
|
||||
@@ -1126,6 +1141,7 @@ namespace CarCareTracker.Controllers
|
||||
existingRecord.Notes = string.IsNullOrWhiteSpace(input.Notes) ? "" : input.Notes;
|
||||
existingRecord.Cost = decimal.Parse(input.Cost);
|
||||
existingRecord.ExtraFields = input.ExtraFields;
|
||||
existingRecord.Files = input.Files;
|
||||
existingRecord.Tags = string.IsNullOrWhiteSpace(input.Tags) ? new List<string>() : input.Tags.Split(' ').Distinct().ToList();
|
||||
_gasRecordDataAccess.SaveGasRecordToVehicle(existingRecord);
|
||||
StaticHelper.NotifyAsync(_config.GetWebHookUrl(), WebHookPayload.FromGasRecord(existingRecord, "gasrecord.update.api", User.Identity.Name));
|
||||
@@ -1166,6 +1182,51 @@ namespace CarCareTracker.Controllers
|
||||
return Json(results);
|
||||
}
|
||||
}
|
||||
[HttpGet]
|
||||
[Route("/api/calendar")]
|
||||
public IActionResult Calendar()
|
||||
{
|
||||
var vehiclesStored = _dataAccess.GetVehicles();
|
||||
if (!User.IsInRole(nameof(UserData.IsRootUser)))
|
||||
{
|
||||
vehiclesStored = _userLogic.FilterUserVehicles(vehiclesStored, GetUserID());
|
||||
}
|
||||
var reminders = _vehicleLogic.GetReminders(vehiclesStored, true);
|
||||
var calendarContent = StaticHelper.RemindersToCalendar(reminders);
|
||||
return File(calendarContent, "text/calendar");
|
||||
}
|
||||
[HttpPost]
|
||||
[Route("/api/documents/upload")]
|
||||
public IActionResult UploadDocument(List<IFormFile> documents)
|
||||
{
|
||||
if (documents.Any())
|
||||
{
|
||||
List<UploadedFiles> uploadedFiles = new List<UploadedFiles>();
|
||||
string uploadDirectory = "documents/";
|
||||
string uploadPath = Path.Combine(_webEnv.ContentRootPath, "data", uploadDirectory);
|
||||
if (!Directory.Exists(uploadPath))
|
||||
Directory.CreateDirectory(uploadPath);
|
||||
foreach (IFormFile document in documents)
|
||||
{
|
||||
string fileName = Guid.NewGuid() + Path.GetExtension(document.FileName);
|
||||
string filePath = Path.Combine(uploadPath, fileName);
|
||||
using (var stream = System.IO.File.Create(filePath))
|
||||
{
|
||||
document.CopyTo(stream);
|
||||
}
|
||||
uploadedFiles.Add(new UploadedFiles
|
||||
{
|
||||
Location = Path.Combine("/", uploadDirectory, fileName),
|
||||
Name = Path.GetFileName(document.FileName)
|
||||
});
|
||||
}
|
||||
return Json(uploadedFiles);
|
||||
} else
|
||||
{
|
||||
Response.StatusCode = 400;
|
||||
return Json(OperationResponse.Failed("No files to upload"));
|
||||
}
|
||||
}
|
||||
[Authorize(Roles = nameof(UserData.IsRootUser))]
|
||||
[HttpGet]
|
||||
[Route("/api/vehicle/reminders/send")]
|
||||
|
||||
@@ -81,7 +81,7 @@ namespace CarCareTracker.Controllers
|
||||
private string UploadFile(IFormFile fileToUpload)
|
||||
{
|
||||
string uploadDirectory = "temp/";
|
||||
string uploadPath = Path.Combine(_webEnv.WebRootPath, uploadDirectory);
|
||||
string uploadPath = Path.Combine(_webEnv.ContentRootPath, "data", uploadDirectory);
|
||||
if (!Directory.Exists(uploadPath))
|
||||
Directory.CreateDirectory(uploadPath);
|
||||
string fileName = Guid.NewGuid() + Path.GetExtension(fileToUpload.FileName);
|
||||
@@ -95,7 +95,7 @@ namespace CarCareTracker.Controllers
|
||||
public IActionResult UploadCoordinates(List<string> coordinates)
|
||||
{
|
||||
string uploadDirectory = "temp/";
|
||||
string uploadPath = Path.Combine(_webEnv.WebRootPath, uploadDirectory);
|
||||
string uploadPath = Path.Combine(_webEnv.ContentRootPath, "data", uploadDirectory);
|
||||
if (!Directory.Exists(uploadPath))
|
||||
Directory.CreateDirectory(uploadPath);
|
||||
string fileName = Guid.NewGuid() + ".csv";
|
||||
|
||||
@@ -25,7 +25,7 @@ namespace CarCareTracker.Controllers
|
||||
return Json(false);
|
||||
}
|
||||
string uploadDirectory = "temp/";
|
||||
string uploadPath = Path.Combine(_webEnv.WebRootPath, uploadDirectory);
|
||||
string uploadPath = Path.Combine(_webEnv.ContentRootPath, "data", uploadDirectory);
|
||||
if (!Directory.Exists(uploadPath))
|
||||
Directory.CreateDirectory(uploadPath);
|
||||
var fileNameToExport = $"temp/{Guid.NewGuid()}.csv";
|
||||
|
||||
@@ -34,7 +34,7 @@ namespace CarCareTracker.Helper
|
||||
}
|
||||
public List<string> GetLanguages()
|
||||
{
|
||||
var languagePath = Path.Combine(_webEnv.WebRootPath, "translations");
|
||||
var languagePath = Path.Combine(_webEnv.ContentRootPath, "data", "translations");
|
||||
var defaultList = new List<string>() { "en_US" };
|
||||
if (Directory.Exists(languagePath))
|
||||
{
|
||||
@@ -72,7 +72,7 @@ namespace CarCareTracker.Helper
|
||||
{
|
||||
currentFilePath = currentFilePath.Substring(1);
|
||||
}
|
||||
string oldFilePath = Path.Combine(_webEnv.WebRootPath, currentFilePath);
|
||||
string oldFilePath = currentFilePath.StartsWith("defaults/") ? Path.Combine(_webEnv.WebRootPath, currentFilePath) : Path.Combine(_webEnv.ContentRootPath, "data", currentFilePath);
|
||||
if (File.Exists(oldFilePath))
|
||||
{
|
||||
return oldFilePath;
|
||||
@@ -94,7 +94,7 @@ namespace CarCareTracker.Helper
|
||||
}
|
||||
try
|
||||
{
|
||||
var tempPath = Path.Combine(_webEnv.WebRootPath, $"temp/{Guid.NewGuid()}");
|
||||
var tempPath = Path.Combine(_webEnv.ContentRootPath, "data", $"temp/{Guid.NewGuid()}");
|
||||
if (!Directory.Exists(tempPath))
|
||||
Directory.CreateDirectory(tempPath);
|
||||
//extract zip file
|
||||
@@ -105,10 +105,10 @@ namespace CarCareTracker.Helper
|
||||
var translationPath = Path.Combine(tempPath, "translations");
|
||||
var dataPath = Path.Combine(tempPath, StaticHelper.DbName);
|
||||
var widgetPath = Path.Combine(tempPath, StaticHelper.AdditionalWidgetsPath);
|
||||
var configPath = Path.Combine(tempPath, StaticHelper.UserConfigPath);
|
||||
var configPath = Path.Combine(tempPath, StaticHelper.LegacyUserConfigPath);
|
||||
if (Directory.Exists(imagePath))
|
||||
{
|
||||
var existingPath = Path.Combine(_webEnv.WebRootPath, "images");
|
||||
var existingPath = Path.Combine(_webEnv.ContentRootPath, "data", "images");
|
||||
if (!Directory.Exists(existingPath))
|
||||
{
|
||||
Directory.CreateDirectory(existingPath);
|
||||
@@ -130,7 +130,7 @@ namespace CarCareTracker.Helper
|
||||
}
|
||||
if (Directory.Exists(documentPath))
|
||||
{
|
||||
var existingPath = Path.Combine(_webEnv.WebRootPath, "documents");
|
||||
var existingPath = Path.Combine(_webEnv.ContentRootPath, "data", "documents");
|
||||
if (!Directory.Exists(existingPath))
|
||||
{
|
||||
Directory.CreateDirectory(existingPath);
|
||||
@@ -152,7 +152,7 @@ namespace CarCareTracker.Helper
|
||||
}
|
||||
if (Directory.Exists(translationPath))
|
||||
{
|
||||
var existingPath = Path.Combine(_webEnv.WebRootPath, "translations");
|
||||
var existingPath = Path.Combine(_webEnv.ContentRootPath, "data", "translations");
|
||||
if (!Directory.Exists(existingPath))
|
||||
{
|
||||
Directory.CreateDirectory(existingPath);
|
||||
@@ -186,9 +186,9 @@ namespace CarCareTracker.Helper
|
||||
if (File.Exists(configPath))
|
||||
{
|
||||
//check if config folder exists.
|
||||
if (!Directory.Exists("config/"))
|
||||
if (!Directory.Exists("data/config"))
|
||||
{
|
||||
Directory.CreateDirectory("config/");
|
||||
Directory.CreateDirectory("data/config");
|
||||
}
|
||||
File.Move(configPath, StaticHelper.UserConfigPath, true);
|
||||
}
|
||||
@@ -203,7 +203,7 @@ namespace CarCareTracker.Helper
|
||||
public string MakeAttachmentsExport(List<GenericReportModel> exportData)
|
||||
{
|
||||
var folderName = Guid.NewGuid();
|
||||
var tempPath = Path.Combine(_webEnv.WebRootPath, $"temp/{folderName}");
|
||||
var tempPath = Path.Combine(_webEnv.ContentRootPath, "data", $"temp/{folderName}");
|
||||
if (!Directory.Exists(tempPath))
|
||||
Directory.CreateDirectory(tempPath);
|
||||
int fileIndex = 0;
|
||||
@@ -227,10 +227,10 @@ namespace CarCareTracker.Helper
|
||||
public string MakeBackup()
|
||||
{
|
||||
var folderName = $"db_backup_{DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss")}";
|
||||
var tempPath = Path.Combine(_webEnv.WebRootPath, $"temp/{folderName}");
|
||||
var imagePath = Path.Combine(_webEnv.WebRootPath, "images");
|
||||
var documentPath = Path.Combine(_webEnv.WebRootPath, "documents");
|
||||
var translationPath = Path.Combine(_webEnv.WebRootPath, "translations");
|
||||
var tempPath = Path.Combine(_webEnv.ContentRootPath, "data", $"temp/{folderName}");
|
||||
var imagePath = Path.Combine(_webEnv.ContentRootPath, "data", "images");
|
||||
var documentPath = Path.Combine(_webEnv.ContentRootPath, "data", "documents");
|
||||
var translationPath = Path.Combine(_webEnv.ContentRootPath, "data", "translations");
|
||||
var dataPath = StaticHelper.DbName;
|
||||
var widgetPath = StaticHelper.AdditionalWidgetsPath;
|
||||
var configPath = StaticHelper.UserConfigPath;
|
||||
@@ -301,8 +301,8 @@ namespace CarCareTracker.Helper
|
||||
{
|
||||
currentFilePath = currentFilePath.Substring(1);
|
||||
}
|
||||
string uploadPath = Path.Combine(_webEnv.WebRootPath, newFolder);
|
||||
string oldFilePath = Path.Combine(_webEnv.WebRootPath, currentFilePath);
|
||||
string uploadPath = Path.Combine(_webEnv.ContentRootPath, "data", newFolder);
|
||||
string oldFilePath = Path.Combine(_webEnv.ContentRootPath, "data", currentFilePath);
|
||||
if (!Directory.Exists(uploadPath))
|
||||
Directory.CreateDirectory(uploadPath);
|
||||
string newFileUploadPath = oldFilePath.Replace(tempPath, newFolder);
|
||||
@@ -319,7 +319,7 @@ namespace CarCareTracker.Helper
|
||||
{
|
||||
currentFilePath = currentFilePath.Substring(1);
|
||||
}
|
||||
string filePath = Path.Combine(_webEnv.WebRootPath, currentFilePath);
|
||||
string filePath = Path.Combine(_webEnv.ContentRootPath, "data", currentFilePath);
|
||||
if (File.Exists(filePath))
|
||||
{
|
||||
File.Delete(filePath);
|
||||
|
||||
@@ -76,7 +76,8 @@ namespace CarCareTracker.Helper
|
||||
MissedFuelUp = currentObject.MissedFuelUp,
|
||||
Notes = currentObject.Notes,
|
||||
Tags = currentObject.Tags,
|
||||
ExtraFields = currentObject.ExtraFields
|
||||
ExtraFields = currentObject.ExtraFields,
|
||||
Files = currentObject.Files
|
||||
};
|
||||
if (currentObject.MissedFuelUp)
|
||||
{
|
||||
@@ -86,9 +87,9 @@ namespace CarCareTracker.Helper
|
||||
unFactoredConsumption = 0;
|
||||
unFactoredMileage = 0;
|
||||
}
|
||||
else if (currentObject.IsFillToFull)
|
||||
else if (currentObject.IsFillToFull && currentObject.Mileage != default)
|
||||
{
|
||||
//if user filled to full.
|
||||
//if user filled to full and an odometer is provided, otherwise we will defer calculations
|
||||
if (convertedConsumption > 0.00M && deltaMileage > 0)
|
||||
{
|
||||
try
|
||||
@@ -130,10 +131,14 @@ namespace CarCareTracker.Helper
|
||||
MissedFuelUp = currentObject.MissedFuelUp,
|
||||
Notes = currentObject.Notes,
|
||||
Tags = currentObject.Tags,
|
||||
ExtraFields = currentObject.ExtraFields
|
||||
ExtraFields = currentObject.ExtraFields,
|
||||
Files = currentObject.Files
|
||||
});
|
||||
}
|
||||
previousMileage = currentObject.Mileage;
|
||||
if (currentObject.Mileage != default)
|
||||
{
|
||||
previousMileage = currentObject.Mileage;
|
||||
}
|
||||
}
|
||||
return computedResults;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
using CarCareTracker.Models;
|
||||
using CsvHelper;
|
||||
using System.Globalization;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace CarCareTracker.Helper
|
||||
@@ -10,9 +12,10 @@ namespace CarCareTracker.Helper
|
||||
/// </summary>
|
||||
public static class StaticHelper
|
||||
{
|
||||
public const string VersionNumber = "1.4.2";
|
||||
public const string VersionNumber = "1.4.3";
|
||||
public const string DbName = "data/cartracker.db";
|
||||
public const string UserConfigPath = "config/userConfig.json";
|
||||
public const string UserConfigPath = "data/config/userConfig.json";
|
||||
public const string LegacyUserConfigPath = "config/userConfig.json";
|
||||
public const string AdditionalWidgetsPath = "data/widgets.html";
|
||||
public const string GenericErrorMessage = "An error occurred, please try again later";
|
||||
public const string ReminderEmailTemplate = "defaults/reminderemailtemplate.txt";
|
||||
@@ -240,7 +243,8 @@ namespace CarCareTracker.Helper
|
||||
|
||||
public static List<ExtraField> AddExtraFields(List<ExtraField> recordExtraFields, List<ExtraField> templateExtraFields)
|
||||
{
|
||||
if (!templateExtraFields.Any()) {
|
||||
if (!templateExtraFields.Any())
|
||||
{
|
||||
return new List<ExtraField>();
|
||||
}
|
||||
if (!recordExtraFields.Any())
|
||||
@@ -261,7 +265,7 @@ namespace CarCareTracker.Helper
|
||||
extraField.IsRequired = templateExtraFields.Where(x => x.Name == extraField.Name).First().IsRequired;
|
||||
}
|
||||
//append extra fields
|
||||
foreach(ExtraField extraField in templateExtraFields)
|
||||
foreach (ExtraField extraField in templateExtraFields)
|
||||
{
|
||||
if (!recordFieldNames.Contains(extraField.Name))
|
||||
{
|
||||
@@ -309,7 +313,8 @@ namespace CarCareTracker.Helper
|
||||
if (mailConfig != null && !string.IsNullOrWhiteSpace(mailConfig.EmailServer))
|
||||
{
|
||||
Console.WriteLine($"SMTP Configured for {mailConfig.EmailServer}");
|
||||
} else
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("SMTP Not Configured");
|
||||
}
|
||||
@@ -317,7 +322,94 @@ namespace CarCareTracker.Helper
|
||||
Console.WriteLine($"Message Of The Day: {motd}");
|
||||
if (string.IsNullOrWhiteSpace(CultureInfo.CurrentCulture.Name))
|
||||
{
|
||||
Console.WriteLine("No Locale or Culture Configured for LubeLogger, Check Environment Variables");
|
||||
Console.WriteLine("WARNING: No Locale or Culture Configured for LubeLogger, Check Environment Variables");
|
||||
}
|
||||
//Create folders if they don't exist.
|
||||
if (!Directory.Exists("data"))
|
||||
{
|
||||
Directory.CreateDirectory("data");
|
||||
Console.WriteLine("Created data directory");
|
||||
}
|
||||
if (!Directory.Exists("data/images"))
|
||||
{
|
||||
Console.WriteLine("Created images directory");
|
||||
Directory.CreateDirectory("data/images");
|
||||
}
|
||||
if (!Directory.Exists("data/documents"))
|
||||
{
|
||||
Directory.CreateDirectory("data/documents");
|
||||
Console.WriteLine("Created documents directory");
|
||||
}
|
||||
if (!Directory.Exists("data/translations"))
|
||||
{
|
||||
Directory.CreateDirectory("data/translations");
|
||||
Console.WriteLine("Created translations directory");
|
||||
}
|
||||
if (!Directory.Exists("data/temp"))
|
||||
{
|
||||
Directory.CreateDirectory("data/temp");
|
||||
Console.WriteLine("Created translations directory");
|
||||
}
|
||||
if (!Directory.Exists("data/config"))
|
||||
{
|
||||
Directory.CreateDirectory("data/config");
|
||||
Console.WriteLine("Created config directory");
|
||||
}
|
||||
}
|
||||
public static void CheckMigration(string webRootPath, string webContentPath)
|
||||
{
|
||||
//check if current working directory differs from content root.
|
||||
if (Directory.GetCurrentDirectory() != webContentPath)
|
||||
{
|
||||
Console.WriteLine("WARNING: The Working Directory differs from the Web Content Path");
|
||||
Console.WriteLine($"Working Directory: {Directory.GetCurrentDirectory()}");
|
||||
Console.WriteLine($"Web Content Path: {webContentPath}");
|
||||
}
|
||||
//migrates all user-uploaded files from webroot to new data folder
|
||||
//images
|
||||
var imagePath = Path.Combine(webRootPath, "images");
|
||||
var docsPath = Path.Combine(webRootPath, "documents");
|
||||
var translationPath = Path.Combine(webRootPath, "translations");
|
||||
var tempPath = Path.Combine(webRootPath, "temp");
|
||||
if (File.Exists(LegacyUserConfigPath))
|
||||
{
|
||||
File.Move(LegacyUserConfigPath, UserConfigPath, true);
|
||||
}
|
||||
if (Directory.Exists(imagePath))
|
||||
{
|
||||
foreach (string fileToMove in Directory.GetFiles(imagePath))
|
||||
{
|
||||
var newFilePath = $"data/images/{Path.GetFileName(fileToMove)}";
|
||||
File.Move(fileToMove, newFilePath, true);
|
||||
Console.WriteLine($"Migrated Image: {Path.GetFileName(fileToMove)}");
|
||||
}
|
||||
}
|
||||
if (Directory.Exists(docsPath))
|
||||
{
|
||||
foreach (string fileToMove in Directory.GetFiles(docsPath))
|
||||
{
|
||||
var newFilePath = $"data/documents/{Path.GetFileName(fileToMove)}";
|
||||
File.Move(fileToMove, newFilePath, true);
|
||||
Console.WriteLine($"Migrated Document: {Path.GetFileName(fileToMove)}");
|
||||
}
|
||||
}
|
||||
if (Directory.Exists(translationPath))
|
||||
{
|
||||
foreach (string fileToMove in Directory.GetFiles(translationPath))
|
||||
{
|
||||
var newFilePath = $"data/translations/{Path.GetFileName(fileToMove)}";
|
||||
File.Move(fileToMove, newFilePath, true);
|
||||
Console.WriteLine($"Migrated Translation: {Path.GetFileName(fileToMove)}");
|
||||
}
|
||||
}
|
||||
if (Directory.Exists(tempPath))
|
||||
{
|
||||
foreach (string fileToMove in Directory.GetFiles(tempPath))
|
||||
{
|
||||
var newFilePath = $"data/temp/{Path.GetFileName(fileToMove)}";
|
||||
File.Move(fileToMove, newFilePath, true);
|
||||
Console.WriteLine($"Migrated Temp File: {Path.GetFileName(fileToMove)}");
|
||||
}
|
||||
}
|
||||
}
|
||||
public static async void NotifyAsync(string webhookURL, WebHookPayload webHookPayload)
|
||||
@@ -332,7 +424,8 @@ namespace CarCareTracker.Helper
|
||||
webhookURL = webhookURL.Replace("discord://", "https://"); //cleanurl
|
||||
//format to discord
|
||||
httpClient.PostAsJsonAsync(webhookURL, DiscordWebHook.FromWebHookPayload(webHookPayload));
|
||||
} else
|
||||
}
|
||||
else
|
||||
{
|
||||
httpClient.PostAsJsonAsync(webhookURL, webHookPayload);
|
||||
}
|
||||
@@ -370,12 +463,14 @@ namespace CarCareTracker.Helper
|
||||
if (vehicle.VehicleIdentifier == "LicensePlate")
|
||||
{
|
||||
return vehicle.LicensePlate;
|
||||
} else
|
||||
}
|
||||
else
|
||||
{
|
||||
if (vehicle.ExtraFields.Any(x=>x.Name == vehicle.VehicleIdentifier))
|
||||
if (vehicle.ExtraFields.Any(x => x.Name == vehicle.VehicleIdentifier))
|
||||
{
|
||||
return vehicle.ExtraFields?.FirstOrDefault(x=>x.Name == vehicle.VehicleIdentifier)?.Value;
|
||||
} else
|
||||
return vehicle.ExtraFields?.FirstOrDefault(x => x.Name == vehicle.VehicleIdentifier)?.Value;
|
||||
}
|
||||
else
|
||||
{
|
||||
return "N/A";
|
||||
}
|
||||
@@ -402,10 +497,11 @@ namespace CarCareTracker.Helper
|
||||
//Translations
|
||||
public static string GetTranslationDownloadPath(string continent, string name)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(continent) || string.IsNullOrWhiteSpace(name)){
|
||||
if (string.IsNullOrWhiteSpace(continent) || string.IsNullOrWhiteSpace(name))
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
else
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (continent)
|
||||
{
|
||||
@@ -424,8 +520,9 @@ namespace CarCareTracker.Helper
|
||||
if (string.IsNullOrWhiteSpace(name))
|
||||
{
|
||||
return string.Empty;
|
||||
} else
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
string cleanedName = name.Contains("_") ? name.Replace("_", "-") : name;
|
||||
@@ -438,7 +535,8 @@ namespace CarCareTracker.Helper
|
||||
{
|
||||
return displayName;
|
||||
}
|
||||
} catch (Exception ex)
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return name;
|
||||
}
|
||||
@@ -609,7 +707,8 @@ namespace CarCareTracker.Helper
|
||||
if (input == 0M.ToString("C2") && hideZero)
|
||||
{
|
||||
return "---";
|
||||
} else
|
||||
}
|
||||
else
|
||||
{
|
||||
return string.IsNullOrWhiteSpace(decorations) ? input : $"{input}{decorations}";
|
||||
}
|
||||
@@ -669,5 +768,52 @@ namespace CarCareTracker.Helper
|
||||
_csv.NextRecord();
|
||||
}
|
||||
}
|
||||
public static byte[] RemindersToCalendar(List<ReminderRecordViewModel> reminders)
|
||||
{
|
||||
//converts reminders to iCal file
|
||||
StringBuilder sb = new StringBuilder();
|
||||
//start the calendar item
|
||||
sb.AppendLine("BEGIN:VCALENDAR");
|
||||
sb.AppendLine("VERSION:2.0");
|
||||
sb.AppendLine("PRODID:lubelogger.com");
|
||||
sb.AppendLine("CALSCALE:GREGORIAN");
|
||||
sb.AppendLine("METHOD:PUBLISH");
|
||||
|
||||
//create events.
|
||||
foreach(ReminderRecordViewModel reminder in reminders)
|
||||
{
|
||||
var dtStart = reminder.Date.Date.ToString("yyyyMMddTHHmm00");
|
||||
var dtEnd = reminder.Date.Date.AddDays(1).AddMilliseconds(-1).ToString("yyyyMMddTHHmm00");
|
||||
var calendarUID = new Guid(MD5.HashData(Encoding.UTF8.GetBytes($"{dtStart}_{reminder.Description}")));
|
||||
sb.AppendLine("BEGIN:VEVENT");
|
||||
sb.AppendLine("DTSTAMP:" + DateTime.Now.ToString("yyyyMMddTHHmm00"));
|
||||
sb.AppendLine("UID:" + calendarUID);
|
||||
sb.AppendLine("DTSTART:" + dtStart);
|
||||
sb.AppendLine("DTEND:" + dtEnd);
|
||||
sb.AppendLine($"SUMMARY:{reminder.Description}");
|
||||
sb.AppendLine($"DESCRIPTION:{reminder.Description}");
|
||||
switch (reminder.Urgency)
|
||||
{
|
||||
case ReminderUrgency.NotUrgent:
|
||||
sb.AppendLine("PRIORITY:3");
|
||||
break;
|
||||
case ReminderUrgency.Urgent:
|
||||
sb.AppendLine("PRIORITY:2");
|
||||
break;
|
||||
case ReminderUrgency.VeryUrgent:
|
||||
sb.AppendLine("PRIORITY:1");
|
||||
break;
|
||||
case ReminderUrgency.PastDue:
|
||||
sb.AppendLine("PRIORITY:1");
|
||||
break;
|
||||
}
|
||||
sb.AppendLine("END:VEVENT");
|
||||
}
|
||||
|
||||
//end calendar item
|
||||
sb.AppendLine("END:VCALENDAR");
|
||||
string calendarContent = sb.ToString();
|
||||
return Encoding.UTF8.GetBytes(calendarContent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
public string Notes { get; set; }
|
||||
public List<string> Tags { get; set; } = new List<string>();
|
||||
public List<ExtraField> ExtraFields { get; set; } = new List<ExtraField>();
|
||||
public bool IncludeInAverage { get { return MilesPerGallon > 0 || (!IsFillToFull && !MissedFuelUp); } }
|
||||
public List<UploadedFiles> Files { get; set; } = new List<UploadedFiles>();
|
||||
public bool IncludeInAverage { get { return MilesPerGallon > 0 || (!IsFillToFull && !MissedFuelUp) || (Mileage == default && !MissedFuelUp); } }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ namespace CarCareTracker.Models
|
||||
public string Cost { get; set; }
|
||||
public string Notes { get; set; }
|
||||
public string Tags { get; set; }
|
||||
public List<ExtraField> ExtraFields { get; set; }
|
||||
public List<ExtraField> ExtraFields { get; set; } = new List<ExtraField>();
|
||||
}
|
||||
public class GenericRecordExportModel
|
||||
{
|
||||
@@ -58,7 +58,8 @@ namespace CarCareTracker.Models
|
||||
[JsonConverter(typeof(FromDecimalOptional))]
|
||||
public string Cost { get; set; }
|
||||
public string Tags { get; set; }
|
||||
public List<ExtraField> ExtraFields { get; set; }
|
||||
public List<ExtraField> ExtraFields { get; set; } = new List<ExtraField>();
|
||||
public List<UploadedFiles> Files { get; set; } = new List<UploadedFiles>();
|
||||
}
|
||||
public class OdometerRecordExportModel
|
||||
{
|
||||
@@ -72,7 +73,8 @@ namespace CarCareTracker.Models
|
||||
public string Odometer { get; set; }
|
||||
public string Notes { get; set; }
|
||||
public string Tags { get; set; }
|
||||
public List<ExtraField> ExtraFields { get; set; }
|
||||
public List<ExtraField> ExtraFields { get; set; } = new List<ExtraField>();
|
||||
public List<UploadedFiles> Files { get; set; } = new List<UploadedFiles>();
|
||||
}
|
||||
public class TaxRecordExportModel
|
||||
{
|
||||
@@ -85,7 +87,8 @@ namespace CarCareTracker.Models
|
||||
[JsonConverter(typeof(FromDecimalOptional))]
|
||||
public string Cost { get; set; }
|
||||
public string Tags { get; set; }
|
||||
public List<ExtraField> ExtraFields { get; set; }
|
||||
public List<ExtraField> ExtraFields { get; set; } = new List<ExtraField>();
|
||||
public List<UploadedFiles> Files { get; set; } = new List<UploadedFiles>();
|
||||
}
|
||||
public class GasRecordExportModel
|
||||
{
|
||||
@@ -107,7 +110,8 @@ namespace CarCareTracker.Models
|
||||
public string MissedFuelUp { get; set; }
|
||||
public string Notes { get; set; }
|
||||
public string Tags { get; set; }
|
||||
public List<ExtraField> ExtraFields { get; set; }
|
||||
public List<ExtraField> ExtraFields { get; set; } = new List<ExtraField>();
|
||||
public List<UploadedFiles> Files { get; set; } = new List<UploadedFiles>();
|
||||
}
|
||||
public class ReminderExportModel
|
||||
{
|
||||
@@ -130,6 +134,6 @@ namespace CarCareTracker.Models
|
||||
public string Priority { get; set; }
|
||||
public string Progress { get; set; }
|
||||
public string Cost { get; set; }
|
||||
public List<ExtraField> ExtraFields { get; set; }
|
||||
public List<ExtraField> ExtraFields { get; set; } = new List<ExtraField>();
|
||||
}
|
||||
}
|
||||
|
||||
58
Program.cs
58
Program.cs
@@ -7,11 +7,14 @@ using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http.Features;
|
||||
using Microsoft.AspNetCore.Server.Kestrel.Core;
|
||||
using Microsoft.Extensions.FileProviders;
|
||||
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
|
||||
//Print Messages
|
||||
StaticHelper.InitMessage(builder.Configuration);
|
||||
//Check Migration
|
||||
StaticHelper.CheckMigration(builder.Environment.WebRootPath, builder.Environment.ContentRootPath);
|
||||
|
||||
// Add services to the container.
|
||||
builder.Services.AddControllersWithViews();
|
||||
@@ -75,15 +78,6 @@ builder.Services.AddSingleton<IUserLogic, UserLogic>();
|
||||
builder.Services.AddSingleton<IOdometerLogic, OdometerLogic>();
|
||||
builder.Services.AddSingleton<IVehicleLogic, VehicleLogic>();
|
||||
|
||||
if (!Directory.Exists("data"))
|
||||
{
|
||||
Directory.CreateDirectory("data");
|
||||
}
|
||||
if (!Directory.Exists("config"))
|
||||
{
|
||||
Directory.CreateDirectory("config");
|
||||
}
|
||||
|
||||
//Additional JsonFile
|
||||
builder.Configuration.AddJsonFile(StaticHelper.UserConfigPath, optional: true, reloadOnChange: true);
|
||||
|
||||
@@ -112,11 +106,55 @@ var app = builder.Build();
|
||||
// Configure the HTTP request pipeline.
|
||||
app.UseExceptionHandler("/Home/Error");
|
||||
|
||||
app.UseStaticFiles();
|
||||
app.UseStaticFiles(new StaticFileOptions
|
||||
{
|
||||
FileProvider = new PhysicalFileProvider(
|
||||
Path.Combine(builder.Environment.ContentRootPath, "data", "images")),
|
||||
RequestPath = "/images",
|
||||
OnPrepareResponse = ctx =>
|
||||
{
|
||||
if (ctx.Context.Request.Path.StartsWithSegments("/images") || ctx.Context.Request.Path.StartsWithSegments("/documents"))
|
||||
if (ctx.Context.Request.Path.StartsWithSegments("/images"))
|
||||
{
|
||||
ctx.Context.Response.Headers.Add("Cache-Control", "no-store");
|
||||
if (!ctx.Context.User.Identity.IsAuthenticated)
|
||||
{
|
||||
ctx.Context.Response.Redirect("/Login");
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
app.UseStaticFiles(new StaticFileOptions
|
||||
{
|
||||
FileProvider = new PhysicalFileProvider(
|
||||
Path.Combine(builder.Environment.ContentRootPath, "data", "documents")),
|
||||
RequestPath = "/documents",
|
||||
OnPrepareResponse = ctx =>
|
||||
{
|
||||
if (ctx.Context.Request.Path.StartsWithSegments("/documents"))
|
||||
{
|
||||
ctx.Context.Response.Headers.Add("Cache-Control", "no-store");
|
||||
if (!ctx.Context.User.Identity.IsAuthenticated)
|
||||
{
|
||||
ctx.Context.Response.Redirect("/Login");
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
app.UseStaticFiles(new StaticFileOptions
|
||||
{
|
||||
FileProvider = new PhysicalFileProvider(
|
||||
Path.Combine(builder.Environment.ContentRootPath, "data", "translations")),
|
||||
RequestPath = "/translations"
|
||||
});
|
||||
app.UseStaticFiles(new StaticFileOptions
|
||||
{
|
||||
FileProvider = new PhysicalFileProvider(
|
||||
Path.Combine(builder.Environment.ContentRootPath, "data", "temp")),
|
||||
RequestPath = "/temp",
|
||||
OnPrepareResponse = ctx =>
|
||||
{
|
||||
if (ctx.Context.Request.Path.StartsWithSegments("/temp"))
|
||||
{
|
||||
ctx.Context.Response.Headers.Add("Cache-Control", "no-store");
|
||||
if (!ctx.Context.User.Identity.IsAuthenticated)
|
||||
|
||||
@@ -118,6 +118,7 @@
|
||||
notes - notes(optional)<br />
|
||||
tags - tags separated by space(optional)<br />
|
||||
extrafields - <a class="link-body-emphasis link-offset-2 link-underline-opacity-25 link-underline-opacity-100-hover reminder-calendar-item" onclick="showExtraFieldsInfo()">extrafields(optional)</a><br />
|
||||
files - <a class="link-body-emphasis link-offset-2 link-underline-opacity-25 link-underline-opacity-100-hover reminder-calendar-item" onclick="showAttachmentsInfo()">attachments(optional)</a><br />
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
@@ -140,6 +141,7 @@
|
||||
notes - notes(optional)<br />
|
||||
tags - tags separated by space(optional)<br />
|
||||
extrafields - <a class="link-body-emphasis link-offset-2 link-underline-opacity-25 link-underline-opacity-100-hover reminder-calendar-item" onclick="showExtraFieldsInfo()">extrafields(optional)</a><br />
|
||||
files - <a class="link-body-emphasis link-offset-2 link-underline-opacity-25 link-underline-opacity-100-hover reminder-calendar-item" onclick="showAttachmentsInfo()">attachments(optional)</a><br />
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
@@ -192,6 +194,7 @@
|
||||
notes - notes(optional)<br />
|
||||
tags - tags separated by space(optional)<br />
|
||||
extrafields - <a class="link-body-emphasis link-offset-2 link-underline-opacity-25 link-underline-opacity-100-hover reminder-calendar-item" onclick="showExtraFieldsInfo()">extrafields(optional)</a><br />
|
||||
files - <a class="link-body-emphasis link-offset-2 link-underline-opacity-25 link-underline-opacity-100-hover reminder-calendar-item" onclick="showAttachmentsInfo()">attachments(optional)</a><br />
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
@@ -215,6 +218,7 @@
|
||||
notes - notes(optional)<br />
|
||||
tags - tags separated by space(optional)<br />
|
||||
extrafields - <a class="link-body-emphasis link-offset-2 link-underline-opacity-25 link-underline-opacity-100-hover reminder-calendar-item" onclick="showExtraFieldsInfo()">extrafields(optional)</a><br />
|
||||
files - <a class="link-body-emphasis link-offset-2 link-underline-opacity-25 link-underline-opacity-100-hover reminder-calendar-item" onclick="showAttachmentsInfo()">attachments(optional)</a><br />
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
@@ -267,6 +271,7 @@
|
||||
notes - notes(optional)<br />
|
||||
tags - tags separated by space(optional)<br />
|
||||
extrafields - <a class="link-body-emphasis link-offset-2 link-underline-opacity-25 link-underline-opacity-100-hover reminder-calendar-item" onclick="showExtraFieldsInfo()">extrafields(optional)</a><br />
|
||||
files - <a class="link-body-emphasis link-offset-2 link-underline-opacity-25 link-underline-opacity-100-hover reminder-calendar-item" onclick="showAttachmentsInfo()">attachments(optional)</a><br />
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
@@ -290,6 +295,7 @@
|
||||
notes - notes(optional)<br />
|
||||
tags - tags separated by space(optional)<br />
|
||||
extrafields - <a class="link-body-emphasis link-offset-2 link-underline-opacity-25 link-underline-opacity-100-hover reminder-calendar-item" onclick="showExtraFieldsInfo()">extrafields(optional)</a><br />
|
||||
files - <a class="link-body-emphasis link-offset-2 link-underline-opacity-25 link-underline-opacity-100-hover reminder-calendar-item" onclick="showAttachmentsInfo()">attachments(optional)</a><br />
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
@@ -342,6 +348,7 @@
|
||||
notes - notes(optional)<br />
|
||||
tags - tags separated by space(optional)<br />
|
||||
extrafields - <a class="link-body-emphasis link-offset-2 link-underline-opacity-25 link-underline-opacity-100-hover reminder-calendar-item" onclick="showExtraFieldsInfo()">extrafields(optional)</a><br />
|
||||
files - <a class="link-body-emphasis link-offset-2 link-underline-opacity-25 link-underline-opacity-100-hover reminder-calendar-item" onclick="showAttachmentsInfo()">attachments(optional)</a><br />
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
@@ -365,6 +372,7 @@
|
||||
notes - notes(optional)<br />
|
||||
tags - tags separated by space(optional)<br />
|
||||
extrafields - <a class="link-body-emphasis link-offset-2 link-underline-opacity-25 link-underline-opacity-100-hover reminder-calendar-item" onclick="showExtraFieldsInfo()">extrafields(optional)</a><br />
|
||||
files - <a class="link-body-emphasis link-offset-2 link-underline-opacity-25 link-underline-opacity-100-hover reminder-calendar-item" onclick="showAttachmentsInfo()">attachments(optional)</a><br />
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
@@ -430,6 +438,7 @@
|
||||
notes - notes(optional)<br />
|
||||
tags - tags separated by space(optional)<br />
|
||||
extrafields - <a class="link-body-emphasis link-offset-2 link-underline-opacity-25 link-underline-opacity-100-hover reminder-calendar-item" onclick="showExtraFieldsInfo()">extrafields(optional)</a><br />
|
||||
files - <a class="link-body-emphasis link-offset-2 link-underline-opacity-25 link-underline-opacity-100-hover reminder-calendar-item" onclick="showAttachmentsInfo()">attachments(optional)</a><br />
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
@@ -452,6 +461,7 @@
|
||||
notes - notes(optional)<br />
|
||||
tags - tags separated by space(optional)<br />
|
||||
extrafields - <a class="link-body-emphasis link-offset-2 link-underline-opacity-25 link-underline-opacity-100-hover reminder-calendar-item" onclick="showExtraFieldsInfo()">extrafields(optional)</a><br />
|
||||
files - <a class="link-body-emphasis link-offset-2 link-underline-opacity-25 link-underline-opacity-100-hover reminder-calendar-item" onclick="showAttachmentsInfo()">attachments(optional)</a><br />
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
@@ -510,6 +520,7 @@
|
||||
notes - notes(optional)<br />
|
||||
tags - tags separated by space(optional)<br />
|
||||
extrafields - <a class="link-body-emphasis link-offset-2 link-underline-opacity-25 link-underline-opacity-100-hover reminder-calendar-item" onclick="showExtraFieldsInfo()">extrafields(optional)</a><br />
|
||||
files - <a class="link-body-emphasis link-offset-2 link-underline-opacity-25 link-underline-opacity-100-hover reminder-calendar-item" onclick="showAttachmentsInfo()">attachments(optional)</a><br />
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
@@ -535,6 +546,7 @@
|
||||
notes - notes(optional)<br />
|
||||
tags - tags separated by space(optional)<br />
|
||||
extrafields - <a class="link-body-emphasis link-offset-2 link-underline-opacity-25 link-underline-opacity-100-hover reminder-calendar-item" onclick="showExtraFieldsInfo()">extrafields(optional)</a><br />
|
||||
files - <a class="link-body-emphasis link-offset-2 link-underline-opacity-25 link-underline-opacity-100-hover reminder-calendar-item" onclick="showAttachmentsInfo()">attachments(optional)</a><br />
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
@@ -566,6 +578,22 @@
|
||||
vehicleId - Id of Vehicle
|
||||
</div>
|
||||
</div>
|
||||
<div class="row api-method">
|
||||
<div class="col-1">
|
||||
<span class="badge bg-primary">POST</span>
|
||||
</div>
|
||||
<div class="col-5 copyable">
|
||||
<code>/api/documents/upload</code>
|
||||
</div>
|
||||
<div class="col-3">
|
||||
Upload Documents
|
||||
</div>
|
||||
<div class="col-3">
|
||||
Body(form-data): {<br />
|
||||
documents[] - Files to Upload<br />
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
@if (User.IsInRole(nameof(UserData.IsRootUser)))
|
||||
{
|
||||
<div class="row api-method">
|
||||
@@ -624,4 +652,11 @@
|
||||
icon: "info"
|
||||
});
|
||||
}
|
||||
function showAttachmentsInfo(){
|
||||
Swal.fire({
|
||||
title: "Attaching Files",
|
||||
html: "The Document Upload Endpoint will upload the files and provide a formatted output which you can pass into this method",
|
||||
icon: "info"
|
||||
});
|
||||
}
|
||||
</script>
|
||||
@@ -34,6 +34,7 @@
|
||||
<meta name="apple-mobile-web-app-capable" content="yes" />
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
|
||||
<title>@ViewData["Title"] - LubeLogger</title>
|
||||
<link rel="icon" type="image/x-icon" href="~/favicon.ico">
|
||||
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
|
||||
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap-icons.css" />
|
||||
<link rel="stylesheet" href="~/lib/bootstrap-datepicker/css/bootstrap-datepicker.min.css" />
|
||||
|
||||
@@ -49,9 +49,13 @@
|
||||
<input type="text" id="inputFileExtensions" class="form-control">
|
||||
<small class="text-body-secondary">Blank for default, * for all files</small>
|
||||
</div>
|
||||
<div class="form-check form-switch">
|
||||
<input class="form-check-input"type="checkbox" role="switch" id="inputCustomWidgets">
|
||||
<label class="form-check-label" for="inputCustomWidgets">Custom Widgets</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<div class="form-group">
|
||||
<div class="form-group">
|
||||
<label for="inputCustomLogo">Custom Logo URL</label>
|
||||
<input type="text" id="inputCustomLogo" class="form-control">
|
||||
<small class="text-body-secondary">Default size: 204x48</small>
|
||||
@@ -66,6 +70,10 @@
|
||||
<input type="text" id="inputWebHook" class="form-control">
|
||||
<small class="text-body-secondary">URL to WebHook Consumer</small>
|
||||
</div>
|
||||
<div class="form-check form-switch">
|
||||
<input class="form-check-input"type="checkbox" role="switch" id="inputInvariantAPI">
|
||||
<label class="form-check-label" for="inputInvariantAPI">Invariant API</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -262,6 +270,12 @@ function generateConfig(){
|
||||
if ($("#inputPostgres").val().trim() != ''){
|
||||
windowConfig["POSTGRES_CONNECTION"]=$("#inputPostgres").val();
|
||||
}
|
||||
if ($("#inputCustomWidgets").is(":checked")){
|
||||
windowConfig["LUBELOGGER_CUSTOM_WIDGETS"]=$('#inputCustomWidgets').is(':checked');
|
||||
}
|
||||
if ($("#inputInvariantAPI").is(":checked")){
|
||||
windowConfig["LUBELOGGER_INVARIANT_API"]=$('#inputInvariantAPI').is(':checked');
|
||||
}
|
||||
if ($('#inputSmtpServer').val().trim() != ''){
|
||||
windowConfig["MailConfig"] = {
|
||||
EmailServer: $("#inputSmtpServer").val(),
|
||||
@@ -327,6 +341,12 @@ function generateConfig(){
|
||||
if ($("#inputPostgres").val().trim() != ''){
|
||||
dockerConfig.push(`POSTGRES_CONNECTION="${$('#inputPostgres').val()}"`);
|
||||
}
|
||||
if ($("#inputCustomWidgets").is(":checked")){
|
||||
dockerConfig.push(`LUBELOGGER_CUSTOM_WIDGETS="${$('#inputCustomWidgets').is(':checked')}"`);
|
||||
}
|
||||
if ($("#inputInvariantAPI").is(":checked")){
|
||||
dockerConfig.push(`LUBELOGGER_INVARIANT_API="${$('#inputInvariantAPI').is(':checked')}"`);
|
||||
}
|
||||
if ($('#inputSmtpServer').val().trim() != ''){
|
||||
dockerConfig.push(`MailConfig__EmailServer="${$('#inputSmtpServer').val()}"`);
|
||||
dockerConfig.push(`MailConfig__EmailFrom="${$('#inputSmtpFrom').val()}"`);
|
||||
|
||||
Reference in New Issue
Block a user