refactors
This commit is contained in:
@@ -3,6 +3,7 @@ using Microsoft.Extensions.Hosting;
|
||||
using ModVersionChecker.managers.filesystem;
|
||||
using ModVersionChecker.managers.interfaces;
|
||||
using ModVersionChecker.managers.litedb;
|
||||
using ModVersionChecker.repository.api;
|
||||
using ModVersionChecker.service;
|
||||
using ModVersionChecker.service.interfaces;
|
||||
using ModVersionChecker.ui.forms;
|
||||
@@ -19,16 +20,19 @@ namespace ModVersionChecker
|
||||
|
||||
builder.ConfigureServices(services =>
|
||||
{
|
||||
services.AddSingleton<IConfigManager, ConfigLiteDb>();
|
||||
services.AddSingleton<IAppsManager, AppLiteDb>();
|
||||
services.AddSingleton<IConfigRepository, ConfigLiteDb>();
|
||||
services.AddSingleton<IAppRepository, AppLiteDb>();
|
||||
services.AddSingleton<ISourcesDefManager, SourcesLiteDb>();
|
||||
services.AddSingleton<IFlightSimsManager, TypeLiteDb>();
|
||||
services.AddSingleton<ITypeManager, TypeConfigLiteDb>();
|
||||
services.AddSingleton<ITypeRepository, TypeLiteDb>();
|
||||
services.AddSingleton<ITypeConfigRepository, TypeConfigLiteDb>();
|
||||
services.AddSingleton<IFormFactory, FormFactory>();
|
||||
services.AddSingleton<IAppStatusManager, AppStatusManager>();
|
||||
services.AddSingleton<INotifyIconService, NotifyIconService>();
|
||||
services.AddSingleton<IAppStatusRepository, AppStatusManager>();
|
||||
services.AddSingleton<INotificationService, NotificationService>();
|
||||
services.AddSingleton<IApiService, ApiService>();
|
||||
services.AddSingleton<IVersionService, VersionService>();
|
||||
services.AddSingleton<IApiRepository, ApiRepository>();
|
||||
services.AddSingleton<IStateService, StateService>();
|
||||
services.AddSingleton<IAppService, AppService>();
|
||||
|
||||
services.AddTransient<MainForm>();
|
||||
services.AddTransient<AppDetailsForm>();
|
||||
@@ -59,9 +63,10 @@ namespace ModVersionChecker
|
||||
|
||||
var serviceProvider = host.Services;
|
||||
var configForm = serviceProvider.GetService<MainForm>();
|
||||
var notifyIconService = serviceProvider.GetRequiredService<INotifyIconService>();
|
||||
var configManager = serviceProvider.GetRequiredService<IConfigManager>();
|
||||
var notifyIconService = serviceProvider.GetRequiredService<INotificationService>();
|
||||
var configManager = serviceProvider.GetRequiredService<IConfigRepository>();
|
||||
var versionService = serviceProvider.GetRequiredService<IVersionService>();
|
||||
var appService = serviceProvider.GetRequiredService<IAppService>();
|
||||
var config = configManager.GetConfig();
|
||||
|
||||
EventHandler openFormHandler = (s, e) =>
|
||||
@@ -101,9 +106,9 @@ namespace ModVersionChecker
|
||||
if (checkOnInitialStart)
|
||||
{
|
||||
|
||||
Task.Run(async () =>
|
||||
Task.Run(() =>
|
||||
{
|
||||
await versionService.CheckAllApps();
|
||||
appService.CheckAllApps();
|
||||
if (configForm != null)
|
||||
{
|
||||
configForm.UpdateListView();
|
||||
|
@@ -7,34 +7,31 @@ namespace ModVersionChecker
|
||||
{
|
||||
public class VersionChecker
|
||||
{
|
||||
private readonly IConfigManager _configManager;
|
||||
private readonly IAppService _appService;
|
||||
private readonly IConfigRepository _configManager;
|
||||
private readonly IVersionService _versionService;
|
||||
|
||||
public event EventHandler<string>? OnFinished;
|
||||
|
||||
public VersionChecker(
|
||||
IAppService appService,
|
||||
IVersionService versionService,
|
||||
IConfigManager configManager)
|
||||
IConfigRepository configManager
|
||||
)
|
||||
{
|
||||
_configManager = configManager ?? throw new ArgumentNullException(nameof(configManager));
|
||||
_versionService = versionService ?? throw new ArgumentNullException(nameof(versionService));
|
||||
_appService = appService ?? throw new ArgumentNullException(nameof(appService));
|
||||
}
|
||||
|
||||
//private void HandleAppError(string message, AppConfig app)
|
||||
//{
|
||||
// errorMessages.Add(message);
|
||||
// _appsManager.UpdateStatus(app, AppStatus.ERROR);
|
||||
//}
|
||||
|
||||
public void StartVersionChecking()
|
||||
{
|
||||
var config = _configManager.Load() ?? new Config();
|
||||
// Run version checks in a background thread
|
||||
new Thread(async () =>
|
||||
new Thread(() =>
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
await _versionService.CheckAllApps();
|
||||
_appService.CheckAllApps();
|
||||
|
||||
Thread.Sleep(config.IntervalMinutes * 60 * 1000);
|
||||
}
|
||||
@@ -42,95 +39,5 @@ namespace ModVersionChecker
|
||||
})
|
||||
{ IsBackground = true }.Start();
|
||||
}
|
||||
|
||||
|
||||
|
||||
//public async Task CheckAsync()
|
||||
//{
|
||||
// var config = _configManager.Load() ?? new GlobalConfig();
|
||||
// var apps = _appsManager.Load() ?? new List<AppConfig>();
|
||||
// var sources = _sourcesDefManager.List() ?? new List<SourceDef>();
|
||||
// var fsMods = _fsManager.Load() ?? new List<TypeDef>();
|
||||
// var types = _typeConfigManager.GetTypeConfigs() ?? new List<TypeConfig>();
|
||||
|
||||
// var appVersionsMap = await _apiVersionService.GetAppVersionsAsync(apps);
|
||||
|
||||
// updateMessages = new List<string>();
|
||||
// errorMessages = new List<string>();
|
||||
|
||||
// foreach (AppConfig app in apps)
|
||||
// {
|
||||
// if (app.Status != AppStatus.ERROR && app.LastCheckedAt != 0 && app.LastCheckedAt < TimeUtils.GetUnixTimeMillis(DateTime.Now.AddMinutes(-60)))
|
||||
// continue;
|
||||
|
||||
// var status = AppStatus.NONE;
|
||||
// var sourceId = app.Source;
|
||||
|
||||
// // Skip apps that are not in the API response
|
||||
|
||||
// if (!appVersionsMap.Any(a => app.Id == a.Id)) {
|
||||
// continue;
|
||||
// }
|
||||
// var latesstVersion = appVersionsMap.FirstOrDefault(a => a.Id == app.Id).LatestVersion;
|
||||
// if (string.IsNullOrWhiteSpace(sourceId))
|
||||
// {
|
||||
// HandleAppError($"{app.Name} has no source configured.", app);
|
||||
// continue;
|
||||
// }
|
||||
// var source = sources.FirstOrDefault(s => s.Id == sourceId);
|
||||
// if (source == null)
|
||||
// {
|
||||
// HandleAppError($"{app.Name} has an invalid source: {sourceId}", app);
|
||||
// continue;
|
||||
// }
|
||||
// try
|
||||
// {
|
||||
// var type = app.Types[0];
|
||||
// var typeConfig = types[0];
|
||||
// if (typeConfig == null)
|
||||
// {
|
||||
// HandleAppError($"{app.Name} has no FS mod path configured for version {type}.", app);
|
||||
// continue;
|
||||
// }
|
||||
// var current = NuGetVersion.Parse(VersionUtils.GetCurrentVersion(app, typeConfig));
|
||||
// var latest = NuGetVersion.Parse(latesstVersion);
|
||||
|
||||
// app.CurrentVersion = current.ToString();
|
||||
// app.LatestVersion = latest.ToString();
|
||||
|
||||
// if (latest.CompareTo(current) == 1)
|
||||
// {
|
||||
// updateMessages.Add($"{app.Name}: New version {latest} (current: {current})");
|
||||
// status = AppStatus.UPDATE_AVAILABLE;
|
||||
// }
|
||||
|
||||
// _appsManager.UpdateStatus(app, status);
|
||||
// }
|
||||
// catch (Exception ex)
|
||||
// {
|
||||
// HandleAppError($"Failed for {app.Name}: {ex.Message}", app);
|
||||
// }
|
||||
// }
|
||||
|
||||
// if (updateMessages.Count > 0)
|
||||
// {
|
||||
// _notifyIconService.ShowBalloonTip(
|
||||
// 10000,
|
||||
// "Updates Available",
|
||||
// string.Join("\n", updateMessages),
|
||||
// ToolTipIcon.Info
|
||||
// );
|
||||
// }
|
||||
// if (errorMessages.Count > 0)
|
||||
// {
|
||||
// _notifyIconService.ShowBalloonTip(
|
||||
// 10000,
|
||||
// "Errors",
|
||||
// string.Join("\n", errorMessages),
|
||||
// ToolTipIcon.Error
|
||||
// );
|
||||
// }
|
||||
// OnFinished?.Invoke(this, "Version check completed.");
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
@@ -141,7 +141,7 @@ namespace ModVersionChecker.repository.api
|
||||
|
||||
public async Task<List<AppResponse>?> SearchApps(string searchText)
|
||||
{
|
||||
var url = $"{baseUrl}/app/search?query={Uri.EscapeDataString(searchText)}";
|
||||
var url = $"{baseUrl}/app/search?q={Uri.EscapeDataString(searchText)}";
|
||||
var request = await CreateRequestAsync(HttpMethod.Get, url);
|
||||
var response = await _httpClient.SendAsync(request);
|
||||
response.EnsureSuccessStatusCode();
|
||||
@@ -149,7 +149,7 @@ namespace ModVersionChecker.repository.api
|
||||
return JsonSerializer.Deserialize<List<AppResponse>>(json, new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
|
||||
}
|
||||
|
||||
public async Task<List<AppResponse>> GetAppsByIds(App[] apps)
|
||||
public async Task<List<AppResponse>> GetAppsByIds(List<App> apps)
|
||||
{
|
||||
var query = string.Join("&", apps.Select(a => $"id={Uri.EscapeDataString(a.Id)}"));
|
||||
var url = $"{baseUrl}/app/search?{query}";
|
||||
|
@@ -12,6 +12,6 @@ namespace ModVersionChecker.repository.api
|
||||
Task<List<AppResponse>?> SearchApps(string searchText);
|
||||
Task<List<TypeResponse>> GetTypes();
|
||||
Task<List<SourceResponse>> GetSources();
|
||||
Task<List<AppResponse>> GetAppsByIds(App[] apps);
|
||||
Task<List<AppResponse>> GetAppsByIds(List<App> apps);
|
||||
}
|
||||
}
|
@@ -1,4 +1,5 @@
|
||||
using ModVersionChecker.enums;
|
||||
using ModVersionChecker.utils;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace ModVersionChecker.repository.api.dto
|
||||
@@ -74,6 +75,7 @@ namespace ModVersionChecker.repository.api.dto
|
||||
LatestVersion = appResponse.LatestVersion,
|
||||
Status = appResponse.Status,
|
||||
LastCheckedAt = appResponse.LastCheckedAt,
|
||||
LocalCheckedAt = TimeUtils.GetUnixTimeMillis(null)
|
||||
|
||||
};
|
||||
}
|
||||
|
@@ -9,7 +9,7 @@ using System.Threading.Tasks;
|
||||
namespace ModVersionChecker.managers.filesystem
|
||||
{
|
||||
|
||||
public class AppStatusManager : IAppStatusManager
|
||||
public class AppStatusManager : IAppStatusRepository
|
||||
{
|
||||
private Dictionary<string, AppStatus> _statuses = new Dictionary<string, AppStatus>();
|
||||
|
||||
|
@@ -6,7 +6,7 @@ using System.Text.Json;
|
||||
|
||||
namespace ModVersionChecker.managers.filesystem
|
||||
{
|
||||
public class ConfigManager : IConfigManager
|
||||
public class ConfigManager : IConfigRepository
|
||||
{
|
||||
|
||||
private static readonly string _filePath = Path.Combine(AppContext.BaseDirectory, "data", "config.json");
|
||||
|
@@ -7,7 +7,7 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace ModVersionChecker.managers.interfaces
|
||||
{
|
||||
public interface IAppsManager
|
||||
public interface IAppRepository
|
||||
{
|
||||
|
||||
List<App> Load();
|
@@ -7,7 +7,7 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace ModVersionChecker.managers.interfaces
|
||||
{
|
||||
public interface IAppStatusManager
|
||||
public interface IAppStatusRepository
|
||||
{
|
||||
List<AppStatus> Load();
|
||||
void Save(List<AppStatus> appStatuses);
|
@@ -7,7 +7,7 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace ModVersionChecker.managers.interfaces
|
||||
{
|
||||
public interface IConfigManager
|
||||
public interface IConfigRepository
|
||||
{
|
||||
Config Load();
|
||||
void Save(Config config);
|
@@ -2,7 +2,7 @@
|
||||
|
||||
namespace ModVersionChecker.managers.interfaces
|
||||
{
|
||||
public interface ITypeManager
|
||||
public interface ITypeConfigRepository
|
||||
{
|
||||
List<TypeConfig> GetTypeConfigs();
|
||||
void SaveTypeConfigs(List<TypeConfig> types);
|
@@ -7,7 +7,7 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace ModVersionChecker.managers.interfaces
|
||||
{
|
||||
public interface IFlightSimsManager
|
||||
public interface ITypeRepository
|
||||
{
|
||||
List<TypeResponse> Load();
|
||||
void Save(TypeResponse config);
|
@@ -9,7 +9,7 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace ModVersionChecker.managers.litedb
|
||||
{
|
||||
public class AppLiteDb : LiteDb, IAppsManager
|
||||
public class AppLiteDb : LiteDb, IAppRepository
|
||||
{
|
||||
protected override string collection => LiteDb.APPS_COLLECTION;
|
||||
|
||||
|
@@ -3,7 +3,7 @@ using ModVersionChecker.model;
|
||||
|
||||
namespace ModVersionChecker.managers.litedb
|
||||
{
|
||||
public class ConfigLiteDb : LiteDb, IConfigManager
|
||||
public class ConfigLiteDb : LiteDb, IConfigRepository
|
||||
{
|
||||
protected override string collection => LiteDb.CONFIG_COLLECTION;
|
||||
public Config Load()
|
||||
|
@@ -3,7 +3,7 @@ using ModVersionChecker.model;
|
||||
|
||||
namespace ModVersionChecker.managers.litedb
|
||||
{
|
||||
internal class TypeConfigLiteDb : LiteDb, ITypeManager
|
||||
internal class TypeConfigLiteDb : LiteDb, ITypeConfigRepository
|
||||
{
|
||||
protected override string collection => TYPES_COLLECTION;
|
||||
|
||||
|
@@ -8,7 +8,7 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace ModVersionChecker.managers.litedb
|
||||
{
|
||||
internal class TypeLiteDb : LiteDb, IFlightSimsManager
|
||||
internal class TypeLiteDb : LiteDb, ITypeRepository
|
||||
{
|
||||
protected override string collection => FLIGHT_SIMS_COLLECTION;
|
||||
|
||||
|
@@ -31,16 +31,16 @@ namespace ModVersionChecker.service
|
||||
public Task<List<SourceResponse>> GetSources()
|
||||
=> _apiRepository.GetSources();
|
||||
|
||||
public async Task<List<App>> GetAppsByIds(App[] apps)
|
||||
public async Task<List<App>> GetAppsByIds(List<App> apps)
|
||||
{
|
||||
var appResponses = await _apiRepository.GetAppsByIds(apps);
|
||||
return appResponses.Select(AppResponse.toModel).ToList();
|
||||
}
|
||||
|
||||
public Task<List<App>?> SearchApps(string searchText)
|
||||
public async Task<List<App>> SearchApps(string searchText)
|
||||
{
|
||||
var appResponses = _apiRepository.SearchApps(searchText);
|
||||
return appResponses.ContinueWith(t => t.Result?.Select(AppResponse.toModel).ToList());
|
||||
var appResponses = await _apiRepository.SearchApps(searchText);
|
||||
return appResponses.Select(AppResponse.toModel).ToList();
|
||||
}
|
||||
|
||||
}
|
||||
|
203
ModVersionChecker/service/AppService.cs
Normal file
203
ModVersionChecker/service/AppService.cs
Normal file
@@ -0,0 +1,203 @@
|
||||
using ModVersionChecker.enums;
|
||||
using ModVersionChecker.managers.interfaces;
|
||||
using ModVersionChecker.model;
|
||||
using ModVersionChecker.service.interfaces;
|
||||
using ModVersionChecker.utils;
|
||||
|
||||
namespace ModVersionChecker.service
|
||||
{
|
||||
public class AppService: IAppService
|
||||
{
|
||||
private readonly IApiService _apiService;
|
||||
private readonly IAppRepository _appRepository;
|
||||
private readonly IVersionService _versionService;
|
||||
private readonly IStateService _stateService;
|
||||
private readonly INotificationService _notificationService;
|
||||
private readonly Config _config;
|
||||
|
||||
public AppService(
|
||||
IApiService apiService,
|
||||
IVersionService versionService,
|
||||
IAppRepository appManager,
|
||||
IStateService stateService,
|
||||
INotificationService notificationService
|
||||
|
||||
) {
|
||||
_apiService = apiService;
|
||||
_appRepository = appManager;
|
||||
_versionService = versionService;
|
||||
_stateService = stateService;
|
||||
_notificationService = notificationService;
|
||||
_config = _stateService.GetConfig();
|
||||
}
|
||||
|
||||
public bool CreateApp(App? app)
|
||||
{
|
||||
if (app != null)
|
||||
{
|
||||
_appRepository.Insert(app);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool DeleteApp(App? app)
|
||||
{
|
||||
if (app !=null)
|
||||
{
|
||||
_appRepository.Delete(app.Id);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool UpdateApp(App? app)
|
||||
{
|
||||
if (app != null)
|
||||
{
|
||||
_appRepository.Update(app);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public async Task<List<App>> GetAndUpdateCurrentApps()
|
||||
{
|
||||
|
||||
try
|
||||
{
|
||||
List<App> apps = _appRepository.Load();
|
||||
|
||||
if (apps == null) throw new InvalidOperationException("Failed to load apps: repository returned null.");
|
||||
if (apps.Count == 0) return new List<App>();
|
||||
|
||||
List<App> updatedApps = await _apiService.GetAppsByIds(apps);
|
||||
|
||||
if (updatedApps == null) throw new InvalidOperationException("Failed to load apps: repository returned null.");
|
||||
if (updatedApps.Count == 0) return apps;
|
||||
|
||||
foreach (App app in updatedApps)
|
||||
{
|
||||
app.CurrentVersion = _versionService.GetCurrentVersion(app);
|
||||
CheckAppStatus(app);
|
||||
_appRepository.Update(app);
|
||||
}
|
||||
_stateService.SetApps(updatedApps);
|
||||
return updatedApps;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine(ex);
|
||||
return new List<App>();
|
||||
}
|
||||
}
|
||||
|
||||
public App CheckAppStatus(App app)
|
||||
{
|
||||
var status = AppStatus.NONE;
|
||||
if (app.LatestVersion == null)
|
||||
{
|
||||
app.Status = AppStatus.ERROR;
|
||||
_appRepository.Update(app);
|
||||
return app;
|
||||
}
|
||||
var currentVersion = app.CurrentVersion;
|
||||
var updateMessage = "";
|
||||
if (_versionService.IsUpdateAvailable(currentVersion, app.LatestVersion))
|
||||
{
|
||||
updateMessage = $"{app.Name}: New version {app.LatestVersion} (current: {currentVersion})";
|
||||
status = AppStatus.UPDATE_AVAILABLE;
|
||||
}
|
||||
app.Status = status;
|
||||
app.LastCheckedAt = TimeUtils.GetUnixTimeMillis(null);
|
||||
return app;
|
||||
}
|
||||
|
||||
public void CheckAllApps()
|
||||
{
|
||||
|
||||
var apps = _appRepository.Load();
|
||||
var sources = _stateService.GetSources();
|
||||
List<string> errorMessages = new List<string>();
|
||||
List<string> updateMessages = new List<string>();
|
||||
|
||||
if (apps == null || apps.Count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
foreach (App app in apps)
|
||||
{
|
||||
|
||||
var sourceId = app.Source;
|
||||
|
||||
if (
|
||||
app.Status != AppStatus.ERROR && app.LastCheckedAt != 0 &&
|
||||
app.LastCheckedAt < TimeUtils.GetUnixTimeMillis(DateTime.UtcNow.AddMinutes(-60)) ||
|
||||
string.IsNullOrWhiteSpace(sourceId)
|
||||
)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var latesstVersion = app.LatestVersion;
|
||||
var source = sources.FirstOrDefault(s => s.Id == sourceId);
|
||||
if (source == null)
|
||||
{
|
||||
errorMessages.Add($"{app.Name} has an invalid source: {sourceId}");
|
||||
continue;
|
||||
}
|
||||
var typeConfig = _config.Types.FirstOrDefault(t => t.ShortName == app.Type);
|
||||
if (typeConfig == null)
|
||||
{
|
||||
errorMessages.Add($"{app.Name} has no valid type config.");
|
||||
continue;
|
||||
}
|
||||
app.CurrentVersion = VersionUtils.GetCurrentVersion(app, typeConfig);
|
||||
|
||||
var updatedApp = CheckAppStatus(app);
|
||||
_appRepository.Update(updatedApp);
|
||||
if (updatedApp.Status == AppStatus.UPDATE_AVAILABLE)
|
||||
{
|
||||
updateMessages.Add($"{app.Name}: New version {app.LatestVersion} (current: {app.CurrentVersion})");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
errorMessages.Add($"Failed to check {app.Name}: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
if (updateMessages.Count > 0)
|
||||
{
|
||||
_notificationService.ShowBalloonTip(
|
||||
10000,
|
||||
"Updates Available",
|
||||
string.Join("\n", updateMessages),
|
||||
ToolTipIcon.Info
|
||||
);
|
||||
}
|
||||
if (errorMessages.Count > 0)
|
||||
{
|
||||
_notificationService.ShowBalloonTip(
|
||||
10000,
|
||||
"Errors",
|
||||
string.Join("\n", errorMessages),
|
||||
ToolTipIcon.Error
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public List<App> PurgeExisitingApps(List<App> apps)
|
||||
{
|
||||
var _existingApps = _stateService.GetApps();
|
||||
if (_existingApps == null || _existingApps.Count == 0)
|
||||
{
|
||||
return apps;
|
||||
}
|
||||
return apps.Where(a => !_existingApps.Any(e => e.Id == a.Id)).ToList();
|
||||
}
|
||||
}
|
||||
}
|
@@ -7,7 +7,7 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace ModVersionChecker.service
|
||||
{
|
||||
public class NotifyIconService : INotifyIconService
|
||||
public class NotificationService : INotificationService
|
||||
{
|
||||
private NotifyIcon? _notifyIcon;
|
||||
public void SetNotifyIcon(NotifyIcon icon)
|
41
ModVersionChecker/service/StateService.cs
Normal file
41
ModVersionChecker/service/StateService.cs
Normal file
@@ -0,0 +1,41 @@
|
||||
using ModVersionChecker.managers.interfaces;
|
||||
using ModVersionChecker.model;
|
||||
using ModVersionChecker.repository.api.dto;
|
||||
using ModVersionChecker.service.interfaces;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ModVersionChecker.service
|
||||
{
|
||||
public class StateService: IStateService
|
||||
{
|
||||
private List<App> apps = new List<App>();
|
||||
private List<SourceResponse> sources = new List<SourceResponse>();
|
||||
private List<TypeResponse> types = new List<TypeResponse>();
|
||||
private Config config = new Config();
|
||||
private readonly IAppRepository _appRepository;
|
||||
|
||||
public StateService(
|
||||
IAppRepository appRepository
|
||||
) {
|
||||
_appRepository = appRepository;
|
||||
}
|
||||
|
||||
public List<App> GetApps() => apps;
|
||||
public void SetApps(List<App> apps) => this.apps = apps;
|
||||
public List<SourceResponse> GetSources() => sources;
|
||||
public void SetSources(List<SourceResponse> sources) => this.sources = sources;
|
||||
public List<TypeResponse> GetTypes() => types;
|
||||
public void SetTypes(List<TypeResponse> types) => this.types = types;
|
||||
public Config GetConfig() => config;
|
||||
public void SetConfig(Config config) => this.config = config;
|
||||
|
||||
|
||||
public void UpdateApps() => this.apps = _appRepository.Load();
|
||||
|
||||
|
||||
}
|
||||
}
|
@@ -9,121 +9,25 @@ namespace ModVersionChecker.service
|
||||
{
|
||||
public class VersionService: IVersionService
|
||||
{
|
||||
private readonly IApiService _apiService;
|
||||
private readonly IAppsManager _appsManager;
|
||||
private readonly INotifyIconService _notifyIconService;
|
||||
private readonly Config _globalConfig;
|
||||
|
||||
public VersionService(
|
||||
IApiService apiVersionService,
|
||||
IAppsManager appsManager,
|
||||
IConfigManager configManager,
|
||||
INotifyIconService notifyIconService)
|
||||
{
|
||||
_apiService = apiVersionService;
|
||||
_appsManager = appsManager ?? throw new ArgumentNullException(nameof(appsManager));
|
||||
_notifyIconService = notifyIconService ?? throw new ArgumentNullException(nameof(notifyIconService));
|
||||
IConfigRepository configManager
|
||||
) {
|
||||
_globalConfig = configManager.Load() ?? new Config();
|
||||
}
|
||||
|
||||
public App CheckApp(App app)
|
||||
public string GetCurrentVersion(App app)
|
||||
{
|
||||
var status = AppStatus.NONE;
|
||||
if (app.LatestVersion== null)
|
||||
{
|
||||
app.Status = AppStatus.ERROR;
|
||||
_appsManager.Update(app);
|
||||
return app;
|
||||
}
|
||||
var currentVersion = app.CurrentVersion;
|
||||
var updateMessage = "";
|
||||
if (isUpdateAvailable(currentVersion, app.LatestVersion))
|
||||
{
|
||||
updateMessage = $"{app.Name}: New version {app.LatestVersion} (current: {currentVersion})";
|
||||
status = AppStatus.UPDATE_AVAILABLE;
|
||||
}
|
||||
app.Status = status;
|
||||
app.LastCheckedAt = TimeUtils.GetUnixTimeMillis(null);
|
||||
_appsManager.Update(app);
|
||||
return app;
|
||||
}
|
||||
|
||||
public async Task CheckAllApps()
|
||||
{
|
||||
|
||||
var apps = _appsManager.Load();
|
||||
var sources = await _apiService.GetSources();
|
||||
var appVersionsMap = await _apiService.GetAppVersionsAsync(apps);
|
||||
List<string> errorMessages = new List<string>();
|
||||
List<string> updateMessages = new List<string>();
|
||||
|
||||
if (apps == null || apps.Count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
foreach (App app in apps)
|
||||
{
|
||||
|
||||
var sourceId = app.Source;
|
||||
|
||||
if (
|
||||
app.Status != AppStatus.ERROR && app.LastCheckedAt != 0 && app.LastCheckedAt < TimeUtils.GetUnixTimeMillis(DateTime.UtcNow.AddMinutes(-60)) ||
|
||||
!app.Active || string.IsNullOrWhiteSpace(sourceId)
|
||||
)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var latesstVersion = appVersionsMap.FirstOrDefault(a => a.Id == app.Id)?.LatestVersion;
|
||||
var source = sources.FirstOrDefault(s => s.Id == sourceId);
|
||||
if (source == null)
|
||||
{
|
||||
errorMessages.Add($"{app.Name} has an invalid source: {sourceId}");
|
||||
continue;
|
||||
}
|
||||
var typeConfig = _globalConfig.Types.FirstOrDefault(t => t.ShortName == app.Type);
|
||||
if (typeConfig == null)
|
||||
{
|
||||
errorMessages.Add($"{app.Name} has no valid type config.");
|
||||
continue;
|
||||
}
|
||||
app.CurrentVersion = VersionUtils.GetCurrentVersion(app, typeConfig);
|
||||
|
||||
var updatedApp = CheckApp(app);
|
||||
if (updatedApp.Status == AppStatus.UPDATE_AVAILABLE)
|
||||
{
|
||||
updateMessages.Add($"{app.Name}: New version {app.LatestVersion} (current: {app.CurrentVersion})");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
errorMessages.Add($"Failed to check {app.Name}: {ex.Message}");
|
||||
throw new InvalidOperationException($"No type config found for app type: {app.Type}");
|
||||
}
|
||||
return VersionUtils.GetCurrentVersion(app, typeConfig);
|
||||
}
|
||||
|
||||
if (updateMessages.Count > 0)
|
||||
{
|
||||
_notifyIconService.ShowBalloonTip(
|
||||
10000,
|
||||
"Updates Available",
|
||||
string.Join("\n", updateMessages),
|
||||
ToolTipIcon.Info
|
||||
);
|
||||
}
|
||||
if (errorMessages.Count > 0)
|
||||
{
|
||||
_notifyIconService.ShowBalloonTip(
|
||||
10000,
|
||||
"Errors",
|
||||
string.Join("\n", errorMessages),
|
||||
ToolTipIcon.Error
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private bool isUpdateAvailable(string currentVersion, string latestVersion)
|
||||
public bool IsUpdateAvailable(string currentVersion, string latestVersion)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
@@ -12,8 +12,7 @@ namespace ModVersionChecker.service.interfaces
|
||||
Task<List<SourceResponse>> GetSources();
|
||||
Task<AppVersionsResponse?> GetAppLatestVersionAsync(App app);
|
||||
Task<bool> AuthenticateAsync(string username, string password);
|
||||
Task<List<App>> GetAppsByIds(App[] apps);
|
||||
Task<List<App>?> SearchApps(string searchText);
|
||||
|
||||
Task<List<App>> GetAppsByIds(List<App> apps);
|
||||
Task<List<App>> SearchApps(string searchText);
|
||||
}
|
||||
}
|
20
ModVersionChecker/service/interfaces/IAppService.cs
Normal file
20
ModVersionChecker/service/interfaces/IAppService.cs
Normal file
@@ -0,0 +1,20 @@
|
||||
namespace ModVersionChecker.service.interfaces
|
||||
{
|
||||
public interface IAppService
|
||||
{
|
||||
// List<App> GetAppsById(List<App> apps);
|
||||
// bool SaveApps(List<App> apps);
|
||||
// App? GetAppById(string id);
|
||||
|
||||
bool CreateApp(App? app);
|
||||
bool UpdateApp(App? app);
|
||||
|
||||
bool DeleteApp(App? app);
|
||||
Task<List<App>> GetAndUpdateCurrentApps();
|
||||
|
||||
App CheckAppStatus(App app);
|
||||
void CheckAllApps();
|
||||
|
||||
List<App> PurgeExisitingApps(List<App> apps);
|
||||
}
|
||||
}
|
@@ -6,7 +6,7 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace ModVersionChecker.service.interfaces
|
||||
{
|
||||
public interface INotifyIconService
|
||||
public interface INotificationService
|
||||
{
|
||||
void SetNotifyIcon(NotifyIcon icon);
|
||||
void ShowBalloonTip(int millis, string title, string message, ToolTipIcon icon);
|
20
ModVersionChecker/service/interfaces/IStateService.cs
Normal file
20
ModVersionChecker/service/interfaces/IStateService.cs
Normal file
@@ -0,0 +1,20 @@
|
||||
using ModVersionChecker.repository.api.dto;
|
||||
using ModVersionChecker.model;
|
||||
|
||||
|
||||
namespace ModVersionChecker.service.interfaces
|
||||
{
|
||||
public interface IStateService
|
||||
{
|
||||
List<App> GetApps();
|
||||
void SetApps(List<App> apps);
|
||||
|
||||
void UpdateApps();
|
||||
List<SourceResponse> GetSources();
|
||||
void SetSources(List<SourceResponse> sources);
|
||||
List<TypeResponse> GetTypes();
|
||||
void SetTypes(List<TypeResponse> types);
|
||||
Config GetConfig();
|
||||
void SetConfig(Config config);
|
||||
}
|
||||
}
|
@@ -8,8 +8,12 @@ namespace ModVersionChecker.service.interfaces
|
||||
{
|
||||
public interface IVersionService
|
||||
{
|
||||
App CheckApp(App app);
|
||||
//App CheckAppStatus(App app);
|
||||
|
||||
Task CheckAllApps();
|
||||
//Task CheckAllApps();
|
||||
|
||||
string GetCurrentVersion(App app);
|
||||
|
||||
bool IsUpdateAvailable(string currentVersion, string latestVersion);
|
||||
}
|
||||
}
|
||||
|
@@ -9,15 +9,18 @@ namespace ModVersionChecker.ui.forms
|
||||
private ListBox _resultsList;
|
||||
private Button _addButton;
|
||||
private readonly IApiService _apiService;
|
||||
private readonly IAppsManager _appsManager;
|
||||
private readonly IAppService _appService;
|
||||
public App? SelectedApp { get; private set; }
|
||||
|
||||
public event EventHandler<string> OnAppAdded;
|
||||
|
||||
public AppDetailsForm(IApiService apiService, IAppsManager appsManager)
|
||||
public AppDetailsForm(
|
||||
IApiService apiService,
|
||||
IAppService appService
|
||||
)
|
||||
{
|
||||
_apiService = apiService ?? throw new ArgumentNullException(nameof(apiService));
|
||||
_appsManager = appsManager ?? throw new ArgumentNullException(nameof(appsManager));
|
||||
_appService = appService ?? throw new ArgumentNullException(nameof(appService));
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
@@ -27,6 +30,7 @@ namespace ModVersionChecker.ui.forms
|
||||
Width = 400;
|
||||
Height = 500;
|
||||
Padding = new Padding(20);
|
||||
StartPosition = FormStartPosition.CenterParent;
|
||||
|
||||
_searchBox = new TextBox { Dock = DockStyle.Top, PlaceholderText = "Search..." };
|
||||
_resultsList = new ListBox { Dock = DockStyle.Fill };
|
||||
@@ -54,8 +58,8 @@ namespace ModVersionChecker.ui.forms
|
||||
_resultsList.DataSource = null;
|
||||
return;
|
||||
}
|
||||
var results = await _apiService.SearchApps(query);
|
||||
_resultsList.DataSource = results;
|
||||
var apiResults = await _apiService.SearchApps(query);
|
||||
_resultsList.DataSource = _appService.PurgeExisitingApps(apiResults);
|
||||
_resultsList.DisplayMember = "Name";
|
||||
}
|
||||
|
||||
@@ -64,7 +68,7 @@ namespace ModVersionChecker.ui.forms
|
||||
if (_resultsList.SelectedItem is App app)
|
||||
{
|
||||
SelectedApp = app;
|
||||
_appsManager.Insert(app);
|
||||
_appService.CreateApp(app);
|
||||
DialogResult = DialogResult.OK;
|
||||
OnAppAdded?.Invoke(this, "App saved");
|
||||
Close();
|
||||
|
@@ -16,8 +16,8 @@ namespace ModVersionChecker.ui.forms
|
||||
public AppDetailsForm CreateAppDetailsForm(App? app, bool isEditable, EventHandler<string>? onAppSaved)
|
||||
{
|
||||
var apiService = _serviceProvider.GetRequiredService<IApiService>();
|
||||
var appsManager = _serviceProvider.GetRequiredService<IAppsManager>();
|
||||
var form = new AppDetailsForm(apiService, appsManager);
|
||||
var appService= _serviceProvider.GetRequiredService<IAppService>();
|
||||
var form = new AppDetailsForm(apiService, appService);
|
||||
if (onAppSaved != null)
|
||||
{
|
||||
form.OnAppAdded += onAppSaved;
|
||||
@@ -27,15 +27,15 @@ namespace ModVersionChecker.ui.forms
|
||||
|
||||
public GlobalConfigForm CreateGlobalConfigForm()
|
||||
{
|
||||
var configManager = _serviceProvider.GetRequiredService<IConfigManager>();
|
||||
var configManager = _serviceProvider.GetRequiredService<IConfigRepository>();
|
||||
return new GlobalConfigForm(configManager);
|
||||
}
|
||||
|
||||
public TypeConfigForm CreateTypeConfigForm()
|
||||
{
|
||||
var typeManager = _serviceProvider.GetRequiredService<ITypeManager>();
|
||||
var typeManager = _serviceProvider.GetRequiredService<ITypeConfigRepository>();
|
||||
var apiService = _serviceProvider.GetRequiredService<IApiService>();
|
||||
var configManager = _serviceProvider.GetRequiredService<IConfigManager>();
|
||||
var configManager = _serviceProvider.GetRequiredService<IConfigRepository>();
|
||||
return new TypeConfigForm(typeManager, apiService, configManager);
|
||||
}
|
||||
|
||||
|
@@ -5,7 +5,7 @@ namespace ModVersionChecker.ui.forms
|
||||
{
|
||||
public class GlobalConfigForm : Form
|
||||
{
|
||||
private IConfigManager _configManager;
|
||||
private IConfigRepository _configManager;
|
||||
private Config _config;
|
||||
|
||||
private Label _millislabel, _checkStartupLabel, _runOnStartupLabel;
|
||||
@@ -15,7 +15,7 @@ namespace ModVersionChecker.ui.forms
|
||||
private TableLayoutPanel _mainLayout, _configsPanel;
|
||||
private FlowLayoutPanel _buttonPanel;
|
||||
|
||||
public GlobalConfigForm(IConfigManager configManager)
|
||||
public GlobalConfigForm(IConfigRepository configManager)
|
||||
{
|
||||
_configManager = configManager;
|
||||
_config = _configManager.GetConfig();
|
||||
|
@@ -1,7 +1,6 @@
|
||||
using ModVersionChecker.enums;
|
||||
using ModVersionChecker.managers.interfaces;
|
||||
using ModVersionChecker.model;
|
||||
using ModVersionChecker.repository.api.dto;
|
||||
using ModVersionChecker.service.interfaces;
|
||||
using ModVersionChecker.utils;
|
||||
|
||||
@@ -10,15 +9,13 @@ namespace ModVersionChecker.ui.forms
|
||||
{
|
||||
public class MainForm : Form
|
||||
{
|
||||
private readonly IAppsManager _appsManager;
|
||||
private readonly IStateService _stateService;
|
||||
private readonly IFormFactory _formFactory;
|
||||
private readonly IFlightSimsManager _fsManager;
|
||||
private readonly IApiService _apiService;
|
||||
private readonly IVersionService _versionService;
|
||||
private readonly IAppService _appService;
|
||||
private readonly TableLayoutPanel _mainLayout;
|
||||
|
||||
private readonly Config _globalConfig;
|
||||
private List<App> _apps = new List<App>();
|
||||
private ListView _listView;
|
||||
private ImageList _statusImageList = new ImageList();
|
||||
|
||||
@@ -26,27 +23,20 @@ namespace ModVersionChecker.ui.forms
|
||||
public event EventHandler<string> OnRecheck;
|
||||
private EventHandler<string> onAppSavedHandler;
|
||||
private MenuStrip _menuStrip;
|
||||
private List<TypeResponse> _fsMods;
|
||||
private readonly Dictionary<string, TextBox> _fsModPathTextBoxes = new Dictionary<string, TextBox>();
|
||||
|
||||
private List<SourceResponse> _sources = new List<SourceResponse>();
|
||||
private List<TypeResponse> _typesDef = new List<TypeResponse>();
|
||||
|
||||
public MainForm(
|
||||
IConfigManager configManager,
|
||||
IAppsManager appsManager,
|
||||
IStateService stateService,
|
||||
IAppService appService,
|
||||
IConfigRepository configManager,
|
||||
IFormFactory formFactory,
|
||||
IFlightSimsManager fsManager,
|
||||
IApiService apiService,
|
||||
ITypeManager typeConfigManager,
|
||||
IVersionService versionService)
|
||||
IApiService apiService
|
||||
)
|
||||
{
|
||||
_appsManager = appsManager ?? throw new ArgumentNullException(nameof(appsManager));
|
||||
_formFactory = formFactory ?? throw new ArgumentNullException(nameof(formFactory));
|
||||
_fsManager = fsManager ?? throw new ArgumentNullException(nameof(fsManager));
|
||||
_apiService = apiService ?? throw new ArgumentNullException(nameof(apiService));
|
||||
_versionService = versionService ?? throw new ArgumentNullException(nameof(versionService));
|
||||
_fsMods = _fsManager.Load();
|
||||
_appService = appService ?? throw new ArgumentNullException(nameof(appService));
|
||||
_stateService = stateService ?? throw new ArgumentNullException(nameof(stateService));
|
||||
|
||||
_statusImageList.Images.Add("none", new Icon("Resources/ok-icon.ico"));
|
||||
_statusImageList.Images.Add("update", new Icon("Resources/up-icon.ico"));
|
||||
@@ -74,6 +64,7 @@ namespace ModVersionChecker.ui.forms
|
||||
|
||||
var app = form.SelectedApp;
|
||||
UpdateCurrentVersion(app);
|
||||
_stateService.UpdateApps();
|
||||
UpdateListView();
|
||||
OnConfigChanged?.Invoke(this, EventArgs.Empty);
|
||||
};
|
||||
@@ -81,6 +72,22 @@ namespace ModVersionChecker.ui.forms
|
||||
this.Load += MainForm_LoadAsync;
|
||||
}
|
||||
|
||||
|
||||
private async void MainForm_LoadAsync(object? sender, EventArgs e)
|
||||
{
|
||||
await _apiService.AuthenticateAsync("user", "user");
|
||||
|
||||
var apps = await _appService.GetAndUpdateCurrentApps();
|
||||
var sources = await _apiService.GetSources();
|
||||
var types = await _apiService.GetTypes();
|
||||
|
||||
_stateService.SetApps(apps);
|
||||
_stateService.SetSources(sources);
|
||||
_stateService.SetTypes(types);
|
||||
_stateService.SetConfig(_globalConfig);
|
||||
UpdateListView();
|
||||
}
|
||||
|
||||
private void UpdateCurrentVersion(App app)
|
||||
{
|
||||
TypeConfig? typeConfig = _globalConfig.Types.FirstOrDefault(tc => app.Type == tc.ShortName);
|
||||
@@ -92,21 +99,12 @@ namespace ModVersionChecker.ui.forms
|
||||
app.CurrentVersion = versionInDisk;
|
||||
app.LastCheckedAt = TimeUtils.GetUnixTimeMillis(DateTime.Now);
|
||||
|
||||
_versionService.CheckApp(app);
|
||||
_appService.CheckAppStatus(app);
|
||||
_appService.UpdateApp(app);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
private async void MainForm_LoadAsync(object? sender, EventArgs e)
|
||||
{
|
||||
await _apiService.AuthenticateAsync("user", "user");
|
||||
_apps = await _apiService.GetAppsByIds([]);
|
||||
_sources = await _apiService.GetSources();
|
||||
_typesDef = await _apiService.GetTypes();
|
||||
UpdateListView();
|
||||
}
|
||||
|
||||
private TableLayoutPanel GetMainLayout()
|
||||
{
|
||||
// Initialize the main layout panel
|
||||
@@ -197,10 +195,10 @@ namespace ModVersionChecker.ui.forms
|
||||
};
|
||||
|
||||
// Add recheck logic here
|
||||
recheckButton.Click += async (s, e) =>
|
||||
recheckButton.Click += (s, e) =>
|
||||
{
|
||||
recheckButton.Enabled = false;
|
||||
await _versionService.CheckAllApps();
|
||||
_appService.CheckAllApps();
|
||||
UpdateListView();
|
||||
//OnRecheck.Invoke(this, "User initiated recheck from ConfigForm");
|
||||
recheckButton.Enabled = true;
|
||||
@@ -212,7 +210,7 @@ namespace ModVersionChecker.ui.forms
|
||||
|
||||
public void UpdateListView()
|
||||
{
|
||||
_apps = _appsManager.Load();
|
||||
var _apps = _stateService.GetApps();
|
||||
_listView.Items.Clear();
|
||||
foreach (var app in _apps)
|
||||
{
|
||||
@@ -252,10 +250,13 @@ namespace ModVersionChecker.ui.forms
|
||||
|
||||
private void DeleteApp(App app)
|
||||
{
|
||||
var result = MessageBox.Show($"Are you sure you want to delete '{app?.Name ?? ""}'?", "Confirm Delete", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
|
||||
if (app == null) return;
|
||||
|
||||
var result = MessageBox.Show($"Are you sure you want to delete '{app.Name ?? ""}'?", "Confirm Delete", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
|
||||
if (result == DialogResult.Yes)
|
||||
{
|
||||
_appsManager.Delete((_listView.SelectedItems[0].Tag as App).Id);
|
||||
_appService.DeleteApp((_listView.SelectedItems[0].Tag as App));
|
||||
_stateService.UpdateApps();
|
||||
UpdateListView();
|
||||
OnConfigChanged?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
|
@@ -19,13 +19,13 @@ namespace ModVersionChecker.ui.forms
|
||||
private FlowLayoutPanel _mainPanel;
|
||||
private Button _saveButton, _cancelButton;
|
||||
private readonly IApiService _apiService;
|
||||
private readonly IConfigManager _configManager;
|
||||
private readonly ITypeManager _typeManager;
|
||||
private readonly IConfigRepository _configManager;
|
||||
private readonly ITypeConfigRepository _typeManager;
|
||||
|
||||
public TypeConfigForm(
|
||||
ITypeManager typeManager,
|
||||
ITypeConfigRepository typeManager,
|
||||
IApiService apiService,
|
||||
IConfigManager configManager
|
||||
IConfigRepository configManager
|
||||
)
|
||||
{
|
||||
_apiService = apiService ?? throw new ArgumentNullException(nameof(apiService));
|
||||
|
Reference in New Issue
Block a user