Core refactoring (app doesn't work)
This commit is contained in:
@@ -0,0 +1,127 @@
|
||||
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;
|
||||
|
||||
namespace FoxTube.Services
|
||||
{
|
||||
public static class DownloadsCenter
|
||||
{
|
||||
public static List<SavedVideo> History { get; private set; }
|
||||
public static List<DownloadItem> Queue { get; } = new List<DownloadItem>();
|
||||
|
||||
static DownloadsCenter() =>
|
||||
Initialize();
|
||||
|
||||
private static async void Initialize()
|
||||
{
|
||||
StorageFile file = await ApplicationData.Current.LocalFolder.CreateFileAsync("DownloadHistory.json", CreationCollisionOption.OpenIfExists);
|
||||
try
|
||||
{
|
||||
History = JsonConvert.DeserializeObject<List<SavedVideo>>(File.ReadAllText(file.Path) ?? "") ?? new List<SavedVideo>();
|
||||
|
||||
foreach (SavedVideo i in History)
|
||||
try { i.IsPathValid = await StorageApplicationPermissions.MostRecentlyUsedList.GetFileAsync(i.AccessToken) != null; }
|
||||
catch { i.IsPathValid = false; }
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
History = new List<SavedVideo>();
|
||||
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 as SavedVideo;
|
||||
savedItem.AccessToken = StorageApplicationPermissions.MostRecentlyUsedList.Add(destination);
|
||||
|
||||
History.Add(savedItem);
|
||||
|
||||
StorageFile file = await ApplicationData.Current.LocalFolder.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 (string.IsNullOrWhiteSpace(Settings.DefaultDownloadsFolder))
|
||||
return await KnownFolders.VideosLibrary.CreateFolderAsync("FoxTube", CreationCollisionOption.OpenIfExists);
|
||||
else
|
||||
return await StorageApplicationPermissions.FutureAccessList.GetFolderAsync(Settings.DefaultDownloadsFolder);
|
||||
}
|
||||
|
||||
public static async Task CancelAll()
|
||||
{
|
||||
Queue.ForEach(i => i.Cancel());
|
||||
while (Queue.Count > 0)
|
||||
await Task.Delay(500);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
using Newtonsoft.Json;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Windows.Storage;
|
||||
|
||||
namespace FoxTube.Services
|
||||
{
|
||||
public static class History
|
||||
{
|
||||
static readonly ApplicationDataContainer storage = ApplicationData.Current.RoamingSettings;
|
||||
|
||||
public static string[] SearchHistory
|
||||
{
|
||||
get => JsonConvert.DeserializeObject<string[]>(storage.Values["SearchHistory"] as string) ?? new string[0];
|
||||
private set => JsonConvert.SerializeObject(value);
|
||||
}
|
||||
|
||||
public static void AddSearchHistoryEntry(string term)
|
||||
{
|
||||
List<string> history = SearchHistory.ToList();
|
||||
history.Insert(0, term);
|
||||
|
||||
if (history.Count > 5)
|
||||
history.RemoveRange(5, history.Count - 5);
|
||||
|
||||
SearchHistory = history.ToArray();
|
||||
}
|
||||
|
||||
public static void ClearSearchHistory() =>
|
||||
SearchHistory = new string[0];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
using FoxTube.Models;
|
||||
using FoxTube.Utils;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using Windows.Storage;
|
||||
using Windows.UI.Notifications;
|
||||
|
||||
namespace FoxTube.Services
|
||||
{
|
||||
public static class Inbox
|
||||
{
|
||||
private static readonly HttpClient client = new HttpClient();
|
||||
private static readonly ApplicationDataContainer storage = ApplicationData.Current.RoamingSettings;
|
||||
|
||||
public static async void PushNew()
|
||||
{
|
||||
try
|
||||
{
|
||||
// TODO: Add backend
|
||||
HttpResponseMessage response = await client.GetAsync($"https://xfox111.net/FoxTube/Messages?toast=true&publishedAfter={storage.Values["Inbox.lastCheck"]}&lang={Settings.Language}&appVersion={Metrics.CurrentVersion}");
|
||||
storage.Values["Inbox.lastCheck"] = DateTime.UtcNow.Ticks;
|
||||
|
||||
if (response.StatusCode == HttpStatusCode.NoContent)
|
||||
return;
|
||||
|
||||
string[] toasts = JsonConvert.DeserializeObject<string[]>(await response.Content.ReadAsStringAsync());
|
||||
|
||||
foreach (string toast in toasts)
|
||||
ToastNotificationManager.CreateToastNotifier().Show(new ToastNotification(toast.ToXml()));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Metrics.SendReport(new Exception("Unable to retrieve toast notifications", e));
|
||||
}
|
||||
}
|
||||
|
||||
public static async Task<InboxItem[]> GetMessages()
|
||||
{
|
||||
try
|
||||
{
|
||||
// TODO: Add backend
|
||||
HttpResponseMessage response = await client.GetAsync($"https://xfox111.net/API/FoxTube/Inbox?lang={Settings.Language}¤tVersion={Metrics.CurrentVersion}");
|
||||
|
||||
if (response.StatusCode == HttpStatusCode.NoContent)
|
||||
return new InboxItem[0];
|
||||
|
||||
return JsonConvert.DeserializeObject<InboxItem[]>(await response.Content.ReadAsStringAsync());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Metrics.SendReport(new Exception("Unable to retrieve inbox messages", e));
|
||||
|
||||
return new InboxItem[0];
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fires toast notification with the last changelog content
|
||||
/// </summary>
|
||||
public static async void PushChangelog()
|
||||
{
|
||||
try
|
||||
{
|
||||
// TODO: Add backend
|
||||
Settings.LastReviewedVersion = Metrics.CurrentVersion;
|
||||
|
||||
HttpResponseMessage response = await client.GetAsync($"https://xfox111.net/API/FoxTube/Changelogs?toast=true&lang={Settings.Language}&version={Metrics.CurrentVersion}");
|
||||
|
||||
if (response.StatusCode == HttpStatusCode.NoContent)
|
||||
return;
|
||||
|
||||
ToastNotificationManager.CreateToastNotifier().Show(new ToastNotification((await response.Content.ReadAsStringAsync()).ToXml()));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Metrics.SendReport(new Exception("Unable to retrieve changelog", e));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
using FoxTube.Models;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml;
|
||||
|
||||
namespace FoxTube.Services
|
||||
{
|
||||
public static class Search
|
||||
{
|
||||
public static async Task<List<SearchSuggestion>> GetSuggestions(string term)
|
||||
{
|
||||
List<SearchSuggestion> suggestions = new List<SearchSuggestion>();
|
||||
|
||||
try
|
||||
{
|
||||
using HttpClient client = new HttpClient();
|
||||
string results = await client.GetStringAsync($"http://suggestqueries.google.com/complete/search?ds=yt&client=toolbar&q={term}&hl={Settings.RelevanceLanguage}");
|
||||
XmlDocument doc = new XmlDocument();
|
||||
doc.LoadXml(results);
|
||||
|
||||
for (int i = 0; i < doc["toplevel"].ChildNodes.Count && i < 5; i++)
|
||||
suggestions.Add(new SearchSuggestion(doc["toplevel"].ChildNodes[i]["suggestion"].GetAttribute("data")));
|
||||
|
||||
// Appending search history
|
||||
suggestions.AddRange(History.SearchHistory.Select(i => new SearchSuggestion(i, true)));
|
||||
|
||||
return suggestions;
|
||||
}
|
||||
catch { }
|
||||
|
||||
return suggestions;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user