add [javdb] into sitelist

This commit is contained in:
mrbunker
2023-01-20 21:59:55 +08:00
parent a9dc863e97
commit 747ed2dbb7
5 changed files with 387 additions and 367 deletions

24
dist/jop.user.js vendored
View File

@@ -1,7 +1,7 @@
// ==UserScript==
// @name JAV 添加跳转在线观看
// @namespace https://greasyfork.org/zh-CN/scripts/429173
// @version 1.1.3
// @version 1.1.4
// @author mission522
// @description [高效寻找最佳的在线资源] 在影片详情页添加跳转在线播放的按钮,并注是否提供在线播放资源或无码资源、字幕资源等信息。支持 JavDB、JavBus 以及 JavLibrary
// @license MIT
@@ -28,6 +28,7 @@
// @connect ggjav.com
// @connect av01.tv
// @connect javbus.com
// @connect javdb.com
// @connect javdb007.com
// @grant GM_getValue
// @grant GM_setValue
@@ -746,6 +747,19 @@
domQuery: {},
method: print,
},
{
name: "JavDB",
disableHostname: "javdb",
disable: false,
hostname: "javdb.com",
url: "https://javdb.com/search?q={{code}}",
fetcher: "parser",
domQuery: {
linkQuery: ".movie-list>.item:first-child>a",
titleQuery: ".video-title",
},
method: print,
},
];
var monkeyWindow = window;
var GM_setValue = /* @__PURE__ */ (() => monkeyWindow.GM_setValue)();
@@ -932,7 +946,7 @@
],
});
});
const Setting = ({ sites, setSites, disable }) => {
const Setting = ({ sites, setSites, disables: disable }) => {
const [showSetting, setShowSetting] = p(false);
const newDisable = disable;
return o(preact2.Fragment, {
@@ -998,13 +1012,13 @@
});
};
const App = R(function ({ current, CODE }) {
const disable = GM_getValue("disable", ["AvJoy", "baihuse", "AV01"]);
const disables = GM_getValue("disable", ["AvJoy", "baihuse", "AV01"]);
const [sites, setSites] = p(siteList);
const sitesDisHost = sites.filter(
(item) => item.disableHostname !== current.name && !item.disable,
);
const filter = sitesDisHost.filter((item) => {
if (!disable.includes(item.name)) return item;
if (!disables.includes(item.name)) return item;
});
return o(preact2.Fragment, {
children: [
@@ -1021,7 +1035,7 @@
children: o(Setting, {
sites,
setSites,
disable,
disables,
}),
}),
],

View File

@@ -1,38 +1,38 @@
import { memo, useState } from "preact/compat";
import { SiteItem, siteList } from "@/utils/siteList";
import { GM_getValue } from "$";
import type { Current } from "@/utils/matchList";
import SiteButton from "./SiteButton";
import { Setting } from "./Setting";
const App = memo(function ({ current, CODE }: { current: Current; CODE: string }) {
const disable = GM_getValue<SiteItem["name"][]>("disable", ["AvJoy", "baihuse", "AV01"]);
// sites 最原始的 siteList.json
const [sites, setSites] = useState(siteList);
/** 禁用 hostname */
const sitesDisHost = sites.filter(
(item) => item.disableHostname !== current.name && !item.disable,
);
/** 禁用 用户自定义 */
const filter = sitesDisHost.filter((item) => {
if (!disable.includes(item.name)) return item;
});
return (
<>
<div class="jop-list">
{filter.map((item) => (
<SiteButton siteItem={item} CODE={CODE} />
))}
</div>
<div>
<Setting sites={sites} setSites={setSites} disable={disable} />
</div>
</>
);
});
export default App;
import { memo, useState } from "preact/compat";
import { SiteItem, siteList } from "@/utils/siteList";
import { GM_getValue } from "$";
import type { Current } from "@/utils/matchList";
import SiteButton from "./SiteButton";
import { Setting } from "./Setting";
const App = memo(function ({ current, CODE }: { current: Current; CODE: string }) {
const disables = GM_getValue<SiteItem["name"][]>("disable", ["AvJoy", "baihuse", "AV01"]);
// sites 最原始的 siteList.json
const [sites, setSites] = useState(siteList);
/** 禁用 hostname */
const sitesDisHost = sites.filter(
(item) => item.disableHostname !== current.name && !item.disable,
);
/** 禁用 用户自定义 */
const filter = sitesDisHost.filter((item) => {
if (!disables.includes(item.name)) return item;
});
return (
<>
<div class="jop-list">
{filter.map((item) => (
<SiteButton siteItem={item} CODE={CODE} />
))}
</div>
<div>
<Setting sites={sites} setSites={setSites} disables={disables} />
</div>
</>
);
});
export default App;

View File

@@ -1,72 +1,72 @@
import { SiteItem } from "@/utils/siteList";
import { StateUpdater, useState } from "preact/hooks";
import { GM_setValue } from "vite-plugin-monkey/dist/client";
export const Setting = ({
sites,
setSites,
disable,
}: {
sites: SiteItem[];
setSites: StateUpdater<SiteItem[]>;
disable: SiteItem["name"][];
}) => {
const [showSetting, setShowSetting] = useState(false);
/** 暂存用户的勾选,最后保存的时候提交 */
const newDisable = disable;
return (
<>
{!showSetting ? (
<div
className="jop-button_def"
onClick={(e) => {
setShowSetting(!showSetting);
}}
>
</div>
) : (
<h4 className="jop-setting-title"></h4>
)}
{showSetting && (
<>
<div className="jop-setting">
<div className="jop-setting-list">
{sites.map((item, index) => (
<div className="jop-setting-item">
{item.name}
<input
type="checkbox"
className="jop-setting-checkbox"
checked={!disable.includes(item.name)}
onChange={(e: any) => {
const checked: boolean = e.target?.checked;
sites[index].disable = !checked;
if (!checked) {
newDisable.push(item.name);
} else {
newDisable.forEach((name, index) => {
if (name === item.name) newDisable.splice(index, 1);
});
}
}}
/>
</div>
))}
</div>
</div>
<div
className="jop-button_def"
onClick={(e) => {
setShowSetting(!showSetting);
GM_setValue("disable", newDisable);
setSites([...sites]);
}}
>
</div>
</>
)}
</>
);
};
import { SiteItem } from "@/utils/siteList";
import { StateUpdater, useState } from "preact/hooks";
import { GM_setValue } from "vite-plugin-monkey/dist/client";
export const Setting = ({
sites,
setSites,
disables: disable,
}: {
sites: SiteItem[];
setSites: StateUpdater<SiteItem[]>;
disables: SiteItem["name"][];
}) => {
const [showSetting, setShowSetting] = useState(false);
/** 暂存用户的勾选,最后保存的时候提交 */
const newDisable = disable;
return (
<>
{!showSetting ? (
<div
className="jop-button_def"
onClick={(e) => {
setShowSetting(!showSetting);
}}
>
</div>
) : (
<h4 className="jop-setting-title"></h4>
)}
{showSetting && (
<>
<div className="jop-setting">
<div className="jop-setting-list">
{sites.map((item, index) => (
<div className="jop-setting-item">
{item.name}
<input
type="checkbox"
className="jop-setting-checkbox"
checked={!disable.includes(item.name)}
onChange={(e: any) => {
const checked: boolean = e.target?.checked;
sites[index].disable = !checked;
if (!checked) {
newDisable.push(item.name);
} else {
newDisable.forEach((name, index) => {
if (name === item.name) newDisable.splice(index, 1);
});
}
}}
/>
</div>
))}
</div>
</div>
<div
className="jop-button_def"
onClick={(e) => {
setShowSetting(!showSetting);
GM_setValue("disable", newDisable);
setSites([...sites]);
}}
>
</div>
</>
)}
</>
);
};

View File

@@ -1,251 +1,257 @@
export interface DomQuery_parser {
/** 部分网站搜索页结果第一个是广告,所以要加一个 index */
listIndex?: number;
/** code 是用空格分割的 */
spaceCode?: boolean;
linkQuery: string;
titleQuery: string;
}
export interface DomQuery_get {
/** 收录视频,但是未提供在线播放资源 */
videoQuery?: string;
subQuery?: string;
leakQuery?: string;
}
interface SiteItemBase {
name: string;
/** 用户定义的 disable */
disable: boolean;
/** 针对 matchList 的 hostname */
disableHostname?: string;
hostname: string;
url: string;
codeFormater?: (arg0: string) => string;
method?: Function;
}
export interface SiteItem_get extends SiteItemBase {
fetcher: "get";
domQuery: DomQuery_get;
}
export interface SiteItem_parser extends SiteItemBase {
fetcher: "parser";
domQuery: DomQuery_parser;
}
export type SiteItem = SiteItem_get | SiteItem_parser;
const print = (name: string) => {
console.log(name);
};
/** 网站列表 */
export const siteList: SiteItem[] = [
{
name: "Jable",
disable: false,
hostname: "jable.tv",
url: "https://jable.tv/videos/{{code}}/",
fetcher: "get",
domQuery: { subQuery: ".header-right>h6" },
method: print,
},
{
name: "MISSAV",
disable: false,
hostname: "missav.com",
url: "https://missav.com/{{code}}/",
fetcher: "get",
domQuery: {
/** 标签区的第一个一般是字幕标签 */
subQuery: '.space-y-2 a.text-nord13[href="https://missav.com/chinese-subtitle"]',
/** videoPage 有个跳转按钮 */
leakQuery: ".order-first div.rounded-md a[href]:last-child",
},
method: print,
},
{
// 有可能搜出仨leakage subtitle 4k
name: "Supjav",
disable: false,
hostname: "supjav.com",
url: "https://supjav.com/zh/?s={{code}}",
fetcher: "parser",
domQuery: {
linkQuery: `.posts.clearfix>.post>a.img[title]`,
titleQuery: `h3>a[rel="bookmark"][itemprop="url"]`,
},
method: print,
},
{
name: "NETFLAV",
disable: false,
hostname: "netflav.com",
url: "https://netflav.com/search?type=title&keyword={{code}}",
fetcher: "parser",
domQuery: {
linkQuery: ".grid_cell>a",
titleQuery: ".grid_cell>a>.grid_title",
},
method: print,
},
{
name: "Avgle",
disable: false,
hostname: "avgle.com",
url: "https://avgle.com/search/videos?search_query={{code}}&search_type=videos",
fetcher: "parser",
domQuery: {
linkQuery: ".container>.row .row .well>a[href]",
titleQuery: ".container>.row .row .well .video-title",
},
method: print,
},
{
name: "JAVHHH",
disable: false,
hostname: "javhhh.com",
url: "https://javhhh.com/v/?wd={{code}}",
fetcher: "parser",
domQuery: {
linkQuery: ".typelist>.i-container>a[href]",
titleQuery: ".typelist>.i-container>a[href]",
},
method: print,
},
{
name: "BestJP",
disable: false,
hostname: "bestjavporn.com",
url: "https://www3.bestjavporn.com/search/{{code}}",
fetcher: "parser",
domQuery: { linkQuery: "article.thumb-block>a", titleQuery: "article.thumb-block>a" },
method: print,
},
{
name: "JAVMENU",
disable: false,
hostname: "javmenu.com",
url: "https://javmenu.com/{{code}}",
fetcher: "get",
domQuery: {
videoQuery: "a.nav-link[aria-controls='pills-0']",
},
method: print,
},
{
name: "Jav.Guru",
disable: false,
hostname: "jav.guru",
url: "https://jav.guru/?s={{code}}",
fetcher: "parser",
domQuery: { linkQuery: ".imgg>a[href]", titleQuery: ".inside-article>.grid1 a[title]" },
method: print,
},
{
name: "JAVMOST",
disable: false,
hostname: "javmost.cx",
url: "https://javmost.cx/search/{{code}}/",
fetcher: "parser",
domQuery: {
linkQuery: "#content .card a#MyImage",
titleQuery: "#content .card-block .card-title",
},
method: print,
},
{
name: "HAYAV",
disable: false,
hostname: "hayav.com",
url: "https://hayav.com/video/{{code}}/",
fetcher: "get",
domQuery: {
// subQuery: `.site__col>.entry-header>h1.entry-title`,
},
method: print,
},
{
name: "AvJoy",
disable: false,
hostname: "avjoy.me",
url: "https://avjoy.me/search/video/{{code}}",
fetcher: "parser",
domQuery: {
titleQuery: `.content-info>.content-title`,
linkQuery: `.content-row>a`,
},
method: print,
},
{
name: "JAVFC2",
disable: false,
hostname: "javfc2.net",
url: "https://javfc2.net/?s={{code}}",
fetcher: "parser",
domQuery: {
linkQuery: "article.loop-video>a[href]",
titleQuery: "article.loop-video .entry-header",
},
method: print,
},
{
name: "baihuse",
disable: false,
hostname: "paipancon.com",
url: "https://paipancon.com/search/{{code}}",
fetcher: "parser",
domQuery: {
linkQuery: "div.col>div.card>a[href]",
// 然而这个不是 title是图片这个站居然 title 里不包含 code反而图片包含
titleQuery: "div.card img.card-img-top",
},
method: print,
},
{
name: "GGJAV",
disable: false,
hostname: "ggjav.com",
url: "https://ggjav.com/main/search?string={{code}}",
fetcher: "parser",
domQuery: {
listIndex: 1,
spaceCode: true,
titleQuery: "div.columns.large-3.medium-6.small-12.item.float-left>div.item_title>a.gray_a",
linkQuery: "div.columns.large-3.medium-6.small-12.item.float-left>div.item_title>a.gray_a",
},
method: print,
},
{
name: "AV01",
disable: false,
hostname: "av01.tv",
url: "https://www.av01.tv/search/videos?search_query={{code}}",
fetcher: "parser",
domQuery: { linkQuery: "div[id].well-sm>a", titleQuery: ".video-views>.pull-left" },
method: print,
},
{
name: "JavBus",
disableHostname: "javbus",
disable: false,
hostname: "javbus.com",
url: "https://javbus.com/{{code}}",
fetcher: "get",
domQuery: {},
method: print,
},
// {
// name: "JavDB",
// disable:"javdb",
// hostname: "javbus.com",
// url: "https://javbus.com/{{code}}",
// fetcher: "get",
// domQuery: {},
// method: print,
// },
];
export interface DomQuery_parser {
/** 部分网站搜索页结果第一个是广告,所以要加一个 index */
listIndex?: number;
/** code 是用空格分割的 */
spaceCode?: boolean;
linkQuery: string;
titleQuery: string;
}
export interface DomQuery_get {
/** 收录视频,但是未提供在线播放资源 */
videoQuery?: string;
subQuery?: string;
leakQuery?: string;
}
interface SiteItemBase {
name: string;
/** 用户定义的 disable */
disable: boolean;
/** 针对 matchList 的 hostname */
disableHostname?: string;
hostname: string;
url: string;
/** 没用 */
codeFormater?: (arg0: string) => string;
/** 没用 */
method?: Function;
}
export interface SiteItem_get extends SiteItemBase {
fetcher: "get";
domQuery: DomQuery_get;
}
export interface SiteItem_parser extends SiteItemBase {
fetcher: "parser";
domQuery: DomQuery_parser;
}
export type SiteItem = SiteItem_get | SiteItem_parser;
const print = (name: string) => {
console.log(name);
};
/** 网站列表 */
export const siteList: SiteItem[] = [
{
name: "Jable",
disable: false,
hostname: "jable.tv",
url: "https://jable.tv/videos/{{code}}/",
fetcher: "get",
domQuery: { subQuery: ".header-right>h6" },
method: print,
},
{
name: "MISSAV",
disable: false,
hostname: "missav.com",
url: "https://missav.com/{{code}}/",
fetcher: "get",
domQuery: {
/** 标签区的第一个一般是字幕标签 */
subQuery: '.space-y-2 a.text-nord13[href="https://missav.com/chinese-subtitle"]',
/** videoPage 有个跳转按钮 */
leakQuery: ".order-first div.rounded-md a[href]:last-child",
},
method: print,
},
{
// 有可能搜出仨leakage subtitle 4k
name: "Supjav",
disable: false,
hostname: "supjav.com",
url: "https://supjav.com/zh/?s={{code}}",
fetcher: "parser",
domQuery: {
linkQuery: `.posts.clearfix>.post>a.img[title]`,
titleQuery: `h3>a[rel="bookmark"][itemprop="url"]`,
},
method: print,
},
{
name: "NETFLAV",
disable: false,
hostname: "netflav.com",
url: "https://netflav.com/search?type=title&keyword={{code}}",
fetcher: "parser",
domQuery: {
linkQuery: ".grid_cell>a",
titleQuery: ".grid_cell>a>.grid_title",
},
method: print,
},
{
name: "Avgle",
disable: false,
hostname: "avgle.com",
url: "https://avgle.com/search/videos?search_query={{code}}&search_type=videos",
fetcher: "parser",
domQuery: {
linkQuery: ".container>.row .row .well>a[href]",
titleQuery: ".container>.row .row .well .video-title",
},
method: print,
},
{
name: "JAVHHH",
disable: false,
hostname: "javhhh.com",
url: "https://javhhh.com/v/?wd={{code}}",
fetcher: "parser",
domQuery: {
linkQuery: ".typelist>.i-container>a[href]",
titleQuery: ".typelist>.i-container>a[href]",
},
method: print,
},
{
name: "BestJP",
disable: false,
hostname: "bestjavporn.com",
url: "https://www3.bestjavporn.com/search/{{code}}",
fetcher: "parser",
domQuery: { linkQuery: "article.thumb-block>a", titleQuery: "article.thumb-block>a" },
method: print,
},
{
name: "JAVMENU",
disable: false,
hostname: "javmenu.com",
url: "https://javmenu.com/{{code}}",
fetcher: "get",
domQuery: {
videoQuery: "a.nav-link[aria-controls='pills-0']",
},
method: print,
},
{
name: "Jav.Guru",
disable: false,
hostname: "jav.guru",
url: "https://jav.guru/?s={{code}}",
fetcher: "parser",
domQuery: { linkQuery: ".imgg>a[href]", titleQuery: ".inside-article>.grid1 a[title]" },
method: print,
},
{
name: "JAVMOST",
disable: false,
hostname: "javmost.cx",
url: "https://javmost.cx/search/{{code}}/",
fetcher: "parser",
domQuery: {
linkQuery: "#content .card a#MyImage",
titleQuery: "#content .card-block .card-title",
},
method: print,
},
{
name: "HAYAV",
disable: false,
hostname: "hayav.com",
url: "https://hayav.com/video/{{code}}/",
fetcher: "get",
domQuery: {
// subQuery: `.site__col>.entry-header>h1.entry-title`,
},
method: print,
},
{
name: "AvJoy",
disable: false,
hostname: "avjoy.me",
url: "https://avjoy.me/search/video/{{code}}",
fetcher: "parser",
domQuery: {
titleQuery: `.content-info>.content-title`,
linkQuery: `.content-row>a`,
},
method: print,
},
{
name: "JAVFC2",
disable: false,
hostname: "javfc2.net",
url: "https://javfc2.net/?s={{code}}",
fetcher: "parser",
domQuery: {
linkQuery: "article.loop-video>a[href]",
titleQuery: "article.loop-video .entry-header",
},
method: print,
},
{
name: "baihuse",
disable: false,
hostname: "paipancon.com",
url: "https://paipancon.com/search/{{code}}",
fetcher: "parser",
domQuery: {
linkQuery: "div.col>div.card>a[href]",
// 然而这个不是 title是图片这个站居然 title 里不包含 code反而图片包含
titleQuery: "div.card img.card-img-top",
},
method: print,
},
{
name: "GGJAV",
disable: false,
hostname: "ggjav.com",
url: "https://ggjav.com/main/search?string={{code}}",
fetcher: "parser",
domQuery: {
listIndex: 1,
spaceCode: true,
titleQuery: "div.columns.large-3.medium-6.small-12.item.float-left>div.item_title>a.gray_a",
linkQuery: "div.columns.large-3.medium-6.small-12.item.float-left>div.item_title>a.gray_a",
},
method: print,
},
{
name: "AV01",
disable: false,
hostname: "av01.tv",
url: "https://www.av01.tv/search/videos?search_query={{code}}",
fetcher: "parser",
domQuery: { linkQuery: "div[id].well-sm>a", titleQuery: ".video-views>.pull-left" },
method: print,
},
{
name: "JavBus",
disableHostname: "javbus",
disable: false,
hostname: "javbus.com",
url: "https://javbus.com/{{code}}",
fetcher: "get",
domQuery: {},
method: print,
},
{
name: "JavDB",
disableHostname: "javdb",
disable: false,
hostname: "javdb.com",
url: "https://javdb.com/search?q={{code}}",
fetcher: "parser",
domQuery: {
linkQuery: ".movie-list>.item:first-child>a",
titleQuery: ".video-title",
},
method: print,
},
];

View File

@@ -7,7 +7,7 @@ const connectList = siteList.map((site) => site.hostname).concat(["javdb007.com"
const UserscriptConfig: MonkeyUserScript = {
author: "mission522",
version: "1.1.3",
version: "1.1.4",
license: "MIT",
name: "JAV 添加跳转在线观看",
match: ["*://*/cn/?v=jav*"],