Compare commits

...

2 Commits

Author SHA1 Message Date
lincube
5d2449fa8f fead.加入jiangtokoto数据源 2026-04-04 02:13:26 +08:00
lincube
00339f0ed0 fix.修Rinshub,怎么不是色色就是逆天 2026-04-03 22:55:35 +08:00
6 changed files with 129 additions and 13 deletions

View File

@@ -1075,7 +1075,9 @@
"zhijiaohub.settings.source": "Image Source",
"zhijiaohub.settings.classisland": "ClassIsland Gallery",
"zhijiaohub.settings.sectl": "SECTL Gallery",
"zhijiaohub.settings.source_desc": "Select the image source. ClassIsland Gallery contains fun moments from the ClassIsland community, SECTL Gallery contains content from the SECTL community.",
"zhijiaohub.settings.rinlit": "Rin's Gallery",
"zhijiaohub.settings.jiangtokoto": "Jiangtokoto Memes",
"zhijiaohub.settings.source_desc": "Select the image source. ClassIsland Gallery contains fun moments from the ClassIsland community, SECTL Gallery contains content from the SECTL community, Rin's Gallery contains content from Rin's community, Jiangtokoto Memes contains rich meme resources.",
"zhijiaohub.settings.mirror_source": "Mirror Acceleration",
"zhijiaohub.settings.mirror_direct": "Direct (GitHub)",
"zhijiaohub.settings.mirror_ghproxy": "Mirror Acceleration (Recommended)",

View File

@@ -1069,7 +1069,9 @@
"zhijiaohub.settings.source": "图片源",
"zhijiaohub.settings.classisland": "ClassIsland 图库",
"zhijiaohub.settings.sectl": "SECTL 图库",
"zhijiaohub.settings.source_desc": "选择图片来源。ClassIsland 图库包含 ClassIsland 社区的趣味瞬间SECTL 图库包含 SECTL 社区的内容。",
"zhijiaohub.settings.rinlit": "Rin's 图库",
"zhijiaohub.settings.jiangtokoto": "Jiangtokoto 表情包",
"zhijiaohub.settings.source_desc": "选择图片来源。ClassIsland 图库包含 ClassIsland 社区的趣味瞬间SECTL 图库包含 SECTL 社区的内容Rin's 图库包含 Rin's 社区的内容Jiangtokoto 表情包包含丰富的表情包资源。",
"zhijiaohub.settings.mirror_source": "镜像加速",
"zhijiaohub.settings.mirror_direct": "直连GitHub",
"zhijiaohub.settings.mirror_ghproxy": "镜像加速(推荐)",

View File

