mirror of
https://github.com/wabbajack-tools/wabbajack.git
synced 2024-08-30 18:42:17 +00:00
Rework how we download/install curated lists
This commit is contained in:
parent
edcf75c28c
commit
70fead926f
@ -106,7 +106,7 @@ namespace Wabbajack.Lib
|
|||||||
}
|
}
|
||||||
|
|
||||||
Utils.Log("Exporting ModList metadata");
|
Utils.Log("Exporting ModList metadata");
|
||||||
var metadata = new ModlistMetadata.DownloadMetadata
|
var metadata = new DownloadMetadata
|
||||||
{
|
{
|
||||||
Size = File.GetSize(ModListOutputFile),
|
Size = File.GetSize(ModListOutputFile),
|
||||||
Hash = ModListOutputFile.FileHash(),
|
Hash = ModListOutputFile.FileHash(),
|
||||||
|
@ -30,6 +30,9 @@ namespace Wabbajack.Lib.ModListRegistry
|
|||||||
[JsonProperty("links")]
|
[JsonProperty("links")]
|
||||||
public LinksObject Links { get; set; } = new LinksObject();
|
public LinksObject Links { get; set; } = new LinksObject();
|
||||||
|
|
||||||
|
[JsonProperty("download_metadata")]
|
||||||
|
public DownloadMetadata DownloadMetadata { get; set; }
|
||||||
|
|
||||||
public class LinksObject
|
public class LinksObject
|
||||||
{
|
{
|
||||||
[JsonProperty("image")]
|
[JsonProperty("image")]
|
||||||
@ -43,26 +46,13 @@ namespace Wabbajack.Lib.ModListRegistry
|
|||||||
|
|
||||||
[JsonProperty("download")]
|
[JsonProperty("download")]
|
||||||
public string Download { get; set; }
|
public string Download { get; set; }
|
||||||
|
|
||||||
[JsonProperty("download_metadata")]
|
|
||||||
public DownloadMetadata DownloadMetadata { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty("machineURL")]
|
[JsonProperty("machineURL")]
|
||||||
public string MachineURL { get; set; }
|
public string MachineURL { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public class DownloadMetadata
|
|
||||||
{
|
|
||||||
public string Hash { get; set; }
|
|
||||||
public long Size { get; set; }
|
|
||||||
|
|
||||||
public long NumberOfArchives { get; set; }
|
|
||||||
public long SizeOfArchives { get; set; }
|
|
||||||
public long NumberOfInstalledFiles { get; set; }
|
|
||||||
public long SizeOfInstalledFiles { get; set; }
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static List<ModlistMetadata> LoadFromGithub()
|
public static List<ModlistMetadata> LoadFromGithub()
|
||||||
@ -76,12 +66,24 @@ namespace Wabbajack.Lib.ModListRegistry
|
|||||||
public bool NeedsDownload(string modlistPath)
|
public bool NeedsDownload(string modlistPath)
|
||||||
{
|
{
|
||||||
if (!File.Exists(modlistPath)) return true;
|
if (!File.Exists(modlistPath)) return true;
|
||||||
if (Links.DownloadMetadata?.Hash == null)
|
if (DownloadMetadata?.Hash == null)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return Links.DownloadMetadata.Hash != modlistPath.FileHash();
|
return DownloadMetadata.Hash != modlistPath.FileHashCached();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class DownloadMetadata
|
||||||
|
{
|
||||||
|
public string Hash { get; set; }
|
||||||
|
public long Size { get; set; }
|
||||||
|
|
||||||
|
public long NumberOfArchives { get; set; }
|
||||||
|
public long SizeOfArchives { get; set; }
|
||||||
|
public long NumberOfInstalledFiles { get; set; }
|
||||||
|
public long SizeOfInstalledFiles { get; set; }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
129
Wabbajack/View Models/ModListMetadataVM.cs
Normal file
129
Wabbajack/View Models/ModListMetadataVM.cs
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net;
|
||||||
|
using System.Reactive.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Input;
|
||||||
|
using Alphaleonis.Win32.Filesystem;
|
||||||
|
using ReactiveUI;
|
||||||
|
using Wabbajack.Common;
|
||||||
|
using Wabbajack.Lib;
|
||||||
|
using Wabbajack.Lib.Downloaders;
|
||||||
|
using Wabbajack.Lib.ModListRegistry;
|
||||||
|
|
||||||
|
namespace Wabbajack.View_Models
|
||||||
|
{
|
||||||
|
public enum DownloadStatus
|
||||||
|
{
|
||||||
|
NotDownloaded,
|
||||||
|
Downloading,
|
||||||
|
Downloaded
|
||||||
|
}
|
||||||
|
public class ModListMetadataVM : ViewModel
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
public ModlistMetadata Metadata { get; }
|
||||||
|
private ModeSelectionVM _parent;
|
||||||
|
|
||||||
|
|
||||||
|
public ModListMetadataVM(ModeSelectionVM parent, ModlistMetadata metadata)
|
||||||
|
{
|
||||||
|
_parent = parent;
|
||||||
|
Metadata = metadata;
|
||||||
|
Click = ReactiveCommand.Create(() => this.DoClick());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DoClick()
|
||||||
|
{
|
||||||
|
switch (Status)
|
||||||
|
{
|
||||||
|
case DownloadStatus.NotDownloaded:
|
||||||
|
Download();
|
||||||
|
break;
|
||||||
|
case DownloadStatus.Downloading:
|
||||||
|
break;
|
||||||
|
case DownloadStatus.Downloaded:
|
||||||
|
Install();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new ArgumentOutOfRangeException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Install()
|
||||||
|
{
|
||||||
|
_parent.OpenInstaller(Location);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Download()
|
||||||
|
{
|
||||||
|
IsDownloading = true;
|
||||||
|
|
||||||
|
var queue = new WorkQueue(1);
|
||||||
|
var sub = queue.Status.Select(i => i.ProgressPercent).ToProperty(this, x => x.DownloadProgress);
|
||||||
|
queue.QueueTask(() =>
|
||||||
|
{
|
||||||
|
var downloader = DownloadDispatcher.ResolveArchive(Metadata.Links.Download);
|
||||||
|
downloader.Download(new Archive{ Name = Metadata.Title, Size = Metadata.DownloadMetadata?.Size ?? 0}, Location);
|
||||||
|
Location.FileHashCached();
|
||||||
|
IsDownloading = false;
|
||||||
|
sub.Dispose();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateDownloadStatuses()
|
||||||
|
{
|
||||||
|
this.RaisePropertyChanged("Status");
|
||||||
|
this.RaisePropertyChanged("DownloadButtonVisibility");
|
||||||
|
this.RaisePropertyChanged("DownloadProgressVisibility");
|
||||||
|
this.RaisePropertyChanged("InstallButtonVisibility");
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Location => Path.Combine(Consts.ModListDownloadFolder, Metadata.Links.MachineURL + ExtensionManager.Extension);
|
||||||
|
|
||||||
|
private bool _isDownloading = false;
|
||||||
|
public bool IsDownloading
|
||||||
|
{
|
||||||
|
get => _isDownloading;
|
||||||
|
private set
|
||||||
|
{
|
||||||
|
RaiseAndSetIfChanged(ref _isDownloading, value);
|
||||||
|
UpdateDownloadStatuses();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private float _downloadProgress;
|
||||||
|
|
||||||
|
public float DownloadProgress
|
||||||
|
{
|
||||||
|
get => _downloadProgress;
|
||||||
|
private set
|
||||||
|
{
|
||||||
|
RaiseAndSetIfChanged(ref _downloadProgress, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public DownloadStatus Status
|
||||||
|
{
|
||||||
|
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (IsDownloading) return DownloadStatus.Downloading;
|
||||||
|
if (!File.Exists(Location)) return DownloadStatus.NotDownloaded;
|
||||||
|
return Metadata.NeedsDownload(Location) ? DownloadStatus.NotDownloaded : DownloadStatus.Downloaded;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Visibility DownloadButtonVisibility => Status == DownloadStatus.NotDownloaded ? Visibility.Visible : Visibility.Collapsed;
|
||||||
|
public Visibility DownloadProgressVisibility => Status == DownloadStatus.Downloading ? Visibility.Visible : Visibility.Collapsed;
|
||||||
|
public Visibility InstallButtonVisibility => Status == DownloadStatus.Downloaded ? Visibility.Visible : Visibility.Collapsed;
|
||||||
|
|
||||||
|
public ICommand Click { get; }
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -8,15 +8,13 @@ using System.Windows.Input;
|
|||||||
using Wabbajack.Common;
|
using Wabbajack.Common;
|
||||||
using Wabbajack.Lib;
|
using Wabbajack.Lib;
|
||||||
using Wabbajack.Lib.ModListRegistry;
|
using Wabbajack.Lib.ModListRegistry;
|
||||||
|
using Wabbajack.View_Models;
|
||||||
|
|
||||||
namespace Wabbajack
|
namespace Wabbajack
|
||||||
{
|
{
|
||||||
public class ModeSelectionVM : ViewModel
|
public class ModeSelectionVM : ViewModel
|
||||||
{
|
{
|
||||||
public ObservableCollection<ModlistMetadata> ModLists { get; } = new ObservableCollection<ModlistMetadata>(ModlistMetadata.LoadFromGithub());
|
public ObservableCollection<ModListMetadataVM> ModLists { get; }
|
||||||
|
|
||||||
[Reactive]
|
|
||||||
public ModlistMetadata SelectedModList { get; set; }
|
|
||||||
|
|
||||||
private MainWindowVM _mainVM;
|
private MainWindowVM _mainVM;
|
||||||
public ICommand DownloadAndInstallCommand { get; }
|
public ICommand DownloadAndInstallCommand { get; }
|
||||||
@ -26,6 +24,9 @@ namespace Wabbajack
|
|||||||
public ModeSelectionVM(MainWindowVM mainVM)
|
public ModeSelectionVM(MainWindowVM mainVM)
|
||||||
{
|
{
|
||||||
_mainVM = mainVM;
|
_mainVM = mainVM;
|
||||||
|
|
||||||
|
ModLists = new ObservableCollection<ModListMetadataVM>(ModlistMetadata.LoadFromGithub().Select(m => new ModListMetadataVM(this, m)));
|
||||||
|
|
||||||
InstallCommand = ReactiveCommand.Create(
|
InstallCommand = ReactiveCommand.Create(
|
||||||
execute: () =>
|
execute: () =>
|
||||||
{
|
{
|
||||||
@ -43,18 +44,9 @@ namespace Wabbajack
|
|||||||
{
|
{
|
||||||
mainVM.ActivePane = mainVM.Compiler.Value;
|
mainVM.ActivePane = mainVM.Compiler.Value;
|
||||||
});
|
});
|
||||||
|
|
||||||
DownloadAndInstallCommand = ReactiveCommand.Create(
|
|
||||||
canExecute: this.WhenAny(x => x.SelectedModList)
|
|
||||||
.Select(x => x != null)
|
|
||||||
.ObserveOnGuiThread(),
|
|
||||||
execute: () =>
|
|
||||||
{
|
|
||||||
OpenInstaller(Download());
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OpenInstaller(string path)
|
internal void OpenInstaller(string path)
|
||||||
{
|
{
|
||||||
if (path == null) return;
|
if (path == null) return;
|
||||||
var installer = _mainVM.Installer.Value;
|
var installer = _mainVM.Installer.Value;
|
||||||
@ -62,23 +54,5 @@ namespace Wabbajack
|
|||||||
_mainVM.ActivePane = installer;
|
_mainVM.ActivePane = installer;
|
||||||
installer.ModListPath.TargetPath = path;
|
installer.ModListPath.TargetPath = path;
|
||||||
}
|
}
|
||||||
|
|
||||||
private string Download()
|
|
||||||
{
|
|
||||||
if (!Directory.Exists(Consts.ModListDownloadFolder))
|
|
||||||
Directory.CreateDirectory(Consts.ModListDownloadFolder);
|
|
||||||
|
|
||||||
string dest = Path.Combine(Consts.ModListDownloadFolder, SelectedModList.Links.MachineURL + ExtensionManager.Extension);
|
|
||||||
|
|
||||||
var window = new DownloadWindow(SelectedModList.Links.Download,
|
|
||||||
SelectedModList.Title,
|
|
||||||
SelectedModList.Links.DownloadMetadata?.Size ?? 0,
|
|
||||||
dest);
|
|
||||||
window.ShowDialog();
|
|
||||||
|
|
||||||
if (window.Result == DownloadWindow.WindowResult.Completed)
|
|
||||||
return dest;
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,9 @@
|
|||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
xmlns:local="clr-namespace:Wabbajack"
|
xmlns:local="clr-namespace:Wabbajack"
|
||||||
|
xmlns:ms="clr-namespace:Wabbajack.View_Models"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:mah="http://metro.mahapps.com/winfx/xaml/controls"
|
||||||
d:DataContext="{d:DesignInstance local:ModeSelectionVM}"
|
d:DataContext="{d:DesignInstance local:ModeSelectionVM}"
|
||||||
d:DesignHeight="450"
|
d:DesignHeight="450"
|
||||||
d:DesignWidth="800"
|
d:DesignWidth="800"
|
||||||
@ -15,7 +17,6 @@
|
|||||||
<RowDefinition Height="*" />
|
<RowDefinition Height="*" />
|
||||||
<RowDefinition Height="70" />
|
<RowDefinition Height="70" />
|
||||||
<RowDefinition Height="70" />
|
<RowDefinition Height="70" />
|
||||||
<RowDefinition Height="70" />
|
|
||||||
</Grid.RowDefinitions>
|
</Grid.RowDefinitions>
|
||||||
<Image
|
<Image
|
||||||
Name="Banner"
|
Name="Banner"
|
||||||
@ -34,8 +35,7 @@
|
|||||||
Grid.ColumnSpan="3"
|
Grid.ColumnSpan="3"
|
||||||
ItemsSource="{Binding ModLists}"
|
ItemsSource="{Binding ModLists}"
|
||||||
ScrollViewer.CanContentScroll="False"
|
ScrollViewer.CanContentScroll="False"
|
||||||
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
|
ScrollViewer.HorizontalScrollBarVisibility="Disabled">
|
||||||
SelectedItem="{Binding Path=SelectedModList, Mode=TwoWay}">
|
|
||||||
<ListBox.ItemTemplate>
|
<ListBox.ItemTemplate>
|
||||||
<DataTemplate>
|
<DataTemplate>
|
||||||
<Grid Margin="10">
|
<Grid Margin="10">
|
||||||
@ -50,27 +50,27 @@
|
|||||||
<RowDefinition Height="20" />
|
<RowDefinition Height="20" />
|
||||||
<RowDefinition Height="15" />
|
<RowDefinition Height="15" />
|
||||||
<RowDefinition Height="150" />
|
<RowDefinition Height="150" />
|
||||||
<RowDefinition Height="20" />
|
<RowDefinition Height="30" />
|
||||||
</Grid.RowDefinitions>
|
</Grid.RowDefinitions>
|
||||||
<Image
|
<Image
|
||||||
Grid.Row="0"
|
Grid.Row="0"
|
||||||
Grid.RowSpan="4"
|
Grid.RowSpan="4"
|
||||||
Grid.Column="0"
|
Grid.Column="0"
|
||||||
Source="{Binding Links.ImageUri}" />
|
Source="{Binding Metadata.Links.ImageUri}" />
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Grid.Row="0"
|
Grid.Row="0"
|
||||||
Grid.Column="2"
|
Grid.Column="2"
|
||||||
FontSize="20"
|
FontSize="20"
|
||||||
Text="{Binding Title}" />
|
Text="{Binding Metadata.Title}" />
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Grid.Row="1"
|
Grid.Row="1"
|
||||||
Grid.Column="2"
|
Grid.Column="2"
|
||||||
Text="{Binding Author}" />
|
Text="{Binding Metadata.Author}" />
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Grid.Row="1"
|
Grid.Row="1"
|
||||||
Grid.Column="4"
|
Grid.Column="4"
|
||||||
HorizontalAlignment="Right"
|
HorizontalAlignment="Right"
|
||||||
Text="{Binding GameName}"
|
Text="{Binding Metadata.GameName}"
|
||||||
TextAlignment="Right" />
|
TextAlignment="Right" />
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Grid.Row="2"
|
Grid.Row="2"
|
||||||
@ -78,24 +78,43 @@
|
|||||||
Grid.ColumnSpan="3"
|
Grid.ColumnSpan="3"
|
||||||
HorizontalAlignment="Left"
|
HorizontalAlignment="Left"
|
||||||
VerticalAlignment="Top"
|
VerticalAlignment="Top"
|
||||||
Text="{Binding Description}"
|
Text="{Binding Metadata.Description}"
|
||||||
TextWrapping="Wrap" />
|
TextWrapping="Wrap" />
|
||||||
<Button Grid.Row="3" Grid.Column="2">More Info</Button>
|
<Button Grid.Row="3" Grid.ColumnSpan="5" Content="Download" Visibility="{Binding DownloadButtonVisibility}" Command="{Binding Click}" ></Button>
|
||||||
|
|
||||||
|
<mah:MetroProgressBar
|
||||||
|
Grid.Row="3"
|
||||||
|
Grid.ColumnSpan="5"
|
||||||
|
Background="{StaticResource WindowBackgroundBrush}"
|
||||||
|
BorderThickness="0"
|
||||||
|
Foreground="Transparent"
|
||||||
|
Maximum="1"
|
||||||
|
Value="{Binding DownloadProgress, Mode=OneWay}"
|
||||||
|
Visibility="{Binding DownloadProgressVisibility}" />
|
||||||
|
<mah:MetroProgressBar
|
||||||
|
Grid.Row="3"
|
||||||
|
Grid.ColumnSpan="5"
|
||||||
|
Background="Transparent"
|
||||||
|
BorderThickness="0"
|
||||||
|
Foreground="{StaticResource PrimaryVariantBrush}"
|
||||||
|
Maximum="1"
|
||||||
|
Opacity="{Binding DownloadProgress, Mode=OneWay}"
|
||||||
|
Value="{Binding DownloadProgress, Mode=OneWay}"
|
||||||
|
Visibility="{Binding DownloadProgressVisibility}" />
|
||||||
|
<Label Grid.Row="3"
|
||||||
|
Grid.ColumnSpan="5"
|
||||||
|
Content="Downloading..."
|
||||||
|
HorizontalContentAlignment="Center"
|
||||||
|
Visibility="{Binding DownloadProgressVisibility}" ></Label>
|
||||||
|
|
||||||
|
<Button Grid.Row="3" Grid.ColumnSpan ="5" Content="Install" Visibility="{Binding InstallButtonVisibility}" Command="{Binding Click}"></Button>
|
||||||
</Grid>
|
</Grid>
|
||||||
</DataTemplate>
|
</DataTemplate>
|
||||||
</ListBox.ItemTemplate>
|
</ListBox.ItemTemplate>
|
||||||
</ListBox>
|
</ListBox>
|
||||||
<Button
|
|
||||||
Name="InstallModlist"
|
|
||||||
Grid.Row="2"
|
|
||||||
Grid.ColumnSpan="3"
|
|
||||||
Margin="2"
|
|
||||||
Command="{Binding DownloadAndInstallCommand}">
|
|
||||||
<TextBlock FontSize="40">Download and Install</TextBlock>
|
|
||||||
</Button>
|
|
||||||
<Button
|
<Button
|
||||||
Name="InstallFromList"
|
Name="InstallFromList"
|
||||||
Grid.Row="3"
|
Grid.Row="2"
|
||||||
Grid.ColumnSpan="3"
|
Grid.ColumnSpan="3"
|
||||||
Margin="2"
|
Margin="2"
|
||||||
Command="{Binding InstallCommand}">
|
Command="{Binding InstallCommand}">
|
||||||
@ -103,7 +122,7 @@
|
|||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
Name="CreateModlist"
|
Name="CreateModlist"
|
||||||
Grid.Row="4"
|
Grid.Row="3"
|
||||||
Grid.ColumnSpan="3"
|
Grid.ColumnSpan="3"
|
||||||
Margin="2"
|
Margin="2"
|
||||||
Command="{Binding CompileCommand}">
|
Command="{Binding CompileCommand}">
|
||||||
|
@ -169,6 +169,7 @@
|
|||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
</ApplicationDefinition>
|
</ApplicationDefinition>
|
||||||
<Compile Include="Converters\EqualsToBoolConverter.cs" />
|
<Compile Include="Converters\EqualsToBoolConverter.cs" />
|
||||||
|
<Compile Include="View Models\ModListMetadataVM.cs" />
|
||||||
<Compile Include="Views\LinksView.xaml.cs">
|
<Compile Include="Views\LinksView.xaml.cs">
|
||||||
<DependentUpon>LinksView.xaml</DependentUpon>
|
<DependentUpon>LinksView.xaml</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
Loading…
Reference in New Issue
Block a user