first commit -push
This commit is contained in:
@@ -0,0 +1,39 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using RobotNet.ScriptManager.Services;
|
||||
using RobotNet.Shares;
|
||||
|
||||
namespace RobotNet.ScriptManager.Controllers;
|
||||
|
||||
[Route("api/[controller]")]
|
||||
[ApiController]
|
||||
public class DashboardConfigController(DashboardConfig Config, ILogger<DashboardConfigController> Logger) : ControllerBase
|
||||
{
|
||||
[HttpGet]
|
||||
public Task<MessageResult<string[]>> GetOpenACSSettings()
|
||||
{
|
||||
try
|
||||
{
|
||||
return Task.FromResult<MessageResult<string[]>>(new(true, "") { Data = Config.MissionNames });
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.LogWarning($"Lấy cấu hình OpenACS xảy ra lỗi: {ex.Message}");
|
||||
return Task.FromResult<MessageResult<string[]>>(new(false, "Hệ thống có lỗi xảy ra"));
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public async Task<MessageResult> UpdatePublishSetting([FromBody] string[] missionNames)
|
||||
{
|
||||
try
|
||||
{
|
||||
await Config.UpdateMissionNames(missionNames);
|
||||
return new(true, "");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.LogWarning($"Cập nhật cấu hình publish OpenACS xảy ra lỗi: {ex.Message}");
|
||||
return new(false, "Hệ thống có lỗi xảy ra");
|
||||
}
|
||||
}
|
||||
}
|
||||
197
RobotNet.ScriptManager/Controllers/ScriptController.cs
Normal file
197
RobotNet.ScriptManager/Controllers/ScriptController.cs
Normal file
@@ -0,0 +1,197 @@
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using RobotNet.Script.Shares;
|
||||
using RobotNet.ScriptManager.Helpers;
|
||||
using RobotNet.ScriptManager.Services;
|
||||
using RobotNet.Shares;
|
||||
|
||||
namespace RobotNet.ScriptManager.Controllers;
|
||||
|
||||
[Route("api/[controller]")]
|
||||
[ApiController]
|
||||
[Authorize]
|
||||
public class ScriptController(ScriptStateManager scriptBuilder) : ControllerBase
|
||||
{
|
||||
[HttpGet]
|
||||
[Route("")]
|
||||
public ScriptFolder Gets() => new("Scripts", GetScriptFolders(ScriptConfiguration.ScriptStorePath), GetScriptFiles(ScriptConfiguration.ScriptStorePath));
|
||||
|
||||
[HttpPost]
|
||||
[Route("Directory")]
|
||||
public MessageResult CreateDirectory([FromBody] CreateModel model)
|
||||
{
|
||||
if(scriptBuilder.State == ProcessorState.Building
|
||||
|| scriptBuilder.State == ProcessorState.Starting
|
||||
|| scriptBuilder.State == ProcessorState.Running
|
||||
|| scriptBuilder.State == ProcessorState.Stopping)
|
||||
{
|
||||
return new(false, $"Hệ thống đang trong trạng thái {scriptBuilder.State}, không thể tạo thư mục");
|
||||
}
|
||||
var fullPath = Path.Combine(ScriptConfiguration.ScriptStorePath, model.Path, model.Name);
|
||||
if (Directory.Exists(fullPath)) return new(false, "Folder đã tồn tại");
|
||||
try
|
||||
{
|
||||
Directory.CreateDirectory(fullPath);
|
||||
return new(true, "");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return new(false, e.Message);
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[Route("File")]
|
||||
public MessageResult CreateFile([FromBody] CreateModel model)
|
||||
{
|
||||
if (scriptBuilder.State == ProcessorState.Building
|
||||
|| scriptBuilder.State == ProcessorState.Starting
|
||||
|| scriptBuilder.State == ProcessorState.Running
|
||||
|| scriptBuilder.State == ProcessorState.Stopping)
|
||||
{
|
||||
return new(false, $"Hệ thống đang trong trạng thái {scriptBuilder.State}, không thể tạo file");
|
||||
}
|
||||
var fullPath = Path.Combine(ScriptConfiguration.ScriptStorePath, model.Path, model.Name);
|
||||
if (System.IO.File.Exists(fullPath)) return new(false, "File đã tồn tại");
|
||||
try
|
||||
{
|
||||
var fs = System.IO.File.Create(fullPath);
|
||||
fs.Close();
|
||||
return new(true, "");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return new(false, e.Message);
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPatch]
|
||||
[Route("File")]
|
||||
public MessageResult UpdateCode([FromBody] UpdateModel model)
|
||||
{
|
||||
if (scriptBuilder.State == ProcessorState.Building
|
||||
|| scriptBuilder.State == ProcessorState.Starting
|
||||
|| scriptBuilder.State == ProcessorState.Running
|
||||
|| scriptBuilder.State == ProcessorState.Stopping)
|
||||
{
|
||||
return new(false, $"Hệ thống đang trong trạng thái {scriptBuilder.State}, không thể update file");
|
||||
}
|
||||
var fullPath = Path.Combine(ScriptConfiguration.ScriptStorePath, model.Path);
|
||||
System.IO.File.WriteAllText(fullPath, model.Code);
|
||||
ResetScriptProcessor();
|
||||
return new(true, "");
|
||||
}
|
||||
|
||||
|
||||
[HttpPatch]
|
||||
[Route("FileName")]
|
||||
public MessageResult RenameFile([FromBody] RenameModel model)
|
||||
{
|
||||
if (scriptBuilder.State == ProcessorState.Building
|
||||
|| scriptBuilder.State == ProcessorState.Starting
|
||||
|| scriptBuilder.State == ProcessorState.Running
|
||||
|| scriptBuilder.State == ProcessorState.Stopping)
|
||||
{
|
||||
return new(false, $"Hệ thống đang trong trạng thái {scriptBuilder.State}, không thể thay đổi tên file");
|
||||
}
|
||||
var fullPath = Path.Combine(ScriptConfiguration.ScriptStorePath, model.Path);
|
||||
if (!System.IO.File.Exists(fullPath)) return new(false, "Source code không tồn tại");
|
||||
|
||||
var folder = Path.GetDirectoryName(fullPath) ?? "";
|
||||
var fi = new FileInfo(fullPath);
|
||||
fi.MoveTo(Path.Combine(folder, model.NewName));
|
||||
return new(true, "");
|
||||
}
|
||||
|
||||
[HttpPatch]
|
||||
[Route("DirectoryName")]
|
||||
public MessageResult RenameDirectory([FromBody] RenameModel model)
|
||||
{
|
||||
if (scriptBuilder.State == ProcessorState.Building
|
||||
|| scriptBuilder.State == ProcessorState.Starting
|
||||
|| scriptBuilder.State == ProcessorState.Running
|
||||
|| scriptBuilder.State == ProcessorState.Stopping)
|
||||
{
|
||||
return new(false, $"Hệ thống đang trong trạng thái {scriptBuilder.State}, không thể thay đổi tên thư mục");
|
||||
}
|
||||
var fullPath = Path.Combine(ScriptConfiguration.ScriptStorePath, model.Path);
|
||||
if (!Directory.Exists(fullPath)) return new(false, "Folder không tồn tại");
|
||||
|
||||
var folder = Path.GetDirectoryName(fullPath) ?? "";
|
||||
var di = new DirectoryInfo(fullPath);
|
||||
di.MoveTo(Path.Combine(folder, model.NewName));
|
||||
return new(true, "");
|
||||
}
|
||||
|
||||
[HttpDelete]
|
||||
[Route("File")]
|
||||
public MessageResult DeleteFile([FromQuery] string path)
|
||||
{
|
||||
if (scriptBuilder.State == ProcessorState.Building
|
||||
|| scriptBuilder.State == ProcessorState.Starting
|
||||
|| scriptBuilder.State == ProcessorState.Running
|
||||
|| scriptBuilder.State == ProcessorState.Stopping)
|
||||
{
|
||||
return new(false, $"Hệ thống đang trong trạng thái {scriptBuilder.State}, không thể xóa file");
|
||||
}
|
||||
var fullPath = Path.Combine(ScriptConfiguration.ScriptStorePath, path);
|
||||
if (!System.IO.File.Exists(fullPath)) return new(false, "Source code không tồn tại");
|
||||
|
||||
System.IO.File.Delete(fullPath);
|
||||
ResetScriptProcessor();
|
||||
return new(true, "");
|
||||
}
|
||||
|
||||
[HttpDelete]
|
||||
[Route("Directory")]
|
||||
public MessageResult DeleteDirectory([FromQuery] string path)
|
||||
{
|
||||
if (scriptBuilder.State == ProcessorState.Building
|
||||
|| scriptBuilder.State == ProcessorState.Starting
|
||||
|| scriptBuilder.State == ProcessorState.Running
|
||||
|| scriptBuilder.State == ProcessorState.Stopping)
|
||||
{
|
||||
return new(false, $"Hệ thống đang trong trạng thái {scriptBuilder.State}, không thể xóa thư mục");
|
||||
}
|
||||
var fullPath = Path.Combine(ScriptConfiguration.ScriptStorePath, path);
|
||||
if (!Directory.Exists(fullPath)) return new(false, "Folder không tồn tại");
|
||||
|
||||
var di = new DirectoryInfo(fullPath);
|
||||
di.Delete(true);
|
||||
ResetScriptProcessor();
|
||||
return new(true, "");
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
[Route("UsingNamespaces")]
|
||||
public IEnumerable<string> GetUsingNamespaces() => ScriptConfiguration.UsingNamespaces;
|
||||
|
||||
[HttpGet]
|
||||
[Route("PreCode")]
|
||||
public string GetPreCode() => ScriptConfiguration.DeveloptGlobalsScript;
|
||||
|
||||
private void ResetScriptProcessor()
|
||||
{
|
||||
string message = string.Empty;
|
||||
scriptBuilder.Reset(ref message);
|
||||
}
|
||||
|
||||
private static IEnumerable<ScriptFile> GetScriptFiles(string parentDir)
|
||||
{
|
||||
var dirInfo = new DirectoryInfo(parentDir);
|
||||
foreach (var fileInfo in dirInfo.GetFiles())
|
||||
{
|
||||
yield return new ScriptFile(fileInfo.Name, System.IO.File.ReadAllText(fileInfo.FullName));
|
||||
}
|
||||
}
|
||||
|
||||
private static IEnumerable<ScriptFolder> GetScriptFolders(string parentDir)
|
||||
{
|
||||
var dirInfo = new DirectoryInfo(parentDir);
|
||||
foreach (var dir in dirInfo.GetDirectories())
|
||||
{
|
||||
yield return new ScriptFolder(dir.Name, GetScriptFolders(dir.FullName), GetScriptFiles(dir.FullName));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace RobotNet.ScriptManager.Controllers;
|
||||
[Route("api/[controller]")]
|
||||
[ApiController]
|
||||
[AllowAnonymous]
|
||||
public class ScriptManagerLoggerController(ILogger<ScriptManagerLoggerController> Logger) : ControllerBase
|
||||
{
|
||||
private readonly string LoggerDirectory = "scriptManagerlogs";
|
||||
|
||||
[HttpGet]
|
||||
public async Task<IEnumerable<string>> GetLogs([FromQuery(Name = "date")] DateTime date)
|
||||
{
|
||||
string temp = "";
|
||||
try
|
||||
{
|
||||
string fileName = $"{date:yyyy-MM-dd}.log";
|
||||
string path = Path.Combine(LoggerDirectory, fileName);
|
||||
if (!Path.GetFullPath(path).StartsWith(Path.GetFullPath(LoggerDirectory)))
|
||||
{
|
||||
Logger.LogWarning($"GetLogs: phát hiện đường dẫn không hợp lệ.");
|
||||
return [];
|
||||
}
|
||||
|
||||
if (!System.IO.File.Exists(path))
|
||||
{
|
||||
Logger.LogWarning($"GetLogs: không tìm thấy file log của ngày {date.ToShortDateString()} - {path}.");
|
||||
return [];
|
||||
}
|
||||
|
||||
temp = Path.Combine(LoggerDirectory, $"{Guid.NewGuid()}.log");
|
||||
System.IO.File.Copy(path, temp);
|
||||
|
||||
return await System.IO.File.ReadAllLinesAsync(temp);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.LogWarning($"GetLogs: Hệ thống có lỗi xảy ra - {ex.Message}");
|
||||
return [];
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (System.IO.File.Exists(temp)) System.IO.File.Delete(temp);
|
||||
}
|
||||
}
|
||||
}
|
||||
154
RobotNet.ScriptManager/Controllers/ScriptMissionsController.cs
Normal file
154
RobotNet.ScriptManager/Controllers/ScriptMissionsController.cs
Normal file
@@ -0,0 +1,154 @@
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using RobotNet.Script.Shares;
|
||||
using RobotNet.ScriptManager.Data;
|
||||
using RobotNet.ScriptManager.Services;
|
||||
using RobotNet.Shares;
|
||||
using System.Security.Claims;
|
||||
|
||||
namespace RobotNet.ScriptManager.Controllers;
|
||||
|
||||
[Route("api/[controller]")]
|
||||
[ApiController]
|
||||
[Authorize]
|
||||
public class ScriptMissionsController(ScriptMissionManager missionManager, ScriptManagerDbContext scriptManagerDb, ScriptMissionCreator missionCreator) : ControllerBase
|
||||
{
|
||||
[HttpGet]
|
||||
[Route("")]
|
||||
public IEnumerable<ScriptMissionDto> GetAlls() => missionManager.GetMissionDatas();
|
||||
|
||||
[HttpGet]
|
||||
[Route("Runner")]
|
||||
public async Task<SearchResult<InstanceMissionDto>> Search(
|
||||
[FromQuery(Name = "txtSearch")] string? txtSearch,
|
||||
[FromQuery(Name = "page")] int page,
|
||||
[FromQuery(Name = "size")] int size)
|
||||
{
|
||||
IOrderedQueryable<InstanceMission> query;
|
||||
|
||||
if (string.IsNullOrWhiteSpace(txtSearch))
|
||||
{
|
||||
query = scriptManagerDb.InstanceMissions.AsQueryable().OrderByDescending(x => x.CreatedAt);
|
||||
}
|
||||
else
|
||||
{
|
||||
query = scriptManagerDb.InstanceMissions.AsQueryable().Where(x => x.MissionName.Contains(txtSearch)).OrderByDescending(x => x.CreatedAt);
|
||||
}
|
||||
|
||||
var total = await query.CountAsync();
|
||||
|
||||
// Đảm bảo size hợp lệ
|
||||
if (size <= 0) size = 10;
|
||||
|
||||
// Tính tổng số trang
|
||||
var totalPages = (int)Math.Ceiling(total / (double)size);
|
||||
|
||||
// Đảm bảo page hợp lệ
|
||||
if (page <= 0) page = 1;
|
||||
if (page > totalPages && totalPages > 0) page = totalPages;
|
||||
|
||||
// Nếu không có dữ liệu, trả về rỗng
|
||||
var items = Enumerable.Empty<InstanceMissionDto>();
|
||||
if (total > 0)
|
||||
{
|
||||
items = [.. await query
|
||||
.OrderByDescending(x => x.CreatedAt)
|
||||
.Skip((page - 1) * size)
|
||||
.Take(size)
|
||||
.Select(x => new InstanceMissionDto
|
||||
{
|
||||
Id = x.Id,
|
||||
MissionName = x.MissionName,
|
||||
Parameters = x.Parameters,
|
||||
CreatedAt = x.CreatedAt,
|
||||
Status = x.Status,
|
||||
Log = x.Log
|
||||
})
|
||||
.ToListAsync()];
|
||||
}
|
||||
|
||||
return new SearchResult<InstanceMissionDto>
|
||||
{
|
||||
Total = total,
|
||||
Page = page,
|
||||
Size = size,
|
||||
Items = items
|
||||
};
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[Route("Runner")]
|
||||
public async Task<MessageResult<Guid>> Create(InstanceMissionCreateModel model)
|
||||
{
|
||||
try
|
||||
{
|
||||
var id = await missionCreator.CreateMissionAsync(model.Name, model.Parameters);
|
||||
return new(true, "Tạo nhiệm vụ thành công") { Data = id };
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new MessageResult<Guid>(false, $"Lỗi khi tạo nhiệm vụ: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
[HttpDelete]
|
||||
[Route("Runner/{id:guid}")]
|
||||
public async Task<MessageResult> Cancel(Guid id, [FromQuery] string? reason)
|
||||
{
|
||||
if (missionManager.Cancel(id, $"Cancel by user '{HttpContext.User.FindFirst(ClaimTypes.Name)?.Value??HttpContext.User.Identity?.Name}' with reason '{reason}'"))
|
||||
{
|
||||
var mission = await scriptManagerDb.InstanceMissions.FindAsync(id);
|
||||
if (mission != null)
|
||||
{
|
||||
mission.Status = MissionStatus.Canceling;
|
||||
await scriptManagerDb.SaveChangesAsync();
|
||||
}
|
||||
return new MessageResult(true, "Gửi yêu cầu hủy nhiệm vụ thành công");
|
||||
}
|
||||
else
|
||||
{
|
||||
return new MessageResult(false, "Không thể hủy nhiệm vụ này hoặc nhiệm vụ không tồn tại");
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPut]
|
||||
[Route("Runner/{id:guid}/pause")]
|
||||
public async Task<MessageResult> Pause(Guid id)
|
||||
{
|
||||
if (missionManager.Pause(id))
|
||||
{
|
||||
var mission = await scriptManagerDb.InstanceMissions.FindAsync(id);
|
||||
if (mission != null)
|
||||
{
|
||||
mission.Status = MissionStatus.Pausing;
|
||||
await scriptManagerDb.SaveChangesAsync();
|
||||
}
|
||||
return new MessageResult(true, "Gửi yêu cầu tạm dừng nhiệm vụ thành công");
|
||||
}
|
||||
else
|
||||
{
|
||||
return new MessageResult(false, "Không thể tạm dừng nhiệm vụ này hoặc nhiệm vụ không tồn tại");
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPut]
|
||||
[Route("Runner/{id:guid}/resume")]
|
||||
public async Task<MessageResult> Resume(Guid id)
|
||||
{
|
||||
if (missionManager.Resume(id))
|
||||
{
|
||||
var mission = await scriptManagerDb.InstanceMissions.FindAsync(id);
|
||||
if (mission != null)
|
||||
{
|
||||
mission.Status = MissionStatus.Resuming;
|
||||
await scriptManagerDb.SaveChangesAsync();
|
||||
}
|
||||
return new MessageResult(true, "Gửi yêu cầu tiếp tục nhiệm vụ thành công");
|
||||
}
|
||||
else
|
||||
{
|
||||
return new MessageResult(false, "Không thể tiếp tục nhiệm vụ này hoặc nhiệm vụ không tồn tại");
|
||||
}
|
||||
}
|
||||
}
|
||||
18
RobotNet.ScriptManager/Controllers/ScriptTasksController.cs
Normal file
18
RobotNet.ScriptManager/Controllers/ScriptTasksController.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using RobotNet.Script.Shares;
|
||||
using RobotNet.ScriptManager.Services;
|
||||
using RobotNet.Shares;
|
||||
|
||||
namespace RobotNet.ScriptManager.Controllers;
|
||||
|
||||
[Route("api/[controller]")]
|
||||
[ApiController]
|
||||
[Authorize]
|
||||
public class ScriptTasksController(ScriptTaskManager taskManager) : ControllerBase
|
||||
{
|
||||
[HttpGet]
|
||||
[Route("")]
|
||||
public IEnumerable<ScriptTaskDto> GetAlls() => taskManager.GetTaskDatas();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using RobotNet.Script.Shares;
|
||||
using RobotNet.ScriptManager.Services;
|
||||
using RobotNet.Shares;
|
||||
|
||||
namespace RobotNet.ScriptManager.Controllers;
|
||||
|
||||
[Route("api/[controller]")]
|
||||
[ApiController]
|
||||
[Authorize]
|
||||
public class ScriptVariablesController(ScriptGlobalsManager globalManager) : ControllerBase
|
||||
{
|
||||
[HttpGet]
|
||||
[Route("")]
|
||||
public IEnumerable<ScriptVariableDto> GetAlls() => globalManager.GetVariablesData();
|
||||
|
||||
|
||||
[HttpGet]
|
||||
[Route("{name}")]
|
||||
public MessageResult<string> GetVariableValue(string name)
|
||||
{
|
||||
if (globalManager.Globals.TryGetValue(name, out var value))
|
||||
{
|
||||
return new (true, "") { Data = value?.ToString() ?? "null" };
|
||||
}
|
||||
else
|
||||
{
|
||||
return new(false, $"Variable \"{name}\" not found.");
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPut]
|
||||
[Route("{name}")]
|
||||
public MessageResult UpdateVariableValue(string name, [FromBody] UpdateVariableModel model)
|
||||
{
|
||||
try
|
||||
{
|
||||
if(name != model.Name)
|
||||
{
|
||||
return new MessageResult(false, "Variable name in the URL does not match the name in the body.");
|
||||
}
|
||||
|
||||
globalManager.SetValue(model.Name, model.Value);
|
||||
return new MessageResult(true, $"Variable \"{model.Name}\" updated {model.Value} successfully.");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new MessageResult(false, ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPut]
|
||||
[Route("{name}/Reset")]
|
||||
public MessageResult ResetVariableValue(string name, [FromBody] UpdateVariableModel model)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (name != model.Name)
|
||||
{
|
||||
return new MessageResult(false, "Variable name in the URL does not match the name in the body.");
|
||||
}
|
||||
|
||||
globalManager.ResetValue(model.Name);
|
||||
return new MessageResult(true, $"Variable \"{model.Name}\" reset successfully.");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new MessageResult(false, ex.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user