299 lines
11 KiB
C#
299 lines
11 KiB
C#
|
using System;
|
|||
|
using System.Collections.Generic;
|
|||
|
using System.Threading.Tasks;
|
|||
|
using YoutubeExplode.Channels;
|
|||
|
using YoutubeExplode.Playlists;
|
|||
|
using YoutubeExplode.Videos;
|
|||
|
using MailKit.Net.Smtp;
|
|||
|
using MimeKit;
|
|||
|
using MailKit;
|
|||
|
using MailKit.Net.Imap;
|
|||
|
using System.IO;
|
|||
|
using System.Threading;
|
|||
|
|
|||
|
namespace Tesses.YouTubeDownloader.MailKit
|
|||
|
{
|
|||
|
public sealed class SMTPDownloader : IDownloader
|
|||
|
{
|
|||
|
string fromEmail;
|
|||
|
string toEmail;
|
|||
|
Func<Task<SmtpClient>> new_client;
|
|||
|
public SMTPDownloader(Func<Task<SmtpClient>> client,string fromEmail,string toEmail)
|
|||
|
{
|
|||
|
this.new_client = client;
|
|||
|
this.fromEmail=fromEmail;
|
|||
|
this.toEmail=toEmail;
|
|||
|
}
|
|||
|
|
|||
|
public SMTPDownloader(string smtpServer,string fromEmail,string toEmail,string username,string password,int port=587,global::MailKit.Security.SecureSocketOptions options=global::MailKit.Security.SecureSocketOptions.StartTls)
|
|||
|
{
|
|||
|
this.new_client = async ()=>{
|
|||
|
var clt= new SmtpClient();
|
|||
|
await clt.ConnectAsync(smtpServer,port,options);
|
|||
|
await clt.AuthenticateAsync(username,password);
|
|||
|
return clt;
|
|||
|
};
|
|||
|
this.fromEmail=fromEmail;
|
|||
|
this.toEmail = toEmail;
|
|||
|
}
|
|||
|
|
|||
|
public event EventHandler<VideoStartedEventArgs> VideoStarted;
|
|||
|
public event EventHandler<VideoProgressEventArgs> VideoProgress;
|
|||
|
public event EventHandler<VideoFinishedEventArgs> VideoFinished;
|
|||
|
public event EventHandler<TYTDErrorEventArgs> Error;
|
|||
|
public event EventHandler<BellEventArgs> Bell;
|
|||
|
|
|||
|
private async Task AddItemToAsync(string url)
|
|||
|
{
|
|||
|
using(var clt = await new_client())
|
|||
|
{
|
|||
|
var messageToSend = new MimeMessage();
|
|||
|
messageToSend.From.Add(MailboxAddress.Parse(fromEmail));
|
|||
|
messageToSend.To.Add(MailboxAddress.Parse(toEmail));
|
|||
|
messageToSend.Body = new TextPart(MimeKit.Text.TextFormat.Plain){Text=url};
|
|||
|
messageToSend.Subject="Sent By Tesses.YouTubeDownloader.MailKit";
|
|||
|
await clt.SendAsync(messageToSend);
|
|||
|
await clt.DisconnectAsync(true);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public async Task AddChannelAsync(ChannelId id, Resolution resolution = Resolution.PreMuxed)
|
|||
|
{
|
|||
|
await AddItemToAsync($"https://www.youtube.com/channel/{id.Value}");
|
|||
|
}
|
|||
|
|
|||
|
public async Task AddFileAsync(string url, bool download = true)
|
|||
|
{
|
|||
|
await Task.CompletedTask;
|
|||
|
}
|
|||
|
|
|||
|
public async Task AddPlaylistAsync(PlaylistId id, Resolution resolution = Resolution.PreMuxed)
|
|||
|
{
|
|||
|
await AddItemToAsync($"https://www.youtube.com/playlist?list={id.Value}");
|
|||
|
}
|
|||
|
|
|||
|
public async Task AddToPersonalPlaylistAsync(string name, IEnumerable<ListContentItem> items)
|
|||
|
{
|
|||
|
await Task.CompletedTask;
|
|||
|
}
|
|||
|
|
|||
|
public async Task AddUserAsync(UserName userName, Resolution resolution = Resolution.PreMuxed)
|
|||
|
{
|
|||
|
await AddItemToAsync($"https://www.youtube.com/user/{userName.Value}");
|
|||
|
}
|
|||
|
|
|||
|
public async Task AddVideoAsync(VideoId id, Resolution resolution = Resolution.PreMuxed)
|
|||
|
{
|
|||
|
await AddItemToAsync($"https://www.youtube.com/watch?v={id.Value}");
|
|||
|
}
|
|||
|
public async Task AddSlugAsync(ChannelSlug slug,Resolution resolution=Resolution.PreMuxed)
|
|||
|
{
|
|||
|
await AddItemToAsync($"https://www.youtube.com/c/{slug.Value}");
|
|||
|
}
|
|||
|
public async Task AddHandleAsync(ChannelHandle handle,Resolution resolution =Resolution.PreMuxed)
|
|||
|
{
|
|||
|
await AddItemToAsync($"https://www.youtube.com/@{handle.Value}");
|
|||
|
}
|
|||
|
public void CancelDownload(bool restart = false)
|
|||
|
{
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
public void DeletePersonalPlaylist(string name)
|
|||
|
{
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
public ExtraData GetExtraData()
|
|||
|
{
|
|||
|
|
|||
|
return new ExtraData();
|
|||
|
}
|
|||
|
|
|||
|
public async IAsyncEnumerable<ListContentItem> GetPersonalPlaylistContentsAsync(string name)
|
|||
|
{
|
|||
|
await Task.CompletedTask;
|
|||
|
yield break;
|
|||
|
}
|
|||
|
|
|||
|
public SavedVideoProgress GetProgress()
|
|||
|
{
|
|||
|
return new SavedVideoProgress();
|
|||
|
}
|
|||
|
|
|||
|
public IReadOnlyList<(SavedVideo Video, Resolution Resolution)> GetQueueList()
|
|||
|
{
|
|||
|
return new List<(SavedVideo Video,Resolution Resolution)>();
|
|||
|
}
|
|||
|
|
|||
|
public async IAsyncEnumerable<Subscription> GetSubscriptionsAsync()
|
|||
|
{
|
|||
|
await Task.CompletedTask;
|
|||
|
yield break;
|
|||
|
}
|
|||
|
|
|||
|
public bool PersonalPlaylistExists(string name)
|
|||
|
{
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
public async Task RemoveItemFromPersonalPlaylistAsync(string name, VideoId id)
|
|||
|
{
|
|||
|
await Task.CompletedTask;
|
|||
|
}
|
|||
|
|
|||
|
public async Task ReplacePersonalPlaylistAsync(string name, IEnumerable<ListContentItem> items)
|
|||
|
{
|
|||
|
await Task.CompletedTask;
|
|||
|
}
|
|||
|
|
|||
|
public async Task ResubscribeAsync(ChannelId id, ChannelBellInfo info = ChannelBellInfo.NotifyAndDownload)
|
|||
|
{
|
|||
|
await Task.CompletedTask;
|
|||
|
}
|
|||
|
|
|||
|
public async Task SetResolutionForItemInPersonalPlaylistAsync(string name, VideoId id, Resolution resolution)
|
|||
|
{
|
|||
|
await Task.CompletedTask;
|
|||
|
}
|
|||
|
|
|||
|
public async Task SubscribeAsync(ChannelId id, ChannelBellInfo bellInfo = ChannelBellInfo.NotifyAndDownload)
|
|||
|
{
|
|||
|
await Task.CompletedTask;
|
|||
|
}
|
|||
|
|
|||
|
public async Task SubscribeAsync(UserName name, ChannelBellInfo info = ChannelBellInfo.NotifyAndDownload)
|
|||
|
{
|
|||
|
await Task.CompletedTask;
|
|||
|
}
|
|||
|
|
|||
|
public async Task UnsubscribeAsync(ChannelId id)
|
|||
|
{
|
|||
|
await Task.CompletedTask;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public sealed class IMAPDownloader
|
|||
|
{
|
|||
|
IDownloader downloader;
|
|||
|
string imapServer;
|
|||
|
int imapPort;
|
|||
|
bool ssl;
|
|||
|
string username;
|
|||
|
string password;
|
|||
|
string[] folders;
|
|||
|
public IMAPDownloader(IDownloader downloader,string imapServer,int imapPort,bool ssl,string username,string password,params string[] folders)
|
|||
|
{
|
|||
|
this.downloader=downloader;
|
|||
|
this.imapServer =imapServer;
|
|||
|
this.imapPort = imapPort;
|
|||
|
this.ssl = ssl;
|
|||
|
this.username = username;
|
|||
|
this.password = password;
|
|||
|
this.folders = folders;
|
|||
|
}
|
|||
|
|
|||
|
public void Scan()
|
|||
|
{
|
|||
|
using (var client = new ImapClient())
|
|||
|
{
|
|||
|
client.Connect(imapServer, imapPort,ssl);
|
|||
|
client.Authenticate(username,password);
|
|||
|
foreach (var folder_name in folders)
|
|||
|
{
|
|||
|
var folder = client.GetFolder(folder_name);
|
|||
|
folder.Open(FolderAccess.ReadOnly);
|
|||
|
foreach(var item in folder)
|
|||
|
{
|
|||
|
using (var ms = new MemoryStream())
|
|||
|
{
|
|||
|
item.Body.WriteTo(ms);
|
|||
|
ms.Position = 0;
|
|||
|
using (var sr = new StreamReader(ms))
|
|||
|
{
|
|||
|
string line;
|
|||
|
while((line=sr.ReadLine()) != null)
|
|||
|
{
|
|||
|
try
|
|||
|
{
|
|||
|
Task.Run(async () => await downloader.AddItemAsync(line)).Wait();
|
|||
|
}
|
|||
|
catch(Exception ex)
|
|||
|
{
|
|||
|
_ = ex;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
}
|
|||
|
client.Disconnect(true);
|
|||
|
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public async Task ScanAsync(CancellationToken token=default)
|
|||
|
{
|
|||
|
using (var client = new ImapClient())
|
|||
|
{
|
|||
|
await client.ConnectAsync(imapServer, imapPort,ssl,token);
|
|||
|
await client.AuthenticateAsync(username,password,token);
|
|||
|
foreach (var folder_name in folders)
|
|||
|
{
|
|||
|
if(token.IsCancellationRequested) break;
|
|||
|
var folder = await client.GetFolderAsync(folder_name,token);
|
|||
|
await folder.OpenAsync(FolderAccess.ReadOnly,token);
|
|||
|
foreach(var item in folder)
|
|||
|
{
|
|||
|
if(token.IsCancellationRequested) break;
|
|||
|
using (var ms = new MemoryStream())
|
|||
|
{
|
|||
|
item.Body.WriteTo(ms);
|
|||
|
ms.Position = 0;
|
|||
|
using (var sr = new StreamReader(ms))
|
|||
|
{
|
|||
|
string line;
|
|||
|
while((line=await sr.ReadLineAsync()) != null)
|
|||
|
{
|
|||
|
if(token.IsCancellationRequested) break;
|
|||
|
try
|
|||
|
{
|
|||
|
await downloader.AddItemAsync(line);
|
|||
|
}
|
|||
|
catch(Exception ex)
|
|||
|
{
|
|||
|
_ = ex;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
}
|
|||
|
await client.DisconnectAsync(true,token);
|
|||
|
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public void ScanLoop(TimeSpan interval,CancellationToken token=default)
|
|||
|
{
|
|||
|
Thread t = new Thread(async()=>{
|
|||
|
try{
|
|||
|
while(!token.IsCancellationRequested)
|
|||
|
{
|
|||
|
await ScanAsync(token);
|
|||
|
await Task.Delay(interval.Milliseconds,token);
|
|||
|
}
|
|||
|
}catch(Exception ex)
|
|||
|
{
|
|||
|
_=ex;
|
|||
|
}
|
|||
|
});
|
|||
|
t.Start();
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
}
|