Had to redo events in TYTDIDownloaderStorageProxy and made personal lists on downloader in proxy
This commit is contained in:
parent
f274647450
commit
6755cb3b3d
|
@ -0,0 +1,26 @@
|
||||||
|
namespace Tesses.YouTubeDownloader
|
||||||
|
{
|
||||||
|
public class ExtraData
|
||||||
|
{
|
||||||
|
public string TYTDTag {get;set;}
|
||||||
|
public string TYTDDownloaderVersion {get;set;}
|
||||||
|
public string TYTDServerVersion {get;set;}
|
||||||
|
|
||||||
|
public string TessesWebServerVersion {get;set;}
|
||||||
|
|
||||||
|
public long ItemsInQueue {get;set;}
|
||||||
|
|
||||||
|
public long ItemsInInfoQueue {get;set;}
|
||||||
|
|
||||||
|
public ExtraData()
|
||||||
|
{
|
||||||
|
ItemsInInfoQueue=0;
|
||||||
|
ItemsInQueue=0;
|
||||||
|
TessesWebServerVersion="0.0.0.0";
|
||||||
|
TYTDServerVersion="0.0.0.0";
|
||||||
|
TYTDTag=TYTDStorage.TYTDTag;
|
||||||
|
TYTDDownloaderVersion = this.GetType().Assembly.GetName().Version.ToString();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -12,6 +12,16 @@ namespace Tesses.YouTubeDownloader
|
||||||
{
|
{
|
||||||
public interface IDownloader : IPersonalPlaylistSet
|
public interface IDownloader : IPersonalPlaylistSet
|
||||||
{
|
{
|
||||||
|
event EventHandler<VideoStartedEventArgs> VideoStarted;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
event EventHandler<VideoProgressEventArgs> VideoProgress;
|
||||||
|
|
||||||
|
event EventHandler<VideoFinishedEventArgs> VideoFinished;
|
||||||
|
event EventHandler<TYTDErrorEventArgs> Error;
|
||||||
|
event EventHandler<BellEventArgs> Bell;
|
||||||
|
|
||||||
void CancelDownload(bool restart=false);
|
void CancelDownload(bool restart=false);
|
||||||
Task AddVideoAsync(VideoId id,Resolution resolution=Resolution.PreMuxed);
|
Task AddVideoAsync(VideoId id,Resolution resolution=Resolution.PreMuxed);
|
||||||
Task AddPlaylistAsync(PlaylistId id,Resolution resolution=Resolution.PreMuxed);
|
Task AddPlaylistAsync(PlaylistId id,Resolution resolution=Resolution.PreMuxed);
|
||||||
|
@ -23,7 +33,7 @@ namespace Tesses.YouTubeDownloader
|
||||||
SavedVideoProgress GetProgress();
|
SavedVideoProgress GetProgress();
|
||||||
IAsyncEnumerable<Subscription> GetSubscriptionsAsync();
|
IAsyncEnumerable<Subscription> GetSubscriptionsAsync();
|
||||||
Task UnsubscribeAsync(ChannelId id);
|
Task UnsubscribeAsync(ChannelId id);
|
||||||
Task SubscribeAsync(ChannelId id,bool downloadChannelInfo=false,ChannelBellInfo bellInfo = ChannelBellInfo.NotifyAndDownload);
|
Task SubscribeAsync(ChannelId id,ChannelBellInfo bellInfo = ChannelBellInfo.NotifyAndDownload);
|
||||||
Task SubscribeAsync(UserName name,ChannelBellInfo info=ChannelBellInfo.NotifyAndDownload);
|
Task SubscribeAsync(UserName name,ChannelBellInfo info=ChannelBellInfo.NotifyAndDownload);
|
||||||
Task ResubscribeAsync(ChannelId id,ChannelBellInfo info=ChannelBellInfo.NotifyAndDownload);
|
Task ResubscribeAsync(ChannelId id,ChannelBellInfo info=ChannelBellInfo.NotifyAndDownload);
|
||||||
void DeletePersonalPlaylist(string name);
|
void DeletePersonalPlaylist(string name);
|
||||||
|
|
|
@ -29,14 +29,8 @@ namespace Tesses.YouTubeDownloader
|
||||||
Logger GetLogger();
|
Logger GetLogger();
|
||||||
LoggerProperties GetLoggerProperties();
|
LoggerProperties GetLoggerProperties();
|
||||||
IReadOnlyList<Subscription> GetLoadedSubscriptions();
|
IReadOnlyList<Subscription> GetLoadedSubscriptions();
|
||||||
event EventHandler<BellEventArgs> Bell;
|
|
||||||
event EventHandler<VideoStartedEventArgs> VideoStarted;
|
|
||||||
|
|
||||||
event EventHandler<BeforeSaveInfoEventArgs> BeforeSaveInfo;
|
|
||||||
|
|
||||||
event EventHandler<VideoProgressEventArgs> VideoProgress;
|
|
||||||
|
|
||||||
public event EventHandler<VideoFinishedEventArgs> VideoFinished;
|
|
||||||
bool CanDownload {get;set;}
|
bool CanDownload {get;set;}
|
||||||
IExtensionContext ExtensionContext {get;set;}
|
IExtensionContext ExtensionContext {get;set;}
|
||||||
HttpClient HttpClient {get;set;}
|
HttpClient HttpClient {get;set;}
|
||||||
|
@ -58,6 +52,6 @@ namespace Tesses.YouTubeDownloader
|
||||||
Task MoveLegacyStreams(SavedVideo video,BestStreams streams);
|
Task MoveLegacyStreams(SavedVideo video,BestStreams streams);
|
||||||
|
|
||||||
void StartLoop(CancellationToken token=default(CancellationToken));
|
void StartLoop(CancellationToken token=default(CancellationToken));
|
||||||
event EventHandler<TYTDErrorEventArgs> Error;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,81 @@
|
||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Net.Http;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
namespace Tesses.YouTubeDownloader
|
||||||
|
{
|
||||||
|
public static class SSEExtensions
|
||||||
|
{
|
||||||
|
public static async Task<SSEClient> GetSSEClientAsync(this HttpClient clt,string url)
|
||||||
|
{
|
||||||
|
var strm=await clt.GetStreamAsync(url);
|
||||||
|
return new SSEClient(strm);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class SSEEvent : EventArgs
|
||||||
|
{
|
||||||
|
public SSEEvent(string data)
|
||||||
|
{
|
||||||
|
Data=data;
|
||||||
|
}
|
||||||
|
public string Data {get;set;}
|
||||||
|
public T ParseJson<T>()
|
||||||
|
{
|
||||||
|
return JsonConvert.DeserializeObject<T>(Data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public class SSEClient
|
||||||
|
{
|
||||||
|
Stream strm;
|
||||||
|
|
||||||
|
public SSEClient(Stream strm)
|
||||||
|
{
|
||||||
|
this.strm=strm;
|
||||||
|
}
|
||||||
|
public EventHandler<SSEEvent> Event;
|
||||||
|
|
||||||
|
public async Task ReadEventsAsync(CancellationToken token=default(CancellationToken))
|
||||||
|
{
|
||||||
|
try{
|
||||||
|
using(var sr = new StreamReader(strm)){
|
||||||
|
token.Register(()=>{
|
||||||
|
sr.Dispose();
|
||||||
|
});
|
||||||
|
|
||||||
|
while(!token.IsCancellationRequested)
|
||||||
|
{
|
||||||
|
|
||||||
|
string text=await sr.ReadLineAsync();
|
||||||
|
if(!string.IsNullOrWhiteSpace(text))
|
||||||
|
Event?.Invoke(this,new SSEEvent(text.Substring(6)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}catch(Exception ex)
|
||||||
|
{
|
||||||
|
_=ex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public class ProgressItem
|
||||||
|
{
|
||||||
|
public long Length {get;set;}
|
||||||
|
public double Percent {get;set;}
|
||||||
|
|
||||||
|
public SavedVideo Video {get;set;}
|
||||||
|
|
||||||
|
public bool StartEvent {get;set;}
|
||||||
|
public bool StopEvent {get;set;}
|
||||||
|
public bool BellEvent {get;set;}
|
||||||
|
|
||||||
|
public bool ErrorEvent {get;set;}
|
||||||
|
public string Error {get;set;}
|
||||||
|
public string Id {get;set;}
|
||||||
|
public string Message {get;set;}
|
||||||
|
public string ExceptionName {get;set;}
|
||||||
|
}
|
||||||
|
}
|
|
@ -114,9 +114,9 @@ namespace Tesses.YouTubeDownloader
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Subscribe to creator
|
/// Subscribe to creator
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public async Task SubscribeAsync(ChannelId id, bool downloadChannelInfo=false,ChannelBellInfo bellInfo = ChannelBellInfo.NotifyAndDownload)
|
public async Task SubscribeAsync(ChannelId id,ChannelBellInfo bellInfo = ChannelBellInfo.NotifyAndDownload)
|
||||||
{
|
{
|
||||||
if(downloadChannelInfo)
|
if(bellInfo.HasFlag(ChannelBellInfo.GetInfo))
|
||||||
{
|
{
|
||||||
ChannelMediaContext context=new ChannelMediaContext(id,Resolution.NoDownload);
|
ChannelMediaContext context=new ChannelMediaContext(id,Resolution.NoDownload);
|
||||||
var c=await context.GetChannel(this);
|
var c=await context.GetChannel(this);
|
||||||
|
@ -136,7 +136,7 @@ namespace Tesses.YouTubeDownloader
|
||||||
{
|
{
|
||||||
ChannelMediaContext context=new ChannelMediaContext(name,Resolution.NoDownload);
|
ChannelMediaContext context=new ChannelMediaContext(name,Resolution.NoDownload);
|
||||||
var c=await context.GetChannel(this);
|
var c=await context.GetChannel(this);
|
||||||
await SubscribeAsync(ChannelId.Parse(c.Id),false,bellInfo);
|
await SubscribeAsync(ChannelId.Parse(c.Id),bellInfo);
|
||||||
}
|
}
|
||||||
public IReadOnlyList<Subscription> GetLoadedSubscriptions()
|
public IReadOnlyList<Subscription> GetLoadedSubscriptions()
|
||||||
{
|
{
|
||||||
|
|
|
@ -17,6 +17,19 @@ namespace Tesses.YouTubeDownloader
|
||||||
|
|
||||||
public abstract partial class TYTDStorage : TYTDBase, IStorage
|
public abstract partial class TYTDStorage : TYTDBase, IStorage
|
||||||
{
|
{
|
||||||
|
public override ExtraData GetExtraData()
|
||||||
|
{
|
||||||
|
ExtraData data=new ExtraData();
|
||||||
|
lock(Temporary){
|
||||||
|
data.ItemsInInfoQueue=Temporary.Count;
|
||||||
|
}
|
||||||
|
lock(QueueList)
|
||||||
|
{
|
||||||
|
data.ItemsInQueue=QueueList.Count;
|
||||||
|
}
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
internal class ConsoleWriterCLS : TextWriter
|
internal class ConsoleWriterCLS : TextWriter
|
||||||
{
|
{
|
||||||
Action<string> cls;
|
Action<string> cls;
|
||||||
|
@ -288,5 +301,20 @@ namespace Tesses.YouTubeDownloader
|
||||||
await WriteAllTextAsync($"PersonalPlaylist/{name}.json",JsonConvert.SerializeObject(items0));
|
await WriteAllTextAsync($"PersonalPlaylist/{name}.json",JsonConvert.SerializeObject(items0));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void RegisterVideoStarted(EventHandler<VideoStartedEventArgs> vs)
|
||||||
|
{
|
||||||
|
VideoStarted+=vs;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RegisterVideoFinished(EventHandler<VideoFinishedEventArgs> vf)
|
||||||
|
{
|
||||||
|
VideoFinished+=vf;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RegisterVideoProgress(EventHandler<VideoProgressEventArgs> vp)
|
||||||
|
{
|
||||||
|
VideoProgress+=vp;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -276,6 +276,12 @@ namespace Tesses.YouTubeDownloader
|
||||||
|
|
||||||
public abstract IAsyncEnumerable<string> EnumerateDirectoriesAsync(string path);
|
public abstract IAsyncEnumerable<string> EnumerateDirectoriesAsync(string path);
|
||||||
|
|
||||||
|
public virtual ExtraData GetExtraData()
|
||||||
|
{
|
||||||
|
ExtraData data=new ExtraData();
|
||||||
|
return data;
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ListContentItem
|
public class ListContentItem
|
||||||
|
@ -857,6 +863,7 @@ namespace Tesses.YouTubeDownloader
|
||||||
}
|
}
|
||||||
public interface IPersonalPlaylistGet
|
public interface IPersonalPlaylistGet
|
||||||
{
|
{
|
||||||
|
ExtraData GetExtraData();
|
||||||
IAsyncEnumerable<ListContentItem> GetPersonalPlaylistContentsAsync(string name);
|
IAsyncEnumerable<ListContentItem> GetPersonalPlaylistContentsAsync(string name);
|
||||||
bool PersonalPlaylistExists(string name);
|
bool PersonalPlaylistExists(string name);
|
||||||
}
|
}
|
||||||
|
|
|
@ -223,7 +223,7 @@ internal class SegmentedHttpStream : Stream
|
||||||
await client.GetStringAsync($"{url}api/v2/AddChannel?v={id.Value}&res={resolution.ToString()}");
|
await client.GetStringAsync($"{url}api/v2/AddChannel?v={id.Value}&res={resolution.ToString()}");
|
||||||
}catch(Exception ex)
|
}catch(Exception ex)
|
||||||
{
|
{
|
||||||
_=ex;
|
_error.Invoke(this,new TYTDErrorEventArgs("jNQXAC9IVRw",ex));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -233,7 +233,7 @@ internal class SegmentedHttpStream : Stream
|
||||||
await client.GetStringAsync($"{url}api/v2/AddPlaylist?v={id.Value}&res={resolution.ToString()}");
|
await client.GetStringAsync($"{url}api/v2/AddPlaylist?v={id.Value}&res={resolution.ToString()}");
|
||||||
}catch(Exception ex)
|
}catch(Exception ex)
|
||||||
{
|
{
|
||||||
_=ex;
|
_error.Invoke(this,new TYTDErrorEventArgs("jNQXAC9IVRw",ex));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -243,7 +243,7 @@ internal class SegmentedHttpStream : Stream
|
||||||
await client.GetStringAsync($"{url}api/v2/AddUser?v={userName.Value}&res={resolution.ToString()}");
|
await client.GetStringAsync($"{url}api/v2/AddUser?v={userName.Value}&res={resolution.ToString()}");
|
||||||
}catch(Exception ex)
|
}catch(Exception ex)
|
||||||
{
|
{
|
||||||
_=ex;
|
_error.Invoke(this,new TYTDErrorEventArgs("jNQXAC9IVRw",ex));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -253,7 +253,7 @@ internal class SegmentedHttpStream : Stream
|
||||||
await client.GetStringAsync($"{url}api/v2/AddVideo?v={id.Value}&res={resolution.ToString()}");
|
await client.GetStringAsync($"{url}api/v2/AddVideo?v={id.Value}&res={resolution.ToString()}");
|
||||||
}catch(Exception ex)
|
}catch(Exception ex)
|
||||||
{
|
{
|
||||||
_=ex;
|
_error.Invoke(this,new TYTDErrorEventArgs("jNQXAC9IVRw",ex));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public async Task AddFileAsync(string url,bool download=true)
|
public async Task AddFileAsync(string url,bool download=true)
|
||||||
|
@ -262,7 +262,7 @@ internal class SegmentedHttpStream : Stream
|
||||||
await client.GetStringAsync($"{url}api/v2/AddFile?url={WebUtility.UrlEncode(url)}&download={download}");
|
await client.GetStringAsync($"{url}api/v2/AddFile?url={WebUtility.UrlEncode(url)}&download={download}");
|
||||||
}catch(Exception ex)
|
}catch(Exception ex)
|
||||||
{
|
{
|
||||||
_=ex;
|
_error.Invoke(this,new TYTDErrorEventArgs("jNQXAC9IVRw",ex));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public override async Task<bool> DirectoryExistsAsync(string path)
|
public override async Task<bool> DirectoryExistsAsync(string path)
|
||||||
|
@ -272,7 +272,7 @@ internal class SegmentedHttpStream : Stream
|
||||||
return v=="true";
|
return v=="true";
|
||||||
}catch(Exception ex)
|
}catch(Exception ex)
|
||||||
{
|
{
|
||||||
_=ex;
|
_error.Invoke(this,new TYTDErrorEventArgs("jNQXAC9IVRw",ex));
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -285,7 +285,7 @@ internal class SegmentedHttpStream : Stream
|
||||||
items=JsonConvert.DeserializeObject<List<string>>(v);
|
items=JsonConvert.DeserializeObject<List<string>>(v);
|
||||||
}catch(Exception ex)
|
}catch(Exception ex)
|
||||||
{
|
{
|
||||||
_=ex;
|
_error.Invoke(this,new TYTDErrorEventArgs("jNQXAC9IVRw",ex));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(items==null)
|
if(items==null)
|
||||||
|
@ -305,7 +305,7 @@ internal class SegmentedHttpStream : Stream
|
||||||
v=await client.GetStringAsync("{url}api/v2/subscriptions");
|
v=await client.GetStringAsync("{url}api/v2/subscriptions");
|
||||||
}catch(Exception ex)
|
}catch(Exception ex)
|
||||||
{
|
{
|
||||||
_=ex;
|
_error.Invoke(this,new TYTDErrorEventArgs("jNQXAC9IVRw",ex));
|
||||||
}
|
}
|
||||||
foreach(var item in JsonConvert.DeserializeObject<List<Subscription>>(v))
|
foreach(var item in JsonConvert.DeserializeObject<List<Subscription>>(v))
|
||||||
{
|
{
|
||||||
|
@ -321,18 +321,18 @@ internal class SegmentedHttpStream : Stream
|
||||||
|
|
||||||
}catch(Exception ex)
|
}catch(Exception ex)
|
||||||
{
|
{
|
||||||
_=ex;
|
_error.Invoke(this,new TYTDErrorEventArgs("jNQXAC9IVRw",ex));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public async Task SubscribeAsync(ChannelId id,bool downloadChannelInfo=false,ChannelBellInfo bellInfo = ChannelBellInfo.NotifyAndDownload)
|
public async Task SubscribeAsync(ChannelId id,ChannelBellInfo bellInfo = ChannelBellInfo.NotifyAndDownload)
|
||||||
{
|
{
|
||||||
try{
|
try{
|
||||||
string dlcid=downloadChannelInfo ? "true" : "false";
|
|
||||||
string v=await client.GetStringAsync($"{url}api/v2/subscribe?id={id.Value}&conf={bellInfo.ToString()}&getinfo={dlcid}");
|
string v=await client.GetStringAsync($"{url}api/v2/subscribe?id={id.Value}&conf={bellInfo.ToString()}");
|
||||||
|
|
||||||
}catch(Exception ex)
|
}catch(Exception ex)
|
||||||
{
|
{
|
||||||
_=ex;
|
_error.Invoke(this,new TYTDErrorEventArgs("jNQXAC9IVRw",ex));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public async Task SubscribeAsync(UserName name,ChannelBellInfo info=ChannelBellInfo.NotifyAndDownload)
|
public async Task SubscribeAsync(UserName name,ChannelBellInfo info=ChannelBellInfo.NotifyAndDownload)
|
||||||
|
@ -344,7 +344,7 @@ internal class SegmentedHttpStream : Stream
|
||||||
|
|
||||||
}catch(Exception ex)
|
}catch(Exception ex)
|
||||||
{
|
{
|
||||||
_=ex;
|
_error.Invoke(this,new TYTDErrorEventArgs("jNQXAC9IVRw",ex));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public async Task ResubscribeAsync(ChannelId id,ChannelBellInfo info=ChannelBellInfo.NotifyAndDownload)
|
public async Task ResubscribeAsync(ChannelId id,ChannelBellInfo info=ChannelBellInfo.NotifyAndDownload)
|
||||||
|
@ -356,7 +356,7 @@ internal class SegmentedHttpStream : Stream
|
||||||
|
|
||||||
}catch(Exception ex)
|
}catch(Exception ex)
|
||||||
{
|
{
|
||||||
_=ex;
|
_error.Invoke(this,new TYTDErrorEventArgs("jNQXAC9IVRw",ex));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public async override IAsyncEnumerable<string> EnumerateFilesAsync(string path)
|
public async override IAsyncEnumerable<string> EnumerateFilesAsync(string path)
|
||||||
|
@ -367,7 +367,7 @@ internal class SegmentedHttpStream : Stream
|
||||||
items=JsonConvert.DeserializeObject<List<string>>(v);
|
items=JsonConvert.DeserializeObject<List<string>>(v);
|
||||||
}catch(Exception ex)
|
}catch(Exception ex)
|
||||||
{
|
{
|
||||||
_=ex;
|
_error.Invoke(this,new TYTDErrorEventArgs("jNQXAC9IVRw",ex));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(items==null)
|
if(items==null)
|
||||||
|
@ -388,7 +388,7 @@ internal class SegmentedHttpStream : Stream
|
||||||
return v=="true";
|
return v=="true";
|
||||||
}catch(Exception ex)
|
}catch(Exception ex)
|
||||||
{
|
{
|
||||||
_=ex;
|
_error.Invoke(this,new TYTDErrorEventArgs("jNQXAC9IVRw",ex));
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -400,7 +400,7 @@ internal class SegmentedHttpStream : Stream
|
||||||
return JsonConvert.DeserializeObject<List<(SavedVideo Video,Resolution res)>>(v);
|
return JsonConvert.DeserializeObject<List<(SavedVideo Video,Resolution res)>>(v);
|
||||||
}catch(Exception ex)
|
}catch(Exception ex)
|
||||||
{
|
{
|
||||||
_=ex;
|
_error.Invoke(this,new TYTDErrorEventArgs("jNQXAC9IVRw",ex));
|
||||||
}
|
}
|
||||||
|
|
||||||
return new List<(SavedVideo video,Resolution resolution)>();
|
return new List<(SavedVideo video,Resolution resolution)>();
|
||||||
|
@ -413,19 +413,24 @@ internal class SegmentedHttpStream : Stream
|
||||||
return JsonConvert.DeserializeObject<SavedVideoProgress>(v);
|
return JsonConvert.DeserializeObject<SavedVideoProgress>(v);
|
||||||
}catch(Exception ex)
|
}catch(Exception ex)
|
||||||
{
|
{
|
||||||
_=ex;
|
_error.Invoke(this,new TYTDErrorEventArgs("jNQXAC9IVRw",ex));
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
public SavedVideoProgress GetProgress()
|
public SavedVideoProgress GetProgress()
|
||||||
{
|
{
|
||||||
return GetProgressAsync().GetAwaiter().GetResult();
|
if(hadBeenListeningToEvents)
|
||||||
|
{
|
||||||
|
return progress;
|
||||||
|
}else{
|
||||||
|
return Task.Run(GetProgressAsync).GetAwaiter().GetResult();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public IReadOnlyList<(SavedVideo Video, Resolution Resolution)> GetQueueList()
|
public IReadOnlyList<(SavedVideo Video, Resolution Resolution)> GetQueueList()
|
||||||
{
|
{
|
||||||
return GetQueueListAsync().GetAwaiter().GetResult();
|
return Task.Run(GetQueueListAsync).GetAwaiter().GetResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -439,7 +444,7 @@ internal class SegmentedHttpStream : Stream
|
||||||
return v;
|
return v;
|
||||||
}catch(Exception ex)
|
}catch(Exception ex)
|
||||||
{
|
{
|
||||||
_=ex;
|
_error.Invoke(this,new TYTDErrorEventArgs("jNQXAC9IVRw",ex));
|
||||||
}
|
}
|
||||||
|
|
||||||
return Stream.Null;
|
return Stream.Null;
|
||||||
|
@ -479,7 +484,7 @@ internal class SegmentedHttpStream : Stream
|
||||||
|
|
||||||
}catch(Exception ex)
|
}catch(Exception ex)
|
||||||
{
|
{
|
||||||
_=ex;
|
_error.Invoke(this,new TYTDErrorEventArgs("jNQXAC9IVRw",ex));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -492,7 +497,7 @@ internal class SegmentedHttpStream : Stream
|
||||||
|
|
||||||
}catch(Exception ex)
|
}catch(Exception ex)
|
||||||
{
|
{
|
||||||
_=ex;
|
_error.Invoke(this,new TYTDErrorEventArgs("jNQXAC9IVRw",ex));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public void DeletePersonalPlaylist(string name)
|
public void DeletePersonalPlaylist(string name)
|
||||||
|
@ -504,7 +509,7 @@ internal class SegmentedHttpStream : Stream
|
||||||
|
|
||||||
}catch(Exception ex)
|
}catch(Exception ex)
|
||||||
{
|
{
|
||||||
_=ex;
|
_error.Invoke(this,new TYTDErrorEventArgs("jNQXAC9IVRw",ex));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -517,8 +522,196 @@ internal class SegmentedHttpStream : Stream
|
||||||
|
|
||||||
}catch(Exception ex)
|
}catch(Exception ex)
|
||||||
{
|
{
|
||||||
_=ex;
|
_error.Invoke(this,new TYTDErrorEventArgs("jNQXAC9IVRw",ex));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SavedVideoProgress progress=new SavedVideoProgress();
|
||||||
|
CancellationTokenSource src=new CancellationTokenSource();
|
||||||
|
bool hadBeenListeningToEvents=false;
|
||||||
|
private async Task _startEventStreamAsync()
|
||||||
|
{
|
||||||
|
try{
|
||||||
|
src=new CancellationTokenSource();
|
||||||
|
hadBeenListeningToEvents=true;
|
||||||
|
var sse=await client.GetSSEClientAsync($"{url}api/v2/event");
|
||||||
|
sse.Event += sse_Event;
|
||||||
|
await sse.ReadEventsAsync(src.Token);
|
||||||
|
|
||||||
|
}catch(Exception ex){
|
||||||
|
_error.Invoke(this,new TYTDErrorEventArgs("jNQXAC9IVRw",ex));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public void ResetEvents()
|
||||||
|
{
|
||||||
|
if(src != null) {
|
||||||
|
src.Cancel();
|
||||||
|
src.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(hadBeenListeningToEvents)
|
||||||
|
{
|
||||||
|
hadBeenListeningToEvents=false;
|
||||||
|
_startEventStream();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
public void CancelEvents()
|
||||||
|
{
|
||||||
|
if(src!= null){
|
||||||
|
src.Cancel();
|
||||||
|
src.Dispose();
|
||||||
|
}
|
||||||
|
src=null;
|
||||||
|
hadBeenListeningToEvents=false;
|
||||||
|
}
|
||||||
|
private event EventHandler<VideoStartedEventArgs> _started_video;
|
||||||
|
private event EventHandler<VideoFinishedEventArgs> _ended_video;
|
||||||
|
private event EventHandler<VideoProgressEventArgs> _progress_video;
|
||||||
|
private event EventHandler<TYTDErrorEventArgs> _error;
|
||||||
|
private event EventHandler<BellEventArgs> _bell;
|
||||||
|
public event EventHandler<VideoStartedEventArgs> VideoStarted
|
||||||
|
{
|
||||||
|
add{
|
||||||
|
_started_video += value;
|
||||||
|
_startEventStream();
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
remove
|
||||||
|
{
|
||||||
|
_started_video-=value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public event EventHandler<VideoProgressEventArgs> VideoProgress
|
||||||
|
{
|
||||||
|
add{
|
||||||
|
_progress_video += value;
|
||||||
|
_startEventStream();
|
||||||
|
|
||||||
|
}
|
||||||
|
remove
|
||||||
|
{
|
||||||
|
_progress_video -=value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public event EventHandler<VideoFinishedEventArgs> VideoFinished
|
||||||
|
{
|
||||||
|
add
|
||||||
|
{
|
||||||
|
_ended_video+=value;
|
||||||
|
_startEventStream();
|
||||||
|
|
||||||
|
}
|
||||||
|
remove
|
||||||
|
{
|
||||||
|
_ended_video -= value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public event EventHandler<TYTDErrorEventArgs> Error
|
||||||
|
{
|
||||||
|
add
|
||||||
|
{
|
||||||
|
_error += value;
|
||||||
|
_startEventStream();
|
||||||
|
}
|
||||||
|
remove
|
||||||
|
{
|
||||||
|
_error-=value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public event EventHandler<BellEventArgs> Bell
|
||||||
|
{
|
||||||
|
add
|
||||||
|
{
|
||||||
|
_bell+=value;
|
||||||
|
_startEventStream();
|
||||||
|
}
|
||||||
|
remove
|
||||||
|
{
|
||||||
|
_bell-=value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sse_Event(object sender,SSEEvent evt)
|
||||||
|
{
|
||||||
|
bool started=false;bool ended=false;bool error=false;bool bell=false;
|
||||||
|
try{
|
||||||
|
ProgressItem item = evt.ParseJson<ProgressItem>();
|
||||||
|
if(item != null)
|
||||||
|
{
|
||||||
|
if(item.Video != null)
|
||||||
|
{
|
||||||
|
progress.Video = item.Video;
|
||||||
|
}
|
||||||
|
if(item.StartEvent)
|
||||||
|
{
|
||||||
|
started = true;
|
||||||
|
}
|
||||||
|
if(item.StopEvent)
|
||||||
|
{
|
||||||
|
ended =true;
|
||||||
|
}
|
||||||
|
if(item.BellEvent)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
progress.Length = item.Length;
|
||||||
|
progress.ProgressRaw=item.Percent;
|
||||||
|
progress.Progress = ((int)(item.Percent * 100) % 101);
|
||||||
|
if(started)
|
||||||
|
{
|
||||||
|
VideoStartedEventArgs evt0=new VideoStartedEventArgs();
|
||||||
|
evt0.EstimatedLength=item.Length;
|
||||||
|
evt0.Resolution=Resolution.PreMuxed;
|
||||||
|
evt0.VideoInfo=progress.Video;
|
||||||
|
|
||||||
|
_started_video?.Invoke(this,evt0);
|
||||||
|
|
||||||
|
}else if(ended)
|
||||||
|
{
|
||||||
|
VideoFinishedEventArgs evt0=new VideoFinishedEventArgs();
|
||||||
|
evt0.Resolution=Resolution.PreMuxed;
|
||||||
|
evt0.VideoInfo=progress.Video;
|
||||||
|
_ended_video?.Invoke(this,evt0);
|
||||||
|
}else if(error)
|
||||||
|
{
|
||||||
|
TYTDErrorEventArgs evt0=new TYTDErrorEventArgs(item.Id,new TYTDException(item.Message,item.Error,item.ExceptionName));
|
||||||
|
_error?.Invoke(this,evt0);
|
||||||
|
}else if(bell)
|
||||||
|
{
|
||||||
|
BellEventArgs evt0=new BellEventArgs();
|
||||||
|
evt0.Id = item.Id;
|
||||||
|
_bell?.Invoke(this,evt0);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
VideoProgressEventArgs evt0=new VideoProgressEventArgs();
|
||||||
|
evt0.Progress = item.Percent;
|
||||||
|
evt0.VideoInfo = progress.Video;
|
||||||
|
_progress_video?.Invoke(this,evt0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
catch(Exception ex)
|
||||||
|
{
|
||||||
|
_error.Invoke(this,new TYTDErrorEventArgs("jNQXAC9IVRw",ex));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private void _startEventStream()
|
||||||
|
{
|
||||||
|
|
||||||
|
Task.Run(_startEventStreamAsync).Wait(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override ExtraData GetExtraData()
|
||||||
|
{
|
||||||
|
return Task.Run<ExtraData>(async()=>{
|
||||||
|
string text= await client.GetStringAsync($"{url}api/v2/extra_data.json");
|
||||||
|
return JsonConvert.DeserializeObject<ExtraData>(text);
|
||||||
|
}).GetAwaiter().GetResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,44 @@
|
||||||
|
using System;
|
||||||
|
using System.Runtime.Serialization;
|
||||||
|
|
||||||
|
namespace Tesses.YouTubeDownloader
|
||||||
|
{
|
||||||
|
[Serializable]
|
||||||
|
internal class TYTDException : Exception
|
||||||
|
{
|
||||||
|
public TYTDException()
|
||||||
|
{
|
||||||
|
this.full="";
|
||||||
|
Type="";
|
||||||
|
}
|
||||||
|
|
||||||
|
public TYTDException(string message) : base(message)
|
||||||
|
{
|
||||||
|
this.full="";
|
||||||
|
Type="";
|
||||||
|
}
|
||||||
|
|
||||||
|
public TYTDException(string message, Exception innerException) : base(message, innerException)
|
||||||
|
{
|
||||||
|
this.full="";
|
||||||
|
Type="";
|
||||||
|
}
|
||||||
|
public TYTDException(string message,string full,string type) : base(message)
|
||||||
|
{
|
||||||
|
this.full=full;
|
||||||
|
Type=type;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected TYTDException(SerializationInfo info, StreamingContext context) : base(info, context)
|
||||||
|
{
|
||||||
|
this.full="";
|
||||||
|
Type="";
|
||||||
|
}
|
||||||
|
string full;
|
||||||
|
public string Type {get;private set;}
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return full;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -15,63 +15,72 @@ namespace Tesses.YouTubeDownloader
|
||||||
{
|
{
|
||||||
public class TYTDDownloaderStorageProxy : IStorage
|
public class TYTDDownloaderStorageProxy : IStorage
|
||||||
{
|
{
|
||||||
public IDownloader Downloader {get;set;}
|
public IDownloader Downloader {get{return _downloader;} set
|
||||||
|
|
||||||
private ITYTDBase _base=null;
|
|
||||||
|
|
||||||
public ITYTDBase Storage {get {return _base;} set{_base=value;
|
|
||||||
var v = value as IStorage;
|
|
||||||
if(v != null)
|
|
||||||
SetStorage(v);}}
|
|
||||||
|
|
||||||
private void SetStorage(IStorage storage)
|
|
||||||
{
|
{
|
||||||
if(_storage !=null)
|
SetDownloader(_downloader);
|
||||||
{
|
|
||||||
_storage.Bell -= _EVT_BELL;
|
|
||||||
_storage.BeforeSaveInfo -= _EVT_BSI;
|
|
||||||
_storage.VideoFinished -= _EVT_VFIN;
|
|
||||||
_storage.VideoProgress -= _EVT_VPROG;
|
|
||||||
_storage.VideoStarted -= _EVT_VSTAR;
|
|
||||||
_storage.Error -= _EVT_ERR;
|
|
||||||
}
|
}
|
||||||
_storage=storage;
|
|
||||||
if(storage != null)
|
}
|
||||||
|
|
||||||
|
private IDownloader _downloader=null;
|
||||||
|
|
||||||
|
public ITYTDBase Storage {get;set;}
|
||||||
|
private int SetEVT_ERR=0;
|
||||||
|
private int SetEVT_VFIN=0;
|
||||||
|
private int SetEVT_VSTAR=0;
|
||||||
|
|
||||||
|
private int SetEVT_VPROG=0;
|
||||||
|
private int SetEVT_BELL=0;
|
||||||
|
|
||||||
|
private void SetDownloader(IDownloader downloader)
|
||||||
{
|
{
|
||||||
_storage.Bell += _EVT_BELL;
|
if(_downloader !=null)
|
||||||
_storage.BeforeSaveInfo += _EVT_BSI;
|
{
|
||||||
_storage.VideoFinished += _EVT_VFIN;
|
if(SetEVT_BELL > 0)_downloader.Bell -= _EVT_BELL;
|
||||||
_storage.VideoProgress += _EVT_VPROG;
|
|
||||||
_storage.VideoStarted += _EVT_VSTAR;
|
if(SetEVT_VFIN > 0)_downloader.VideoFinished -= _EVT_VFIN;
|
||||||
_storage.Error += _EVT_ERR;
|
if(SetEVT_VPROG > 0)_downloader.VideoProgress -= _EVT_VPROG;
|
||||||
|
if(SetEVT_VSTAR > 0)_downloader.VideoStarted -= _EVT_VSTAR;
|
||||||
|
if(SetEVT_ERR > 0)_downloader.Error -= _EVT_ERR;
|
||||||
|
}
|
||||||
|
_downloader=downloader;
|
||||||
|
if(downloader != null)
|
||||||
|
{
|
||||||
|
if(SetEVT_BELL > 0)_downloader.Bell += _EVT_BELL;
|
||||||
|
|
||||||
|
if(SetEVT_VFIN > 0)_downloader.VideoFinished += _EVT_VFIN;
|
||||||
|
if(SetEVT_VPROG > 0)_downloader.VideoProgress += _EVT_VPROG;
|
||||||
|
if(SetEVT_VSTAR > 0)_downloader.VideoStarted += _EVT_VSTAR;
|
||||||
|
if(SetEVT_ERR > 0)_downloader.Error += _EVT_ERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
private void _EVT_VSTAR(object sender,VideoStartedEventArgs evt)
|
private void _EVT_VSTAR(object sender,VideoStartedEventArgs evt)
|
||||||
{
|
{
|
||||||
VideoStarted?.Invoke(this,evt);
|
_vstar?.Invoke(this,evt);
|
||||||
}
|
}
|
||||||
private void _EVT_VPROG(object sender,VideoProgressEventArgs evt)
|
private void _EVT_VPROG(object sender,VideoProgressEventArgs evt)
|
||||||
{
|
{
|
||||||
VideoProgress?.Invoke(this,evt);
|
_vprog?.Invoke(this,evt);
|
||||||
}
|
}
|
||||||
private void _EVT_VFIN(object sender,VideoFinishedEventArgs evt)
|
private void _EVT_VFIN(object sender,VideoFinishedEventArgs evt)
|
||||||
{
|
{
|
||||||
VideoFinished?.Invoke(this,evt);
|
_vfin?.Invoke(this,evt);
|
||||||
}
|
|
||||||
private void _EVT_BSI(object sender,BeforeSaveInfoEventArgs evt)
|
|
||||||
{
|
|
||||||
BeforeSaveInfo?.Invoke(this,evt);
|
|
||||||
}
|
}
|
||||||
|
private event EventHandler<BellEventArgs> _bell;
|
||||||
|
private event EventHandler<VideoStartedEventArgs> _vstar;
|
||||||
|
private event EventHandler<VideoProgressEventArgs> _vprog;
|
||||||
|
private event EventHandler<VideoFinishedEventArgs> _vfin;
|
||||||
|
private event EventHandler<TYTDErrorEventArgs> _error;
|
||||||
|
|
||||||
private void _EVT_BELL(object sender,BellEventArgs evt)
|
private void _EVT_BELL(object sender,BellEventArgs evt)
|
||||||
{
|
{
|
||||||
Bell?.Invoke(this,evt);
|
_bell?.Invoke(this,evt);
|
||||||
}
|
}
|
||||||
private void _EVT_ERR(object sender,TYTDErrorEventArgs evt)
|
private void _EVT_ERR(object sender,TYTDErrorEventArgs evt)
|
||||||
{
|
{
|
||||||
Error?.Invoke(this,evt);
|
_error?.Invoke(this,evt);
|
||||||
}
|
}
|
||||||
IStorage _storage=null;
|
|
||||||
|
|
||||||
public LegacyConverter Legacy {
|
public LegacyConverter Legacy {
|
||||||
get{
|
get{
|
||||||
|
@ -126,13 +135,137 @@ namespace Tesses.YouTubeDownloader
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public event EventHandler<BellEventArgs> Bell;
|
public event EventHandler<BellEventArgs> Bell
|
||||||
public event EventHandler<VideoStartedEventArgs> VideoStarted;
|
{
|
||||||
public event EventHandler<BeforeSaveInfoEventArgs> BeforeSaveInfo;
|
add
|
||||||
public event EventHandler<VideoProgressEventArgs> VideoProgress;
|
{
|
||||||
public event EventHandler<VideoFinishedEventArgs> VideoFinished;
|
if(SetEVT_BELL == 0)
|
||||||
|
{
|
||||||
|
Downloader.Bell += _EVT_BELL;
|
||||||
|
|
||||||
public event EventHandler<TYTDErrorEventArgs> Error;
|
}
|
||||||
|
_bell += value;
|
||||||
|
SetEVT_BELL++;
|
||||||
|
|
||||||
|
}
|
||||||
|
remove
|
||||||
|
{
|
||||||
|
SetEVT_BELL--;
|
||||||
|
if(SetEVT_BELL <= 0)
|
||||||
|
{
|
||||||
|
SetEVT_BELL=0;
|
||||||
|
Downloader.Bell -= _EVT_BELL;
|
||||||
|
|
||||||
|
}
|
||||||
|
_bell -= value;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public event EventHandler<VideoStartedEventArgs> VideoStarted
|
||||||
|
{
|
||||||
|
add
|
||||||
|
{
|
||||||
|
if(SetEVT_VSTAR == 0)
|
||||||
|
{
|
||||||
|
Downloader.VideoStarted += _EVT_VSTAR;
|
||||||
|
|
||||||
|
}
|
||||||
|
_vstar += value;
|
||||||
|
SetEVT_VSTAR++;
|
||||||
|
|
||||||
|
}
|
||||||
|
remove
|
||||||
|
{
|
||||||
|
SetEVT_VSTAR--;
|
||||||
|
if(SetEVT_VSTAR <= 0)
|
||||||
|
{
|
||||||
|
SetEVT_VSTAR=0;
|
||||||
|
Downloader.VideoStarted -= _EVT_VSTAR;
|
||||||
|
|
||||||
|
}
|
||||||
|
_vstar -= value;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public event EventHandler<VideoProgressEventArgs> VideoProgress
|
||||||
|
{
|
||||||
|
add
|
||||||
|
{
|
||||||
|
if(SetEVT_VPROG == 0)
|
||||||
|
{
|
||||||
|
Downloader.VideoProgress += _EVT_VPROG;
|
||||||
|
|
||||||
|
}
|
||||||
|
_vprog += value;
|
||||||
|
SetEVT_VPROG++;
|
||||||
|
|
||||||
|
}
|
||||||
|
remove
|
||||||
|
{
|
||||||
|
SetEVT_VPROG--;
|
||||||
|
if(SetEVT_VPROG <= 0)
|
||||||
|
{
|
||||||
|
SetEVT_VPROG=0;
|
||||||
|
Downloader.VideoProgress -= _EVT_VPROG;
|
||||||
|
|
||||||
|
}
|
||||||
|
_vprog -= value;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public event EventHandler<VideoFinishedEventArgs> VideoFinished
|
||||||
|
{
|
||||||
|
add
|
||||||
|
{
|
||||||
|
if(SetEVT_VFIN == 0)
|
||||||
|
{
|
||||||
|
Downloader.VideoFinished += _EVT_VFIN;
|
||||||
|
|
||||||
|
}
|
||||||
|
_vfin += value;
|
||||||
|
SetEVT_VFIN++;
|
||||||
|
|
||||||
|
}
|
||||||
|
remove
|
||||||
|
{
|
||||||
|
SetEVT_VFIN--;
|
||||||
|
if(SetEVT_VFIN <= 0)
|
||||||
|
{
|
||||||
|
SetEVT_VFIN=0;
|
||||||
|
Downloader.VideoFinished -= _EVT_VFIN;
|
||||||
|
|
||||||
|
}
|
||||||
|
_vfin -= value;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public event EventHandler<TYTDErrorEventArgs> Error
|
||||||
|
{
|
||||||
|
add
|
||||||
|
{
|
||||||
|
if(SetEVT_ERR == 0)
|
||||||
|
{
|
||||||
|
Downloader.Error += _EVT_ERR;
|
||||||
|
|
||||||
|
}
|
||||||
|
_error += value;
|
||||||
|
SetEVT_ERR++;
|
||||||
|
|
||||||
|
}
|
||||||
|
remove
|
||||||
|
{
|
||||||
|
SetEVT_ERR--;
|
||||||
|
if(SetEVT_ERR <= 0)
|
||||||
|
{
|
||||||
|
SetEVT_ERR=0;
|
||||||
|
Downloader.Error -= _EVT_ERR;
|
||||||
|
|
||||||
|
}
|
||||||
|
_error -= value;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public async Task StorageAsStorageAsync(Func<IStorage,Task> callback)
|
public async Task StorageAsStorageAsync(Func<IStorage,Task> callback)
|
||||||
{
|
{
|
||||||
|
@ -412,10 +545,10 @@ namespace Tesses.YouTubeDownloader
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task SubscribeAsync(ChannelId id, bool downloadChannelInfo = false, ChannelBellInfo bellInfo = ChannelBellInfo.NotifyAndDownload)
|
public async Task SubscribeAsync(ChannelId id, ChannelBellInfo bellInfo = ChannelBellInfo.NotifyAndDownload)
|
||||||
{
|
{
|
||||||
await StorageAsStorageAsync(async(e)=>{
|
await StorageAsStorageAsync(async(e)=>{
|
||||||
await e.SubscribeAsync(id,downloadChannelInfo,bellInfo);
|
await e.SubscribeAsync(id,bellInfo);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -732,6 +865,11 @@ namespace Tesses.YouTubeDownloader
|
||||||
{
|
{
|
||||||
Downloader.CancelDownload(restart);
|
Downloader.CancelDownload(restart);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ExtraData GetExtraData()
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class DownloaderMigration
|
public class DownloaderMigration
|
||||||
|
|
|
@ -7,9 +7,9 @@
|
||||||
<PackageId>Tesses.YouTubeDownloader</PackageId>
|
<PackageId>Tesses.YouTubeDownloader</PackageId>
|
||||||
<Author>Mike Nolan</Author>
|
<Author>Mike Nolan</Author>
|
||||||
<Company>Tesses</Company>
|
<Company>Tesses</Company>
|
||||||
<Version>1.2.3</Version>
|
<Version>1.2.4</Version>
|
||||||
<AssemblyVersion>1.2.3</AssemblyVersion>
|
<AssemblyVersion>1.2.4</AssemblyVersion>
|
||||||
<FileVersion>1.2.3</FileVersion>
|
<FileVersion>1.2.4</FileVersion>
|
||||||
<Description>A YouTube Downloader</Description>
|
<Description>A YouTube Downloader</Description>
|
||||||
<PackageLicenseExpression>LGPL-3.0-only</PackageLicenseExpression>
|
<PackageLicenseExpression>LGPL-3.0-only</PackageLicenseExpression>
|
||||||
<PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance>
|
<PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance>
|
||||||
|
|
Loading…
Reference in New Issue