start a big rework

This commit is contained in:
Schedel Pascal
2024-06-19 15:01:27 +02:00
parent c9216ac79b
commit 77ddd2a72a
25 changed files with 599 additions and 1697 deletions

View File

@@ -1,74 +0,0 @@
using System;
using Telerik.WinControls.UI;
namespace Pilz.Updating.Administration.GUI;
public partial class ApplicationVersionInput
{
// C o n s t r u c t o r s
public ApplicationVersionInput()
{
InitializeComponent();
// Init Channel-ComboBox
radDropDownList_Channel.Items.Add(new RadListDataItem() { Text = My.Resources.UpdatingAdministrationLangRes.Channel_Stable, Tag = Channels.Stable });
radDropDownList_Channel.Items.Add(new RadListDataItem() { Text = My.Resources.UpdatingAdministrationLangRes.Channel_PreRelease, Tag = Channels.PreRelease });
radDropDownList_Channel.Items.Add(new RadListDataItem() { Text = My.Resources.UpdatingAdministrationLangRes.Channel_Beta, Tag = Channels.Beta });
radDropDownList_Channel.Items.Add(new RadListDataItem() { Text = My.Resources.UpdatingAdministrationLangRes.Channel_Alpha, Tag = Channels.Alpha });
radDropDownList_Channel.SelectedIndex = 0;
}
// P r o p e r t i e s
public Version Version
{
get
{
return new Version(radTextBoxControl_Version.Text.Trim());
}
set
{
radTextBoxControl_Version.Text = value.ToString();
}
}
public Channels Channel
{
get
{
return (Channels)radDropDownList_Channel.SelectedItem.Tag;
}
set
{
foreach (var ci in radDropDownList_Channel.Items)
{
if ((Channels)ci.Tag == value)
{
radDropDownList_Channel.SelectedItem = ci;
}
}
}
}
public int Build
{
get
{
return (int)Math.Round(radSpinEditor_Build.Value);
}
set
{
radSpinEditor_Build.Value = value;
}
}
private void radButton_Accept_Click(object sender, EventArgs e)
{
}
}

View File

