Files
MegghysAPI/Modules/PixivFavoriteDownloader.cs
2025-02-26 08:07:32 +08:00

247 lines
11 KiB
C#

using System.Text.Json.Nodes;
using System.Web;
using FreeSql.DataAnnotations;
using MegghysAPI.Attributes;
using static MegghysAPI.Modules.PixivFavoriteDownloader.Pixiv;
namespace MegghysAPI.Modules
{
public static class PixivFavoriteDownloader
{
[AutoInit(Async = true)]
public static void Init()
{
Favorites = DB.SQL.Select<PixivImgInfo>().ToList();
Favorites.ForEach(f =>
{
f.S3URL = f.URL.Select(u => new PixivURLInfo()
{
Origin = $"http://eternalland.top:9000/{Config.Instance.MinIOBucket}{FileManager.FavoritePath}{f.Id}_{f.URL.IndexOf(u)}.{u.Extension}",
Large = $"http://194.104.147.128:880/{u.Large?.Replace("i.pixiv.re", "i.pximg.net")}?referer=https://www.pixiv.net/",
Medium = $"http://194.104.147.128:880/{u.Medium?.Replace("i.pixiv.re", "i.pximg.net")}?referer=https://www.pixiv.net/",
Small = $"http://194.104.147.128:880/{u.Small?.Replace("i.pixiv.re", "i.pximg.net")}?referer=https://www.pixiv.net/",
}).ToList();
});
Logs.Success($"Pixiv 收藏图片总数: {Favorites.Count}");
}
public static readonly string PIXIV_FAVORITE_URL = Datas.HIBI_URL + "api/pixiv/favorite?id=19045447";
public const string PixivFavoritePath = "/files/favorite/";
public static List<PixivImgInfo> Favorites = [];
[AutoTimer(Time = 5 * 60, CallOnRegister = true)]
public static void UpdateMyFavorite()
{
Logs.Info("正在更新收藏图片");
var url = PIXIV_FAVORITE_URL;
var num = 0;
while (num < 5)
{
try
{
var result = Utils.RequestString(url);
var json = JsonNode.Parse(result);
if (json is null)
return;
json["illusts"]?.AsArray().ForEach(i =>
{
if (!Favorites.Any(f => f.Id == (long)i["id"]))
{
var img = new PixivImgInfo(i, PixivImgType.Favorite);
Favorites.Add(img);
DB.SQL.InsertOrUpdate<PixivImgInfo>()
.SetSource(img)
.ExecuteAffrows();
Logs.Success($"[{Favorites.Count}] 发现新增收藏: {Favorites.Last().Title}, 类型: {Favorites.Last().Restrict}");
}
});
var next = (string)json["next_url"];
if (next is null)
break;
var list = next.Split("max_bookmark_id=", StringSplitOptions.RemoveEmptyEntries);
if (list.Length != 0)
url = PIXIV_FAVORITE_URL + $"&max_bookmark_id={list[1]}";
else
break;
}
catch (Exception ex)
{
Logs.Error(ex);
num++;
}
}
Logs.Success($"收藏图片更新完成. 当前共 {Favorites.Count} 个");
}
static bool uploading = false;
[AutoTimer(Time = 60 * 5, CallOnRegister = true)]
public static async Task DownloadFavoriteToBucket()
{
if (uploading)
{
Logs.Info($"正在下载收藏, 忽略");
return;
}
uploading = true;
var files = await FileManager.ListFilesAsync(FileManager.FavoritePath, true);
if (files is null)
return;
Logs.Info($"FTP 总收藏数: {files.Length}");
int num = 0;
for (int i = 0; i < Favorites.Count; i++)
{
var s = Favorites[i];
try
{
num = 0;
foreach (var u in s?.URL)
{
var url = u.Origin.Replace("i.pixiv.re", "i.pximg.net");
url = $"http://194.104.147.128:880/{url}?referer=https://www.pixiv.net/";
var fileName = $"{s.Id}_{num}.{u.Extension}";
if (!files.Any(f => f.Name == fileName))
{
var data = await Utils.DownloadBytesAsync(url);
if (data.code == System.Net.HttpStatusCode.OK)
{
using var stream = new MemoryStream(data.data);
if (await FileManager.UploadStreamAsync(stream, FileManager.FavoritePath + fileName))
Logs.Success($"已上传收藏图片 {s.Title}({s.Id})[{num + 1}-{s.URL.Count}]:{Favorites.IndexOf(s)} 至储存空间 [{(double)data.data.Length / 1024 / 1024:0.00} Mb].");
else
Logs.Warn($"{s.Title} 上传失败");
}
num++;
}
}
}
catch (Exception ex) { Logs.Error(ex); }
}
uploading = false;
}
public enum PixivImgType
{
None,
Setu,
Favorite
}
public partial class Pixiv
{
public class PixivImgInfo
{
public PixivImgInfo() { Type = PixivImgType.None; }
public PixivImgInfo(PixivImgType t) { Type = t; }
public PixivImgInfo(JsonNode node, PixivImgType t)
{
Type = t;
ArgumentNullException.ThrowIfNull(node);
var tag = new List<PixivTagInfo>();
node["tags"].AsArray().ForEach(t => tag.Add(new((string)t["name"], (string)t["translated_name"])));
Id = (long)node["id"];
Author = new()
{
UID = ((long)node["user"]["id"]).ToString(),
Name = (string)node["user"]["name"],
Account = (string)node["user"]["account"],
HeadURL = (string)node["user"]["profile_image_urls"]["medium"]
};
Title = (string)node["title"];
Restrict = (PixivRestrictInfo)(int)node["x_restrict"];
Description = (string)node["caption"];
Tags = tag;
var url = new List<PixivURLInfo>();
if ((int)node["page_count"] == 1)
url.Add(new() { Origin = ((string)node["meta_single_page"]["original_image_url"]).Replace("i.pximg.net", "i.pixiv.cat") });
else
node["meta_pages"].AsArray().ForEach(p =>
{
var imgs = p["image_urls"];
url.Add(new()
{
Origin = ((string)imgs["original"] ?? "")
.Replace("i.pximg.net", "i.pixiv.re"),
Large = ((string)imgs["large"] ?? "")
.Replace("i.pximg.net", "i.pixiv.re"),
Medium = ((string)imgs["medium"] ?? "")
.Replace("i.pximg.net", "i.pixiv.re"),
Small = ((string)imgs["square_medium"] ?? "")
.Replace("i.pximg.net", "i.pixiv.re")
});
});
URL = url;
Width = (int)node["width"];
Height = (int)node["height"];
UploadDate = DateTime.TryParse((string)node["create_date"], out var date) ? date.Ticks : 0;
ViewCount = (long)node["total_view"];
FavoriteCount = (long)node["total_bookmarks"];
}
public long Id { get; set; }
public PixivImgType Type { get; set; }
public string Title { get; set; }
[JsonMap]
public PixivRestrictInfo Restrict { get; set; }
[Column(DbType = "text")]
public string Description { get; set; }
[JsonMap]
public PixivAuthorInfo Author { get; set; }
public bool R18 => Restrict != PixivRestrictInfo.Normal;
[JsonMap]
public List<PixivTagInfo> Tags { get; set; } = [];
[JsonMap]
public List<PixivURLInfo> URL { get; set; } = [];
[JsonMap]
public List<PixivURLInfo> S3URL { get; set; } = [];
public int Width { get; set; }
public int Height { get; set; }
public long UploadDate { set; get; }
public long ViewCount { get; set; }
public long FavoriteCount { get; set; }
}
public enum PixivRestrictInfo
{
Normal,
R18,
R18G
}
public record PixivAuthorInfo
{
public string Name { get; set; }
public string UID { get; set; }
public string Account { get; set; }
public string HeadURL { get; set; }
}
public record PixivURLInfo
{
public override string ToString()
{
return Origin;
}
public string Extension => Path.GetExtension(HttpUtility.UrlDecode(new Uri(Origin).Segments.Last()))?.Replace(".", "");
public string Name => HttpUtility.UrlDecode(new Uri(Origin).Segments.Last()) is { } url ? $"{url}" : "";
public string Origin { get; set; }
public string Large { get; set; }
public string Medium { get; set; }
public string Small { get; set; }
}
public record PixivTagInfo
{
public override string ToString() => $"{Name} {(TranslateName is null ? "" : $"<{TranslateName}>")}";
public PixivTagInfo(string name, string translateName)
{
Name = name;
TranslateName = translateName;
}
public bool Contains(string tag)
{
return Name.ToLower().Contains(tag.ToLower()) || (TranslateName != null && TranslateName.ToLower().Contains(tag.ToLower()));
}
public string Name { get; set; }
public string TranslateName { get; set; }
}
}
}
}