add files I forgot

This commit is contained in:
Timothy Baldridge 2019-10-23 19:22:11 -06:00
parent 49d49887a8
commit 35f5730737
7 changed files with 327 additions and 0 deletions

View File

@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Wabbajack.Lib.Downloaders
{
public static class DownloaderUtils
{
public static Uri GetDirectURL(dynamic meta)
{
var url = meta?.General?.directURL;
if (url == null) return null;
return Uri.TryCreate((string) url, UriKind.Absolute, out var result) ? result : null;
}
}
}

View File

@ -0,0 +1,91 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Runtime.InteropServices.WindowsRuntime;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Wabbajack.Lib.Validation;
using Wabbajack.Lib.WebAutomation;
namespace Wabbajack.Lib.Downloaders
{
public class MediaFireDownloader : IUrlDownloader
{
public AbstractDownloadState GetDownloaderState(dynamic archive_ini)
{
Uri url = DownloaderUtils.GetDirectURL(archive_ini);
if (url == null || url.Host != "www.mediafire.com") return null;
return new State
{
Url = url.ToString()
};
}
public class State : AbstractDownloadState
{
public string Url { get; set; }
public override bool IsWhitelisted(ServerWhitelist whitelist)
{
return whitelist.AllowedPrefixes.Any(p => Url.StartsWith(p));
}
public override void Download(Archive a, string destination)
{
Resolve().Result.Download(a, destination);
}
public override bool Verify()
{
return Resolve().Result != null;
}
private async Task<HTTPDownloader.State> Resolve()
{
using (var d = await Driver.Create())
{
await d.NavigateTo(new Uri("http://www.mediafire.com/file/agiqzm1xwebczpx/WABBAJACK_TEST_FILE.tx"));
// MediaFire creates the link after all the JS loads
await Task.Delay(1000);
var new_url = await d.GetAttr("a.input", "href");
if (new_url == null || !new_url.StartsWith("http")) return null;
return new HTTPDownloader.State()
{
Client = new HttpClient(),
Url = new_url
};
}
}
public override IDownloader GetDownloader()
{
return DownloadDispatcher.GetInstance<MediaFireDownloader>();
}
public override string GetReportEntry(Archive a)
{
return $"* [{a.Name} - {Url}]({Url})";
}
}
public void Prepare()
{
}
public AbstractDownloadState GetDownloaderState(string u)
{
var url = new Uri(u);
if (url.Host != "www.mediafire.com") return null;
return new State
{
Url = url.ToString()
};
}
}
}

View File

@ -0,0 +1,97 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
namespace Wabbajack.Lib.WebAutomation
{
public enum DisplayMode
{
Visible,
Hidden
}
public class Driver : IDisposable
{
private WebAutomationWindow _window;
private WebAutomationWindowViewModel _ctx;
private Task<WebAutomationWindow> _windowTask;
private Driver(DisplayMode displayMode = DisplayMode.Hidden)
{
var windowTask = new TaskCompletionSource<WebAutomationWindow>();
var t = new Thread(() =>
{
_window = new WebAutomationWindow();
_ctx = (WebAutomationWindowViewModel)_window.DataContext;
// Initiates the dispatcher thread shutdown when the window closes
_window.Closed += (s, e) => _window.Dispatcher.InvokeShutdown();
if (displayMode == DisplayMode.Hidden)
{
_window.WindowState = WindowState.Minimized;
_window.ShowInTaskbar = false;
}
_window.Show();
windowTask.SetResult(_window);
// Makes the thread support message pumping
System.Windows.Threading.Dispatcher.Run();
});
_windowTask = windowTask.Task;
t.SetApartmentState(ApartmentState.STA);
t.Start();
}
public static async Task<Driver> Create()
{
var driver = new Driver();
driver._window = await driver._windowTask;
driver._ctx = (WebAutomationWindowViewModel) driver._window.DataContext;
return driver;
}
public Task<Uri> NavigateTo(Uri uri)
{
return _ctx.NavigateTo(uri);
}
public Task<Uri> GetLocation()
{
var tcs = new TaskCompletionSource<Uri>();
_window.Dispatcher.Invoke(() => tcs.SetResult(_window.WebView.Source));
return tcs.Task;
}
public Task<string> GetAttr(string selector, string attr)
{
var tcs = new TaskCompletionSource<string>();
_window.Dispatcher.Invoke(() =>
{
try
{
var script = $"document.querySelector(\"{selector}\").{attr}";
var result = _window.WebView.InvokeScript("eval", script);
tcs.SetResult(result);
}
catch (Exception ex)
{
tcs.SetException(ex);
}
});
return tcs.Task;
}
public void Dispose()
{
_window.Dispatcher.Invoke(_window.Close);
}
}
}

View File

@ -0,0 +1,14 @@
<Window x:Class="Wabbajack.WebAutomationWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Wabbajack"
xmlns:controls="clr-namespace:Microsoft.Toolkit.Wpf.UI.Controls;assembly=Microsoft.Toolkit.Wpf.UI.Controls.WebView"
mc:Ignorable="d"
Title="WebAutomationWindow" Height="450" Width="800">
<Grid>
<controls:WebView Name="WebView">
</controls:WebView>
</Grid>
</Window>

View File

@ -0,0 +1,29 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using Wabbajack.Lib.WebAutomation;
namespace Wabbajack
{
/// <summary>
/// Interaction logic for WebAutomationWindow.xaml
/// </summary>
public partial class WebAutomationWindow : Window
{
public WebAutomationWindow()
{
InitializeComponent();
DataContext = new WebAutomationWindowViewModel(this);
}
}
}

View File

@ -0,0 +1,39 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Toolkit.Win32.UI.Controls.Interop.WinRT;
using Microsoft.Toolkit.Wpf.UI.Controls;
namespace Wabbajack.Lib.WebAutomation
{
public class WebAutomationWindowViewModel : ViewModel
{
private WebAutomationWindow _window;
private WebView Browser => _window.WebView;
public WebAutomationWindowViewModel(WebAutomationWindow window)
{
_window = window;
}
public Task<Uri> NavigateTo(Uri uri)
{
var tcs = new TaskCompletionSource<Uri>();
EventHandler<WebViewControlNavigationCompletedEventArgs> handler = null;
handler = (s, e) =>
{
Browser.NavigationCompleted -= handler;
tcs.SetResult(uri);
};
Browser.NavigationCompleted += handler;
Browser.Navigate(uri);
return tcs.Task;
}
}
}

View File

@ -0,0 +1,38 @@
using System;
using System.Text;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Wabbajack.Lib.Downloaders;
using Wabbajack.Lib.WebAutomation;
using System.Windows.Threading;
namespace Wabbajack.Test
{
/// <summary>
/// Summary description for WebAutomationTests
/// </summary>
[TestClass]
public class WebAutomationTests
{
[TestMethod]
public async Task TestBasicNavigation()
{
using (var w = await Driver.Create())
{
await w.NavigateTo(new Uri("http://www.google.com"));
Assert.AreEqual(new Uri("https://www.google.com"), await w.GetLocation());
}
}
[TestMethod]
public async Task TestAttrSelection()
{
using (var w = await Driver.Create())
{
await w.NavigateTo(new Uri("http://www.mediafire.com/file/agiqzm1xwebczpx/WABBAJACK_TEST_FILE.tx"));
Assert.IsTrue((await w.GetAttr("a.input", "href")).StartsWith("http://"));
}
}
}
}