236 lines
8.0 KiB
C#
236 lines
8.0 KiB
C#
using HtmlAgilityPack;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.ComponentModel;
|
|
using System.Data;
|
|
using System.Drawing;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using System.Windows.Forms;
|
|
|
|
namespace EHDownloader
|
|
{
|
|
public partial class Form1 : System.Windows.Forms.Form
|
|
{
|
|
string baseFolder;
|
|
string _folder;
|
|
static System.Text.RegularExpressions.Regex _regex_url = new System.Text.RegularExpressions.Regex(@"^https?://e-hentai.org/g/[^/]*/[^/]*/?$",
|
|
System.Text.RegularExpressions.RegexOptions.Compiled);
|
|
static System.Text.RegularExpressions.Regex _ex_regex_url = new System.Text.RegularExpressions.Regex(@"^https?://exhentai.org/g/[^/]*/[^/]*/?$",
|
|
System.Text.RegularExpressions.RegexOptions.Compiled);
|
|
|
|
System.Threading.Thread _clipboardMonitorThread;
|
|
bool _clipboardMonitorThreadWorking = false;
|
|
|
|
DbContext _dbContext;
|
|
|
|
public Form1()
|
|
{
|
|
InitializeComponent();
|
|
|
|
baseFolder = Properties.Settings.Default.BaseFolder;
|
|
resetFolder();
|
|
_dbContext = new DbContext();
|
|
|
|
|
|
_clipboardMonitorThread = new System.Threading.Thread(clipboardMonitorProc);
|
|
_clipboardMonitorThread.SetApartmentState(System.Threading.ApartmentState.STA);
|
|
_clipboardMonitorThread.Start();
|
|
}
|
|
|
|
protected override void OnClosing(CancelEventArgs e)
|
|
{
|
|
base.OnClosing(e);
|
|
_clipboardMonitorThreadWorking = false;
|
|
|
|
}
|
|
|
|
bool isEhUrl(string url)
|
|
{
|
|
return _regex_url.IsMatch(url) || _ex_regex_url.IsMatch(url);
|
|
}
|
|
|
|
|
|
private void clipboardMonitorProc()
|
|
{
|
|
_clipboardMonitorThreadWorking = true;
|
|
string lastText = string.Empty;
|
|
while (!IsDisposed && _clipboardMonitorThreadWorking)
|
|
{
|
|
try
|
|
{
|
|
var clipboardText = Clipboard.GetText();
|
|
if (lastText != clipboardText &&
|
|
!string.IsNullOrWhiteSpace(clipboardText))
|
|
{
|
|
lastText = clipboardText;
|
|
var lines = clipboardText.Split(new[] { "\r\n", "\r", "\n" }, StringSplitOptions.None);
|
|
foreach (var url in lines)
|
|
{
|
|
if (isEhUrl(url))
|
|
{
|
|
BeginInvoke(new Action(() => AddTask(url)));
|
|
}
|
|
}
|
|
}
|
|
System.Threading.Thread.Sleep(1000);
|
|
}
|
|
catch (Exception)
|
|
{
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
private void btn_Add_Click(object sender, EventArgs e)
|
|
{
|
|
if (!string.IsNullOrEmpty(txt_url.Text))
|
|
{
|
|
AddTask(txt_url.Text);
|
|
}
|
|
|
|
// await Book.DownloadBookAsync("https://e-hentai.org/g/1464116/fa326cdb2b/", @"Z:\");
|
|
//await Book.GetBookAsync("https://e-hentai.org/g/1464871/56158ca706/");
|
|
|
|
// await Book.GetBookAsync("https://e-hentai.org/g/1463748/3a40615ef7");
|
|
// Book.GetBook("https://e-hentai.org/g/1411798/ac15344281/");
|
|
|
|
}
|
|
|
|
bool downloading = false;
|
|
// object downloadingLck = new object();
|
|
// System.Threading.Mutex downloadingMutex = new System.Threading.Mutex(true);
|
|
|
|
private async void AddTask(string url)
|
|
{
|
|
if (!isEhUrl(url)) return;
|
|
if (lv_Tasks.Items.ContainsKey(url)) return;
|
|
// if (_dbContext.BookIsExists(url)) return;
|
|
await newTask(url);
|
|
}
|
|
|
|
private async Task newTask(string url)
|
|
{
|
|
BookStates? newBookState = _dbContext.QueryBookState(url);
|
|
if (newBookState.IsCompleted())
|
|
{
|
|
// 已完成
|
|
return;
|
|
}
|
|
Book book = new Book(url, _folder);
|
|
if (!newBookState.HasValue)
|
|
_dbContext.InsertBook(book);
|
|
else
|
|
_dbContext.UpdateBook(book);
|
|
|
|
|
|
ListViewItem lvi = new ListViewItem(url) { Name = url };
|
|
lvi.SubItems.Add("Wait");
|
|
lvi.Text = url;
|
|
lvi.Tag = book;
|
|
|
|
lv_Tasks.Items.Add(lvi);
|
|
await TryStartTask(lvi);
|
|
}
|
|
|
|
private async Task TryStartTask()
|
|
=> await TryStartTask(lv_Tasks.Items[0]);
|
|
|
|
private async Task TryStartTask(ListViewItem lvi)
|
|
{
|
|
if (downloading)
|
|
return;
|
|
try
|
|
{
|
|
downloading = true;
|
|
Book book = (Book)lvi.Tag;
|
|
bool running = true;
|
|
while (running)
|
|
{
|
|
|
|
lvi.SubItems[1].Text = book.State.GetDescription();
|
|
switch (book.State)
|
|
{
|
|
case BookStates.Wait:
|
|
await book.FetchAsync();
|
|
_dbContext.UpdateBook(book);
|
|
break;
|
|
case BookStates.FetchCompleted:
|
|
await book.DownloadBookAsync(new Progress<DownloadProgressInfo>(
|
|
(info) => lvi.SubItems[1].Text = $"下載中 {info.PageNumber}/{info.PageCount}"));
|
|
_dbContext.UpdateBook(book);
|
|
break;
|
|
case BookStates.DownloadCompleted:
|
|
await book.CompressAsync();
|
|
_dbContext.UpdateBook(book);
|
|
goto default;
|
|
case BookStates.Compressed:
|
|
case BookStates.LoadFailed:
|
|
case BookStates.FetchTitleFailed:
|
|
case BookStates.FetchPageSetFailed:
|
|
case BookStates.FetchPageLinkFailed:
|
|
case BookStates.DownloadFinishedButSomePageError:
|
|
default:
|
|
var i = lv_Tasks.Items.IndexOf(lvi) + 1;
|
|
if (i >= lv_Tasks.Items.Count) return;
|
|
lvi = lv_Tasks.Items[i];
|
|
book = (Book)lvi.Tag;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
finally
|
|
{
|
|
downloading = false;
|
|
}
|
|
}
|
|
|
|
private async void Btn_Retry_Click(object sender, EventArgs e)
|
|
{
|
|
if (downloading)
|
|
return;
|
|
for (int i = 0; i < lv_Tasks.Items.Count; i++)
|
|
{
|
|
var lvi = lv_Tasks.Items[i];
|
|
var book = (Book)lvi.Tag;
|
|
switch (book.State)
|
|
{
|
|
case BookStates.Wait:
|
|
case BookStates.FetchCompleted:
|
|
case BookStates.DownloadCompleted:
|
|
case BookStates.Compressed:
|
|
default:
|
|
continue;
|
|
case BookStates.LoadFailed:
|
|
case BookStates.FetchTitleFailed:
|
|
case BookStates.FetchPageSetFailed:
|
|
case BookStates.FetchPageLinkFailed:
|
|
book.State = BookStates.Wait;
|
|
continue;
|
|
case BookStates.DownloadFinishedButSomePageError:
|
|
book.State = BookStates.FetchCompleted;
|
|
continue;
|
|
}
|
|
}
|
|
await TryStartTask();
|
|
}
|
|
|
|
private void setFolder(string folder)
|
|
{
|
|
_folder = folder;
|
|
txt_folder.Text = folder;
|
|
}
|
|
|
|
void resetFolder()
|
|
{
|
|
setFolder(System.IO.Path.Combine(baseFolder, DateTime.Today.ToString("yyMMdd")));
|
|
}
|
|
|
|
private void btn_resetFolder_Click(object sender, EventArgs e)
|
|
{
|
|
resetFolder();
|
|
}
|
|
}
|
|
}
|