864 lines
30 KiB
C#
864 lines
30 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Net;
|
|
using System.Net.Http;
|
|
using System.Text;
|
|
using System.Text.RegularExpressions;
|
|
using System.Threading.Tasks;
|
|
using Newtonsoft.Json;
|
|
using Gallery.Illust;
|
|
using Xamarin.Essentials;
|
|
using Xamarin.Forms;
|
|
|
|
namespace Gallery.Utils
|
|
{
|
|
public static class Stores
|
|
{
|
|
public static readonly string PersonalFolder = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
|
|
public static readonly string CacheFolder = FileSystem.CacheDirectory;
|
|
|
|
private const string favoriteFile = "favorites.json";
|
|
private const string globalFile = "global.json";
|
|
private const string imageFolder = "img-original";
|
|
private const string previewFolder = "img-master";
|
|
private const string ugoiraFolder = "img-zip-ugoira";
|
|
private const string illustFile = "illust.json";
|
|
|
|
private const string pagesFolder = "pages";
|
|
private const string preloadsFolder = "preloads";
|
|
private const string thumbFolder = "img-thumb";
|
|
private const string userFolder = "user-profile";
|
|
//private const string recommendsFolder = "recommends";
|
|
|
|
public static bool NetworkAvailable
|
|
{
|
|
get
|
|
{
|
|
try
|
|
{
|
|
return Connectivity.NetworkAccess == Xamarin.Essentials.NetworkAccess.Internet;
|
|
}
|
|
catch
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
public static FavoriteList Favorites => GetFavoriteObject().Illusts;
|
|
public static string FavoritesPath => Path.Combine(PersonalFolder, favoriteFile);
|
|
public static DateTime FavoritesLastUpdated { get; set; } = DateTime.Now;
|
|
|
|
private static IllustFavorite favoriteObject;
|
|
|
|
public static IllustFavorite GetFavoriteObject(bool force = false)
|
|
{
|
|
if (force || favoriteObject == null)
|
|
{
|
|
var favorites = LoadFavoritesIllusts();
|
|
if (favorites != null)
|
|
{
|
|
favoriteObject = favorites;
|
|
}
|
|
else
|
|
{
|
|
favoriteObject = new IllustFavorite
|
|
{
|
|
Illusts = new FavoriteList()
|
|
};
|
|
}
|
|
}
|
|
return favoriteObject;
|
|
}
|
|
|
|
public static IllustFavorite LoadFavoritesIllusts(string file = null)
|
|
{
|
|
if (file == null)
|
|
{
|
|
file = FavoritesPath;
|
|
}
|
|
return ReadObject<IllustFavorite>(file);
|
|
}
|
|
|
|
public static void SaveFavoritesIllusts()
|
|
{
|
|
var file = FavoritesPath;
|
|
var data = GetFavoriteObject();
|
|
data.LastFavoriteUtc = DateTime.UtcNow;
|
|
WriteObject(file, data);
|
|
}
|
|
|
|
public static string LoadUgoiraImage(string zip, string frame)
|
|
{
|
|
var file = Path.Combine(PersonalFolder, ugoiraFolder, zip, frame);
|
|
if (File.Exists(file))
|
|
{
|
|
return file;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public static string SaveUgoiraImage(string zip, string frame, byte[] data)
|
|
{
|
|
try
|
|
{
|
|
var directory = Path.Combine(PersonalFolder, ugoiraFolder, zip);
|
|
if (!Directory.Exists(directory))
|
|
{
|
|
Directory.CreateDirectory(directory);
|
|
}
|
|
|
|
var file = Path.Combine(directory, frame);
|
|
File.WriteAllBytes(file, data);
|
|
return file;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
App.DebugError("save.ugoira", $"failed to save ugoira frame: {zip}/{frame}, error: {ex.Message}");
|
|
return null;
|
|
}
|
|
}
|
|
|
|
public static string GetUgoiraPath(string url, string ext)
|
|
{
|
|
return Path.Combine(PersonalFolder, ugoiraFolder, Path.GetFileNameWithoutExtension(url) + ext);
|
|
}
|
|
|
|
private static T ReadObject<T>(string file)
|
|
{
|
|
string content = null;
|
|
if (File.Exists(file))
|
|
{
|
|
try
|
|
{
|
|
content = File.ReadAllText(file);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
App.DebugError("read", $"failed to read file: {file}, error: {ex.Message}");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//App.DebugError("read", $"file not found: {file}");
|
|
return default;
|
|
}
|
|
try
|
|
{
|
|
return JsonConvert.DeserializeObject<T>(content);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
App.DebugError("read", $"failed to parse illust JSON object, error: {ex.Message}");
|
|
return default;
|
|
}
|
|
}
|
|
|
|
private static void WriteObject(string file, object obj)
|
|
{
|
|
var dir = Path.GetDirectoryName(file);
|
|
if (!Directory.Exists(dir))
|
|
{
|
|
Directory.CreateDirectory(dir);
|
|
}
|
|
string content;
|
|
try
|
|
{
|
|
content = JsonConvert.SerializeObject(obj, Formatting.None);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
App.DebugError("write", $"failed to serialize object, error: {ex.Message}");
|
|
return;
|
|
}
|
|
|
|
try
|
|
{
|
|
File.WriteAllText(file, content, Encoding.UTF8);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
App.DebugError("write", $"failed to write file: {file}, error: {ex.Message}");
|
|
}
|
|
}
|
|
|
|
public static IllustData LoadIllustData(bool force = false)
|
|
{
|
|
var file = Path.Combine(PersonalFolder, illustFile);
|
|
var result = HttpUtility.LoadObject<IllustData>(
|
|
file,
|
|
Configs.UrlIllustList,
|
|
Configs.Referer,
|
|
out _,
|
|
force: force);
|
|
if (result == null || result.error)
|
|
{
|
|
App.DebugPrint($"error when load illust data: {result?.message}, force({force})");
|
|
}
|
|
return result;
|
|
}
|
|
|
|
public static IllustRankingData LoadIllustRankingData(string mode, string date, int page, out string error, bool force = false)
|
|
{
|
|
var file = Path.Combine(CacheFolder, mode, $"{date}_{page}.json");
|
|
string query = $"mode={mode}";
|
|
if (mode != "male" && mode != "male_r18")
|
|
{
|
|
query += "&content=illust";
|
|
}
|
|
if (date != null)
|
|
{
|
|
query += $"&date={date}";
|
|
}
|
|
var referer = string.Format(Configs.RefererIllustRanking, query);
|
|
if (page > 1)
|
|
{
|
|
query += $"&p={page}";
|
|
}
|
|
query += "&format=json";
|
|
var result = HttpUtility.LoadObject<IllustRankingData>(
|
|
file,
|
|
string.Format(Configs.UrlIllustRanking, query),
|
|
referer,
|
|
out error,
|
|
namehandler: rst =>
|
|
{
|
|
return Path.Combine(CacheFolder, mode, $"{rst.date}_{page}.json");
|
|
},
|
|
header: headers =>
|
|
{
|
|
headers.Add("X-Requested-With", "XMLHttpRequest");
|
|
},
|
|
force: force);
|
|
if (result == null)
|
|
{
|
|
App.DebugPrint($"error when load ranking data: mode({mode}), date({date}), page({page}), force({force})");
|
|
}
|
|
return result;
|
|
}
|
|
|
|
public static IllustRecommendsData LoadIllustRecommendsInitData(string id)
|
|
{
|
|
//var file = Path.Combine(CacheFolder, recommendsFolder, $"{id}.json");
|
|
var result = HttpUtility.LoadObject<IllustRecommendsData>(
|
|
null,
|
|
string.Format(Configs.UrlIllustRecommendsInit, id),
|
|
string.Format(Configs.RefererIllust, id),
|
|
out _);
|
|
if (result == null || result.error)
|
|
{
|
|
App.DebugPrint($"error when load recommends init data: {result?.message}");
|
|
}
|
|
return result;
|
|
}
|
|
|
|
public static IllustRecommendsData LoadIllustRecommendsListData(string id, string[] ids)
|
|
{
|
|
if (ids == null || ids.Length == 0)
|
|
{
|
|
return null;
|
|
}
|
|
var ps = string.Concat(ids.Select(i => $"illust_ids%5B%5D={i}&"));
|
|
var result = HttpUtility.LoadObject<IllustRecommendsData>(
|
|
null,
|
|
string.Format(Configs.UrlIllustRecommendsList, ps),
|
|
string.Format(Configs.RefererIllust, id),
|
|
out _);
|
|
if (result == null || result.error)
|
|
{
|
|
App.DebugPrint($"error when load recommends list data: {result?.message}");
|
|
}
|
|
return result;
|
|
}
|
|
|
|
public static IllustGlobalData LoadGlobalData(bool force = false)
|
|
{
|
|
var file = Path.Combine(PersonalFolder, globalFile);
|
|
var result = HttpUtility.LoadObject<IllustGlobalData>(
|
|
file,
|
|
Configs.Prefix,
|
|
null,
|
|
out _,
|
|
force: force,
|
|
header: h => { },
|
|
action: content =>
|
|
{
|
|
var index = content.IndexOf(Configs.SuffixGlobal);
|
|
if (index > 0)
|
|
{
|
|
index += Configs.SuffixGlobalLength;
|
|
var end = content.IndexOf('\'', index);
|
|
if (end > index)
|
|
{
|
|
content = content.Substring(index, end - index);
|
|
}
|
|
}
|
|
return content;
|
|
});
|
|
if (result == null)
|
|
{
|
|
App.DebugPrint($"error when load global data, is null");
|
|
}
|
|
else
|
|
{
|
|
#if LOG
|
|
App.DebugPrint($"current csrf token: {result.token}");
|
|
#endif
|
|
Configs.CsrfToken = result.token;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
public static string AddBookmark(string id)
|
|
{
|
|
if (string.IsNullOrEmpty(Configs.CsrfToken))
|
|
{
|
|
return null;
|
|
}
|
|
var content = new StringContent(
|
|
"{\"illust_id\":\"" + id + "\",\"restrict\":0,\"comment\":\"\",\"tags\":[]}",
|
|
Encoding.UTF8,
|
|
Configs.AcceptJson);
|
|
var result = HttpUtility.LoadObject<IllustResponse<BookmarkResultData>>(
|
|
null,
|
|
Configs.BookmarkAdd,
|
|
Configs.Referer,
|
|
out string error,
|
|
force: true,
|
|
post: content);
|
|
if (error != null)
|
|
{
|
|
App.DebugPrint($"failed to add bookmark, error: {error}");
|
|
}
|
|
else if (result == null || result.error || result.body == null)
|
|
{
|
|
App.DebugPrint($"failed to add bookmark, message: {result?.message}");
|
|
}
|
|
else
|
|
{
|
|
#if LOG
|
|
App.DebugPrint($"successs, bookmark id: {result.body.last_bookmark_id}, status: {result.body.stacc_status_id}");
|
|
#endif
|
|
return result.body.last_bookmark_id;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public static bool DeleteBookmark(string id)
|
|
{
|
|
if (string.IsNullOrEmpty(Configs.CsrfToken))
|
|
{
|
|
return false;
|
|
}
|
|
var content = new StringContent(
|
|
"mode=delete_illust_bookmark&bookmark_id=" + id,
|
|
Encoding.UTF8,
|
|
Configs.AcceptUrlEncoded);
|
|
var result = HttpUtility.LoadObject<object>(
|
|
null,
|
|
Configs.BookmarkRpc,
|
|
Configs.Referer,
|
|
out string error,
|
|
force: true,
|
|
nojson: true,
|
|
post: content);
|
|
if (error != null)
|
|
{
|
|
App.DebugPrint($"failed to delete bookmark, error: {error}");
|
|
return false;
|
|
}
|
|
else if (result == null)
|
|
{
|
|
App.DebugPrint("failed to delete bookmark, result is null");
|
|
return false;
|
|
}
|
|
#if LOG
|
|
App.DebugPrint($"successs, delete bookmark");
|
|
#endif
|
|
return true;
|
|
}
|
|
|
|
public static IllustPreloadBody LoadIllustPreloadData(string id, bool downloading, bool force = false)
|
|
{
|
|
var file = Path.Combine(CacheFolder, preloadsFolder, $"{id}.json");
|
|
IllustPreloadBody result;
|
|
if (!force)
|
|
{
|
|
result = ReadObject<IllustPreloadBody>(file);
|
|
if (result != null)
|
|
{
|
|
return result;
|
|
}
|
|
else if (!downloading)
|
|
{
|
|
return null;
|
|
}
|
|
}
|
|
if (downloading)
|
|
{
|
|
result = HttpUtility.LoadObject<IllustPreloadBody>(
|
|
file,
|
|
string.Format(Configs.UrlIllust, id),
|
|
null,
|
|
out _,
|
|
force: force,
|
|
action: content =>
|
|
{
|
|
var index = content.IndexOf(Configs.SuffixPreload);
|
|
if (index > 0)
|
|
{
|
|
index += Configs.SuffixPreloadLength;
|
|
var end = content.IndexOf('\'', index);
|
|
if (end > index)
|
|
{
|
|
content = content.Substring(index, end - index);
|
|
}
|
|
}
|
|
return content;
|
|
});
|
|
}
|
|
else
|
|
{
|
|
result = null;
|
|
}
|
|
if (result == null)
|
|
{
|
|
App.DebugPrint($"error when load preload data: force({force})");
|
|
}
|
|
return result;
|
|
}
|
|
|
|
public static IllustPageData LoadIllustPageData(string id, out string error, bool force = false)
|
|
{
|
|
var file = Path.Combine(CacheFolder, pagesFolder, $"{id}.json");
|
|
var result = HttpUtility.LoadObject<IllustPageData>(
|
|
file,
|
|
string.Format(Configs.UrlIllustPage, id),
|
|
string.Format(Configs.RefererIllust, id),
|
|
out _,
|
|
force: force);
|
|
if (result == null || result.error)
|
|
{
|
|
error = result?.message ?? "result is null";
|
|
App.DebugPrint($"error when load page data: {error}, force({force})");
|
|
return null;
|
|
}
|
|
error = null;
|
|
return result;
|
|
}
|
|
|
|
public static IllustUgoiraData LoadIllustUgoiraData(string id, bool force = false)
|
|
{
|
|
var file = Path.Combine(PersonalFolder, ugoiraFolder, $"{id}.json");
|
|
var result = HttpUtility.LoadObject<IllustUgoiraData>(
|
|
file,
|
|
string.Format(Configs.UrlIllustUgoira, id),
|
|
string.Format(Configs.RefererIllust, id),
|
|
out _,
|
|
force: force);
|
|
if (result == null || result.error)
|
|
{
|
|
App.DebugPrint($"error when load ugoira data: {result?.message}, force({force})");
|
|
}
|
|
return result;
|
|
}
|
|
|
|
public static IllustUserListData LoadIllustUserInitData(string userId)
|
|
{
|
|
var list = HttpUtility.LoadObject<IllustUserListData>(
|
|
null,
|
|
string.Format(Configs.UrlIllustUserAll, userId),
|
|
string.Format(Configs.RefererIllustUser, userId),
|
|
out _);
|
|
if (list == null || list.error)
|
|
{
|
|
App.DebugPrint($"error when load user data: {list?.message}");
|
|
}
|
|
return list;
|
|
}
|
|
|
|
public static IllustUserData LoadIllustUserData(string userId, string[] ids, bool firstPage)
|
|
{
|
|
if (ids == null || ids.Length == 0)
|
|
{
|
|
return null;
|
|
}
|
|
var ps = string.Concat(ids.Select(i => $"ids%5B%5D={i}&"));
|
|
var result = HttpUtility.LoadObject<IllustUserData>(
|
|
null,
|
|
string.Format(Configs.UrlIllustUserArtworks, userId, ps, firstPage ? 1 : 0),
|
|
string.Format(Configs.RefererIllustUser, userId),
|
|
out _);
|
|
if (result == null || result.error)
|
|
{
|
|
App.DebugPrint($"error when load user illust data: {result?.message}");
|
|
}
|
|
return result;
|
|
}
|
|
|
|
//private static readonly Regex regexIllust = new Regex(
|
|
// @"book_id\[\]"" value=""([0-9]+)"".*data-src=""([^""]+)"".*data-id=""([0-9]+)"".*" +
|
|
// @"data-tags=""([^""]+)"".*data-user-id=""([0-9]+)"".*" +
|
|
// @"class=""title"" title=""([^""]+)"".*data-user_name=""([^""]+)"".*" +
|
|
// @"_bookmark-icon-inline""></i>([0-9]+)</a>",
|
|
// RegexOptions.Compiled);
|
|
|
|
public static IllustItem[] LoadOnlineFavorites()
|
|
{
|
|
var userId = Configs.UserId;
|
|
var list = new List<IllustItem>();
|
|
int offset = 0;
|
|
while (offset >= 0)
|
|
{
|
|
var result = HttpUtility.LoadObject<IllustFavoriteData>(
|
|
null,
|
|
string.Format(Configs.UrlFavoriteList, userId, offset, 48),
|
|
string.Format(Configs.RefererFavorites, userId),
|
|
out _);
|
|
if (result == null || result.error)
|
|
{
|
|
App.DebugPrint($"error when load favorites data: {result?.message}");
|
|
}
|
|
else
|
|
{
|
|
if (offset + 48 < result.body.total)
|
|
{
|
|
offset += 48;
|
|
}
|
|
else
|
|
{
|
|
offset = -1;
|
|
}
|
|
list.AddRange(result.body.works.Select(i => i.ConvertToItem()));
|
|
}
|
|
}
|
|
return list.Where(l => l != null).ToArray();
|
|
}
|
|
|
|
public static ImageSource LoadIllustImage(string url)
|
|
{
|
|
return LoadImage(url, PersonalFolder, imageFolder, true);
|
|
}
|
|
|
|
public static ImageSource LoadPreviewImage(string url, bool downloading, string id = null, bool force = false)
|
|
{
|
|
if (downloading && Configs.DownloadIllustThreads > 1)
|
|
{
|
|
return LoadImageAsync(url, id, PersonalFolder, previewFolder, force).Result;
|
|
}
|
|
return LoadImage(url, PersonalFolder, previewFolder, downloading, force);
|
|
}
|
|
|
|
public static ImageSource LoadThumbnailImage(string url, bool downloading, bool force = false)
|
|
{
|
|
return LoadImage(url, CacheFolder, thumbFolder, downloading, force);
|
|
}
|
|
|
|
public static ImageSource LoadUserProfileImage(string url, bool downloading, bool force = false)
|
|
{
|
|
return LoadImage(url, CacheFolder, userFolder, downloading, force);
|
|
}
|
|
|
|
public static bool CheckIllustImage(string url)
|
|
{
|
|
var file = Path.Combine(PersonalFolder, imageFolder, Path.GetFileName(url));
|
|
return File.Exists(file);
|
|
}
|
|
public static bool CheckUgoiraVideo(string url)
|
|
{
|
|
var file = Path.Combine(PersonalFolder, ugoiraFolder, Path.GetFileNameWithoutExtension(url) + ".mp4");
|
|
return File.Exists(file);
|
|
}
|
|
|
|
public static string GetPreviewImagePath(string url)
|
|
{
|
|
var file = Path.Combine(PersonalFolder, previewFolder, Path.GetFileName(url));
|
|
if (File.Exists(file))
|
|
{
|
|
return file;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
private static ImageSource LoadImage(string url, string working, string folder, bool downloading, bool force = false)
|
|
{
|
|
var file = Path.Combine(working, folder, Path.GetFileName(url));
|
|
ImageSource image;
|
|
if (!force && File.Exists(file))
|
|
{
|
|
try
|
|
{
|
|
image = ImageSource.FromFile(file);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
App.DebugError("image.load", $"failed to load image from file: {file}, error: {ex.Message}");
|
|
image = null;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
image = null;
|
|
}
|
|
if (downloading && image == null)
|
|
{
|
|
file = HttpUtility.DownloadImage(url, working, folder);
|
|
if (file != null)
|
|
{
|
|
return ImageSource.FromFile(file);
|
|
}
|
|
}
|
|
return image;
|
|
}
|
|
|
|
private static Task<ImageSource> LoadImageAsync(string url, string id, string working, string folder, bool force = false)
|
|
{
|
|
var file = Path.Combine(working, folder, Path.GetFileName(url));
|
|
ImageSource image;
|
|
if (!force && File.Exists(file))
|
|
{
|
|
try
|
|
{
|
|
image = ImageSource.FromFile(file);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
App.DebugError("image.load", $"failed to load image from file: {file}, error: {ex.Message}");
|
|
image = null;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
image = null;
|
|
}
|
|
if (image == null)
|
|
{
|
|
file = HttpUtility.DownloadImageAsync(url, id, working, folder).Result;
|
|
if (file != null)
|
|
{
|
|
image = ImageSource.FromFile(file);
|
|
}
|
|
}
|
|
return Task.FromResult(image);
|
|
}
|
|
}
|
|
|
|
public class IllustFavorite
|
|
{
|
|
public DateTime LastFavoriteUtc { get; set; }
|
|
public FavoriteList Illusts { get; set; }
|
|
}
|
|
|
|
public class FavoriteList : List<IllustItem>
|
|
{
|
|
public bool Changed { get; private set; }
|
|
|
|
public FavoriteList() : base() { }
|
|
public FavoriteList(IEnumerable<IllustItem> collection) : base(collection) { }
|
|
|
|
public new void Insert(int index, IllustItem item)
|
|
{
|
|
base.Insert(index, item);
|
|
Changed = true;
|
|
}
|
|
|
|
public new void InsertRange(int index, IEnumerable<IllustItem> collection)
|
|
{
|
|
base.InsertRange(index, collection);
|
|
Changed = true;
|
|
}
|
|
|
|
public new void RemoveAt(int index)
|
|
{
|
|
base.RemoveAt(index);
|
|
Changed = true;
|
|
}
|
|
|
|
public FavoriteList Reload()
|
|
{
|
|
Changed = false;
|
|
return this;
|
|
}
|
|
}
|
|
|
|
public enum SyncType
|
|
{
|
|
None = 0,
|
|
Prompt,
|
|
AutoSync
|
|
}
|
|
|
|
public static class Configs
|
|
{
|
|
public const string ProfileNameKey = "name";
|
|
public const string ProfileIdKey = "pixiv_id";
|
|
public const string ProfileImageKey = "profile_img";
|
|
public const string CookieKey = "cookies";
|
|
public const string UserIdKey = "user_id";
|
|
public const string DownloadIllustThreadsKey = "download_illust_threads";
|
|
public const string IsOnR18Key = "is_on_r18";
|
|
public const string SyncFavTypeKey = "sync_fav_type";
|
|
public const string IsProxiedKey = "is_proxied";
|
|
public const string HostKey = "host";
|
|
public const string PortKey = "port";
|
|
public const string QueryModeKey = "query_mode";
|
|
public const string QueryTypeKey = "query_type";
|
|
public const string QueryDateKey = "query_date";
|
|
public const string FavoriteTypeKey = "favorite_type";
|
|
|
|
public const int MaxPageThreads = 3;
|
|
public const int MaxThreads = 8;
|
|
public const string Referer = "https://www.pixiv.net/";
|
|
public const string RefererIllust = "https://www.pixiv.net/artworks/{0}";
|
|
public const string RefererIllustRanking = "https://www.pixiv.net/ranking.php?{0}";
|
|
public const string RefererIllustUser = "https://www.pixiv.net/users/{0}/illustrations";
|
|
public const string RefererFavorites = "https://www.pixiv.net/users/{0}/bookmarks/artworks";
|
|
|
|
public static int DownloadIllustThreads;
|
|
public static bool IsOnR18;
|
|
public static SyncType SyncFavType;
|
|
public static WebProxy Proxy;
|
|
public static string Prefix => Proxy == null ?
|
|
"https://www.pixiv.net/" : // https://hk.tsanie.org/reverse/
|
|
"https://www.pixiv.net/";
|
|
public static string UserId { get; private set; }
|
|
public static string Cookie { get; private set; }
|
|
public static string CsrfToken;
|
|
|
|
public static void SetUserId(string userId, bool save = false)
|
|
{
|
|
UserId = userId;
|
|
if (!save)
|
|
{
|
|
return;
|
|
}
|
|
if (userId == null)
|
|
{
|
|
Preferences.Remove(UserIdKey);
|
|
}
|
|
else
|
|
{
|
|
Preferences.Set(UserIdKey, userId);
|
|
}
|
|
}
|
|
|
|
public static void SetCookie(string cookie, bool save = false)
|
|
{
|
|
Cookie = cookie;
|
|
if (!save)
|
|
{
|
|
return;
|
|
}
|
|
if (cookie == null)
|
|
{
|
|
Preferences.Remove(CookieKey);
|
|
}
|
|
else
|
|
{
|
|
Preferences.Set(CookieKey, cookie);
|
|
}
|
|
}
|
|
|
|
#if __IOS__
|
|
public static Task<bool> RequestCookieContainer(WebKit.WKHttpCookieStore cookieStore)
|
|
{
|
|
var task = new TaskCompletionSource<bool>();
|
|
cookieStore.GetAllCookies(cookies =>
|
|
{
|
|
var list = new List<string>();
|
|
foreach (var c in cookies)
|
|
{
|
|
#if DEBUG
|
|
App.DebugPrint($"domain: {c.Domain}, path: {c.Path}, {c.Name}={c.Value}, http only: {c.IsHttpOnly}, session only: {c.IsSessionOnly}");
|
|
#endif
|
|
var domain = c.Domain;
|
|
if (domain == null)
|
|
{
|
|
continue;
|
|
}
|
|
if (domain != "www.pixiv.net" && domain != ".pixiv.net")
|
|
{
|
|
continue;
|
|
}
|
|
list.Add($"{c.Name}={c.Value}");
|
|
}
|
|
var cookie = string.Join("; ", list);
|
|
Cookie = cookie;
|
|
|
|
Preferences.Set(CookieKey, cookie);
|
|
task.SetResult(true);
|
|
});
|
|
return task.Task;
|
|
}
|
|
#endif
|
|
|
|
public const string SuffixGlobal = " id=\"meta-global-data\" content='";
|
|
public const int SuffixGlobalLength = 32;
|
|
public const string SuffixPreload = " id=\"meta-preload-data\" content='";
|
|
public const int SuffixPreloadLength = 33; // SuffixPreload.Length
|
|
|
|
public static string UrlIllustList => Prefix + "ajax/top/illust?mode=all&lang=zh";
|
|
public static string UrlIllust => Prefix + "artworks/{0}";
|
|
public static string UrlIllustRanking => Prefix + "ranking.php?{0}";
|
|
public static string UrlIllustUserAll => Prefix + "ajax/user/{0}/profile/all?lang=zh";
|
|
public static string UrlIllustUserArtworks => Prefix + "ajax/user/{0}/profile/illusts?{1}work_category=illust&is_first_page={2}&lang=zh";
|
|
public static string UrlIllustPage => Prefix + "ajax/illust/{0}/pages?lang=zh";
|
|
public static string UrlIllustUgoira => Prefix + "ajax/illust/{0}/ugoira_meta?lang=zh";
|
|
public static string UrlIllustRecommendsInit => Prefix + "ajax/illust/{0}/recommend/init?limit=18&lang=zh";
|
|
public static string UrlIllustRecommendsList => Prefix + "ajax/illust/recommend/illusts?{0}lang=zh";
|
|
public static string UrlFavoriteList => Prefix + "ajax/user/{0}/illusts/bookmarks?tag=&offset={1}&limit={2}&rest=show&lang=zh";
|
|
|
|
public static string BookmarkAdd => Prefix + "ajax/illusts/bookmarks/add";
|
|
public static string BookmarkRpc => Prefix + "rpc/index.php";
|
|
|
|
public const string UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.107 Safari/537.36";
|
|
public const string AcceptImage = "image/png,image/svg+xml,image/*;q=0.8,video/*;q=0.8,*/*;q=0.5";
|
|
public const string AcceptPureImage = "image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8";
|
|
public const string AcceptJson = "application/json";
|
|
public const string AcceptUrlEncoded = "application/x-www-form-urlencoded";
|
|
//public const string AcceptEncoding = "gzip, deflate";
|
|
public const string AcceptLanguage = "zh-cn";
|
|
|
|
private const string URL_PREVIEW = "https://i.pximg.net/c/360x360_70";
|
|
|
|
public static string GetThumbnailUrl(string url)
|
|
{
|
|
if (url == null)
|
|
{
|
|
return null;
|
|
}
|
|
url = url.ToLower().Replace("/custom-thumb/", "/img-master/");
|
|
var index = url.LastIndexOf("_square1200.jpg");
|
|
if (index < 0)
|
|
{
|
|
index = url.LastIndexOf("_custom1200.jpg");
|
|
}
|
|
if (index > 0)
|
|
{
|
|
url = url.Substring(0, index) + "_master1200.jpg";
|
|
}
|
|
|
|
var start = url.IndexOf("/img-master/");
|
|
if (start > 0)
|
|
{
|
|
url = URL_PREVIEW + url.Substring(start);
|
|
}
|
|
return url;
|
|
}
|
|
}
|
|
|
|
public static class Routes
|
|
{
|
|
public const string Illust = "illust";
|
|
public const string Detail = "detail";
|
|
public const string Follow = "follow";
|
|
public const string Recommends = "recommends";
|
|
public const string ByUser = "byuser";
|
|
public const string Ranking = "ranking";
|
|
public const string Favorites = "favorites";
|
|
public const string Option = "option";
|
|
}
|
|
}
|