mirror of
https://github.com/stashapp/stash.git
synced 2025-12-17 12:24:38 +03:00
Reload scrapers button (#592)
* Add reload scraper option to performer details * Add scraper reload to scene edit page * Show scene scraper menu when no queryable scrapers * Add 0.3 changelog
This commit is contained in:
3
graphql/documents/mutations/scrapers.graphql
Normal file
3
graphql/documents/mutations/scrapers.graphql
Normal file
@@ -0,0 +1,3 @@
|
||||
mutation ReloadScrapers {
|
||||
reloadScrapers
|
||||
}
|
||||
@@ -53,6 +53,7 @@ type Query {
|
||||
"""List available scrapers"""
|
||||
listPerformerScrapers: [Scraper!]!
|
||||
listSceneScrapers: [Scraper!]!
|
||||
|
||||
"""Scrape a list of performers based on name"""
|
||||
scrapePerformerList(scraper_id: ID!, query: String!): [ScrapedPerformer!]!
|
||||
"""Scrapes a complete performer record based on a scrapePerformerList result"""
|
||||
@@ -153,6 +154,9 @@ type Mutation {
|
||||
"""Clean metadata. Returns the job ID"""
|
||||
metadataClean: String!
|
||||
|
||||
"""Reload scrapers"""
|
||||
reloadScrapers: Boolean!
|
||||
|
||||
stopJob: Boolean!
|
||||
}
|
||||
|
||||
|
||||
17
pkg/api/resolver_mutation_scraper.go
Normal file
17
pkg/api/resolver_mutation_scraper.go
Normal file
@@ -0,0 +1,17 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/stashapp/stash/pkg/scraper"
|
||||
)
|
||||
|
||||
func (r *mutationResolver) ReloadScrapers(ctx context.Context) (bool, error) {
|
||||
err := scraper.ReloadScrapers()
|
||||
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return true, nil
|
||||
}
|
||||
@@ -50,6 +50,12 @@ func loadScrapers() ([]scraperConfig, error) {
|
||||
return scrapers, nil
|
||||
}
|
||||
|
||||
func ReloadScrapers() error {
|
||||
scrapers = nil
|
||||
_, err := loadScrapers()
|
||||
return err
|
||||
}
|
||||
|
||||
func ListPerformerScrapers() ([]*models.Scraper, error) {
|
||||
// read scraper config files from the directory and cache
|
||||
scrapers, err := loadScrapers()
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React from "react";
|
||||
import { useChangelogStorage } from "src/hooks";
|
||||
import Version from "./Version";
|
||||
import { V010, V011, V020, V021 } from "./versions";
|
||||
import { V010, V011, V020, V021, V030 } from "./versions";
|
||||
|
||||
const Changelog: React.FC = () => {
|
||||
const [{ data, loading }, setOpenState] = useChangelogStorage();
|
||||
@@ -21,12 +21,19 @@ const Changelog: React.FC = () => {
|
||||
return (
|
||||
<>
|
||||
<h1 className="mb-4">Changelog:</h1>
|
||||
<Version
|
||||
version="v0.3.0"
|
||||
openState={openState}
|
||||
setOpenState={setVersionOpenState}
|
||||
defaultOpen
|
||||
>
|
||||
<V030 />
|
||||
</Version>
|
||||
<Version
|
||||
version="v0.2.1"
|
||||
date="2020-06-10"
|
||||
openState={openState}
|
||||
setOpenState={setVersionOpenState}
|
||||
defaultOpen
|
||||
>
|
||||
<V021 />
|
||||
</Version>
|
||||
@@ -35,7 +42,6 @@ const Changelog: React.FC = () => {
|
||||
date="2020-06-06"
|
||||
openState={openState}
|
||||
setOpenState={setVersionOpenState}
|
||||
defaultOpen
|
||||
>
|
||||
<V020 />
|
||||
</Version>
|
||||
|
||||
@@ -2,3 +2,4 @@ export { default as V010 } from "./v010";
|
||||
export { default as V011 } from "./v011";
|
||||
export { default as V020 } from "./v020";
|
||||
export { default as V021 } from "./v021";
|
||||
export { default as V030 } from "./v030";
|
||||
|
||||
10
ui/v2.5/src/components/Changelog/versions/v030.tsx
Normal file
10
ui/v2.5/src/components/Changelog/versions/v030.tsx
Normal file
@@ -0,0 +1,10 @@
|
||||
import React from "react";
|
||||
import ReactMarkdown from "react-markdown";
|
||||
|
||||
const markup = `
|
||||
### 🎨 Improvements
|
||||
* Add reload scrapers button.
|
||||
|
||||
`;
|
||||
|
||||
export default () => <ReactMarkdown source={markup} />;
|
||||
@@ -11,6 +11,7 @@ import {
|
||||
stringToGender,
|
||||
queryScrapePerformer,
|
||||
queryScrapePerformerURL,
|
||||
mutateReloadScrapers,
|
||||
} from "src/core/StashService";
|
||||
import {
|
||||
Icon,
|
||||
@@ -224,10 +225,24 @@ export const PerformerDetailsPanel: React.FC<IPerformerDetails> = ({
|
||||
ImageUtils.onImageChange(event, onImageLoad);
|
||||
}
|
||||
|
||||
function onDisplayFreeOnesDialog(scraper: GQL.Scraper) {
|
||||
function onDisplayScrapeDialog(scraper: GQL.Scraper) {
|
||||
setIsDisplayingScraperDialog(scraper);
|
||||
}
|
||||
|
||||
async function onReloadScrapers() {
|
||||
setIsLoading(true);
|
||||
try {
|
||||
await mutateReloadScrapers();
|
||||
|
||||
// reload the performer scrapers
|
||||
await Scrapers.refetch();
|
||||
} catch (e) {
|
||||
Toast.error(e);
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
}
|
||||
|
||||
function getQueryScraperPerformerInput() {
|
||||
if (!scrapePerformerDetails) return {};
|
||||
|
||||
@@ -300,13 +315,21 @@ export const PerformerDetailsPanel: React.FC<IPerformerDetails> = ({
|
||||
<Button
|
||||
key={s.name}
|
||||
className="minimal"
|
||||
onClick={() => onDisplayFreeOnesDialog(s)}
|
||||
onClick={() => onDisplayScrapeDialog(s)}
|
||||
>
|
||||
{s.name}
|
||||
</Button>
|
||||
</div>
|
||||
))
|
||||
: ""}
|
||||
<div>
|
||||
<Button className="minimal" onClick={() => onReloadScrapers()}>
|
||||
<span className="fa-icon">
|
||||
<Icon icon="sync-alt" />
|
||||
</span>
|
||||
<span>Reload scrapers</span>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</Popover.Content>
|
||||
</Popover>
|
||||
|
||||
@@ -9,6 +9,7 @@ import {
|
||||
useListSceneScrapers,
|
||||
useSceneUpdate,
|
||||
useSceneDestroy,
|
||||
mutateReloadScrapers,
|
||||
} from "src/core/StashService";
|
||||
import {
|
||||
PerformerSelect,
|
||||
@@ -270,11 +271,21 @@ export const SceneEditPanel: React.FC<IProps> = (props: IProps) => {
|
||||
}
|
||||
}
|
||||
|
||||
function renderScraperMenu() {
|
||||
if (!queryableScrapers || queryableScrapers.length === 0) {
|
||||
return;
|
||||
}
|
||||
async function onReloadScrapers() {
|
||||
setIsLoading(true);
|
||||
try {
|
||||
await mutateReloadScrapers();
|
||||
|
||||
// reload the performer scrapers
|
||||
await Scrapers.refetch();
|
||||
} catch (e) {
|
||||
Toast.error(e);
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
}
|
||||
|
||||
function renderScraperMenu() {
|
||||
return (
|
||||
<DropdownButton id="scene-scrape" title="Scrape with...">
|
||||
{queryableScrapers.map((s) => (
|
||||
@@ -282,6 +293,12 @@ export const SceneEditPanel: React.FC<IProps> = (props: IProps) => {
|
||||
{s.name}
|
||||
</Dropdown.Item>
|
||||
))}
|
||||
<Dropdown.Item onClick={() => onReloadScrapers()}>
|
||||
<span className="fa-icon">
|
||||
<Icon icon="sync-alt" />
|
||||
</span>
|
||||
<span>Reload scrapers</span>
|
||||
</Dropdown.Item>
|
||||
</DropdownButton>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -410,6 +410,11 @@ export const queryScrapeScene = (
|
||||
},
|
||||
});
|
||||
|
||||
export const mutateReloadScrapers = () =>
|
||||
client.mutate<GQL.ReloadScrapersMutation>({
|
||||
mutation: GQL.ReloadScrapersDocument,
|
||||
});
|
||||
|
||||
export const mutateMetadataScan = (input: GQL.ScanMetadataInput) =>
|
||||
client.mutate<GQL.MetadataScanMutation>({
|
||||
mutation: GQL.MetadataScanDocument,
|
||||
|
||||
@@ -424,6 +424,11 @@ div.dropdown-menu {
|
||||
}
|
||||
}
|
||||
|
||||
.popover-body .btn .fa-icon,
|
||||
.dropdown-item .fa-icon {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.brand-icon {
|
||||
padding: 3px 6px;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user