Skip to content

Commit

Permalink
9.4.5 支持pixiv动图下载,并自动转换为gif格式;
Browse files Browse the repository at this point in the history
  • Loading branch information
xplusky committed Apr 23, 2020
1 parent 5628b2e commit 0821e49
Show file tree
Hide file tree
Showing 21 changed files with 490 additions and 194 deletions.
171 changes: 120 additions & 51 deletions MoeLoaderP.Core/DownloadItem.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.IO.Compression;
using System.Net;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using ImageMagick;
using Newtonsoft.Json;

namespace MoeLoaderP.Core
{
Expand All @@ -14,7 +18,7 @@ namespace MoeLoaderP.Core
public class DownloadItem : BindingObject
{
public Settings Set { get; set; }
public MoeItem ImageItem { get; set; }
public MoeItem CurrentMoeItem { get; set; }
public dynamic BitImg { get; set; } // bitmap image
public string OriginFileName { get; set; }
public string OriginFileNameWithoutExt { get; set; }
Expand All @@ -27,7 +31,6 @@ public string LocalFileShortNameWithoutExt
}

public string LocalFileFullPath { get; set; }
public string LocalExtraFileFullPath { get; set; }

public event Action<DownloadItem> DownloadStatusChanged;

Expand Down Expand Up @@ -99,7 +102,7 @@ public DownloadItem(Settings set, dynamic bitimg, MoeItem item, int subindex = 0
{
Set = set;
BitImg = bitimg;
ImageItem = item;
CurrentMoeItem = item;
SubIndex = subindex;
OriginFileName = Path.GetFileName(item.DownloadUrlInfo.Url);
OriginFileName = Path.GetFileNameWithoutExtension(item.DownloadUrlInfo.Url);
Expand All @@ -119,13 +122,13 @@ public async Task DownloadFileAsync()
Status = DownloadStatusEnum.Downloading;
for (var i = 0; i < SubItems.Count; i++)
{
if (i < Set.DownladFirstSeveralCount || Set.IsDownladFirstSeveral == false)
if (i < Set.DownloadFirstSeveralCount || Set.IsDownloadFirstSeveral == false)
{
var item = SubItems[i];
await item.DownloadFileAsync();
}

var count = Set.DownladFirstSeveralCount < SubItems.Count ? Set.DownladFirstSeveralCount : SubItems.Count;
var count = Set.DownloadFirstSeveralCount < SubItems.Count ? Set.DownloadFirstSeveralCount : SubItems.Count;
Progress = (i + 1d) / count * 100d;
}
Status = DownloadStatusEnum.Success;
Expand All @@ -138,7 +141,7 @@ public async Task DownloadFileAsync()
var token = CurrentDownloadTaskCts.Token;
try
{
var url = ImageItem.DownloadUrlInfo;
var url = CurrentMoeItem.DownloadUrlInfo;
if (url == null)
{
Status = DownloadStatusEnum.Failed;
Expand All @@ -161,16 +164,12 @@ public async Task DownloadFileAsync()

}

var net = ImageItem.Net == null ? new NetDocker(Set) : ImageItem.Net.CloneWithOldCookie();
if (!string.IsNullOrWhiteSpace(url.Referer)) net.SetReferer(url.Referer);
var net = CurrentMoeItem.Net == null ? new NetDocker(Set) : CurrentMoeItem.Net.CloneWithOldCookie();
if (!url.Referer.IsNaN()) net.SetReferer(url.Referer);
net.ProgressMessageHandler.HttpReceiveProgress += (sender, args) =>
{
Progress = args.ProgressPercentage;
StatusText = $"正在下载:{Progress}%";
if (Progress >= 100)
{
StatusText = "下载完成";
}
};
net.SetTimeOut(500);

Expand All @@ -183,20 +182,49 @@ public async Task DownloadFileAsync()
Status = DownloadStatusEnum.Downloading;
var data = await net.Client.GetAsync(url.Url, token);
var bytes = await data.Content.ReadAsByteArrayAsync();

var dir = Path.GetDirectoryName(LocalFileFullPath);
if (!Directory.Exists(dir)) Directory.CreateDirectory(dir ?? throw new InvalidOperationException());
using (var fs = new FileStream(LocalFileFullPath, FileMode.Create))
{
await fs.WriteAsync(bytes, 0, bytes.Length, token);

}

if (ImageItem.ExtraFile != null)
if (CurrentMoeItem.ExtraFile != null)
{
File.WriteAllText(LocalExtraFileFullPath, ImageItem.ExtraFile.Content);
var path = Path.ChangeExtension(LocalFileFullPath, CurrentMoeItem.ExtraFile.FileExt) ?? $"{LocalFileFullPath}.{CurrentMoeItem.ExtraFile.FileExt}";
File.WriteAllText(path, CurrentMoeItem.ExtraFile.Content);
}

if (url.IsPixivGifZip && CurrentMoeItem.ExtraFile!=null)
{
dynamic json = JsonConvert.DeserializeObject(CurrentMoeItem.ExtraFile.Content);
var list = json.body.frames;
var gifpath = Path.ChangeExtension(LocalFileFullPath, "gif");
if (gifpath != null)
{
var fi = new FileInfo(gifpath);
try
{
StatusText = "正在转换为GIF格式...";
using (var stream = await data.Content.ReadAsStreamAsync())
{
await Task.Run(() =>
{
ConvertPixivZipToGif(stream, list, fi);
}, token);
}
}
catch (Exception e)
{
Extend.Log(e);
}
}
}
data.Dispose();
Progress = 100;
StatusText = "下载完成";
Extend.Log($"{url.Url} download ok");
Status = DownloadStatusEnum.Success;
}
Expand All @@ -209,6 +237,39 @@ public async Task DownloadFileAsync()
}
}

public void ConvertPixivZipToGif(Stream stream,dynamic frames,FileInfo fi)
{
var delayList= new List<int>();
using (var images = new MagickImageCollection())
{
foreach (var frame in frames)
{
delayList.Add($"{frame.delay}".ToInt());
}
using (var zip = new ZipArchive(stream, ZipArchiveMode.Read))
{
for (var i = 0; i < zip.Entries.Count; i++)
{
var ms = new MemoryStream();
using (var aStream = zip.Entries[i].Open())
{
aStream.CopyTo(ms);
ms.Position = 0L;
}
var img = new MagickImage(ms);
img.AnimationDelay = delayList[i] / 10;
images.Add(img);
ms.Dispose();
}
}
var set = new QuantizeSettings();
set.Colors = 256;
images.Quantize(set);
images.Optimize();
images.Write(fi, MagickFormat.Gif);
}
}

private string _statusText;
public string StatusText
{
Expand All @@ -218,50 +279,58 @@ public string StatusText

public void GenLocalFileFullPath(MoeItem father = null)
{
var img = father ?? ImageItem;
var sub = (Set.IsSortFolderByKeyword && !string.IsNullOrWhiteSpace(img.Para.Keyword))
? $"{img.Para.Keyword}\\" : "";
LocalFileFullPath = Path.Combine(Set.ImageSavePath, img.Site.ShortName, $"{sub}{LocalFileShortNameWithoutExt}.{img.FileType?.ToLower()}");
if (img.ExtraFile != null)
var img = father ?? CurrentMoeItem;
var format = Set.SortFolderNameFormat;
var sub = format.IsNaN() ? $"{img.Site.ShortName}" : FormatText(format, img, true);

LocalFileFullPath = Path.Combine(Set.ImageSavePath, sub, $"{LocalFileShortNameWithoutExt}.{img.FileType?.ToLower()}");
}

public void GenFileNameWithoutExt(MoeItem father = null)
{
var img = father ?? CurrentMoeItem;

var format = Set.SaveFileNameFormat;
if (format.IsNaN())
{
LocalExtraFileFullPath = Path.Combine(Set.ImageSavePath, img.Site.ShortName, $"{sub}{LocalFileShortNameWithoutExt}.{img.ExtraFile.FileExt}");
LocalFileShortNameWithoutExt = $"{img.Site.ShortName} {img.Id}";
return;
}

var sb = FormatText(format, img);

LocalFileShortNameWithoutExt = SubIndex > 0 ? $"{sb} p{SubIndex}" : $"{sb}";
}
public void GenFileNameWithoutExt(MoeItem father = null)

public string FormatText(string format,MoeItem img,bool isFolder=false)
{
var img = father ?? ImageItem;
if (Set.IsUseCustomFileNameFormat)
var sb = new StringBuilder(format);
sb.Replace("%site", img.Site.ShortName);
sb.Replace("%id", $"{img.Id}");
sb.Replace("%keyword", img.Para.Keyword.IsNaN() ? "no-keyword" : img.Para.Keyword);
var tags = string.Empty;
var i = 0;
foreach (var tag in img.Tags)
{
var format = Set.SaveFileNameFormat;

var sb = new StringBuilder(format);
sb.Replace("%site", img.Site.DisplayName);
sb.Replace("%id", $"{img.Id}");
var tags = string.Empty;
var i = 0;
foreach (var tag in img.Tags)
{
if (i > 15) break;
tags += $"{tag} ";
i++;
}
sb.Replace("%tag", $"{tags}");
sb.Replace("%title", img.Title ?? "no-title");
sb.Replace("%uploader", img.Uploader ?? "no-uploader");
sb.Replace("%date", img.DateString ?? "no-date");
sb.Replace("%origin", OriginFileNameWithoutExt);
sb.Replace("%character", img.Character ?? "no-character");
sb.Replace("%artist", img.Artist ?? "no-artist");
sb.Replace("%copyright", img.Copyright ?? "no-copyright");
foreach (var c in Path.GetInvalidFileNameChars()) sb.Replace($"{c}", "");

LocalFileShortNameWithoutExt = SubIndex > 0 ? $"{sb} item-{SubIndex}" : $"{sb}";
if (i > 15) break;
tags += $"{tag} ";
i++;
}
else
sb.Replace("%tag", $"{tags}");
sb.Replace("%title", img.Title ?? "no-title");
sb.Replace("%uploader", img.Uploader ?? "no-uploader");
sb.Replace("%date", img.DateString ?? "no-date");
sb.Replace("%origin", OriginFileNameWithoutExt);
sb.Replace("%character", img.Character ?? "no-character");
sb.Replace("%artist", img.Artist ?? "no-artist");
sb.Replace("%copyright", img.Copyright ?? "no-copyright");
foreach (var c in Path.GetInvalidFileNameChars())
{
LocalFileShortNameWithoutExt = $"{img.Site.ShortName} {img.Id}";
LocalFileShortNameWithoutExt = SubIndex > 0 ? $"{img.Site.ShortName} {img.Id} p{SubIndex}" : $"{img.Site.ShortName} {img.Id}";
if(c == '\\' && isFolder) continue;
sb.Replace($"{c}", "");
}

return sb.ToString();
}


Expand Down
22 changes: 19 additions & 3 deletions MoeLoaderP.Core/MoeItem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,16 @@ public string DateString
public double Score { get; set; }
public int Rank { get; set; }
public bool TipHighLight { get; set; }
public string Tip { get; set; }

public string Tip
{
get => _tip;
set
{
_tip = value; OnPropertyChanged(nameof(Tip));
}
}

public string Source { get; set; }
public string Description { get; set; }
public List<string> Tags { get; set; } = new List<string>();
Expand Down Expand Up @@ -102,6 +111,7 @@ public string ResolutionText

private int _imageCount;
private string _dateString;
private string _tip;

public int ImagesCount
{
Expand Down Expand Up @@ -177,6 +187,7 @@ public class UrlInfo
public string Md5 { get; set; }
public string Referer { get; set; }
public ulong BiteSize { get; set; }
public bool IsPixivGifZip { get; set; }

public UrlInfo(int priority, string url, string referer = null)
{
Expand Down Expand Up @@ -232,9 +243,14 @@ public UrlInfo GetMin()
return info;
}

public void Add(int p, string url, string referer=null)
public void Add(int p, string url, string referer=null,bool ispixivgif = false)
{
Add(new UrlInfo(p,url,referer));
var urlinfo = new UrlInfo(p, url, referer);
if (ispixivgif)
{
urlinfo.IsPixivGifZip = true;
}
Add(urlinfo);
}
}
}
1 change: 1 addition & 0 deletions MoeLoaderP.Core/MoeLoaderP.Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

<ItemGroup>
<PackageReference Include="HtmlAgilityPack" Version="1.11.23" />
<PackageReference Include="Magick.NET-Q16-AnyCPU" Version="7.16.0" />
<PackageReference Include="Microsoft.AspNet.WebApi.Client" Version="5.2.7" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
</ItemGroup>
Expand Down
8 changes: 4 additions & 4 deletions MoeLoaderP.Core/NetDocker.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Handlers;
Expand Down Expand Up @@ -83,10 +82,11 @@ public IWebProxy Proxy
try
{
var strs = Settings.ProxySetting.Split(':');
var port = int.Parse(strs[1]);
var port = strs[1].ToInt();
if (port == 0) return WebRequest.DefaultWebProxy;
var address = IPAddress.Parse(strs[0]);
var porxy = new WebProxy(address.ToString(), port);
return porxy;
var proxy = new WebProxy(address.ToString(), port);
return proxy;
}
catch (Exception e)
{
Expand Down
Loading

0 comments on commit 0821e49

Please sign in to comment.