280 lines
7.8 KiB
C#
280 lines
7.8 KiB
C#
using Seenginx.Models;
|
|
using Seenginx.Services;
|
|
using Seenginx.Services.Models;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace Seenginx.Services
|
|
{
|
|
public class SystemDService : ISystemDService
|
|
{
|
|
|
|
private readonly SeenginxSettings Settings;
|
|
|
|
private readonly CommandService CommandService;
|
|
|
|
public SystemDService(SeenginxSettings configPaths, CommandService commandService)
|
|
{
|
|
Settings = configPaths;
|
|
CommandService = commandService;
|
|
}
|
|
|
|
public async Task<IEnumerable<ConfigFile>> GetFilesAsync()
|
|
{
|
|
await Task.Run(() => { });
|
|
var rootConfigs = Directory.GetFiles(Settings.systemd.rootPath, "*.service");
|
|
var rootDraftConfigs = Directory.GetFiles(Settings.systemd.rootPath, "*.service.draft");
|
|
|
|
var rootConfigFiles = rootConfigs.Select(fp =>
|
|
{
|
|
var name = Path.GetFileNameWithoutExtension(fp);
|
|
var configFile = new ConfigFile();
|
|
configFile.CanBeDeleted = true;
|
|
configFile.Folder = string.Empty;
|
|
configFile.LastUpdated = File.GetLastWriteTime(fp);
|
|
configFile.Name = name;
|
|
configFile.FullPath = Path.Combine(Settings.systemd.rootPath, $"{configFile.Name}.service");
|
|
configFile.Body = File.ReadAllText(fp);
|
|
if (rootDraftConfigs.Any(cfp => cfp.Contains(name)))
|
|
configFile.DraftBody = File.ReadAllText(rootDraftConfigs.First(cfp => cfp.Contains(name)));
|
|
|
|
return configFile;
|
|
});
|
|
|
|
var finalList = new List<ConfigFile>();
|
|
finalList.AddRange(rootConfigFiles);
|
|
|
|
finalList = finalList.OrderBy(cf => cf.Name).ToList();
|
|
|
|
return finalList;
|
|
}
|
|
|
|
public async Task<IEnumerable<Template>> GetTemplates()
|
|
{
|
|
var templates = new List<Template>();
|
|
try
|
|
{
|
|
var systemdTemplateDirectory = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "templates", "systemd");
|
|
var systemdTemplateFiles = Directory.GetFiles(systemdTemplateDirectory, "*.template");
|
|
|
|
foreach (var templateFilePath in systemdTemplateFiles)
|
|
{
|
|
var template = new Template();
|
|
var templateFileLines = await File.ReadAllLinesAsync(templateFilePath);
|
|
template.Name = templateFileLines.FirstOrDefault();
|
|
template.Code = string.Join(Environment.NewLine, templateFileLines.Skip(2));
|
|
templates.Add(template);
|
|
}
|
|
|
|
return templates;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
throw ex;
|
|
}
|
|
}
|
|
|
|
|
|
public async Task<Result> ValidateForAddFileAsync(NewFileForm newFileForm)
|
|
{
|
|
var validationResult = new Result();
|
|
try
|
|
{
|
|
var filePath = Path.Combine(Settings.systemd.rootPath, $"{newFileForm.Name}.service");
|
|
|
|
if (File.Exists(filePath))
|
|
return validationResult.Invalidate($"There's already a file with the '{newFileForm.Name}.service' name.");
|
|
|
|
return validationResult;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return validationResult.Invalidate($"Exception at {nameof(ValidateForAddFileAsync)}()", ex);
|
|
}
|
|
}
|
|
|
|
public async Task<Result<ConfigFile>> AddFileAsync(NewFileForm newFileForm)
|
|
{
|
|
var addResult = new Result<ConfigFile>();
|
|
try
|
|
{
|
|
var newFile = new ConfigFile();
|
|
newFile.Name = newFileForm.Name;
|
|
newFile.Folder = string.Empty;
|
|
newFile.FullPath = Path.Combine(Settings.systemd.rootPath, newFile.Folder, $"{newFileForm.Name}.service");
|
|
newFile.Body = newFileForm.SelectedTemplate == 0.ToString() ? string.Empty : (await GetTemplates()).SingleOrDefault(t => t.Name == newFileForm.SelectedTemplate)?.Code;
|
|
newFile.LastUpdated = DateTime.UtcNow;
|
|
|
|
await File.WriteAllTextAsync(newFile.FullPath, newFile.Body, Encoding.UTF8);
|
|
|
|
addResult.SetData(newFile);
|
|
|
|
return addResult;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return addResult.Invalidate(ex.Message, ex);
|
|
}
|
|
}
|
|
|
|
|
|
public async Task<Result> ValidateForDeleteFileAsync(ConfigFile configFile)
|
|
{
|
|
var validationResult = new Result();
|
|
try
|
|
{
|
|
if (File.Exists(configFile.FullPath))
|
|
return validationResult.Invalidate($"File '{configFile.FullPath}' not found.");
|
|
|
|
return validationResult;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return validationResult.Invalidate(ex.Message, ex);
|
|
}
|
|
}
|
|
|
|
public async Task<Result> DeleteFileAsync(ConfigFile configFile)
|
|
{
|
|
var result = new Result();
|
|
try
|
|
{
|
|
if (!File.Exists(configFile.FullPath))
|
|
return result.Invalidate($"File '{configFile.FullPath}' not found.");
|
|
|
|
File.Delete(configFile.FullPath);
|
|
|
|
return result;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return result.Invalidate(ex.Message, ex);
|
|
}
|
|
}
|
|
|
|
|
|
public async Task<Result> ValidateForSaveFileAsync(ConfigFile configFile)
|
|
{
|
|
var validationResult = new Result();
|
|
try
|
|
{
|
|
if (File.Exists(configFile.FullPath))
|
|
return validationResult.Invalidate($"File '{configFile.FullPath}' not found.");
|
|
|
|
return validationResult;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return validationResult.Invalidate(ex.Message, ex);
|
|
}
|
|
}
|
|
|
|
public async Task<Result<ConfigFile>> SaveFileAsync(ConfigFile configFile)
|
|
{
|
|
var saveResult = new Result<ConfigFile>();
|
|
try
|
|
{
|
|
await File.WriteAllTextAsync(Path.Combine(Settings.systemd.rootPath, $"{configFile.Name}.service"), configFile.Body, Encoding.UTF8);
|
|
|
|
return saveResult;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return saveResult.Invalidate(ex.Message, ex);
|
|
}
|
|
}
|
|
|
|
|
|
public async Task<Result> ValidateForSaveDraftFileAsync(ConfigFile configFile)
|
|
{
|
|
var validationResult = new Result();
|
|
try
|
|
{
|
|
var draftPathName = $"{configFile.FullPath}.draft";
|
|
|
|
if (!File.Exists(draftPathName))
|
|
return validationResult.Invalidate($"File '{draftPathName}' not found.");
|
|
|
|
return validationResult;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return validationResult.Invalidate(ex.Message, ex);
|
|
}
|
|
}
|
|
|
|
public async Task<Result<ConfigFile>> SaveDraftFileAsync(ConfigFile configFile)
|
|
{
|
|
var saveDraftResult = new Result<ConfigFile>();
|
|
try
|
|
{
|
|
await File.WriteAllTextAsync(Path.Combine(Settings.systemd.rootPath, $"{configFile.Name}.service.draft"), configFile.DraftBody, Encoding.UTF8);
|
|
|
|
return saveDraftResult;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return saveDraftResult.Invalidate(ex.Message, ex);
|
|
}
|
|
}
|
|
|
|
|
|
public async Task<Result> ValidateForRenameFileAsync(List<ConfigFile> configFiles, ConfigFile selectedConfigFile, string newName)
|
|
{
|
|
var renameResult = new Result();
|
|
try
|
|
{
|
|
|
|
|
|
if (configFiles.Count(cf => cf.Name == newName) > 0)
|
|
return renameResult.Invalidate($"File '{selectedConfigFile.FullPath}' already exists.");
|
|
|
|
|
|
|
|
|
|
if (!File.Exists(selectedConfigFile.FullPath))
|
|
return renameResult.Invalidate($"Original file '{selectedConfigFile.FullPath}' not found.");
|
|
|
|
var newPathName = Path.Combine(Settings.systemd.rootPath, $"{newName}.service");
|
|
if (File.Exists(newPathName))
|
|
return renameResult.Invalidate($"The file '{newPathName}' already exists.");
|
|
|
|
return renameResult;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return renameResult.Invalidate(ex.Message, ex);
|
|
}
|
|
}
|
|
|
|
public async Task<Result<ConfigFile>> RenameFileAsync(ConfigFile configFile, string newName)
|
|
{
|
|
var renameResult = new Result<ConfigFile>();
|
|
try
|
|
{
|
|
var originalPathName = Path.Combine(Settings.systemd.rootPath, $"{configFile.Name}.service");
|
|
var newPathName = Path.Combine(Settings.systemd.rootPath, newName);
|
|
|
|
File.Move(originalPathName, newPathName, overwrite: false);
|
|
if(configFile.DraftBody != null)
|
|
File.Move(originalPathName, newPathName, overwrite: false);
|
|
|
|
configFile.FullPath = newPathName;
|
|
renameResult.SetData(configFile);
|
|
|
|
return renameResult;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return renameResult.Invalidate(ex.Message, ex);
|
|
}
|
|
}
|
|
|
|
|
|
}
|
|
}
|