This commit is contained in:
hyperdefined 2025-07-07 06:50:40 +00:00 committed by GitHub
commit ca3e0d0451
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 143 additions and 0 deletions

View File

@ -104,6 +104,7 @@ export default function({
case "snapchat": case "snapchat":
case "bsky": case "bsky":
case "xiaohongshu": case "xiaohongshu":
case "duitang":
params = { picker: r.picker }; params = { picker: r.picker };
break; break;

View File

@ -29,6 +29,7 @@ import loom from "./services/loom.js";
import facebook from "./services/facebook.js"; import facebook from "./services/facebook.js";
import bluesky from "./services/bluesky.js"; import bluesky from "./services/bluesky.js";
import xiaohongshu from "./services/xiaohongshu.js"; import xiaohongshu from "./services/xiaohongshu.js";
import duitang from "./services/duitang.js";
let freebind; let freebind;
@ -267,6 +268,13 @@ export default async function({ host, patternMatch, params, authType }) {
dispatcher, dispatcher,
}); });
break; break;
case "duitang":
r = await duitang({
id: patternMatch.id,
type: patternMatch.type,
});
break;
default: default:
return createResponse("error", { return createResponse("error", {

View File

@ -22,6 +22,10 @@ export const services = {
dailymotion: { dailymotion: {
patterns: ["video/:id"], patterns: ["video/:id"],
}, },
duitang: {
patterns: [ ":type?id=:id" ],
subdomains: ["m"]
},
facebook: { facebook: {
patterns: [ patterns: [
"_shortLink/:shortLink", "_shortLink/:shortLink",

View File

@ -5,6 +5,10 @@ export const testers = {
"dailymotion": pattern => pattern.id?.length <= 32, "dailymotion": pattern => pattern.id?.length <= 32,
"duitang": pattern =>
(pattern.type == 'blog' || pattern.type == 'atlas') &&
pattern.id?.length <= 10,
"instagram": pattern => "instagram": pattern =>
pattern.postId?.length <= 48 pattern.postId?.length <= 48
|| pattern.shareId?.length <= 16 || pattern.shareId?.length <= 16

View File

@ -0,0 +1,84 @@
import { genericUserAgent } from "../../config.js";
import { createStream } from "../../stream/manage.js"
export default async function(post) {
let filenameBase = `duitang_${post.id}`
if (post.type == 'blog') {
let req = await fetch(`https://www.duitang.com/napi/blog/detail/?blog_id=${post.id}`, {
headers: {
'User-Agent': genericUserAgent,
}
})
.then(request => request.text())
.catch(() => {});
if (!req) return { error: 'fetch.fail' };
let json;
try {
json = JSON.parse(req);
} catch { return { error: 'fetch.empty' }; }
let originalUrl = json.data.photo.path.toString();
let image = {
// always proxy here because of headers
type: "photo",
url: createStream({
service: "duitang",
type: "proxy",
url: originalUrl,
filename: `${filenameBase}_photo.jpg`,
headers: {
'Host': 'c-ssl.dtstatic.com',
'Referer': 'https://duitang.com'
}
})
}
return {
picker: [image]
};
}
if (post.type == 'atlas') {
let req = await fetch(`https://www.duitang.com/napi/vienna/atlas/detail/?atlas_id=${post.id}`, {
headers: {
'User-Agent': genericUserAgent,
}
})
.then(request => request.text())
.catch(() => {});
if (!req) return { error: 'fetch.fail' };
let json;
try {
json = JSON.parse(req);
} catch { return { error: 'fetch.empty' }; }
let imageLinks = json.data.blogs
.map(blog => blog.photo?.path)
.map((url, i) => {
// always proxy here because of headers
url = createStream({
service: "duitang",
type: "proxy",
url: url,
filename: `${filenameBase}_photo_${i + 1}.jpg`,
headers: {
'Host': 'c-ssl.dtstatic.com',
'Referer': 'https://duitang.com'
}
});
return {
type: "photo",
url
};
});
return {
picker: imageLinks
}
}
}

View File

@ -134,6 +134,11 @@ function cleanURL(url) {
} }
switch (host) { switch (host) {
case "duitang":
if (url.searchParams.get('id')) {
limitQuery('id');
}
break;
case "pinterest": case "pinterest":
url.hostname = 'pinterest.com'; url.hostname = 'pinterest.com';
break; break;

View File

@ -0,0 +1,37 @@
[
{
"name": "regular album",
"url": "https://www.duitang.com/atlas/?id=135382417",
"params": {},
"expected": {
"code": 200,
"status": "picker"
}
},
{
"name": "single image",
"url": "https://www.duitang.com/blog/?id=1517805784",
"params": {},
"expected": {
"code": 200,
"status": "picker"
}
},
{
"name": "single image, mobile link",
"url": "https://m.duitang.com/blog/?id=1517805784",
"params": {},
"expected": {
"code": 200,
"status": "picker"
}
},
{
"name": "regular album, mobile link",
"url": "https://m.duitang.com/atlas/?id=135382417",
"expected": {
"code": 200,
"status": "picker"
}
}
]