diff --git a/graphql/documents/mutations/scrapers.graphql b/graphql/documents/mutations/scrapers.graphql
new file mode 100644
index 000000000..3f186faec
--- /dev/null
+++ b/graphql/documents/mutations/scrapers.graphql
@@ -0,0 +1,3 @@
+mutation ReloadScrapers {
+ reloadScrapers
+}
diff --git a/graphql/schema/schema.graphql b/graphql/schema/schema.graphql
index 3a57a551e..5f9d9878a 100644
--- a/graphql/schema/schema.graphql
+++ b/graphql/schema/schema.graphql
@@ -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!
}
diff --git a/pkg/api/resolver_mutation_scraper.go b/pkg/api/resolver_mutation_scraper.go
new file mode 100644
index 000000000..74d9a0f7d
--- /dev/null
+++ b/pkg/api/resolver_mutation_scraper.go
@@ -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
+}
diff --git a/pkg/scraper/scrapers.go b/pkg/scraper/scrapers.go
index c352dfd20..8f3f6b6eb 100644
--- a/pkg/scraper/scrapers.go
+++ b/pkg/scraper/scrapers.go
@@ -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()
diff --git a/ui/v2.5/src/components/Changelog/Changelog.tsx b/ui/v2.5/src/components/Changelog/Changelog.tsx
index e5ec22014..2e22c0155 100644
--- a/ui/v2.5/src/components/Changelog/Changelog.tsx
+++ b/ui/v2.5/src/components/Changelog/Changelog.tsx
@@ -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 (
<>
Changelog:
+
+
+
@@ -35,7 +42,6 @@ const Changelog: React.FC = () => {
date="2020-06-06"
openState={openState}
setOpenState={setVersionOpenState}
- defaultOpen
>
diff --git a/ui/v2.5/src/components/Changelog/versions/index.ts b/ui/v2.5/src/components/Changelog/versions/index.ts
index c0b03708f..1d3060a63 100644
--- a/ui/v2.5/src/components/Changelog/versions/index.ts
+++ b/ui/v2.5/src/components/Changelog/versions/index.ts
@@ -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";
diff --git a/ui/v2.5/src/components/Changelog/versions/v030.tsx b/ui/v2.5/src/components/Changelog/versions/v030.tsx
new file mode 100644
index 000000000..4ce277bdb
--- /dev/null
+++ b/ui/v2.5/src/components/Changelog/versions/v030.tsx
@@ -0,0 +1,10 @@
+import React from "react";
+import ReactMarkdown from "react-markdown";
+
+const markup = `
+### 🎨 Improvements
+* Add reload scrapers button.
+
+`;
+
+export default () => ;
diff --git a/ui/v2.5/src/components/Performers/PerformerDetails/PerformerDetailsPanel.tsx b/ui/v2.5/src/components/Performers/PerformerDetails/PerformerDetailsPanel.tsx
index 2db9c820f..1cafe7fed 100644
--- a/ui/v2.5/src/components/Performers/PerformerDetails/PerformerDetailsPanel.tsx
+++ b/ui/v2.5/src/components/Performers/PerformerDetails/PerformerDetailsPanel.tsx
@@ -11,6 +11,7 @@ import {
stringToGender,
queryScrapePerformer,
queryScrapePerformerURL,
+ mutateReloadScrapers,
} from "src/core/StashService";
import {
Icon,
@@ -224,10 +225,24 @@ export const PerformerDetailsPanel: React.FC = ({
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 = ({
))
: ""}
+
+
+
diff --git a/ui/v2.5/src/components/Scenes/SceneDetails/SceneEditPanel.tsx b/ui/v2.5/src/components/Scenes/SceneDetails/SceneEditPanel.tsx
index 61251fcdf..34e6dc804 100644
--- a/ui/v2.5/src/components/Scenes/SceneDetails/SceneEditPanel.tsx
+++ b/ui/v2.5/src/components/Scenes/SceneDetails/SceneEditPanel.tsx
@@ -9,6 +9,7 @@ import {
useListSceneScrapers,
useSceneUpdate,
useSceneDestroy,
+ mutateReloadScrapers,
} from "src/core/StashService";
import {
PerformerSelect,
@@ -270,11 +271,21 @@ export const SceneEditPanel: React.FC = (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 (
{queryableScrapers.map((s) => (
@@ -282,6 +293,12 @@ export const SceneEditPanel: React.FC = (props: IProps) => {
{s.name}
))}
+ onReloadScrapers()}>
+
+
+
+ Reload scrapers
+
);
}
diff --git a/ui/v2.5/src/core/StashService.ts b/ui/v2.5/src/core/StashService.ts
index c3805fc52..ffe6e6d11 100644
--- a/ui/v2.5/src/core/StashService.ts
+++ b/ui/v2.5/src/core/StashService.ts
@@ -410,6 +410,11 @@ export const queryScrapeScene = (
},
});
+export const mutateReloadScrapers = () =>
+ client.mutate({
+ mutation: GQL.ReloadScrapersDocument,
+ });
+
export const mutateMetadataScan = (input: GQL.ScanMetadataInput) =>
client.mutate({
mutation: GQL.MetadataScanDocument,
diff --git a/ui/v2.5/src/index.scss b/ui/v2.5/src/index.scss
index 9d10ce082..35dd8fb4d 100755
--- a/ui/v2.5/src/index.scss
+++ b/ui/v2.5/src/index.scss
@@ -424,6 +424,11 @@ div.dropdown-menu {
}
}
+.popover-body .btn .fa-icon,
+.dropdown-item .fa-icon {
+ margin-left: 0;
+}
+
.brand-icon {
padding: 3px 6px;