mirror of
https://github.com/stashapp/stash.git
synced 2025-12-17 12:24:38 +03:00
Add filesystem based blob storage (#3187)
* Refactor transaction hooks. Add preCommit * Add BlobStore * Use blobStore for tag images * Use blobStore for studio images * Use blobStore for performer images * Use blobStore for scene covers * Don't generate screenshots in legacy directory * Run post-hooks outside original transaction * Use blobStore for movie images * Remove unnecessary DestroyImage methods * Add missing filter for scene cover * Add covers to generate options * Add generate cover option to UI * Add screenshot migration * Delete thumb files as part of screenshot migration
This commit is contained in:
@@ -8,6 +8,8 @@ import {
|
||||
mutateMetadataImport,
|
||||
mutateMetadataClean,
|
||||
mutateAnonymiseDatabase,
|
||||
mutateMigrateSceneScreenshots,
|
||||
mutateMigrateBlobs,
|
||||
} from "src/core/StashService";
|
||||
import { useToast } from "src/hooks/Toast";
|
||||
import downloadFile from "src/utils/download";
|
||||
@@ -170,6 +172,17 @@ export const DataManagementTasks: React.FC<IDataManagementTasks> = ({
|
||||
dryRun: false,
|
||||
});
|
||||
|
||||
const [migrateBlobsOptions, setMigrateBlobsOptions] =
|
||||
useState<GQL.MigrateBlobsInput>({
|
||||
deleteOld: true,
|
||||
});
|
||||
|
||||
const [migrateSceneScreenshotsOptions, setMigrateSceneScreenshotsOptions] =
|
||||
useState<GQL.MigrateSceneScreenshotsInput>({
|
||||
deleteFiles: false,
|
||||
overwriteExisting: false,
|
||||
});
|
||||
|
||||
type DialogOpenState = typeof dialogOpen;
|
||||
|
||||
function setDialogOpen(s: Partial<DialogOpenState>) {
|
||||
@@ -256,6 +269,42 @@ export const DataManagementTasks: React.FC<IDataManagementTasks> = ({
|
||||
}
|
||||
}
|
||||
|
||||
async function onMigrateSceneScreenshots() {
|
||||
try {
|
||||
await mutateMigrateSceneScreenshots(migrateSceneScreenshotsOptions);
|
||||
Toast.success({
|
||||
content: intl.formatMessage(
|
||||
{ id: "config.tasks.added_job_to_queue" },
|
||||
{
|
||||
operation_name: intl.formatMessage({
|
||||
id: "actions.migrate_scene_screenshots",
|
||||
}),
|
||||
}
|
||||
),
|
||||
});
|
||||
} catch (err) {
|
||||
Toast.error(err);
|
||||
}
|
||||
}
|
||||
|
||||
async function onMigrateBlobs() {
|
||||
try {
|
||||
await mutateMigrateBlobs(migrateBlobsOptions);
|
||||
Toast.success({
|
||||
content: intl.formatMessage(
|
||||
{ id: "config.tasks.added_job_to_queue" },
|
||||
{
|
||||
operation_name: intl.formatMessage({
|
||||
id: "actions.migrate_blobs",
|
||||
}),
|
||||
}
|
||||
),
|
||||
});
|
||||
} catch (err) {
|
||||
Toast.error(err);
|
||||
}
|
||||
}
|
||||
|
||||
async function onExport() {
|
||||
try {
|
||||
await mutateMetadataExport();
|
||||
@@ -507,6 +556,69 @@ export const DataManagementTasks: React.FC<IDataManagementTasks> = ({
|
||||
<FormattedMessage id="actions.rename_gen_files" />
|
||||
</Button>
|
||||
</Setting>
|
||||
|
||||
<div className="setting-group">
|
||||
<Setting
|
||||
headingID="actions.migrate_blobs"
|
||||
subHeadingID="config.tasks.migrate_blobs.description"
|
||||
>
|
||||
<Button
|
||||
id="migrateBlobs"
|
||||
variant="danger"
|
||||
onClick={() => onMigrateBlobs()}
|
||||
>
|
||||
<FormattedMessage id="actions.migrate_blobs" />
|
||||
</Button>
|
||||
</Setting>
|
||||
|
||||
<BooleanSetting
|
||||
id="migrate-blobs-delete-old"
|
||||
checked={migrateBlobsOptions.deleteOld ?? false}
|
||||
headingID="config.tasks.migrate_blobs.delete_old"
|
||||
onChange={(v) =>
|
||||
setMigrateBlobsOptions({ ...migrateBlobsOptions, deleteOld: v })
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="setting-group">
|
||||
<Setting
|
||||
headingID="actions.migrate_scene_screenshots"
|
||||
subHeadingID="config.tasks.migrate_scene_screenshots.description"
|
||||
>
|
||||
<Button
|
||||
id="migrateSceneScreenshots"
|
||||
variant="danger"
|
||||
onClick={() => onMigrateSceneScreenshots()}
|
||||
>
|
||||
<FormattedMessage id="actions.migrate_scene_screenshots" />
|
||||
</Button>
|
||||
</Setting>
|
||||
|
||||
<BooleanSetting
|
||||
id="migrate-scene-screenshots-overwrite-existing"
|
||||
checked={migrateSceneScreenshotsOptions.overwriteExisting ?? false}
|
||||
headingID="config.tasks.migrate_scene_screenshots.overwrite_existing"
|
||||
onChange={(v) =>
|
||||
setMigrateSceneScreenshotsOptions({
|
||||
...migrateSceneScreenshotsOptions,
|
||||
overwriteExisting: v,
|
||||
})
|
||||
}
|
||||
/>
|
||||
|
||||
<BooleanSetting
|
||||
id="migrate-scene-screenshots-delete-files"
|
||||
checked={migrateSceneScreenshotsOptions.deleteFiles ?? false}
|
||||
headingID="config.tasks.migrate_scene_screenshots.delete_files"
|
||||
onChange={(v) =>
|
||||
setMigrateSceneScreenshotsOptions({
|
||||
...migrateSceneScreenshotsOptions,
|
||||
deleteFiles: v,
|
||||
})
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</SettingSection>
|
||||
</Form.Group>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user