@@ -7,7 +7,7 @@ using Microsoft.VisualBasic.CompilerServices;
namespace Pilz.Updating.Administration.GUI namespace Pilz.Updating.Administration.GUI
{ {
[DesignerGenerated()] [DesignerGenerated()]
public partial class ApplicationVersionInput : Telerik.WinControls.UI.RadForm public partial class PackageMetaEditor : Telerik.WinControls.UI.RadForm
{ {
// Form overrides dispose to clean up the component list. // Form overrides dispose to clean up the component list.
@@ -36,7 +36,7 @@ namespace Pilz.Updating.Administration.GUI
[DebuggerStepThrough()] [DebuggerStepThrough()]
private void InitializeComponent() private void InitializeComponent()
{ {
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ApplicationVersionInput)); System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(PackageMetaEditor));
this.radLabel1 = new Telerik.WinControls.UI.RadLabel(); this.radLabel1 = new Telerik.WinControls.UI.RadLabel();
this.radLabel2 = new Telerik.WinControls.UI.RadLabel(); this.radLabel2 = new Telerik.WinControls.UI.RadLabel();
this.radLabel3 = new Telerik.WinControls.UI.RadLabel(); this.radLabel3 = new Telerik.WinControls.UI.RadLabel();

View File

@@ -0,0 +1,51 @@
using System;
using Telerik.WinControls.UI;
namespace Pilz.Updating.Administration.GUI;
public partial class PackageMetaEditor
{
// C o n s t r u c t o r s
public PackageMetaEditor()
{
InitializeComponent();
// Init Channel-ComboBox
radDropDownList_Channel.Items.Add(new RadListDataItem(My.Resources.UpdatingAdministrationLangRes.Channel_Stable, Channels.Stable));
radDropDownList_Channel.Items.Add(new RadListDataItem(My.Resources.UpdatingAdministrationLangRes.Channel_PreRelease, Channels.PreRelease));
radDropDownList_Channel.Items.Add(new RadListDataItem(My.Resources.UpdatingAdministrationLangRes.Channel_Beta, Channels.Beta));
radDropDownList_Channel.Items.Add(new RadListDataItem(My.Resources.UpdatingAdministrationLangRes.Channel_Alpha, Channels.Alpha));
radDropDownList_Channel.SelectedIndex = 0;
}
// P r o p e r t i e s
public Version Version
{
get => new(radTextBoxControl_Version.Text.Trim());
set => radTextBoxControl_Version.Text = value.ToString();
}
public Channels Channel
{
get => (Channels)radDropDownList_Channel.SelectedItem.Value;
set => radDropDownList_Channel.SelectedValue = value;
}
public int Build
{
get => (int)Math.Round(radSpinEditor_Build.Value);
set => radSpinEditor_Build.Value = value;
}
public string Packagelink
{
get => ;
set => ;
}
private void radButton_Accept_Click(object sender, EventArgs e)
{
}
}

View File

@@ -80,10 +80,10 @@
<Compile Update="PackageDescriptionEditor.Designer.cs"> <Compile Update="PackageDescriptionEditor.Designer.cs">
<DependentUpon>PackageDescriptionEditor.cs</DependentUpon> <DependentUpon>PackageDescriptionEditor.cs</DependentUpon>
</Compile> </Compile>
<Compile Update="ApplicationVersionInput.Designer.cs"> <Compile Update="PackageMetaEditor.Designer.cs">
<DependentUpon>ApplicationVersionInput.cs</DependentUpon> <DependentUpon>PackageMetaEditor.cs</DependentUpon>
</Compile> </Compile>
<Compile Update="ApplicationVersionInput.cs" /> <Compile Update="PackageMetaEditor.cs" />
<Compile Update="UpdateManagerWindow.cs" /> <Compile Update="UpdateManagerWindow.cs" />
<Compile Update="UpdateManagerWindow.Designer.cs"> <Compile Update="UpdateManagerWindow.Designer.cs">
<DependentUpon>UpdateManagerWindow.cs</DependentUpon> <DependentUpon>UpdateManagerWindow.cs</DependentUpon>
@@ -122,8 +122,8 @@
<EmbeddedResource Update="PackageDescriptionEditor.resx"> <EmbeddedResource Update="PackageDescriptionEditor.resx">
<DependentUpon>PackageDescriptionEditor.cs</DependentUpon> <DependentUpon>PackageDescriptionEditor.cs</DependentUpon>
</EmbeddedResource> </EmbeddedResource>
<EmbeddedResource Update="ApplicationVersionInput.resx"> <EmbeddedResource Update="PackageMetaEditor.resx">
<DependentUpon>ApplicationVersionInput.cs</DependentUpon> <DependentUpon>PackageMetaEditor.cs</DependentUpon>
</EmbeddedResource> </EmbeddedResource>
<EmbeddedResource Update="UpdateManagerWindow.resx"> <EmbeddedResource Update="UpdateManagerWindow.resx">
<DependentUpon>UpdateManagerWindow.cs</DependentUpon> <DependentUpon>UpdateManagerWindow.cs</DependentUpon>

File diff suppressed because it is too large Load Diff

View File

@@ -1,9 +1,9 @@
using global::System.IO; using Microsoft.VisualBasic.CompilerServices;
using Microsoft.VisualBasic.CompilerServices;
using Pilz.Updating.Administration.Discord; using Pilz.Updating.Administration.Discord;
using Pilz.Updating.Administration.Packaging; using Pilz.Updating.Administration.Integrations;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows.Forms; using System.Windows.Forms;
using Telerik.WinControls; using Telerik.WinControls;
@@ -14,22 +14,17 @@ namespace Pilz.Updating.Administration.GUI;
public partial class UpdateManagerWindow public partial class UpdateManagerWindow
{ {
// C o n s t a n t s // C o n s t a n t s
private const string FILTER_UPDATEINFO_CONFIGURATION = "JSON (*.json)|*.json"; private const string FILTER_UPDATEINFO_CONFIGURATION = "Json file (*.json)|*.json";
private const string FILTER_UPDATEPROJECT = "Update-Info-Konfiguration (*.udic)|*.udic"; private const string FILTER_UPDATEPROJECT = "Project file (*.udic)|*.udic";
private const string FILTER_UPDATEPACKAGE = "ZIP-Archiv (*.zip)|*.zip"; private const string FILTER_UPDATEPACKAGE = "Zip archiv (*.zip)|*.zip";
private const string FILTER_PACKAGE_TEMPLATE = "Update-Paket-Vorlagen (*.udpt)|*.udpt";
private const string FILTER_PACKAGE_ZIP_PACKAGE = "ZIP-Paket (*.zip)|*.zip";
private const string FILTER_PACKAGE_ADDON = "Anwendungserweiterung (*.dll)|*.dll";
// F i e l d s // F i e l d s
private string curProjectFilePath; private string curProjectFilePath;
private UpdateServerManager manager = null; private UpdateServerManager manager = null;
private DiscordBot discordBot = null; private DiscordBot discordBot = null;
private readonly UpdatePackageManager packageManager = new UpdatePackageManager();
private string curPackageTemplatePath = string.Empty; private string curPackageTemplatePath = string.Empty;
// P r o p e r t i e s // P r o p e r t i e s
@@ -58,20 +53,11 @@ public partial class UpdateManagerWindow
radWaitingBar_PackageLoading.StopWaiting(); radWaitingBar_PackageLoading.StopWaiting();
} }
private void ProgressPackagingControls(bool enabled)
{
if (enabled)
radWaitingBar_PackageCreation.StartWaiting();
else
radWaitingBar_PackageCreation.StopWaiting();
}
private void SetEnabledUiControls(bool enabled, bool setProjectOptionsAlwayToTrue = false) private void SetEnabledUiControls(bool enabled, bool setProjectOptionsAlwayToTrue = false)
{ {
radRibbonBarGroup_Options.Enabled = enabled || setProjectOptionsAlwayToTrue; radRibbonBarGroup_Options.Enabled = enabled || setProjectOptionsAlwayToTrue;
radButtonElement_SaveProject.Enabled = enabled || setProjectOptionsAlwayToTrue; radButtonElement_SaveProject.Enabled = enabled || setProjectOptionsAlwayToTrue;
radRibbonBarGroup_Configuration.Enabled = enabled; radRibbonBarGroup_Configuration.Enabled = enabled;
radRibbonBarGroup_NewPackage.Enabled = enabled;
} }
private async Task CreateNewProject(string filePath) private async Task CreateNewProject(string filePath)
@@ -110,11 +96,10 @@ public partial class UpdateManagerWindow
{ {
manager = new UpdateServerManager(General.CurProject.UpdateServerConfig); manager = new UpdateServerManager(General.CurProject.UpdateServerConfig);
if (await manager.LoadInfoFromServer()) if (manager.Config.GitLabSnippetConfig.Enabled && await manager.ReadInfoFromGitLabSnippet())
{ {
await LoadPackageList(); LoadPackageList();
LoadUpdateInstallerInfos(); LoadUpdateInstallerInfos();
hasError = false; hasError = false;
} }
else else
@@ -136,27 +121,27 @@ public partial class UpdateManagerWindow
ProgressControls(false); ProgressControls(false);
} }
private async Task LoadPackageList() private void LoadPackageList()
{ {
ProgressControls(true); ProgressControls(true);
radListView_Packages.BeginUpdate(); radListView_Packages.BeginUpdate();
radListView_Packages.Items.Clear(); radListView_Packages.Items.Clear();
foreach (var pkgVersion in await manager.GetUpdatePackagesList()) foreach (var pkg in manager.UpdateInfo.Packages)
{ {
var name = manager.GetPackageDescription(pkgVersion).name; var name = pkg.Name;
var cells = new List<string> var cells = new List<string>
{ {
string.IsNullOrEmpty(name) ? "<Kein Titel>" : name, string.IsNullOrEmpty(name) ? "<No title>" : name,
pkgVersion.Version.ToString(), pkg.Version.Version.ToString(),
pkgVersion.Channel.ToString(), pkg.Version.Channel.ToString(),
pkgVersion.Build.ToString(), pkg.Version.Build.ToString(),
"Ja" "Yes"
}; };
var item = new ListViewDataItem(String.Empty, cells.ToArray()) var item = new ListViewDataItem(string.Empty, [.. cells])
{ {
Tag = pkgVersion Tag = pkg
}; };
radListView_Packages.Items.Add(item); radListView_Packages.Items.Add(item);
@@ -174,79 +159,61 @@ public partial class UpdateManagerWindow
radTextBoxControl_DownloadURL.Text = manager.UpdateInfo.UpdateInstallerLink; radTextBoxControl_DownloadURL.Text = manager.UpdateInfo.UpdateInstallerLink;
} }
private ApplicationVersion GetSelectedPackageVersion() private UpdatePackageInfo GetSelectedPackage()
{ {
return radListView_Packages.SelectedItem?.Tag as ApplicationVersion; return radListView_Packages.SelectedItem?.Tag as UpdatePackageInfo;
} }
private async Task<bool> UploadPackage(string filePath) private bool CreatePackage(string filePath)
{ {
var success = false; var pkg = new UpdatePackageInfo();
var resVersion = EditApplicationVersion(); var canceld = EditPackageMeta(pkg);
if (!resVersion.canceled) if (!canceld)
{ manager.UpdateInfo.Packages.Add(pkg);
ProgressControls(true);
if (await manager.UploadPackage(filePath, resVersion.newVersion)) return !canceld;
success = true;
ProgressControls(false);
await SaveInfoToServer();
} }
return success; private bool EditPackageMeta(UpdatePackageInfo pkg)
}
private (ApplicationVersion newVersion, bool canceled) EditApplicationVersion()
{ {
return EditApplicationVersion(new ApplicationVersion()); var frm = new PackageMetaEditor
}
private (ApplicationVersion newVersion, bool canceled) EditApplicationVersion(ApplicationVersion inputVersion)
{ {
var frm = new ApplicationVersionInput() Version = pkg.Version.Version,
{ Channel = pkg.Version.Channel,
Version = inputVersion.Version, Build = pkg.Version.Build,
Channel = inputVersion.Channel, Packagelink = pkg.Packagelink
Build = inputVersion.Build
}; };
if (frm.ShowDialog(this) == DialogResult.OK) if (frm.ShowDialog(this) != DialogResult.OK)
return (new ApplicationVersion(frm.Version, frm.Build, frm.Channel), false); return false;
else
return (inputVersion, true); pkg.Version.Version = frm.Version;
pkg.Version.Build = frm.Build;
pkg.Version.Channel = frm.Channel;
pkg.Packagelink = frm.Packagelink;
return true;
} }
private async Task<bool> DeletePackage(ApplicationVersion version) private bool DeletePackage(UpdatePackageInfo pkg)
{ {
ProgressControls(true); ProgressControls(true);
bool success = await manager.DeletePackage(version); var success = manager.UpdateInfo.Packages.Remove(pkg);
ProgressControls(false); ProgressControls(false);
return success; return success;
} }
private async Task<bool> SaveInfoToServer() private async Task<bool> SaveInfoToServer()
{ {
if (!manager.Config.GitLabSnippetConfig.Enabled)
return false;
ProgressControls(true); ProgressControls(true);
bool success = await manager.SaveInfoToServer(); var success = await manager.SaveInfoToGitLabSnippet();
ProgressControls(false); ProgressControls(false);
return success; return success;
} }
private async Task<bool> ChangePackageVersion(ApplicationVersion version)
{
bool success = false;
var (newVersion, canceled) = EditApplicationVersion(version);
if (!canceled)
{
ProgressControls(true);
success = await manager.ChangePackageVersion(version, newVersion);
ProgressControls(false);
}
return success;
}
// G u i // G u i
private void UpdateManagerWindow_Shown(object sender, EventArgs e) private void UpdateManagerWindow_Shown(object sender, EventArgs e)
@@ -269,8 +236,7 @@ public partial class UpdateManagerWindow
private void UpdateManagerWindow_FormClosing(object sender, FormClosingEventArgs e) private void UpdateManagerWindow_FormClosing(object sender, FormClosingEventArgs e)
{ {
if (discordBot is object) discordBot?.Stop();
discordBot.Stop();
} }
private async void ButtonItem_NewProject_Click(object sender, EventArgs e) private async void ButtonItem_NewProject_Click(object sender, EventArgs e)
@@ -313,52 +279,31 @@ public partial class UpdateManagerWindow
await SaveInfoToServer(); await SaveInfoToServer();
} }
private async void ButtonItem_ExportUpdateConfiguration_Click(object sender, EventArgs e) private void ButtonItem_ExportUpdateConfiguration_Click(object sender, EventArgs e)
{ {
var sfd_UpdateAdministration_UpdateConfiguration = new RadSaveFileDialog() var sfd_UpdateAdministration_UpdateConfiguration = new RadSaveFileDialog()
{ {
Filter = FILTER_UPDATEINFO_CONFIGURATION Filter = FILTER_UPDATEINFO_CONFIGURATION
}; };
if (sfd_UpdateAdministration_UpdateConfiguration.ShowDialog(this) == DialogResult.OK) if (sfd_UpdateAdministration_UpdateConfiguration.ShowDialog(this) == DialogResult.OK)
await manager.SaveInfoToFile(sfd_UpdateAdministration_UpdateConfiguration.FileName); manager.SaveInfoToFile(sfd_UpdateAdministration_UpdateConfiguration.FileName);
} }
private async void ButtonItem_CreateAndUploadPackage_Click(object sender, EventArgs e) private void ButtonItem_CreateAndUploadPackage_Click(object sender, EventArgs e)
{ {
var success = false; if (CreatePackage(TempPackageFilePath))
if (await ExportTempUpdatePackage())
{ {
if (await UploadPackage(TempPackageFilePath)) LoadPackageList();
{ return;
await LoadPackageList();
success = true;
}
} }
if (!success)
RadMessageBox.Show(this, My.Resources.UpdatingAdministrationLangRes.MsgBox_PkgExportSuccess, My.Resources.UpdatingAdministrationLangRes.MsgBox_PkgExportSuccess_Titel, MessageBoxButtons.OK, RadMessageIcon.Info); RadMessageBox.Show(this, My.Resources.UpdatingAdministrationLangRes.MsgBox_PkgExportSuccess, My.Resources.UpdatingAdministrationLangRes.MsgBox_PkgExportSuccess_Titel, MessageBoxButtons.OK, RadMessageIcon.Info);
} }
private async void ButtonItem_UploadExistingPackage_Click(object sender, EventArgs e) private void ButtonItem_RemovePackage_Click(object sender, EventArgs e)
{ {
var ofd_UpdateAdministration_UpdatePackage = new RadOpenFileDialog() if (DeletePackage(GetSelectedPackage()))
{ LoadPackageList();
Filter = FILTER_UPDATEPACKAGE
};
if (ofd_UpdateAdministration_UpdatePackage.ShowDialog(this) == DialogResult.OK)
{
if (await UploadPackage(ofd_UpdateAdministration_UpdatePackage.FileName))
await LoadPackageList();
}
}
private async void ButtonItem_RemovePackage_Click(object sender, EventArgs e)
{
var version = GetSelectedPackageVersion();
if (await DeletePackage(version))
await LoadPackageList();
} }
private void TextBoxX_UpdateInstallerDownloadUrl_TextChanged(object sender, EventArgs e) private void TextBoxX_UpdateInstallerDownloadUrl_TextChanged(object sender, EventArgs e)
@@ -371,10 +316,9 @@ public partial class UpdateManagerWindow
if (discordBot == null) if (discordBot == null)
LoadDiscordBot(); LoadDiscordBot();
if (discordBot is object) if (discordBot is not null)
{ {
var version = GetSelectedPackageVersion(); var pkg = GetSelectedPackage();
var pkg = manager.GetUpdatePackageInfo(version);
var frm = new DiscordPostDialog(discordBot, pkg); var frm = new DiscordPostDialog(discordBot, pkg);
frm.ShowDialog(this); frm.ShowDialog(this);
} }
@@ -384,7 +328,7 @@ public partial class UpdateManagerWindow
private void LoadDiscordBot() private void LoadDiscordBot()
{ {
if (discordBot is object) if (discordBot is not null)
discordBot.Stop(); discordBot.Stop();
discordBot = new DiscordBot(General.CurProject.DiscordBotConfig); discordBot = new DiscordBot(General.CurProject.DiscordBotConfig);
@@ -410,31 +354,28 @@ public partial class UpdateManagerWindow
discordBot = null; discordBot = null;
} }
private async void ButtonItem_ChangeVersion_Click(object sender, EventArgs e) private void ButtonItem_ChangeVersion_Click(object sender, EventArgs e)
{ {
var version = GetSelectedPackageVersion(); if (EditPackageMeta(GetSelectedPackage()))
if (await ChangePackageVersion(version)) LoadPackageList();
{
await SaveInfoToServer();
await LoadPackageList();
}
} }
private async void ButtonItem_EditDescription_Click(object sender, EventArgs e) private async void ButtonItem_EditDescription_Click(object sender, EventArgs e)
{ {
var version = GetSelectedPackageVersion(); var pkg = GetSelectedPackage();
var desc = manager.GetPackageDescription(version);
var frm = new PackageDescriptionEditor() var frm = new PackageDescriptionEditor
{ {
Titel = desc.name, Titel = pkg.Name,
Description = desc.description, Description = pkg.Notes.Content,
DescriptionType = desc.descriptionType DescriptionType = pkg.Notes.ContentType
}; };
if (frm.ShowDialog(this) == DialogResult.OK) if (frm.ShowDialog(this) == DialogResult.OK)
{ {
manager.SetPackageDescription(version, frm.Titel, frm.Description, frm.DescriptionType); pkg.Name = frm.Titel;
pkg.Notes.Content = frm.Description;
pkg.Notes.ContentType = frm.DescriptionType;
await SaveInfoToServer(); await SaveInfoToServer();
} }
} }
@@ -475,252 +416,5 @@ public partial class UpdateManagerWindow
private void RadPageView1_SelectedPageChanged(object sender, EventArgs e) private void RadPageView1_SelectedPageChanged(object sender, EventArgs e)
{ {
var selPage = radPageView1.SelectedPage;
if (selPage == radPageViewPage_Extensions)
{
radRibbonBarGroup_PackageFiles.Visibility = ElementVisibility.Collapsed;
radRibbonBarGroup_PackageExtensions.Visibility = ElementVisibility.Visible;
}
else if (selPage == radPageViewPage_Packaging)
{
radRibbonBarGroup_PackageFiles.Visibility = ElementVisibility.Visible;
radRibbonBarGroup_PackageExtensions.Visibility = ElementVisibility.Collapsed;
}
}
// F e a t u r e s - P a c k a g i n g
private void ShowAllPackageTemplateConfig()
{
ShowPackageFiles();
ShowPackageExtensions();
}
private void ShowPackageFiles()
{
radTreeView_PackagingFiles.BeginUpdate();
radTreeView_PackagingFiles.Nodes.Clear();
if (!string.IsNullOrEmpty(packageManager.FilesToCopyPath))
{
Action<RadTreeNodeCollection, string> nodeCreation = null;
nodeCreation = (parentCollection, p) =>
{
bool isDir = (File.GetAttributes(p) & FileAttributes.Directory) == FileAttributes.Directory;
var n = new RadTreeNode()
{
Tag = p,
Text = radTreeView_PackagingFiles.Nodes == parentCollection ? p : Path.GetFileName(p),
ImageIndex = isDir ? 0 : 1
};
parentCollection.Add(n);
if (isDir)
{
var dirInfo = new DirectoryInfo(p);
dirInfo.EnumerateDirectories().ForEach(di => nodeCreation(n.Nodes, di.FullName));
dirInfo.EnumerateFiles().ForEach(fi => nodeCreation(n.Nodes, fi.FullName));
}
};
nodeCreation(radTreeView_PackagingFiles.Nodes, packageManager.FilesToCopyPath);
}
radTreeView_PackagingFiles.EndUpdate();
}
private void ShowPackageExtensions()
{
radListView_Extensions.BeginUpdate();
radListView_Extensions.Items.Clear();
foreach (string fAddOn in packageManager.GetAllUpdateInstallerÁddOn())
{
var cells = new List<string>
{
Path.GetFileName(fAddOn),
Path.GetDirectoryName(fAddOn)
};
var item = new ListViewDataItem(string.Empty, cells.ToArray())
{
Tag = fAddOn
};
radListView_Extensions.Items.Add(item);
}
radListView_Extensions.EndUpdate();
}
private IEnumerable<string> GetSelectedUpdateInstallAddOns()
{
var list = new List<string>();
foreach (var item in radListView_Extensions.SelectedItems)
list.Add(Conversions.ToString(item.Tag));
return list;
}
private void NewPackageTemplate()
{
packageManager.NewTemplate();
curPackageTemplatePath = string.Empty;
ShowAllPackageTemplateConfig();
}
private void OpenPackageTemplate()
{
var ofd_UpdateAdmin_LoadTemplate = new RadOpenFileDialog() { Filter = FILTER_PACKAGE_TEMPLATE };
if (ofd_UpdateAdmin_LoadTemplate.ShowDialog() == DialogResult.OK)
{
packageManager.LoadTemplate(ofd_UpdateAdmin_LoadTemplate.FileName);
curPackageTemplatePath = ofd_UpdateAdmin_LoadTemplate.FileName;
ShowAllPackageTemplateConfig();
}
}
private void SavePackageTemplate()
{
if (string.IsNullOrEmpty(curPackageTemplatePath))
{
SavePackageTemplateAs();
}
else
{
packageManager.SaveTemplate(curPackageTemplatePath);
}
}
private void SavePackageTemplateAs()
{
var sfd_UpdateAdmin_SaveTemplate = new RadSaveFileDialog() { Filter = FILTER_PACKAGE_TEMPLATE };
if (sfd_UpdateAdmin_SaveTemplate.ShowDialog() == DialogResult.OK)
{
packageManager.SaveTemplate(sfd_UpdateAdmin_SaveTemplate.FileName);
curPackageTemplatePath = sfd_UpdateAdmin_SaveTemplate.FileName;
}
}
private void SelectPackageFileFolder()
{
var ofd_UpdateAdmin_PkgFileFolder = new RadOpenFolderDialog();
if (ofd_UpdateAdmin_PkgFileFolder.ShowDialog() == DialogResult.OK)
{
packageManager.FilesToCopyPath = ofd_UpdateAdmin_PkgFileFolder.FileName;
ShowPackageFiles();
}
}
private void RemovePackageFileFolder()
{
packageManager.FilesToCopyPath = string.Empty;
ShowPackageFiles();
}
private async Task<bool> ExportUpdatePackage(string filePath)
{
bool success = false;
ProgressPackagingControls(true);
try
{
await Task.Run(() => packageManager.ExportPackage(filePath));
success = true;
}
catch (Exception)
{
success = false;
}
ProgressPackagingControls(false);
return success;
}
private async Task<bool> ExportTempUpdatePackage()
{
var filePath = Path.GetTempFileName();
bool res = await ExportUpdatePackage(filePath);
if (res) TempPackageFilePath = filePath;
return res;
}
private void AddUpdateInstallerExtension()
{
var ofd_UpdateAdmin_AddExtension = new RadOpenFileDialog()
{
MultiSelect = true,
Filter = FILTER_PACKAGE_ADDON
};
if (ofd_UpdateAdmin_AddExtension.ShowDialog() == DialogResult.OK)
{
foreach (string f in ofd_UpdateAdmin_AddExtension.FileNames)
{
if (!packageManager.AddUpdateInstallerAddOn(f))
{
RadMessageBox.Show(My.Resources.UpdatingAdministrationLangRes.MsgBox_ErrorAddingInstallerAddOn, My.Resources.UpdatingAdministrationLangRes.MsgBox_Error_Titel, MessageBoxButtons.OK, RadMessageIcon.Error);
}
}
}
}
private void RemoveUpdateInstallerExtension()
{
foreach (string fAddOn in GetSelectedUpdateInstallAddOns())
packageManager.RemoveUpdateInstallerAddOn(fAddOn);
}
// G u i - P a c k a g i n g
private void ButtonItem_Pkg_NewTemplate_Click(object sender, EventArgs e)
{
NewPackageTemplate();
}
private void ButtonItem_Pkg_OpenTemplate_Click(object sender, EventArgs e)
{
OpenPackageTemplate();
}
private void ButtonItem_Pkg_SaveTemplate_Click(object sender, EventArgs e)
{
SavePackageTemplate();
}
private void ButtonItem_Pkg_SaveTemplateAs_Click(object sender, EventArgs e)
{
SavePackageTemplateAs();
}
private void ButtonItem_Pkg_SelectFileFolder_Click(object sender, EventArgs e)
{
SelectPackageFileFolder();
}
private void ButtonItem_Pkg_RemoveFileFolder_Click(object sender, EventArgs e)
{
RemovePackageFileFolder();
}
private async void ButtonItem_Pkg_Export_Click(object sender, EventArgs e)
{
var sfd_UpdateAdmin_ExportPkg = new RadSaveFileDialog()
{
Filter = FILTER_PACKAGE_ZIP_PACKAGE
};
if (sfd_UpdateAdmin_ExportPkg.ShowDialog() == DialogResult.OK)
{
if (await ExportUpdatePackage(sfd_UpdateAdmin_ExportPkg.FileName))
RadMessageBox.Show(this, My.Resources.UpdatingAdministrationLangRes.MsgBox_PkgExportSuccess, My.Resources.UpdatingAdministrationLangRes.MsgBox_PkgExportSuccess_Titel, MessageBoxButtons.OK, RadMessageIcon.Info);
}
}
private void ButtonItem_Pkg_AddExtension_Click(object sender, EventArgs e)
{
AddUpdateInstallerExtension();
}
private void ButtonItem_Pkg_RemoveExtension_Click(object sender, EventArgs e)
{
RemoveUpdateInstallerExtension();
} }
} }

View File

@@ -1,4 +1,64 @@
<root> <?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" /> <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true"> <xsd:element name="root" msdata:IsDataSet="true">

View File

@@ -0,0 +1,13 @@
using Pilz.Cryptography;
namespace Pilz.Updating.Administration.Integrations;
public class GitLabSnippetConfig
{
public bool Enabled { get; set; }
public string GitLabUrl { get; set; }
public SecureString PersonalAccessToken { get; set; }
public int ProjectId { get; set; }
public int SnippetId { get; set; }
public string SnippetFilePath { get; set; }
}

View File

@@ -0,0 +1,65 @@
using NGitLab;
using NGitLab.Models;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
namespace Pilz.Updating.Administration.Integrations;
public static class GitLabSnippetExtension
{
private static IGitLabClient GetClient(GitLabSnippetConfig config)
{
return new GitLabClient(config.GitLabUrl, config.PersonalAccessToken);
}
private static bool LoadSnippet(UpdateServerManager manager)
{
var httpClient = new HttpClient();
var glClient = GetClient(manager.Config.GitLabSnippetConfig);
if (glClient.Snippets.Get(manager.Config.GitLabSnippetConfig.ProjectId, manager.Config.GitLabSnippetConfig.SnippetId) is not Snippet snippet
|| snippet.Files.FirstOrDefault(f => f.Path == manager.Config.GitLabSnippetConfig.SnippetFilePath) is not SnippetFile file
|| httpClient.GetStringAsync(snippet.Files[1].RawUrl).Result is not string content)
return false;
manager.UpdateInfo = UpdateInfo.Parse(content);
return true;
}
private static bool SaveSnippet(UpdateServerManager manager)
{
var glClient = GetClient(manager.Config.GitLabSnippetConfig);
if (glClient == null)
return false;
glClient.Snippets.Update(new SnippetProjectUpdate
{
SnippetId = manager.Config.GitLabSnippetConfig.SnippetId,
ProjectId = manager.Config.GitLabSnippetConfig.ProjectId,
Files = [
new SnippetUpdateFile
{
Action = SnippetUpdateFileAction.Update,
FilePath = manager.Config.GitLabSnippetConfig.SnippetFilePath,
Content = manager.UpdateInfo.ToString(),
}
],
Visibility = VisibilityLevel.Public,
});
return true;
}
public static Task<bool> ReadInfoFromGitLabSnippet(this UpdateServerManager manager)
{
return Task.Run(() => LoadSnippet(manager));
}
public static Task<bool> SaveInfoToGitLabSnippet(this UpdateServerManager manager)
{
return Task.Run(() => SaveSnippet(manager));
}
}

View File

@@ -1,106 +0,0 @@
using global::Newtonsoft.Json.Linq;
using global::System.IO;
using global::System.Reflection;
using Microsoft.VisualBasic.CompilerServices;
using Pilz.Updating.UpdateInstaller;
using System.Collections.Generic;
using Z.Collections.Extensions;
namespace Pilz.Updating.Administration.Packaging;
internal class UpdatePackageManager
{
// F i e l d s
private UpdatePackageTemplate template;
// P r o p e r t i e s
public string FilesToCopyPath
{
get
{
return template.FilesToCopyPath;
}
set
{
template.FilesToCopyPath = value;
}
}
// C o n s t r u c o t r s
public UpdatePackageManager()
{
NewTemplate();
}
// F e a t u r e s
public void LoadTemplate(string filePath)
{
template = JObject.Parse(File.ReadAllText(filePath)).ToObject<UpdatePackageTemplate>();
}
public void SaveTemplate(string filePath)
{
File.WriteAllText(filePath, JObject.FromObject(template).ToString());
}
public void NewTemplate()
{
template = new UpdatePackageTemplate();
}
public void ExportPackage(string path)
{
var exporter = new UpdatePackagePackager(template);
exporter.Export(path);
}
private bool CheckUpdateInstallerAddOn(string path)
{
var asm = Assembly.ReflectionOnlyLoadFrom(path);
var t = asm.GetType($"{UpdateInstallerAddOnNameDefinitions.UPDATE_INSTALLER_ADDON_NAMESPACE}.{UpdateInstallerAddOnNameDefinitions.UPDATE_INSTALLER_ADDON_TYPE}", false);
bool isSupported = false;
if (t is object)
{
var mi = t.GetMethod(UpdateInstallerAddOnNameDefinitions.UPDATE_INSTALLER_ADDON_METHOD, BindingFlags.Static | BindingFlags.Public);
if (mi is object)
{
var @params = mi.GetParameters();
if (@params.Length == 1 && @params.GetType() == typeof(Dictionary<string, object>))
{
isSupported = true;
}
}
}
return isSupported;
}
public bool AddUpdateInstallerAddOn(string path)
{
if (Conversions.ToBoolean(!template.UpdateInstallerAddOns.Contains(path) && CheckUpdateInstallerAddOn(path)))
{
template.UpdateInstallerAddOns.Add(path);
return true;
}
else
{
return false;
}
}
public IEnumerable<string> GetAllUpdateInstallerÁddOn()
{
return template.UpdateInstallerAddOns;
}
public void RemoveUpdateInstallerAddOn(string path)
{
template.UpdateInstallerAddOns.RemoveIfContains(path);
}
}

View File

@@ -1,51 +0,0 @@
using System.IO;
using System.IO.Compression;
using Pilz.Updating.UpdateInstaller;
using Z.IO.Extensions;
namespace Pilz.Updating.Administration.Packaging;
public class UpdatePackagePackager
{
public UpdatePackageTemplate UpdatePackageTemplate { get; set; }
public UpdatePackagePackager(UpdatePackageTemplate updatePackageTemplate)
{
UpdatePackageTemplate = updatePackageTemplate;
}
public void Export(string exportPath)
{
string tempPath = MyPaths.GetMyAppDataPath();
var packageDir = new DirectoryInfo(Path.Combine(tempPath, "UpdatePackageCreation"));
// Ensure package directory exists and is empty
if (packageDir.Exists)
packageDir.Delete(true);
packageDir.Create();
// Copy local data to temp data directory
var dataDir = packageDir.CreateSubdirectory(PackageFileNameDefinations.ZIP_APP_DATA_FILES_DIRECTORY);
var localDataDir = new DirectoryInfo(UpdatePackageTemplate.FilesToCopyPath);
localDataDir.CopyTo(dataDir.FullName, SearchOption.AllDirectories);
// Copy all UpdateInstaller AddOns
var addOnsDir = packageDir.CreateSubdirectory(PackageFileNameDefinations.ZIP_UPDATE_INSTALLER_ADDONS_DIRECTORY);
uint curAddOnID = 0;
foreach (string fAddOn in UpdatePackageTemplate.UpdateInstallerAddOns)
{
File.Copy(fAddOn, Path.Combine(addOnsDir.FullName, $"installer_addon_{curAddOnID}.dll"));
curAddOnID += 1;
}
// Ensure destination file doesn't exist
if (File.Exists(exportPath))
File.Delete(exportPath);
// Export to ZIP
ZipFile.CreateFromDirectory(packageDir.FullName, exportPath);
// Delete temp directory
packageDir.Delete(true);
}
}

View File

@@ -1,9 +0,0 @@
using System.Collections.Generic;
namespace Pilz.Updating.Administration.Packaging;
public class UpdatePackageTemplate
{
public string FilesToCopyPath { get; set; }
public List<string> UpdateInstallerAddOns { get; set; } = [];
}

View File

@@ -41,6 +41,7 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.CSharp" Version="4.7.0" /> <PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
<PackageReference Include="Microsoft.VisualBasic" Version="10.3.0" /> <PackageReference Include="Microsoft.VisualBasic" Version="10.3.0" />
<PackageReference Include="NGitLab" Version="6.50.3" />
<PackageReference Include="Pilz.Cryptography" Version="2.0.1" /> <PackageReference Include="Pilz.Cryptography" Version="2.0.1" />
<PackageReference Include="System.Data.DataSetExtensions" Version="4.5.0" /> <PackageReference Include="System.Data.DataSetExtensions" Version="4.5.0" />
<PackageReference Include="System.Net.Http" Version="4.3.4" /> <PackageReference Include="System.Net.Http" Version="4.3.4" />

View File

@@ -3,6 +3,4 @@
public static class PackageFileNameDefinations public static class PackageFileNameDefinations
{ {
public const string ZIP_PACKAGE_FILENAME = "updatepackage.zip"; public const string ZIP_PACKAGE_FILENAME = "updatepackage.zip";
public const string ZIP_UPDATE_INSTALLER_ADDONS_DIRECTORY = "installer_addons";
public const string ZIP_APP_DATA_FILES_DIRECTORY = "appdata";
} }

View File

@@ -1,25 +1,26 @@
using Newtonsoft.Json.Linq; using Newtonsoft.Json;
using Pilz.Updating.Administration.Discord; using Pilz.Updating.Administration.Discord;
using Pilz.Updating.Administration.Integrations;
using System.IO; using System.IO;
namespace Pilz.Updating.Administration; namespace Pilz.Updating.Administration;
public class UpdateProject public class UpdateProject
{ {
public UpdateServerConfig UpdateServerConfig { get; } = new UpdateServerConfig(); public UpdateServerConfig UpdateServerConfig { get; } = new();
public DiscordBotConfig DiscordBotConfig { get; } = new DiscordBotConfig(); public DiscordBotConfig DiscordBotConfig { get; } = new();
public ProxyConfiguration ProxyConfig { get; } = new ProxyConfiguration(); public ProxyConfiguration ProxyConfig { get; } = new();
public static UpdateProject Load(string filePath) public static UpdateProject Load(string filePath)
{ {
if (File.Exists(filePath)) if (File.Exists(filePath))
return JObject.Parse(File.ReadAllText(filePath)).ToObject<UpdateProject>(); return JsonConvert.DeserializeObject<UpdateProject>(File.ReadAllText(filePath));
else else
return new UpdateProject(); return new();
} }
public void Save(string filePath) public void Save(string filePath)
{ {
File.WriteAllText(filePath, JObject.FromObject(this).ToString()); File.WriteAllText(filePath, JsonConvert.SerializeObject(this));
} }
} }

View File

@@ -1,16 +1,8 @@
using Newtonsoft.Json; using Pilz.Updating.Administration.Integrations;
using Pilz.Cryptography;
namespace Pilz.Updating.Administration; namespace Pilz.Updating.Administration;
public class UpdateServerConfig public class UpdateServerConfig
{ {
public bool UseProxyForWebDAV { get; set; } = false; public GitLabSnippetConfig GitLabSnippetConfig { get; } = new();
public string ServerAdress { get; set; }
public string PublicPackageBaseURL { get; set; }
public string UpdateInfoFilename { get; set; }
public string Username { get; set; }
[JsonProperty("PasswordV3")]
public SecureString Password { get; set; }
} }

View File

@@ -1,403 +1,25 @@
using Microsoft.VisualBasic; using System.IO;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Threading.Tasks;
using WebDav;
using static Microsoft.VisualBasic.CompilerServices.LikeOperator;
namespace Pilz.Updating.Administration; namespace Pilz.Updating.Administration;
public class UpdateServerManager public class UpdateServerManager(UpdateServerConfig config)
{ {
private const string PKG_SEARCHTEXT = "pkg*.*.*.*.zip"; public UpdateInfo UpdateInfo { get; internal set; } = new();
private const string PKG_FILENAME_TEMPLATE = "pkg{0}{1}.zip"; public UpdateServerConfig Config { get; private set; } = config;
private const string PKG_FILENAME_ALPHADEFINITION = "a";
private const string PKG_FILENAME_BETADEFINITION = "b";
private const string PKG_FILENAME_RCDEFINITION = "rc";
private const string PKG_FILENAME_RELEASEDEFINITION = "r";
private WebDavClient client;
public UpdateInfo UpdateInfo { get; private set; }
public UpdateServerConfig Config { get; private set; }
public bool IsReady { get; private set; } public bool IsReady { get; private set; }
public UpdateServerManager(UpdateServerConfig config)
{
GenerateClient(config);
NewInfo();
}
public bool GenerateClient(UpdateServerConfig config)
{
bool success;
try
{
// Create client params
var clientparams = new WebDavClientParams()
{
BaseAddress = new Uri(config.ServerAdress),
Credentials = new NetworkCredential(config.Username, config.Password),
UseProxy = false
};
// Create client
client = new WebDavClient(clientparams);
// Remember config
Config = config;
success = true;
}
catch (Exception)
{
success = false;
Config = null;
client = null;
}
return success;
}
public async Task<bool> LoadInfoFromServer()
{
bool success;
try
{
var response = await client.GetProcessedFile(Config.UpdateInfoFilename);
if (response.IsSuccessful)
{
var sr = new StreamReader(response.Stream);
var raw = await sr.ReadToEndAsync();
sr.Close();
UpdateInfo = JObject.Parse(raw).ToObject<UpdateInfo>();
}
success = true;
}
catch (Exception)
{
success = false;
}
return success;
}
public async Task<bool> SaveInfoToServer()
{
bool success;
try
{
// Remove configs of non-existing packages
await ClearUpdateInfo();
// Update Packagelinks
UpdatePackageLinks();
// Write
var raw = UpdateInfo.ToString();
var ms = new MemoryStream();
var sw = new StreamWriter(ms);
await sw.WriteAsync(raw);
await sw.FlushAsync();
// Upload
ms.Position = 0;
await client.PutFile(Config.UpdateInfoFilename, ms);
ms.Close();
success = true;
}
catch (Exception)
{
success = false;
}
return success;
}
public void LoadInfoFromFile(string filePath) public void LoadInfoFromFile(string filePath)
{ {
UpdateInfo = JObject.Parse(File.ReadAllText(filePath)).ToObject<UpdateInfo>(); UpdateInfo = UpdateInfo.Parse(File.ReadAllText(filePath));
} }
public async Task SaveInfoToFile(string filePath) public void SaveInfoToFile(string filePath)
{ {
// Remove configs of non-existing packages
await ClearUpdateInfo();
// Update Packagelinks
UpdatePackageLinks();
// Write
File.WriteAllText(filePath, UpdateInfo.ToString()); File.WriteAllText(filePath, UpdateInfo.ToString());
} }
public void NewInfo() public void NewInfo()
{ {
UpdateInfo = new UpdateInfo(); UpdateInfo = new();
}
private async Task ClearUpdateInfo()
{
var pkgs = await GetUpdatePackagesList();
var infosToRemove = new List<UpdatePackageInfo>();
// Find non-existing packages
foreach (var info in UpdateInfo.Packages)
{
if (!pkgs.Where((n) => n == info.Version).Any())
{
infosToRemove.Add(info);
}
}
// Remove found packages
foreach (var info in infosToRemove)
UpdateInfo.Packages.Remove(info);
}
private void UpdatePackageLinks()
{
foreach (var info in UpdateInfo.Packages)
UpdatePackageLink(info);
}
private void UpdatePackageLink(UpdatePackageInfo info)
{
info.Packagelink = Config.PublicPackageBaseURL + BuildPackageFilename(info.Version);
}
public async Task<IEnumerable<ApplicationVersion>> GetUpdatePackagesList()
{
var pkgs = new List<ApplicationVersion>();
var response = await client.Propfind(string.Empty);
if (response.IsSuccessful)
{
foreach (var resource in response.Resources)
{
var fileName = Path.GetFileName(resource.Uri);
if (!string.IsNullOrEmpty(fileName) && fileName.ToLower() != Config.UpdateInfoFilename && LikeString(fileName, "pkg*.*.*.*.zip", CompareMethod.Text))
{
var appVersion = new ApplicationVersion();
bool allowAdd = true;
fileName = Path.GetFileNameWithoutExtension(fileName);
fileName = fileName.Substring(3);
// Get alpha/beta/rc value
{
int indexAlpha, indexBeta, indexRC, indexRelease;
indexAlpha = fileName.IndexOf(PKG_FILENAME_ALPHADEFINITION);
indexBeta = fileName.IndexOf(PKG_FILENAME_BETADEFINITION);
indexRC = fileName.IndexOf(PKG_FILENAME_RCDEFINITION);
indexRelease = fileName.IndexOf(PKG_FILENAME_RELEASEDEFINITION);
int indexDef;
string pkgFilenameDef;
if (indexAlpha > -1)
{
indexDef = indexAlpha;
pkgFilenameDef = PKG_FILENAME_ALPHADEFINITION;
}
else if (indexBeta > -1)
{
indexDef = indexBeta;
pkgFilenameDef = PKG_FILENAME_BETADEFINITION;
}
else if (indexRC > -1)
{
indexDef = indexRC;
pkgFilenameDef = PKG_FILENAME_RCDEFINITION;
}
else if (indexRelease > -1)
{
indexDef = indexRelease;
pkgFilenameDef = PKG_FILENAME_RELEASEDEFINITION;
}
else
{
indexDef = -1;
pkgFilenameDef = null;
}
if (indexDef > -1)
{
// Get def from filename
var def = fileName.Substring(indexDef);
fileName = fileName.Remove(indexDef);
// Get channel
switch (pkgFilenameDef)
{
case PKG_FILENAME_ALPHADEFINITION:
appVersion.Channel = Channels.Alpha;
break;
case PKG_FILENAME_BETADEFINITION:
appVersion.Channel = Channels.Beta;
break;
case PKG_FILENAME_RCDEFINITION:
appVersion.Channel = Channels.PreRelease;
break;
case PKG_FILENAME_RELEASEDEFINITION:
appVersion.Channel = Channels.Stable;
break;
}
// Get build
var defBuild = def.Substring(pkgFilenameDef.Length);
appVersion.Build = Convert.ToInt32(defBuild);
}
else
{
// Set to default
appVersion.Build = 1;
appVersion.Channel = Channels.Stable;
}
}
// Get version
if (Version.TryParse(fileName, out Version version))
appVersion.Version = version;
else
allowAdd = false;
if (allowAdd)
pkgs.Add(appVersion);
}
}
}
return pkgs;
}
public async Task<bool> DeletePackage(ApplicationVersion version)
{
var fileName = BuildPackageFilename(version);
var response = await client.Delete(fileName);
return response.IsSuccessful;
}
public async Task<bool> UploadPackage(string filePath, ApplicationVersion version)
{
bool success;
var fileName = BuildPackageFilename(version);
// Upload
var fs = new FileStream(filePath, FileMode.Open, FileAccess.Read);
var response = await client.PutFile(fileName, fs);
fs.Close();
success = response.IsSuccessful;
// Generate public downloadlink
if (success)
{
var pkgInfo = GetOrCreateUpdatePackageInfo(version);
pkgInfo.Packagelink = Config.PublicPackageBaseURL + fileName;
}
return success;
}
private string BuildPackageFilename(ApplicationVersion version)
{
// Build channel/build definition of filename
string def = string.Empty;
switch (version.Channel)
{
case Channels.Alpha:
def = PKG_FILENAME_ALPHADEFINITION + version.Build;
break;
case Channels.Stable:
if (version.Build != 1)
def = PKG_FILENAME_RELEASEDEFINITION + version.Build;
break;
case Channels.PreRelease:
def = PKG_FILENAME_RCDEFINITION + version.Build;
break;
case Channels.Beta:
def = PKG_FILENAME_BETADEFINITION + version.Build;
break;
}
// Build filename
var fileName = string.Format(PKG_FILENAME_TEMPLATE, version.Version, def);
return fileName;
}
private UpdatePackageInfo GetOrCreateUpdatePackageInfo(ApplicationVersion version)
{
var info = GetUpdatePackageInfo(version);
info ??= CreateUpdatePackageInfo(version);
return info;
}
public UpdatePackageInfo GetUpdatePackageInfo(ApplicationVersion version)
{
return UpdateInfo.Packages.FirstOrDefault((n) => n.Version == version);
}
private UpdatePackageInfo CreateUpdatePackageInfo(ApplicationVersion version)
{
var info = new UpdatePackageInfo()
{
Version = version
};
UpdateInfo.Packages.Add(info);
return info;
}
public (string name, string description, UpdateNotesContentType descriptionType) GetPackageDescription(ApplicationVersion version)
{
var pkg = GetUpdatePackageInfo(version);
if (pkg is object)
return (pkg.Name, pkg.Notes.Content, pkg.Notes.ContentType);
else
return default;
}
public void SetPackageDescription(ApplicationVersion version, string name, string description, UpdateNotesContentType descriptionType)
{
var pkg = GetOrCreateUpdatePackageInfo(version);
if (pkg is object)
{
pkg.Name = name;
pkg.Notes.Content = description;
pkg.Notes.ContentType = descriptionType;
}
}
public async Task<bool> ChangePackageVersion(ApplicationVersion currentVersion, ApplicationVersion newVersion)
{
bool success = false;
// Get file names
var currentFilename = BuildPackageFilename(currentVersion);
var newFilename = BuildPackageFilename(newVersion);
// Move
var response = await client.Move(currentFilename, newFilename);
// Change package info version, if exists
if (response.IsSuccessful)
{
var pkg = GetUpdatePackageInfo(currentVersion);
if (pkg is object)
pkg.Version = newVersion;
success = true;
}
return success;
} }
} }

View File

@@ -1,4 +1,5 @@
using Microsoft.VisualBasic.CompilerServices; using Microsoft.VisualBasic.CompilerServices;
using Pilz.Updating.UpdateInstaller;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
@@ -150,15 +151,15 @@ public class UpdateClient
{ {
curDownloadingStatus = UpdateStatus.DownloadingPackage; curDownloadingStatus = UpdateStatus.DownloadingPackage;
RaiseUpdateStatusChanged(curDownloadingStatus); RaiseUpdateStatusChanged(curDownloadingStatus);
string dirPath = Path.Combine(MyPaths.GetMyAppDataPath(), Conversions.ToString(package.GetHashCode())); var dirPath = Path.Combine(MyPaths.GetMyAppDataPath(), package.GetHashCode().ToString());
string zipPath = Path.Combine(dirPath, PackageFileNameDefinations.ZIP_PACKAGE_FILENAME); var zipPath = Path.Combine(dirPath, "package.zip");
var dir = new DirectoryInfo(dirPath); var dir = new DirectoryInfo(dirPath);
try try
{ {
// Ensure existing and empty directory for the Zip File // Ensure existing and empty directory for the Zip File
if (dir.Exists) if (dir.Exists)
dir.Delete(true); dir.Delete(true);
dir.Create(); dir.Create();
// Download zip package // Download zip package

View File

@@ -4,7 +4,7 @@ using System.IO.Compression;
namespace Pilz.Updating.UpdateInstaller.Lib; namespace Pilz.Updating.UpdateInstaller.Lib;
public class UpdateInstaller public class UpdateInstaller(UpdateInstallerConfig config)
{ {
// E v e n t s // E v e n t s
@@ -12,8 +12,8 @@ public class UpdateInstaller
public delegate void UpdateInstallerStepEventHandler(object sender, UpdateInstallerStepEventArgs e); public delegate void UpdateInstallerStepEventHandler(object sender, UpdateInstallerStepEventArgs e);
public delegate void StatusChangesEventHandler(object sender, UpdateInstallerStatusChangedEventArgs e); public delegate void StatusChangesEventHandler(object sender, UpdateInstallerStatusChangedEventArgs e);
public event StatusChangesEventHandler StatusChanges; public event StatusChangesEventHandler? StatusChanges;
public event UpdateInstallerStepEventHandler OnStep; public event UpdateInstallerStepEventHandler? OnStep;
// F i e l d s // F i e l d s
@@ -21,14 +21,7 @@ public class UpdateInstaller
// P r o p e r t i e s // P r o p e r t i e s
public UpdateInstallerConfig Configuration { get; private set; } public UpdateInstallerConfig Configuration { get; private set; } = config;
// C o n s t r c u t o r s
public UpdateInstaller(UpdateInstallerConfig config)
{
Configuration = config;
}
// F e a t u r e s // F e a t u r e s
@@ -45,10 +38,8 @@ public class UpdateInstaller
public void StartHostApplication() public void StartHostApplication()
{ {
if (!string.IsNullOrEmpty(Conversions.ToString(Configuration.RestartHostApplication)) && File.Exists(Configuration.HostApplicationProcessPath)) if (!string.IsNullOrEmpty(Conversions.ToString(Configuration.RestartHostApplication)) && File.Exists(Configuration.HostApplicationProcessPath))
{
Process.Start(Configuration.HostApplicationProcessPath, Configuration.RestartHostApplicationArguments); Process.Start(Configuration.HostApplicationProcessPath, Configuration.RestartHostApplicationArguments);
} }
}
public void InstallUpdate() public void InstallUpdate()
{ {
@@ -105,11 +96,9 @@ public class UpdateInstaller
} }
} }
else else
{
enabled = false; enabled = false;
} }
} }
}
private void ExtractPackage() private void ExtractPackage()
{ {
@@ -129,7 +118,7 @@ public class UpdateInstaller
private void CopyFiles() private void CopyFiles()
{ {
var sourceDir = new DirectoryInfo(Path.Combine(dataPath, PackageFileNameDefinations.ZIP_APP_DATA_FILES_DIRECTORY)); var sourceDir = new DirectoryInfo(dataPath);
var destDir = new DirectoryInfo(Configuration.HostApplicationPath); var destDir = new DirectoryInfo(Configuration.HostApplicationPath);
CopyFiles(sourceDir, destDir); CopyFiles(sourceDir, destDir);
} }
@@ -137,9 +126,7 @@ public class UpdateInstaller
private void CopyFiles(DirectoryInfo sourceDir, DirectoryInfo destinationDir) private void CopyFiles(DirectoryInfo sourceDir, DirectoryInfo destinationDir)
{ {
if (!destinationDir.Exists) if (!destinationDir.Exists)
{
destinationDir.Create(); destinationDir.Create();
}
foreach (FileInfo sFile in sourceDir.EnumerateFiles("*", SearchOption.TopDirectoryOnly)) foreach (FileInfo sFile in sourceDir.EnumerateFiles("*", SearchOption.TopDirectoryOnly))
{ {

View File

@@ -1,11 +1,6 @@
namespace Pilz.Updating.UpdateInstaller.Lib; namespace Pilz.Updating.UpdateInstaller.Lib;
public class UpdateInstallerEventArgs : EventArgs public class UpdateInstallerEventArgs(UpdateInstaller updateInstaller) : EventArgs
{ {
public UpdateInstaller UpdateInstaller { get; init; } public UpdateInstaller UpdateInstaller { get; init; } = updateInstaller;
public UpdateInstallerEventArgs(UpdateInstaller updateInstaller)
{
UpdateInstaller = updateInstaller;
}
} }

View File

@@ -3,16 +3,16 @@ using System;
namespace Pilz.Updating; namespace Pilz.Updating;
public class ApplicationVersion public class ApplicationVersion(Version version, int build, Channels channel)
{ {
// P r o p e r t i e s // P r o p e r t i e s
[JsonConverter(typeof(Newtonsoft.Json.Converters.VersionConverter))] [JsonConverter(typeof(Newtonsoft.Json.Converters.VersionConverter))]
public Version Version { get; set; } public Version Version { get; set; } = version;
public int Build { get; set; } public int Build { get; set; } = build;
[JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))] [JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
public Channels Channel { get; set; } public Channels Channel { get; set; } = channel;
// C o n s t r u c t o r s // C o n s t r u c t o r s
@@ -24,13 +24,6 @@ public class ApplicationVersion
{ {
} }
public ApplicationVersion(Version version, int build, Channels channel)
{
Version = version;
Build = build;
Channel = channel;
}
// F e a t u r e s // F e a t u r e s
public override string ToString() public override string ToString()

View File

@@ -1,5 +1,5 @@
using global::System.IO; using System;
using System; using System.IO;
namespace Pilz.Updating; namespace Pilz.Updating;
@@ -13,11 +13,8 @@ internal static class MyPaths
{ {
p = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "PilzUpdater"); p = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "PilzUpdater");
if (!Directory.Exists(p)) if (!Directory.Exists(p))
{
Directory.CreateDirectory(p); Directory.CreateDirectory(p);
} }
}
return p; return p;
} }
} }

View File

@@ -1,4 +1,4 @@
using global::Newtonsoft.Json.Linq; using Newtonsoft.Json;
using System.Collections.Generic; using System.Collections.Generic;
namespace Pilz.Updating; namespace Pilz.Updating;
@@ -10,11 +10,11 @@ public class UpdateInfo
public static UpdateInfo Parse(string str) public static UpdateInfo Parse(string str)
{ {
return JObject.Parse(str).ToObject<UpdateInfo>(); return JsonConvert.DeserializeObject<UpdateInfo>(str);
} }
public override string ToString() public override string ToString()
{ {
return JObject.FromObject(this).ToString(); return JsonConvert.SerializeObject(this);
} }
} }

View File

@@ -1,22 +1,9 @@
namespace Pilz.Updating;
using Newtonsoft.Json;
namespace Pilz.Updating;
public class UpdatePackageInfo public class UpdatePackageInfo
{ {
public string Name { get; set; } public string Name { get; set; }
public ApplicationVersion Version { get; set; } public ApplicationVersion Version { get; set; }
public UpdateNotes Notes { get; } = new UpdateNotes(); public UpdateNotes Notes { get; } = new();
public string Packagelink { get; set; } public string Packagelink { get; set; }
[JsonProperty]
private string Changelog
{
set
{
Notes.Content = value;
Notes.ContentType = UpdateNotesContentType.PlainText;
}
}
} }