Fix gallery resolution parsing for split archive paragraphs

This commit is contained in:
root
2026-10-07 23:09:47 +08:00
parent e6c7dab12e
commit 4c1a2d22e2
2 changed files with 150 additions and 7 deletions
@@ -11,6 +11,10 @@ import java.util.regex.Pattern;
public final class GalleryPageParser {
private GalleryPageParser() { }
/** 归档页 #db 单元格开头:分辨率标签 + 正数体积 + 受支持单位;后缀费用文本(Free、50GP)忽略。 */
private static final Pattern RESOLUTION_ENTRY =
Pattern.compile("^(Original|(\\d+)x)\\s+(\\d+(?:\\.\\d+)?)\\s*([A-Za-z]+)(?=\\s|$)", Pattern.CASE_INSENSITIVE);
public static Gallery metadata(Document document, String link, int gid) throws IOException {
String title = document.select("#gn").text();
if (title.isBlank()) title = document.select("#gj").text();
@@ -52,16 +56,37 @@ public final class GalleryPageParser {
throw new IOException("上游页面缺少归档入口");
}
/**
* 解析归档页 #db 的可选分辨率。每个单元格合并后的文本形如 {@code Original 36.31 MiB Free}、
* {@code 800x 5.65 MiB Free}、{@code 2560x N/A N/A},单段布局形如 {@code 1280x 12.5 MiB},
* 都由同一条锚定规则覆盖;只看开头(分辨率 + 正数体积 + 单位),故 N/A 与费用文本不匹配,
* 配对也不会跨 {@code <td>} 借用相邻格。体积须能被 {@link CustomUtil#stringToFileSize(String)}
* 解析为正数,宽度须为正且不溢出。结果按宽度升序、{@code Original} 最后;无可用项抛 IOException。
*/
public static Map<String, String> resolutions(Document document) throws IOException {
var expression = Pattern.compile("^(\\d+x|Original)\\s+([\\d.]+)\\s*([A-Za-z]+)$", Pattern.CASE_INSENSITIVE);
TreeMap<Integer, String> sizes = new TreeMap<>();
String original = null;
for (Element paragraph : document.select("#db td p")) {
var matcher = expression.matcher(paragraph.text().strip());
if (!matcher.matches()) continue;
String size = matcher.group(2) + matcher.group(3);
if (matcher.group(1).equalsIgnoreCase("Original")) original = size;
else sizes.put(Integer.parseInt(matcher.group(1).replace("x", "")), size);
for (Element cell : document.select("#db td")) {
var matcher = RESOLUTION_ENTRY.matcher(cell.text().replace('\u00a0', ' ').strip());
if (!matcher.find()) continue;
String size = matcher.group(3) + matcher.group(4);
try {
if (CustomUtil.stringToFileSize(size) <= 0) continue;
} catch (RuntimeException unsupported) {
continue;
}
if (matcher.group(1).equalsIgnoreCase("Original")) {
original = size;
continue;
}
int width;
try {
width = Integer.parseInt(matcher.group(2));
} catch (NumberFormatException outOfRange) {
continue;
}
if (width <= 0) continue;
sizes.put(width, size);
}
Map<String, String> result = new LinkedHashMap<>();
sizes.forEach((width, size) -> result.put(width + "x", size));