@@ -125,6 +125,7 @@ public static class ZhiJiaoHubSources
public const string ClassIsland = "classisland";
public const string Sectl = "sectl";
public const string RinLit = "rinlit";
public const string Jiangtokoto = "jiangtokoto";
public static string Normalize(string? value)
{
@@ -132,6 +133,7 @@ public static class ZhiJiaoHubSources
{
"sectl" => Sectl,
"rinlit" => RinLit,
"jiangtokoto" => Jiangtokoto,
_ => ClassIsland
};
}
@@ -142,6 +144,7 @@ public static class ZhiJiaoHubSources
{
Sectl => "SECTL 图库",
RinLit => "Rin's 图库",
Jiangtokoto => "Jiangtokoto 表情包",
_ => "ClassIsland 图库"
};
}
@@ -154,8 +157,13 @@ public sealed class ZhiJiaoHubSourceConfig
public string Repo { get; init; } = string.Empty;
public string Path { get; init; } = string.Empty;
public string DisplayName { get; init; } = string.Empty;
public bool UseJsonIndex { get; init; } = false;
public string? JsonIndexPath { get; init; } = null;
public string ApiUrl => $"https://api.github.com/repos/{Owner}/{Repo}/contents/{Path}";
public string RawUrlTemplate => $"https://raw.githubusercontent.com/{Owner}/{Repo}/main/{Path}/{{0}}";
public string? JsonIndexUrl => JsonIndexPath != null
? $"https://raw.githubusercontent.com/{Owner}/{Repo}/main/{JsonIndexPath}"
: null;
public static ZhiJiaoHubSourceConfig GetConfig(string source)
{
@@ -172,8 +180,17 @@ public sealed class ZhiJiaoHubSourceConfig
{
Owner = "RinLit-233-shiroko",
Repo = "Rin-sHub",
Path = "assets/images",
DisplayName = "Rin's 图库"
Path = "updates/images",
DisplayName = "Rin's 图库",
UseJsonIndex = true,
JsonIndexPath = "updates/images.json"
},
ZhiJiaoHubSources.Jiangtokoto => new ZhiJiaoHubSourceConfig
{
Owner = "unDefFtr",
Repo = "jiangtokoto-images",
Path = "images",
DisplayName = "Jiangtokoto 表情包"
},
_ => new ZhiJiaoHubSourceConfig
{

View File

@@ -3246,16 +3246,27 @@ public sealed class RecommendationDataService : IRecommendationInfoService, IDis
{
var config = ZhiJiaoHubSourceConfig.GetConfig(source);
var contentsUrl = config.ApiUrl;
if (string.Equals(mirrorSource, ZhiJiaoHubMirrorSources.GhProxy, StringComparison.OrdinalIgnoreCase))
{
contentsUrl = ZhiJiaoHubMirrorSources.GhProxyBaseUrl.TrimEnd('/') + "/" + contentsUrl;
}
try
{
var images = await FetchImagesFromContentsApi(config, contentsUrl, mirrorSource, cancellationToken);
List<ZhiJiaoHubImageItem> images;
// 如果使用JSON索引模式Rin's Hub
if (config.UseJsonIndex && !string.IsNullOrEmpty(config.JsonIndexUrl))
{
images = await FetchImagesFromJsonIndex(config, mirrorSource, cancellationToken);
}
else
{
// 标准模式ClassIsland/SECTL
var contentsUrl = config.ApiUrl;
if (string.Equals(mirrorSource, ZhiJiaoHubMirrorSources.GhProxy, StringComparison.OrdinalIgnoreCase))
{
contentsUrl = ZhiJiaoHubMirrorSources.GhProxyBaseUrl.TrimEnd('/') + "/" + contentsUrl;
}
images = await FetchImagesFromContentsApi(config, contentsUrl, mirrorSource, cancellationToken);
}
if (images.Count == 0)
{
@@ -3380,6 +3391,85 @@ public sealed class RecommendationDataService : IRecommendationInfoService, IDis
return images;
}
/// <summary>
/// 从JSON索引文件获取图片列表Rin's Hub专用
/// </summary>
private async Task<List<ZhiJiaoHubImageItem>> FetchImagesFromJsonIndex(
ZhiJiaoHubSourceConfig config,
string mirrorSource,
CancellationToken cancellationToken)
{
var images = new List<ZhiJiaoHubImageItem>();
// 下载JSON索引文件
var jsonUrl = config.JsonIndexUrl!;
if (string.Equals(mirrorSource, ZhiJiaoHubMirrorSources.GhProxy, StringComparison.OrdinalIgnoreCase))
{
jsonUrl = ZhiJiaoHubMirrorSources.GhProxyBaseUrl.TrimEnd('/') + "/" + jsonUrl;
}
using var request = new HttpRequestMessage(HttpMethod.Get, jsonUrl);
request.Headers.TryAddWithoutValidation("User-Agent", "LanMountainDesktop/1.0");
using var response = await _httpClient.SendAsync(request, cancellationToken);
response.EnsureSuccessStatusCode();
var jsonText = await response.Content.ReadAsStringAsync(cancellationToken);
using var document = JsonDocument.Parse(jsonText);
var root = document.RootElement;
// 解析 hub_items 数组
if (!root.TryGetProperty("hub_items", out var hubItems) || hubItems.ValueKind != JsonValueKind.Array)
{
throw new InvalidOperationException($"JSON索引文件格式无效缺少 hub_items 数组");
}
int index = 0;
foreach (var item in hubItems.EnumerateArray())
{
// 获取图片路径
if (!item.TryGetProperty("image", out var imageProp))
{
continue;
}
var imagePath = imageProp.GetString();
if (string.IsNullOrWhiteSpace(imagePath))
{
continue;
}
// 获取标题(用于显示名称)
string title = string.Empty;
if (item.TryGetProperty("title", out var titleProp))
{
title = titleProp.GetString() ?? string.Empty;
}
// 如果没有标题,使用文件名
if (string.IsNullOrWhiteSpace(title))
{
title = Path.GetFileNameWithoutExtension(imagePath);
}
// 构建完整的图片URL
// imagePath 格式如: "Discord/姐姐好香.png"
// 需要拼接为: https://raw.githubusercontent.com/.../updates/images/Discord/姐姐好香.png
// 并对路径中的每个部分进行URL编码
var pathParts = imagePath.Split('/');
var encodedPath = string.Join("/", pathParts.Select(part => Uri.EscapeDataString(part)));
var imageUrl = $"https://raw.githubusercontent.com/{config.Owner}/{config.Repo}/main/{config.Path}/{encodedPath}";
// 应用镜像加速
imageUrl = ZhiJiaoHubMirrorSources.ApplyMirror(imageUrl, mirrorSource);
images.Add(new ZhiJiaoHubImageItem(title, imageUrl, index));
index++;
}
return images;
}
private bool TryGetZhiJiaoHubFromCache(string cacheKey, out ZhiJiaoHubSnapshot snapshot)
{
lock (_cacheGate)

View File

@@ -24,6 +24,9 @@
<ComboBoxItem x:Name="RinLitItem"
Classes="component-editor-select-item"
Tag="rinlit" />
<ComboBoxItem x:Name="JiangtokotoItem"
Classes="component-editor-select-item"
Tag="jiangtokoto" />
</ComboBox>
<TextBlock x:Name="SourceDescriptionTextBlock"
Classes="component-editor-secondary-text"

View File

@@ -30,10 +30,11 @@ public partial class ZhiJiaoHubComponentEditor : ComponentEditorViewBase
ClassIslandItem.Content = L("zhijiaohub.settings.classisland", "ClassIsland 图库");
SectlItem.Content = L("zhijiaohub.settings.sectl", "SECTL 图库");
RinLitItem.Content = L("zhijiaohub.settings.rinlit", "Rin's 图库");
JiangtokotoItem.Content = L("zhijiaohub.settings.jiangtokoto", "Jiangtokoto 表情包");
// 数据源描述
SourceDescriptionTextBlock.Text = L("zhijiaohub.settings.source_desc",
"选择图片来源。ClassIsland 图库包含 ClassIsland 社区的趣味瞬间SECTL 图库包含 SECTL 社区的内容Rin's 图库包含 Rin's 社区的内容。");
"选择图片来源。ClassIsland 图库包含 ClassIsland 社区的趣味瞬间SECTL 图库包含 SECTL 社区的内容Rin's 图库包含 Rin's 社区的内容Jiangtokoto 表情包包含丰富的表情包资源。");
// 镜像加速源
MirrorSourceLabelTextBlock.Text = L("zhijiaohub.settings.mirror_source", "镜像加速");
@@ -67,6 +68,7 @@ public partial class ZhiJiaoHubComponentEditor : ComponentEditorViewBase
{
ZhiJiaoHubSources.Sectl => SectlItem,
ZhiJiaoHubSources.RinLit => RinLitItem,
ZhiJiaoHubSources.Jiangtokoto => JiangtokotoItem,
_ => ClassIslandItem
};