Archived
1
0

Core update. Base core features are done (main app doesn't compile)

Related Work Items: #416, #422, #423, #424
This commit is contained in:
Michael Gordeev
2020-06-11 21:17:18 +03:00
parent b3212738e8
commit c58d846057
18 changed files with 386 additions and 281 deletions
+152
View File
@@ -0,0 +1,152 @@
using Newtonsoft.Json;
using System;
using System.IO;
using System.Collections.Generic;
using System.Threading.Tasks;
using Windows.Storage;
using Windows.Storage.AccessCache;
using YoutubeExplode.Videos;
using YoutubeExplode.Videos.Streams;
using FoxTube.Utils;
using FoxTube.Models;
using Windows.Storage.Pickers;
namespace FoxTube.Services
{
public static class DownloadsService
{
public static List<SavedVideo> History { get; } = new List<SavedVideo>();
public static List<DownloadItem> Queue { get; } = new List<DownloadItem>();
static DownloadsService() =>
Initialize();
private static async void Initialize()
{
StorageFile file = await Storage.Folder.CreateFileAsync("DownloadHistory.json", CreationCollisionOption.OpenIfExists);
try
{
List<SavedVideo> savedVideos = JsonConvert.DeserializeObject<List<SavedVideo>>(File.ReadAllText(file.Path) ?? "") ?? new List<SavedVideo>();
History.AddRange(savedVideos);
foreach (SavedVideo i in History)
try { i.IsPathValid = await StorageApplicationPermissions.MostRecentlyUsedList.GetFileAsync(i.AccessToken) != null; }
catch { i.IsPathValid = false; }
}
catch (Exception e)
{
await file.DeleteAsync(StorageDeleteOption.PermanentDelete);
StorageApplicationPermissions.MostRecentlyUsedList.Clear();
Metrics.SendReport(new Exception("Failed to load downloads history", e));
}
}
public static Task DownloadVideo(Video meta, IStreamInfo streamInfo) =>
DownloadVideo(meta, streamInfo, null);
public static async Task DownloadVideo(Video meta, IStreamInfo streamInfo, IStorageFile destination)
{
DownloadItem item = new DownloadItem
{
Title = $"[{(streamInfo as IVideoStreamInfo)?.VideoQualityLabel ?? "Audio"}] {meta.Title}",
Author = meta.Author,
Thumbnail = meta.Thumbnails.LowResUrl,
Duration = meta.Duration,
Id = meta.Id
};
Queue.Add(item);
if (destination == null)
destination = await (await GetDefaultDownloadsFolder()).CreateFileAsync($"{meta.Title.ReplaceInvalidChars('_')}.{streamInfo.Container.Name}", CreationCollisionOption.GenerateUniqueName);
item.Path = destination.Path;
try
{
await item.CommenceDownload(streamInfo, destination);
SavedVideo savedItem = item;
savedItem.AccessToken = StorageApplicationPermissions.MostRecentlyUsedList.Add(destination);
History.Add(savedItem);
StorageFile file = await Storage.Folder.CreateFileAsync("DownloadHistory.json", CreationCollisionOption.OpenIfExists);
File.WriteAllText(file.Path, JsonConvert.SerializeObject(History));
}
catch (OperationCanceledException) { }
catch (Exception e)
{
await destination.DeleteAsync(StorageDeleteOption.PermanentDelete);
Metrics.SendReport(new Exception("Failed to download video", e), null,
("Video ID", meta.Id),
("Stream tag", streamInfo.Tag.ToString()));
}
finally
{
Queue.Remove(item);
}
}
public static async Task RemoveItems(bool removeFiles, params SavedVideo[] items)
{
foreach(SavedVideo i in items)
{
History.Remove(i);
try
{
if (removeFiles)
{
StorageFile file = await StorageApplicationPermissions.MostRecentlyUsedList.GetFileAsync(i.AccessToken);
await file?.DeleteAsync();
}
}
finally
{
StorageApplicationPermissions.MostRecentlyUsedList.Remove(i.AccessToken);
}
}
StorageFile historyFile = await ApplicationData.Current.LocalFolder.CreateFileAsync("DownloadHistory.json", CreationCollisionOption.OpenIfExists);
File.WriteAllText(historyFile.Path, JsonConvert.SerializeObject(History));
}
public static async Task<StorageFolder> GetDefaultDownloadsFolder()
{
if (Storage.GetValue<string>(Storage.Settings.DefaultDownloadsFolder) is string token && !string.IsNullOrWhiteSpace(token))
return await StorageApplicationPermissions.FutureAccessList.GetFolderAsync(token) ??
await KnownFolders.VideosLibrary.CreateFolderAsync("FoxTube", CreationCollisionOption.OpenIfExists);
else
return await KnownFolders.VideosLibrary.CreateFolderAsync("FoxTube", CreationCollisionOption.OpenIfExists);
}
public static async Task CancelAll()
{
Queue.ForEach(i => i.Cancel());
while (Queue.Count > 0)
await Task.Delay(500);
}
public static async Task<StorageFolder> ChangeDefaultFolder()
{
FolderPicker picker = new FolderPicker
{
SuggestedStartLocation = PickerLocationId.Downloads
};
StorageFolder folder = await picker.PickSingleFolderAsync();
if (folder != null)
{
if (Storage.GetValue<string>(Storage.Settings.DefaultDownloadsFolder) is string token && !string.IsNullOrWhiteSpace(token))
StorageApplicationPermissions.FutureAccessList.AddOrReplace(token, folder);
else
{
token = StorageApplicationPermissions.FutureAccessList.Add(folder);
Storage.SetValue(Storage.Settings.DefaultDownloadsFolder, token);
}
}
return folder;
}
}
}