mirror of
https://github.com/stashapp/stash.git
synced 2025-12-18 12:54:38 +03:00
Add scrape gallery from fragment to UI (#1166)
This commit is contained in:
@@ -2,6 +2,7 @@
|
|||||||
* Added Performer tags.
|
* Added Performer tags.
|
||||||
|
|
||||||
### 🎨 Improvements
|
### 🎨 Improvements
|
||||||
|
* Add scrape gallery from fragment to UI
|
||||||
* Improved performer details and edit UI pages.
|
* Improved performer details and edit UI pages.
|
||||||
* Resolve python executable to `python3` or `python` for python script scrapers.
|
* Resolve python executable to `python3` or `python` for python script scrapers.
|
||||||
* Add `url` field to `URLReplace`, and make `queryURLReplace` available when scraping by URL.
|
* Add `url` field to `URLReplace`, and make `queryURLReplace` available when scraping by URL.
|
||||||
|
|||||||
@@ -1,13 +1,22 @@
|
|||||||
import React, { useEffect, useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import { useHistory } from "react-router-dom";
|
import { useHistory } from "react-router-dom";
|
||||||
import { Button, Form, Col, Row } from "react-bootstrap";
|
import {
|
||||||
|
Button,
|
||||||
|
Dropdown,
|
||||||
|
DropdownButton,
|
||||||
|
Form,
|
||||||
|
Col,
|
||||||
|
Row,
|
||||||
|
} from "react-bootstrap";
|
||||||
import Mousetrap from "mousetrap";
|
import Mousetrap from "mousetrap";
|
||||||
import * as GQL from "src/core/generated-graphql";
|
import * as GQL from "src/core/generated-graphql";
|
||||||
import {
|
import {
|
||||||
|
queryScrapeGallery,
|
||||||
queryScrapeGalleryURL,
|
queryScrapeGalleryURL,
|
||||||
useGalleryCreate,
|
useGalleryCreate,
|
||||||
useGalleryUpdate,
|
useGalleryUpdate,
|
||||||
useListGalleryScrapers,
|
useListGalleryScrapers,
|
||||||
|
mutateReloadScrapers,
|
||||||
} from "src/core/StashService";
|
} from "src/core/StashService";
|
||||||
import {
|
import {
|
||||||
PerformerSelect,
|
PerformerSelect,
|
||||||
@@ -64,6 +73,7 @@ export const GalleryEditPanel: React.FC<
|
|||||||
);
|
);
|
||||||
|
|
||||||
const Scrapers = useListGalleryScrapers();
|
const Scrapers = useListGalleryScrapers();
|
||||||
|
const [queryableScrapers, setQueryableScrapers] = useState<GQL.Scraper[]>([]);
|
||||||
|
|
||||||
const [
|
const [
|
||||||
scrapedGallery,
|
scrapedGallery,
|
||||||
@@ -118,6 +128,16 @@ export const GalleryEditPanel: React.FC<
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const newQueryableScrapers = (
|
||||||
|
Scrapers?.data?.listGalleryScrapers ?? []
|
||||||
|
).filter((s) =>
|
||||||
|
s.gallery?.supported_scrapes.includes(GQL.ScrapeType.Fragment)
|
||||||
|
);
|
||||||
|
|
||||||
|
setQueryableScrapers(newQueryableScrapers);
|
||||||
|
}, [Scrapers]);
|
||||||
|
|
||||||
function getGalleryInput() {
|
function getGalleryInput() {
|
||||||
return {
|
return {
|
||||||
id: isNew ? undefined : gallery?.id ?? "",
|
id: isNew ? undefined : gallery?.id ?? "",
|
||||||
@@ -162,6 +182,39 @@ export const GalleryEditPanel: React.FC<
|
|||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function onScrapeClicked(scraper: GQL.Scraper) {
|
||||||
|
setIsLoading(true);
|
||||||
|
try {
|
||||||
|
const galleryInput = getGalleryInput() as GQL.GalleryUpdateInput;
|
||||||
|
const result = await queryScrapeGallery(scraper.id, galleryInput);
|
||||||
|
if (!result.data || !result.data.scrapeGallery) {
|
||||||
|
Toast.success({
|
||||||
|
content: "No galleries found",
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setScrapedGallery(result.data.scrapeGallery);
|
||||||
|
} catch (e) {
|
||||||
|
Toast.error(e);
|
||||||
|
} finally {
|
||||||
|
setIsLoading(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function onReloadScrapers() {
|
||||||
|
setIsLoading(true);
|
||||||
|
try {
|
||||||
|
await mutateReloadScrapers();
|
||||||
|
|
||||||
|
// reload the performer scrapers
|
||||||
|
await Scrapers.refetch();
|
||||||
|
} catch (e) {
|
||||||
|
Toast.error(e);
|
||||||
|
} finally {
|
||||||
|
setIsLoading(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function onScrapeDialogClosed(data?: GQL.ScrapedGalleryDataFragment) {
|
function onScrapeDialogClosed(data?: GQL.ScrapedGalleryDataFragment) {
|
||||||
if (data) {
|
if (data) {
|
||||||
updateGalleryFromScrapedGallery(data);
|
updateGalleryFromScrapedGallery(data);
|
||||||
@@ -187,6 +240,32 @@ export const GalleryEditPanel: React.FC<
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function renderScraperMenu() {
|
||||||
|
if (isNew) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<DropdownButton
|
||||||
|
className="d-inline-block"
|
||||||
|
id="gallery-scrape"
|
||||||
|
title="Scrape with..."
|
||||||
|
>
|
||||||
|
{queryableScrapers.map((s) => (
|
||||||
|
<Dropdown.Item key={s.name} onClick={() => onScrapeClicked(s)}>
|
||||||
|
{s.name}
|
||||||
|
</Dropdown.Item>
|
||||||
|
))}
|
||||||
|
<Dropdown.Item onClick={() => onReloadScrapers()}>
|
||||||
|
<span className="fa-icon">
|
||||||
|
<Icon icon="sync-alt" />
|
||||||
|
</span>
|
||||||
|
<span>Reload scrapers</span>
|
||||||
|
</Dropdown.Item>
|
||||||
|
</DropdownButton>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
function urlScrapable(scrapedUrl: string): boolean {
|
function urlScrapable(scrapedUrl: string): boolean {
|
||||||
return (Scrapers?.data?.listGalleryScrapers ?? []).some((s) =>
|
return (Scrapers?.data?.listGalleryScrapers ?? []).some((s) =>
|
||||||
(s?.gallery?.urls ?? []).some((u) => scrapedUrl.includes(u))
|
(s?.gallery?.urls ?? []).some((u) => scrapedUrl.includes(u))
|
||||||
@@ -290,6 +369,9 @@ export const GalleryEditPanel: React.FC<
|
|||||||
Delete
|
Delete
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
<Col xs={6} className="text-right">
|
||||||
|
{renderScraperMenu()}
|
||||||
|
</Col>
|
||||||
</div>
|
</div>
|
||||||
<div className="form-container row px-3">
|
<div className="form-container row px-3">
|
||||||
<div className="col-12 col-lg-6 col-xl-12">
|
<div className="col-12 col-lg-6 col-xl-12">
|
||||||
|
|||||||
@@ -776,13 +776,13 @@ export const queryStashBoxScene = (stashBoxIndex: number, sceneID: string) =>
|
|||||||
|
|
||||||
export const queryScrapeGallery = (
|
export const queryScrapeGallery = (
|
||||||
scraperId: string,
|
scraperId: string,
|
||||||
scene: GQL.GalleryUpdateInput
|
gallery: GQL.GalleryUpdateInput
|
||||||
) =>
|
) =>
|
||||||
client.query<GQL.ScrapeGalleryQuery>({
|
client.query<GQL.ScrapeGalleryQuery>({
|
||||||
query: GQL.ScrapeGalleryDocument,
|
query: GQL.ScrapeGalleryDocument,
|
||||||
variables: {
|
variables: {
|
||||||
scraper_id: scraperId,
|
scraper_id: scraperId,
|
||||||
scene,
|
gallery,
|
||||||
},
|
},
|
||||||
fetchPolicy: "network-only",
|
fetchPolicy: "network-only",
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user