diff --git a/README.md b/README.md index 0a81c28..993e223 100644 --- a/README.md +++ b/README.md @@ -12,10 +12,11 @@ Microsoft is creating a new Windows Package Manager CLI (aka winget) which is ba Clone the winget-pkgs repository to a local folder and specify that folder in WingetRepoBrowser and click on 'Search'. -**Commandline Arguments:** +**New Features in v0.1.2** -- First Arg will be used to fill 'Repo-Folder' edit -- Second Arg will be used to fill 'Installers-Folder' edit +- moved from command-line switches to AppSettings.json (that allows to configure which locales should be downloaded) +- context menu in 'New Downloads'-window allows to ignore a ParsedVersion for download (VersionsToIgnoreDownload stored .wingetid-files) +- ParsedVersion-column allows to sort by PackageVersion (using a separate column makes it easier to find problems with the sorting-implementation) **New Feature in v0.0.2** diff --git a/src/WingetRepoBrowser/AppSettings.cs b/src/WingetRepoBrowser/AppSettings.cs new file mode 100644 index 0000000..20add61 --- /dev/null +++ b/src/WingetRepoBrowser/AppSettings.cs @@ -0,0 +1,10 @@ +namespace WingetRepoBrowser +{ + public class AppSettings + { + public string InstallersFolder { get; set; } + public string RepoFolder { get; set; } + public string[] LocalesToDownload { get; set; } + + } +} diff --git a/src/WingetRepoBrowser/AppSettings.json b/src/WingetRepoBrowser/AppSettings.json new file mode 100644 index 0000000..d3636e9 --- /dev/null +++ b/src/WingetRepoBrowser/AppSettings.json @@ -0,0 +1,8 @@ +{ + "RepoFolder": "V:\\projects_os_git\\winget-pkgs\\manifests", + "InstallersFolder": "W:\\installers", + "LocalesToDownload": [ + "en-us", + "de-de" + ] +} diff --git a/src/WingetRepoBrowser/MainForm.Designer.cs b/src/WingetRepoBrowser/MainForm.Designer.cs index 55fdd7a..cf256c6 100644 --- a/src/WingetRepoBrowser/MainForm.Designer.cs +++ b/src/WingetRepoBrowser/MainForm.Designer.cs @@ -1,33 +1,33 @@ namespace WingetRepoBrowser { - partial class MainForm - { - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; + partial class MainForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) - { - if (disposing && (components != null)) - { - components.Dispose(); - } - base.Dispose(disposing); - } + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } - #region Windows Form Designer generated code + #region Windows Form Designer generated code - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() - { + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { DevExpress.XtraGrid.GridLevelNode gridLevelNode1 = new DevExpress.XtraGrid.GridLevelNode(); this.gridView2 = new DevExpress.XtraGrid.Views.Grid.GridView(); this.colInstArch = new DevExpress.XtraGrid.Columns.GridColumn(); @@ -53,6 +53,7 @@ private void InitializeComponent() this.colId = new DevExpress.XtraGrid.Columns.GridColumn(); this.colName = new DevExpress.XtraGrid.Columns.GridColumn(); this.colVersion = new DevExpress.XtraGrid.Columns.GridColumn(); + this.colParsedVersion = new DevExpress.XtraGrid.Columns.GridColumn(); this.colDefaultLocale = new DevExpress.XtraGrid.Columns.GridColumn(); this.colPackageLocale = new DevExpress.XtraGrid.Columns.GridColumn(); this.colPublisher = new DevExpress.XtraGrid.Columns.GridColumn(); @@ -74,7 +75,7 @@ private void InitializeComponent() this.colInstallerType = new DevExpress.XtraGrid.Columns.GridColumn(); this.colInstallersCount = new DevExpress.XtraGrid.Columns.GridColumn(); this.colInstallersArch = new DevExpress.XtraGrid.Columns.GridColumn(); - this.colInstallersLanguage = new DevExpress.XtraGrid.Columns.GridColumn(); + this.colInstallersLocale = new DevExpress.XtraGrid.Columns.GridColumn(); this.colInstallersInstallerType = new DevExpress.XtraGrid.Columns.GridColumn(); this.colManifestSwitchInteractive = new DevExpress.XtraGrid.Columns.GridColumn(); this.colManifestSwitchSilent = new DevExpress.XtraGrid.Columns.GridColumn(); @@ -185,7 +186,8 @@ private void InitializeComponent() // // colInstLanguage // - this.colInstLanguage.FieldName = "Language"; + this.colInstLanguage.Caption = "InstallerLocale"; + this.colInstLanguage.FieldName = "InstallerLocale"; this.colInstLanguage.Name = "colInstLanguage"; this.colInstLanguage.Visible = true; this.colInstLanguage.VisibleIndex = 6; @@ -281,6 +283,7 @@ private void InitializeComponent() this.colId, this.colName, this.colVersion, + this.colParsedVersion, this.colDefaultLocale, this.colPackageLocale, this.colPublisher, @@ -301,7 +304,7 @@ private void InitializeComponent() this.colInstallerType, this.colInstallersCount, this.colInstallersArch, - this.colInstallersLanguage, + this.colInstallersLocale, this.colInstallersInstallerType, this.colManifestSwitchInteractive, this.colManifestSwitchSilent, @@ -359,7 +362,17 @@ private void InitializeComponent() this.colVersion.Name = "colVersion"; this.colVersion.OptionsColumn.ReadOnly = true; this.colVersion.Visible = true; - this.colVersion.VisibleIndex = 6; + this.colVersion.VisibleIndex = 4; + // + // colParsedVersion + // + this.colParsedVersion.Caption = "ParsedVersion"; + this.colParsedVersion.FieldName = "ParsedPackageVersion"; + this.colParsedVersion.Name = "colParsedVersion"; + this.colParsedVersion.OptionsColumn.AllowSort = DevExpress.Utils.DefaultBoolean.True; + this.colParsedVersion.SortMode = DevExpress.XtraGrid.ColumnSortMode.DisplayText; + this.colParsedVersion.Visible = true; + this.colParsedVersion.VisibleIndex = 5; // // colDefaultLocale // @@ -367,7 +380,7 @@ private void InitializeComponent() this.colDefaultLocale.FieldName = "DefaultLocale"; this.colDefaultLocale.Name = "colDefaultLocale"; this.colDefaultLocale.Visible = true; - this.colDefaultLocale.VisibleIndex = 5; + this.colDefaultLocale.VisibleIndex = 7; // // colPackageLocale // @@ -375,7 +388,7 @@ private void InitializeComponent() this.colPackageLocale.FieldName = "PackageLocale"; this.colPackageLocale.Name = "colPackageLocale"; this.colPackageLocale.Visible = true; - this.colPackageLocale.VisibleIndex = 4; + this.colPackageLocale.VisibleIndex = 6; // // colPublisher // @@ -383,7 +396,7 @@ private void InitializeComponent() this.colPublisher.Name = "colPublisher"; this.colPublisher.OptionsColumn.ReadOnly = true; this.colPublisher.Visible = true; - this.colPublisher.VisibleIndex = 7; + this.colPublisher.VisibleIndex = 8; // // colMoniker // @@ -391,7 +404,7 @@ private void InitializeComponent() this.colMoniker.Name = "colMoniker"; this.colMoniker.OptionsColumn.ReadOnly = true; this.colMoniker.Visible = true; - this.colMoniker.VisibleIndex = 8; + this.colMoniker.VisibleIndex = 9; // // colAuthor // @@ -399,7 +412,7 @@ private void InitializeComponent() this.colAuthor.Name = "colAuthor"; this.colAuthor.OptionsColumn.ReadOnly = true; this.colAuthor.Visible = true; - this.colAuthor.VisibleIndex = 9; + this.colAuthor.VisibleIndex = 10; // // colLicense // @@ -407,7 +420,7 @@ private void InitializeComponent() this.colLicense.Name = "colLicense"; this.colLicense.OptionsColumn.ReadOnly = true; this.colLicense.Visible = true; - this.colLicense.VisibleIndex = 10; + this.colLicense.VisibleIndex = 11; // // colLicenseUrl // @@ -416,7 +429,7 @@ private void InitializeComponent() this.colLicenseUrl.Name = "colLicenseUrl"; this.colLicenseUrl.OptionsColumn.ReadOnly = true; this.colLicenseUrl.Visible = true; - this.colLicenseUrl.VisibleIndex = 11; + this.colLicenseUrl.VisibleIndex = 12; // // repositoryItemButtonEditUrl // @@ -432,7 +445,7 @@ private void InitializeComponent() this.colPublisherUrl.FieldName = "PublisherUrl"; this.colPublisherUrl.Name = "colPublisherUrl"; this.colPublisherUrl.Visible = true; - this.colPublisherUrl.VisibleIndex = 12; + this.colPublisherUrl.VisibleIndex = 13; // // colPrivacyUrl // @@ -440,7 +453,7 @@ private void InitializeComponent() this.colPrivacyUrl.FieldName = "PrivacyUrl"; this.colPrivacyUrl.Name = "colPrivacyUrl"; this.colPrivacyUrl.Visible = true; - this.colPrivacyUrl.VisibleIndex = 13; + this.colPrivacyUrl.VisibleIndex = 14; // // colMinOSVersion // @@ -448,7 +461,7 @@ private void InitializeComponent() this.colMinOSVersion.Name = "colMinOSVersion"; this.colMinOSVersion.OptionsColumn.ReadOnly = true; this.colMinOSVersion.Visible = true; - this.colMinOSVersion.VisibleIndex = 14; + this.colMinOSVersion.VisibleIndex = 15; // // colPackageUrl // @@ -457,7 +470,7 @@ private void InitializeComponent() this.colPackageUrl.Name = "colPackageUrl"; this.colPackageUrl.OptionsColumn.ReadOnly = true; this.colPackageUrl.Visible = true; - this.colPackageUrl.VisibleIndex = 15; + this.colPackageUrl.VisibleIndex = 16; // // colShortDescription // @@ -465,7 +478,7 @@ private void InitializeComponent() this.colShortDescription.FieldName = "ShortDescription"; this.colShortDescription.Name = "colShortDescription"; this.colShortDescription.Visible = true; - this.colShortDescription.VisibleIndex = 17; + this.colShortDescription.VisibleIndex = 18; // // colDescription // @@ -473,7 +486,7 @@ private void InitializeComponent() this.colDescription.Name = "colDescription"; this.colDescription.OptionsColumn.ReadOnly = true; this.colDescription.Visible = true; - this.colDescription.VisibleIndex = 16; + this.colDescription.VisibleIndex = 17; // // colTags // @@ -481,7 +494,7 @@ private void InitializeComponent() this.colTags.Name = "colTags"; this.colTags.OptionsColumn.ReadOnly = true; this.colTags.Visible = true; - this.colTags.VisibleIndex = 18; + this.colTags.VisibleIndex = 19; // // colFileExtensions // @@ -489,7 +502,7 @@ private void InitializeComponent() this.colFileExtensions.Name = "colFileExtensions"; this.colFileExtensions.OptionsColumn.ReadOnly = true; this.colFileExtensions.Visible = true; - this.colFileExtensions.VisibleIndex = 19; + this.colFileExtensions.VisibleIndex = 20; // // colProtocols // @@ -497,7 +510,7 @@ private void InitializeComponent() this.colProtocols.Name = "colProtocols"; this.colProtocols.OptionsColumn.ReadOnly = true; this.colProtocols.Visible = true; - this.colProtocols.VisibleIndex = 20; + this.colProtocols.VisibleIndex = 21; // // colCommands // @@ -505,7 +518,7 @@ private void InitializeComponent() this.colCommands.Name = "colCommands"; this.colCommands.OptionsColumn.ReadOnly = true; this.colCommands.Visible = true; - this.colCommands.VisibleIndex = 21; + this.colCommands.VisibleIndex = 22; // // colInstallerType // @@ -513,7 +526,7 @@ private void InitializeComponent() this.colInstallerType.Name = "colInstallerType"; this.colInstallerType.OptionsColumn.ReadOnly = true; this.colInstallerType.Visible = true; - this.colInstallerType.VisibleIndex = 22; + this.colInstallerType.VisibleIndex = 23; // // colInstallersCount // @@ -521,49 +534,50 @@ private void InitializeComponent() this.colInstallersCount.Name = "colInstallersCount"; this.colInstallersCount.OptionsColumn.ReadOnly = true; this.colInstallersCount.Visible = true; - this.colInstallersCount.VisibleIndex = 23; + this.colInstallersCount.VisibleIndex = 24; // // colInstallersArch // this.colInstallersArch.FieldName = "InstallersArch"; this.colInstallersArch.Name = "colInstallersArch"; this.colInstallersArch.Visible = true; - this.colInstallersArch.VisibleIndex = 25; + this.colInstallersArch.VisibleIndex = 26; // - // colInstallersLanguage + // colInstallersLocale // - this.colInstallersLanguage.FieldName = "InstallersLanguage"; - this.colInstallersLanguage.Name = "colInstallersLanguage"; - this.colInstallersLanguage.Visible = true; - this.colInstallersLanguage.VisibleIndex = 26; + this.colInstallersLocale.Caption = "InstallersLocale"; + this.colInstallersLocale.FieldName = "InstallersLocale"; + this.colInstallersLocale.Name = "colInstallersLocale"; + this.colInstallersLocale.Visible = true; + this.colInstallersLocale.VisibleIndex = 27; // // colInstallersInstallerType // this.colInstallersInstallerType.FieldName = "InstallersInstallerType"; this.colInstallersInstallerType.Name = "colInstallersInstallerType"; this.colInstallersInstallerType.Visible = true; - this.colInstallersInstallerType.VisibleIndex = 24; + this.colInstallersInstallerType.VisibleIndex = 25; // // colManifestSwitchInteractive // this.colManifestSwitchInteractive.FieldName = "ManifestSwitchInteractive"; this.colManifestSwitchInteractive.Name = "colManifestSwitchInteractive"; this.colManifestSwitchInteractive.Visible = true; - this.colManifestSwitchInteractive.VisibleIndex = 27; + this.colManifestSwitchInteractive.VisibleIndex = 28; // // colManifestSwitchSilent // this.colManifestSwitchSilent.FieldName = "ManifestSwitchSilentWithProgress"; this.colManifestSwitchSilent.Name = "colManifestSwitchSilent"; this.colManifestSwitchSilent.Visible = true; - this.colManifestSwitchSilent.VisibleIndex = 28; + this.colManifestSwitchSilent.VisibleIndex = 29; // // colManifestSwitchSilentWithProgress // this.colManifestSwitchSilentWithProgress.FieldName = "ManifestSwitchSilentWithProgress"; this.colManifestSwitchSilentWithProgress.Name = "colManifestSwitchSilentWithProgress"; this.colManifestSwitchSilentWithProgress.Visible = true; - this.colManifestSwitchSilentWithProgress.VisibleIndex = 29; + this.colManifestSwitchSilentWithProgress.VisibleIndex = 30; // // textEditRepoFolder // @@ -757,7 +771,7 @@ private void InitializeComponent() this.ClientSize = new System.Drawing.Size(1012, 639); this.Controls.Add(this.layoutControl1); this.Name = "MainForm"; - this.Text = "WingetRepo Browser 0.1.1"; + this.Text = "WingetRepo Browser 0.1.2"; ((System.ComponentModel.ISupportInitialize)(this.gridView2)).EndInit(); ((System.ComponentModel.ISupportInitialize)(this.gridControl1)).EndInit(); ((System.ComponentModel.ISupportInitialize)(this.gridView1)).EndInit(); @@ -779,11 +793,11 @@ private void InitializeComponent() ((System.ComponentModel.ISupportInitialize)(this.splitterItem1)).EndInit(); this.ResumeLayout(false); - } + } - #endregion - private DevExpress.XtraGrid.GridControl gridControl1; - private DevExpress.XtraGrid.Views.Grid.GridView gridView1; + #endregion + private DevExpress.XtraGrid.GridControl gridControl1; + private DevExpress.XtraGrid.Views.Grid.GridView gridView1; private DevExpress.XtraGrid.Columns.GridColumn colFilePath; private DevExpress.XtraGrid.Columns.GridColumn colInstallersCount; private DevExpress.XtraGrid.Columns.GridColumn colId; @@ -834,7 +848,7 @@ private void InitializeComponent() private DevExpress.XtraEditors.SimpleButton simpleButtonCreateSubFoldersForSelected; private DevExpress.XtraLayout.LayoutControlItem layoutControlItem6; private DevExpress.XtraGrid.Columns.GridColumn colInstallersArch; - private DevExpress.XtraGrid.Columns.GridColumn colInstallersLanguage; + private DevExpress.XtraGrid.Columns.GridColumn colInstallersLocale; private DevExpress.XtraGrid.Columns.GridColumn colInstallersInstallerType; private DevExpress.XtraGrid.Columns.GridColumn colSwitchesInteractive; private DevExpress.XtraGrid.Columns.GridColumn colManifestSwitchInteractive; @@ -850,6 +864,6 @@ private void InitializeComponent() private DevExpress.XtraEditors.MemoEdit memoEditMessages; private DevExpress.XtraLayout.LayoutControlItem layoutControlItemMessages; private DevExpress.XtraLayout.SplitterItem splitterItem1; + private DevExpress.XtraGrid.Columns.GridColumn colParsedVersion; } } - diff --git a/src/WingetRepoBrowser/MainForm.cs b/src/WingetRepoBrowser/MainForm.cs index 45ccaef..023babf 100644 --- a/src/WingetRepoBrowser/MainForm.cs +++ b/src/WingetRepoBrowser/MainForm.cs @@ -2,6 +2,7 @@ using DevExpress.XtraEditors; using DevExpress.XtraEditors.Controls; using DevExpress.XtraGrid; +using DevExpress.XtraGrid.Views.Base; using DevExpress.XtraGrid.Views.Grid; using System; using System.Collections.Generic; @@ -10,11 +11,11 @@ using System.Drawing; using System.IO; using System.Linq; +using System.Text.Json; using System.Windows.Forms; using WingetRepoBrowserCore; - //todo: // support multiple repo paths (; separated) // implement/find custom sort algorithm for version-column @@ -23,7 +24,7 @@ namespace WingetRepoBrowser { public partial class MainForm : XtraForm { - + AppSettings _appSettings; GridRowPopupMenuBehavior _gridViewManifestsRowPopup; List _manifestVMs; @@ -85,15 +86,32 @@ protected override void OnLoad(EventArgs e) { base.OnLoad(e); - var args = Environment.GetCommandLineArgs(); - if (args.Length >= 2) - { - textEditRepoFolder.Text = args[1]; - } - if (args.Length >= 3) + //var args = Environment.GetCommandLineArgs(); + //if (args.Length >= 2) + //{ + // textEditRepoFolder.Text = args[1]; + //} + //if (args.Length >= 3) + //{ + // textEditInstallersFolder.Text = args[2]; + //} + + string settingsFilePath = Path.Combine(Application.StartupPath, "AppSettings.json"); + if (File.Exists(settingsFilePath)) { - textEditInstallersFolder.Text = args[2]; + try + { + string json = File.ReadAllText(settingsFilePath); + _appSettings = JsonSerializer.Deserialize(json); + textEditRepoFolder.Text = _appSettings.RepoFolder; + textEditInstallersFolder.Text = _appSettings.InstallersFolder; + } + catch (Exception ex) + { + ShowMessageBox("Error while deserializing AppSettings: " + ex.Message); + } } + } @@ -127,6 +145,8 @@ private void simpleButtonSearch_Click(object sender, EventArgs e) return; } + memoEditMessages.Text = string.Empty; + Cursor saveCursor = Cursor.Current; try { @@ -259,6 +279,10 @@ private void simpleButtonCheckForNewDownloads_Click(object sender, EventArgs e) List newDownloads = FindNewDownloads(packageIds, _manifestVMs); NewDownloadsForm form = new NewDownloadsForm(); form.NewDownloads = newDownloads; + if (_appSettings != null) + { + form.LocalesToDownload = _appSettings.LocalesToDownload; + } form.ShowDialog(); } finally @@ -271,6 +295,7 @@ static string GetKeyFromIdFilePath(string wingetidFilePath) return Path.GetFileNameWithoutExtension(wingetidFilePath).ToLower(); } + private static List FindNewDownloads(Dictionary packageIds, IEnumerable manifestPackages) { List result = new List(); @@ -278,9 +303,11 @@ private static List FindNewDownloads(Dictionary pac { if (packageIds.TryGetValue(manifestPackage.Id.ToLower(), out string idFilePath)) { + string[] versionsToIgnoreDownload = Helpers.GetVersionsToIgnoreDownload(idFilePath); + string idFileFolder = Path.GetDirectoryName(idFilePath); string versionFolder = Path.Combine(idFileFolder, ConvertVersionToDirectoryName(manifestPackage.Version)); // illegal chars in version shouldn't be a problem, because yaml files are stored in folders with version as name - bool exists = Directory.Exists(versionFolder); + bool exists = versionsToIgnoreDownload.Any(v => v == manifestPackage.Version) || Directory.Exists(versionFolder); //if (manifestPackage.Version == "latest" && exists) if (false)//TODO: the following code crashes when downloaded yaml-files are not version 1.0.0 { @@ -306,7 +333,8 @@ private static List FindNewDownloads(Dictionary pac ManifestPackage = manifestPackage.Package, VersionFolder = versionFolder, FilePath = manifestPackage.FilePath, - InstallerPackageFilePath = GetInstallerPackageFilePath(manifestPackage) + InstallerPackageFilePath = GetInstallerPackageFilePath(manifestPackage), + IdFilePath = idFilePath }; result.Add(dl); } @@ -360,7 +388,7 @@ private void simpleButtonCreateSubFoldersForSelected_Click(object sender, EventA } } - private void gridView1_CustomDrawFooter(object sender, DevExpress.XtraGrid.Views.Base.RowObjectCustomDrawEventArgs e) + private void gridView1_CustomDrawFooter(object sender, RowObjectCustomDrawEventArgs e) { if (this.gridView1.GroupCount > 0) { @@ -370,6 +398,22 @@ private void gridView1_CustomDrawFooter(object sender, DevExpress.XtraGrid.Views e.Handled = true; } } + + /* + private void gridView1_CustomColumnSort(object sender, CustomColumnSortEventArgs e) + { + GridView view = gridView1; + if (e.Column.FieldName == nameof(ManifestPackageVM.ParsedPackageVersion)) + { + object val1 = view.GetListSourceRowCellValue(e.ListSourceRowIndex1, e.Column); + object val2 = view.GetListSourceRowCellValue(e.ListSourceRowIndex2, e.Column); + e.Handled = true; + e.Result = System.Collections.Comparer.Default.Compare(val1.ToString(), val2.ToString()); + } + } + */ + + } @@ -380,6 +424,7 @@ class NewDownload public string FilePath { get; set; } //public ManifestPackage_1_0_0 InstallerPackage { get; set; } public string InstallerPackageFilePath { get; set; } + public string IdFilePath { get; set; } } diff --git a/src/WingetRepoBrowser/ManifestInstallerVM.cs b/src/WingetRepoBrowser/ManifestInstallerVM.cs index 7b0c38a..b37b2f4 100644 --- a/src/WingetRepoBrowser/ManifestInstallerVM.cs +++ b/src/WingetRepoBrowser/ManifestInstallerVM.cs @@ -22,7 +22,7 @@ public ManifestInstallerVM(ManifestInstaller_1_0_0 installers) public string InstallerType { get { return _installers.InstallerType; } } - public string Language { get { return _installers.InstallerLocale; } } + public string InstallerLocale { get { return _installers.InstallerLocale; } } public string Scope { get { return _installers.Scope; } } diff --git a/src/WingetRepoBrowser/ManifestPackageVM.cs b/src/WingetRepoBrowser/ManifestPackageVM.cs index ebb0e52..4d3067a 100644 --- a/src/WingetRepoBrowser/ManifestPackageVM.cs +++ b/src/WingetRepoBrowser/ManifestPackageVM.cs @@ -21,6 +21,8 @@ public class ManifestPackageVM ManifestPackage_1_0_0 _installerPackage; internal ManifestPackage_1_0_0 InstallerPackage { get { return _installerPackage; } } + ParsedPackageVersion _parsedPackageVersion; + public ParsedPackageVersion ParsedPackageVersion { get { return _parsedPackageVersion; } } public ManifestPackageVM(ManifestPackage_1_0_0 package, string filePath, MultiFileYaml multiFileYaml) { @@ -30,6 +32,7 @@ public ManifestPackageVM(ManifestPackage_1_0_0 package, string filePath, MultiFi _defaultLocalePackage = _multiFileYaml.Packages.FirstOrDefault(p => p.PackageLocale == package.DefaultLocale); _installerPackage = _multiFileYaml.Packages.FirstOrDefault(p => p.ManifestType == "installer"); _installerVMs = _installerPackage?.Installers.Select(item => new ManifestInstallerVM(item)).ToArray(); + _parsedPackageVersion = new ParsedPackageVersion(package.PackageVersion); } public ManifestPackageVM(ManifestPackage_1_0_0 package, string filePath) @@ -37,6 +40,7 @@ public ManifestPackageVM(ManifestPackage_1_0_0 package, string filePath) _package = package; _filePath = filePath; _installerVMs = _package.Installers.Select(item => new ManifestInstallerVM(item)).ToArray(); + _parsedPackageVersion = new ParsedPackageVersion(package.PackageVersion); } ManifestPackage_1_0_0 GetDefaultPackage() @@ -100,7 +104,7 @@ static string SafeJoin(string separator, IEnumerable arr) public string Commands { get { return SafeJoin("|", _package.Commands); } } public string InstallersArch { get { return SafeJoin("|", GetInstallerPackage().Installers?.Select(item => item.Architecture)); } } - public string InstallersLanguage { get { return SafeJoin("|", GetInstallerPackage().Installers?.Select(item => item.InstallerLocale)); } } + public string InstallersLocale { get { return SafeJoin("|", GetInstallerPackage().Installers?.Select(item => item.InstallerLocale)); } } public string InstallersInstallerType { get { return SafeJoin("|", GetInstallerPackage().Installers?.Select(item => item.InstallerType)); } } public string ManifestSwitchInteractive { get { return GetInstallerPackage().InstallerSwitches?.Interactive; } } @@ -191,4 +195,44 @@ public class MultiFileYaml public List Packages { get; } = new List(); } + public class ParsedPackageVersion + { + private string[] _parts; + private int?[] _intParts; + + public ParsedPackageVersion(string version) + { + _parts = version.Split('.'); + _intParts = _parts.Select(p => ParseInt(p)).ToArray(); + } + + private static int? ParseInt(string text) + { + if (!int.TryParse(text, out int result)) + { + return null; + } + return result; + } + + public override string ToString() + { + List resultParts = new List(); + for (int index = 0; index < _intParts.Length; index++) + { + string part; + if (_intParts[index].HasValue) + { + part = _intParts[index].Value.ToString("0000000000"); + } + else + { + part = _parts[index]; + } + resultParts.Add(part); + } + return string.Join(".", resultParts); + } + } + } diff --git a/src/WingetRepoBrowser/NewDownloadsForm.Designer.cs b/src/WingetRepoBrowser/NewDownloadsForm.Designer.cs index 1fe2bb7..4447c76 100644 --- a/src/WingetRepoBrowser/NewDownloadsForm.Designer.cs +++ b/src/WingetRepoBrowser/NewDownloadsForm.Designer.cs @@ -119,6 +119,7 @@ private void InitializeComponent() this.colId}); this.gridView1.GridControl = this.gridControl1; this.gridView1.Name = "gridView1"; + this.gridView1.OptionsSelection.MultiSelect = true; this.gridView1.OptionsView.ShowGroupPanel = false; // // ColName diff --git a/src/WingetRepoBrowser/NewDownloadsForm.cs b/src/WingetRepoBrowser/NewDownloadsForm.cs index c032cc4..5cc444f 100644 --- a/src/WingetRepoBrowser/NewDownloadsForm.cs +++ b/src/WingetRepoBrowser/NewDownloadsForm.cs @@ -1,4 +1,5 @@ -using DevExpress.XtraEditors; +using DevExpress.Utils.Menu; +using DevExpress.XtraEditors; using DevExpress.XtraLayout.Utils; using System; using System.Collections.Generic; @@ -14,22 +15,66 @@ namespace WingetRepoBrowser { public partial class NewDownloadsForm : XtraForm { + GridRowPopupMenuBehavior _gridViewDownloadRowPopup; public NewDownloadsForm() { InitializeComponent(); + + _gridViewDownloadRowPopup = new GridRowPopupMenuBehavior(gridView1); + _gridViewDownloadRowPopup.SetMenuItems(CreateMenuItemsDownloadPopup()); + } + + private DXMenuItem[] CreateMenuItemsDownloadPopup() + { + DXMenuItem[] result = new DXMenuItem[] { + new DXMenuItem("Ignore selected version(s)", ItemIgnoreVersion_Click) + }; + return result; + } + + private void ItemIgnoreVersion_Click(object sender, EventArgs e) + { + NewDownloadVM[] rows = GetSelectedRows().ToArray(); + if (rows.Length == 0) + { + return; + } + IEnumerable> groupedByWingetId = rows.GroupBy(r => r.NewDownload.IdFilePath, r => r.NewDownload); + foreach (IGrouping group in groupedByWingetId) + { + string wingetidFilePath = group.Key; + string[] versionsToIgnore = group.Select(nd => nd.ManifestPackage.PackageVersion).ToArray(); + WingetIdSettings wingetidSettings = Helpers.LoadWingetIdSettings(wingetidFilePath); + if (wingetidSettings == null) + { + wingetidSettings = new WingetIdSettings(); + } + IEnumerable oldVersions = wingetidSettings.VersionsToIgnoreDownload ?? new string[] { }; + wingetidSettings.VersionsToIgnoreDownload = oldVersions.Concat(versionsToIgnore).ToArray(); + Helpers.SaveWingetIdSettings(wingetidFilePath, wingetidSettings); + } + } + + private IEnumerable GetSelectedRows() + { + return gridView1.GetSelectedRows().Select(item => gridView1.GetRow(item)).Cast(); } internal List NewDownloads { get; set; } + public string[] LocalesToDownload { get; set; } + + protected override void OnLoad(EventArgs e) { base.OnLoad(e); - List ds = NewDownloads.Select(item => item.ManifestPackage).ToList(); + List ds = NewDownloads.Select(item => new NewDownloadVM(item)).ToList(); gridControl1.DataSource = ds; } + InstallerDownloader _installerDownloader; int _errorCount; @@ -61,6 +106,15 @@ private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) } } + private static bool HasMatchingLocale(ManifestInstaller_1_0_0 manifestInstaller, string[] localesToDownload) + { + if (string.IsNullOrEmpty(manifestInstaller.InstallerLocale)) + { + return true; + } + return localesToDownload.Any(locale => string.Compare(locale, manifestInstaller.InstallerLocale, true) == 0); + } + private void ProcessOneNewDownload(NewDownload newDownload) { string versionFolder = newDownload.VersionFolder; @@ -75,7 +129,9 @@ private void ProcessOneNewDownload(NewDownload newDownload) installers = installerPackage.Installers; } - foreach (ManifestInstaller_1_0_0 manifestInstaller in installers) + var installersWithMatchingLocale = installers.Where(i => HasMatchingLocale(i, LocalesToDownload)); + + foreach (ManifestInstaller_1_0_0 manifestInstaller in installersWithMatchingLocale) { string downloadUrl = manifestInstaller.InstallerUrl; string downloadFileName = _installerDownloader.GetFileNameFromUrl(downloadUrl, out Uri responseUri); @@ -210,5 +266,19 @@ private void NewDownloadsForm_FormClosing(object sender, FormClosingEventArgs e) } } + class NewDownloadVM + { + NewDownload _newDownload; + public NewDownloadVM(NewDownload newDownload) + { + _newDownload = newDownload; + } + internal NewDownload NewDownload { get { return _newDownload; } } + + + public string PackageName { get { return _newDownload.ManifestPackage.PackageName; } } + public string PackageVersion { get { return _newDownload.ManifestPackage.PackageVersion; } } + public string PackageIdentifier { get { return _newDownload.ManifestPackage.PackageIdentifier; } } + } } diff --git a/src/WingetRepoBrowser/Program.cs b/src/WingetRepoBrowser/Program.cs index 3bcce95..00daad8 100644 --- a/src/WingetRepoBrowser/Program.cs +++ b/src/WingetRepoBrowser/Program.cs @@ -1,9 +1,7 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; using System.Windows.Forms; + namespace WingetRepoBrowser { static class Program diff --git a/src/WingetRepoBrowser/WingetRepoBrowser.csproj b/src/WingetRepoBrowser/WingetRepoBrowser.csproj index caa6588..5eb9277 100644 --- a/src/WingetRepoBrowser/WingetRepoBrowser.csproj +++ b/src/WingetRepoBrowser/WingetRepoBrowser.csproj @@ -89,6 +89,7 @@ + @@ -122,6 +123,9 @@ NewDownloadsForm.cs + + PreserveNewest + @@ -144,8 +148,11 @@ + + 5.0.2 + - 11.0.1 + 11.1.1 diff --git a/src/WingetRepoBrowserCore/Helpers.cs b/src/WingetRepoBrowserCore/Helpers.cs index b829b9c..60cd62f 100644 --- a/src/WingetRepoBrowserCore/Helpers.cs +++ b/src/WingetRepoBrowserCore/Helpers.cs @@ -1,7 +1,9 @@ using System; +using System.Diagnostics; using System.IO; using System.Security.Cryptography; using System.Text; +using System.Text.Json; using YamlDotNet.Serialization; @@ -9,6 +11,39 @@ namespace WingetRepoBrowserCore { public class Helpers { + public static void SaveWingetIdSettings(string idFilePath, WingetIdSettings wingetidSettings) + { + string json = JsonSerializer.Serialize(wingetidSettings, new JsonSerializerOptions() { WriteIndented = true }); + File.WriteAllText(idFilePath, json); + } + + public static WingetIdSettings LoadWingetIdSettings(string idFilePath) + { + string json = File.ReadAllText(idFilePath); + if (string.IsNullOrWhiteSpace(json)) + { + return null; + } + return JsonSerializer.Deserialize(json); + } + + public static string[] GetVersionsToIgnoreDownload(string idFilePath) + { + string[] result = new string[] { }; + try + { + WingetIdSettings settings = LoadWingetIdSettings(idFilePath); + if (settings?.VersionsToIgnoreDownload != null) + { + result = settings.VersionsToIgnoreDownload; + } + } + catch (JsonException ex) + { + Trace.WriteLine("Error during deserialization of '" + idFilePath + "': " + ex.Message); + } + return result; + } public static ManifestPackage_1_0_0 ReadYamlFile(string yamlFile) { diff --git a/src/WingetRepoBrowserCore/WingetIdSettings.cs b/src/WingetRepoBrowserCore/WingetIdSettings.cs new file mode 100644 index 0000000..126ef06 --- /dev/null +++ b/src/WingetRepoBrowserCore/WingetIdSettings.cs @@ -0,0 +1,8 @@ +namespace WingetRepoBrowserCore +{ + public class WingetIdSettings + { + public string[] VersionsToIgnoreDownload { get; set; } + + } +} diff --git a/src/WingetRepoBrowserCore/WingetRepoBrowserCore.csproj b/src/WingetRepoBrowserCore/WingetRepoBrowserCore.csproj index 3b2466a..1cf7ade 100644 --- a/src/WingetRepoBrowserCore/WingetRepoBrowserCore.csproj +++ b/src/WingetRepoBrowserCore/WingetRepoBrowserCore.csproj @@ -6,7 +6,8 @@ - + + diff --git a/src/WingetRepoBrowserCoreTests/WingetRepoBrowserCoreTests.csproj b/src/WingetRepoBrowserCoreTests/WingetRepoBrowserCoreTests.csproj index 29320d6..8ab3644 100644 --- a/src/WingetRepoBrowserCoreTests/WingetRepoBrowserCoreTests.csproj +++ b/src/WingetRepoBrowserCoreTests/WingetRepoBrowserCoreTests.csproj @@ -61,7 +61,7 @@ 2.2.3 - 11.0.1 + 11.1.1