mirror of
https://github.com/seerr-team/seerr.git
synced 2026-07-30 09:37:05 -04:00
feat: allow to disable version check (#3137)
Signed-off-by: Ludovic Ortega <ludovic.ortega@adminafk.fr>
This commit is contained in:
@@ -250,6 +250,9 @@ components:
|
||||
enableSpecialEpisodes:
|
||||
type: boolean
|
||||
example: false
|
||||
versionCheck:
|
||||
type: boolean
|
||||
example: false
|
||||
NetworkSettings:
|
||||
type: object
|
||||
properties:
|
||||
@@ -2151,10 +2154,18 @@ paths:
|
||||
/status:
|
||||
get:
|
||||
summary: Get Seerr status
|
||||
description: Returns the current Seerr status in a JSON object.
|
||||
description: Returns the current Seerr status in a JSON object. updateAvailable and commitsBehind are omitted when checkUpdateAvailable is false.
|
||||
security: []
|
||||
tags:
|
||||
- public
|
||||
parameters:
|
||||
- in: query
|
||||
name: checkUpdateAvailable
|
||||
description: If false, updateAvailable and commitsBehind will be omitted from the response. Defaults to the versionCheck setting.
|
||||
required: false
|
||||
example: false
|
||||
schema:
|
||||
type: boolean
|
||||
responses:
|
||||
'200':
|
||||
description: Returned status
|
||||
|
||||
@@ -48,6 +48,7 @@ export interface PublicSettingsResponse {
|
||||
emailEnabled: boolean;
|
||||
newPlexLogin: boolean;
|
||||
youtubeUrl: string;
|
||||
versionCheck: boolean;
|
||||
plexClientIdentifier: string;
|
||||
}
|
||||
|
||||
@@ -75,7 +76,7 @@ export interface CacheResponse {
|
||||
export interface StatusResponse {
|
||||
version: string;
|
||||
commitTag: string;
|
||||
updateAvailable: boolean;
|
||||
commitsBehind: number;
|
||||
updateAvailable?: boolean;
|
||||
commitsBehind?: number;
|
||||
restartRequired: boolean;
|
||||
}
|
||||
|
||||
@@ -156,6 +156,7 @@ export interface MainSettings {
|
||||
enableSpecialEpisodes: boolean;
|
||||
locale: string;
|
||||
youtubeUrl: string;
|
||||
versionCheck: boolean;
|
||||
}
|
||||
|
||||
export interface ProxySettings {
|
||||
@@ -214,6 +215,7 @@ interface FullPublicSettings extends PublicSettings {
|
||||
userEmailRequired: boolean;
|
||||
newPlexLogin: boolean;
|
||||
youtubeUrl: string;
|
||||
versionCheck: boolean;
|
||||
plexClientIdentifier: string;
|
||||
}
|
||||
|
||||
@@ -429,6 +431,7 @@ class Settings {
|
||||
enableSpecialEpisodes: false,
|
||||
locale: 'en',
|
||||
youtubeUrl: '',
|
||||
versionCheck: true,
|
||||
},
|
||||
plex: {
|
||||
name: '',
|
||||
@@ -734,6 +737,7 @@ class Settings {
|
||||
this.data.notifications.agents.email.options.userEmailRequired,
|
||||
newPlexLogin: this.data.main.newPlexLogin,
|
||||
youtubeUrl: this.data.main.youtubeUrl,
|
||||
versionCheck: this.data.main.versionCheck,
|
||||
plexClientIdentifier: this.data.clientId,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -48,40 +48,47 @@ const router = Router();
|
||||
router.use(checkUser);
|
||||
|
||||
router.get<unknown, StatusResponse>('/status', async (req, res) => {
|
||||
const githubApi = new GithubAPI();
|
||||
|
||||
const settings = getSettings();
|
||||
const currentVersion = getAppVersion();
|
||||
const commitTag = getCommitTag();
|
||||
const checkUpdate =
|
||||
req.query.checkUpdateAvailable !== undefined
|
||||
? req.query.checkUpdateAvailable
|
||||
: settings.fullPublicSettings.versionCheck;
|
||||
let updateAvailable = false;
|
||||
let commitsBehind = 0;
|
||||
|
||||
if (currentVersion.startsWith('develop-') && commitTag !== 'local') {
|
||||
const commits = await githubApi.getSeerrCommits();
|
||||
if (checkUpdate) {
|
||||
const githubApi = new GithubAPI();
|
||||
|
||||
if (commits.length) {
|
||||
const filteredCommits = commits.filter(
|
||||
(commit) => !commit.commit.message.includes('[skip ci]')
|
||||
);
|
||||
if (filteredCommits[0].sha !== commitTag) {
|
||||
updateAvailable = true;
|
||||
if (currentVersion.startsWith('develop-') && commitTag !== 'local') {
|
||||
const commits = await githubApi.getSeerrCommits();
|
||||
|
||||
if (commits.length) {
|
||||
const filteredCommits = commits.filter(
|
||||
(commit) => !commit.commit.message.includes('[skip ci]')
|
||||
);
|
||||
if (filteredCommits[0].sha !== commitTag) {
|
||||
updateAvailable = true;
|
||||
}
|
||||
|
||||
const commitIndex = filteredCommits.findIndex(
|
||||
(commit) => commit.sha === commitTag
|
||||
);
|
||||
|
||||
if (updateAvailable) {
|
||||
commitsBehind = commitIndex;
|
||||
}
|
||||
}
|
||||
} else if (commitTag !== 'local') {
|
||||
const releases = await githubApi.getSeerrReleases();
|
||||
|
||||
const commitIndex = filteredCommits.findIndex(
|
||||
(commit) => commit.sha === commitTag
|
||||
);
|
||||
if (releases.length) {
|
||||
const latestVersion = releases[0];
|
||||
|
||||
if (updateAvailable) {
|
||||
commitsBehind = commitIndex;
|
||||
}
|
||||
}
|
||||
} else if (commitTag !== 'local') {
|
||||
const releases = await githubApi.getSeerrReleases();
|
||||
|
||||
if (releases.length) {
|
||||
const latestVersion = releases[0];
|
||||
|
||||
if (!latestVersion.name.includes(currentVersion)) {
|
||||
updateAvailable = true;
|
||||
if (!latestVersion.name.includes(currentVersion)) {
|
||||
updateAvailable = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -89,8 +96,7 @@ router.get<unknown, StatusResponse>('/status', async (req, res) => {
|
||||
return res.status(200).json({
|
||||
version: getAppVersion(),
|
||||
commitTag: getCommitTag(),
|
||||
updateAvailable,
|
||||
commitsBehind,
|
||||
...(checkUpdate && { updateAvailable, commitsBehind }),
|
||||
restartRequired: restartFlag.isSet(),
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import useSettings from '@app/hooks/useSettings';
|
||||
import defineMessages from '@app/utils/defineMessages';
|
||||
import {
|
||||
ArrowUpCircleIcon,
|
||||
@@ -23,10 +24,14 @@ interface VersionStatusProps {
|
||||
}
|
||||
|
||||
const VersionStatus = ({ onClick }: VersionStatusProps) => {
|
||||
const settings = useSettings();
|
||||
const intl = useIntl();
|
||||
const { data } = useSWR<StatusResponse>('/api/v1/status', {
|
||||
refreshInterval: 60 * 1000,
|
||||
});
|
||||
const { data } = useSWR<StatusResponse>(
|
||||
`/api/v1/status?checkUpdateAvailable=${settings.currentSettings.versionCheck}`,
|
||||
{
|
||||
refreshInterval: 60 * 1000,
|
||||
}
|
||||
);
|
||||
|
||||
if (!data) {
|
||||
return null;
|
||||
@@ -65,21 +70,23 @@ const VersionStatus = ({ onClick }: VersionStatusProps) => {
|
||||
)}
|
||||
<div className="flex min-w-0 flex-1 flex-col truncate px-2 last:pr-0">
|
||||
<span className="font-bold">{versionStream}</span>
|
||||
<span className="truncate">
|
||||
{data.commitTag === 'local' ? (
|
||||
'(⌐■_■)'
|
||||
) : data.commitsBehind > 0 ? (
|
||||
intl.formatMessage(messages.commitsbehind, {
|
||||
commitsBehind: data.commitsBehind,
|
||||
})
|
||||
) : data.commitsBehind === -1 ? (
|
||||
intl.formatMessage(messages.outofdate)
|
||||
) : (
|
||||
<code className="bg-transparent p-0">
|
||||
{data.version.replace('develop-', '')}
|
||||
</code>
|
||||
)}
|
||||
</span>
|
||||
{data.commitsBehind !== undefined && (
|
||||
<span className="truncate">
|
||||
{data.commitTag === 'local' ? (
|
||||
'(⌐■_■)'
|
||||
) : data.commitsBehind > 0 ? (
|
||||
intl.formatMessage(messages.commitsbehind, {
|
||||
commitsBehind: data.commitsBehind,
|
||||
})
|
||||
) : data.commitsBehind === -1 ? (
|
||||
intl.formatMessage(messages.outofdate)
|
||||
) : (
|
||||
<code className="bg-transparent p-0">
|
||||
{data.version.replace('develop-', '')}
|
||||
</code>
|
||||
)}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
{data.updateAvailable && <ArrowUpCircleIcon className="h-6 w-6" />}
|
||||
</Link>
|
||||
|
||||
@@ -4,6 +4,7 @@ import List from '@app/components/Common/List';
|
||||
import LoadingSpinner from '@app/components/Common/LoadingSpinner';
|
||||
import PageTitle from '@app/components/Common/PageTitle';
|
||||
import Releases from '@app/components/Settings/SettingsAbout/Releases';
|
||||
import useSettings from '@app/hooks/useSettings';
|
||||
import globalMessages from '@app/i18n/globalMessages';
|
||||
import ErrorPage from '@app/pages/_error';
|
||||
import defineMessages from '@app/utils/defineMessages';
|
||||
@@ -29,17 +30,21 @@ const messages = defineMessages('components.Settings.SettingsAbout', {
|
||||
documentation: 'Documentation',
|
||||
outofdate: 'Out of Date',
|
||||
uptodate: 'Up to Date',
|
||||
versionCheckDisabled: 'Version Check Disabled',
|
||||
runningDevelop:
|
||||
'You are running the <code>develop</code> branch of Seerr, which is only recommended for those contributing to development or assisting with bleeding-edge testing.',
|
||||
});
|
||||
|
||||
const SettingsAbout = () => {
|
||||
const settings = useSettings();
|
||||
const intl = useIntl();
|
||||
const { data, error } = useSWR<SettingsAboutResponse>(
|
||||
'/api/v1/settings/about'
|
||||
);
|
||||
|
||||
const { data: status } = useSWR<StatusResponse>('/api/v1/status');
|
||||
const { data: status } = useSWR<StatusResponse>(
|
||||
settings.currentSettings.versionCheck ? '/api/v1/status' : null
|
||||
);
|
||||
|
||||
if (!data && !error) {
|
||||
return <LoadingSpinner />;
|
||||
@@ -75,42 +80,62 @@ const SettingsAbout = () => {
|
||||
<code className="truncate">
|
||||
{data.version.replace('develop-', '')}
|
||||
</code>
|
||||
{status?.commitTag !== 'local' &&
|
||||
(status?.updateAvailable ? (
|
||||
<a
|
||||
href={
|
||||
data.version.startsWith('develop-')
|
||||
? `https://github.com/seerr-team/seerr/compare/${status.commitTag}...develop`
|
||||
: 'https://github.com/seerr-team/seerr/releases'
|
||||
}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<Badge
|
||||
badgeType="warning"
|
||||
className="ml-2 !cursor-pointer transition hover:bg-yellow-400"
|
||||
{settings.currentSettings.versionCheck ? (
|
||||
status && status.commitTag !== 'local' ? (
|
||||
status.updateAvailable ? (
|
||||
<a
|
||||
href={
|
||||
data.version.startsWith('develop-')
|
||||
? `https://github.com/seerr-team/seerr/compare/${status.commitTag}...develop`
|
||||
: 'https://github.com/seerr-team/seerr/releases'
|
||||
}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
{intl.formatMessage(messages.outofdate)}
|
||||
</Badge>
|
||||
</a>
|
||||
) : (
|
||||
<a
|
||||
href={
|
||||
data.version.startsWith('develop-')
|
||||
? 'https://github.com/seerr-team/seerr/commits/develop'
|
||||
: 'https://github.com/seerr-team/seerr/releases'
|
||||
}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<Badge
|
||||
badgeType="success"
|
||||
className="ml-2 !cursor-pointer transition hover:bg-green-400"
|
||||
<Badge
|
||||
badgeType="warning"
|
||||
className="ml-2 !cursor-pointer transition hover:bg-yellow-400"
|
||||
>
|
||||
{intl.formatMessage(messages.outofdate)}
|
||||
</Badge>
|
||||
</a>
|
||||
) : (
|
||||
<a
|
||||
href={
|
||||
data.version.startsWith('develop-')
|
||||
? 'https://github.com/seerr-team/seerr/commits/develop'
|
||||
: 'https://github.com/seerr-team/seerr/releases'
|
||||
}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
{intl.formatMessage(messages.uptodate)}
|
||||
</Badge>
|
||||
</a>
|
||||
))}
|
||||
<Badge
|
||||
badgeType="success"
|
||||
className="ml-2 !cursor-pointer transition hover:bg-green-400"
|
||||
>
|
||||
{intl.formatMessage(messages.uptodate)}
|
||||
</Badge>
|
||||
</a>
|
||||
)
|
||||
) : null
|
||||
) : (
|
||||
<a
|
||||
href={
|
||||
data.version.startsWith('develop-')
|
||||
? 'https://github.com/seerr-team/seerr/commits/develop'
|
||||
: 'https://github.com/seerr-team/seerr/releases'
|
||||
}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<Badge
|
||||
badgeType="primary"
|
||||
className="ml-2 !cursor-pointer transition hover:bg-yellow-400"
|
||||
>
|
||||
{intl.formatMessage(messages.versionCheckDisabled)}
|
||||
</Badge>
|
||||
</a>
|
||||
)}
|
||||
</List.Item>
|
||||
<List.Item title={intl.formatMessage(messages.totalmedia)}>
|
||||
{intl.formatNumber(data.totalMediaItems)}
|
||||
|
||||
@@ -74,6 +74,8 @@ const messages = defineMessages('components.Settings.SettingsMain', {
|
||||
youtubeUrl: 'YouTube URL',
|
||||
youtubeUrlTip:
|
||||
'Base URL for YouTube videos if a self-hosted YouTube instance is used.',
|
||||
versionCheck: 'Version Check',
|
||||
versionCheckTip: 'Automatically check for new versions on GitHub.',
|
||||
validationUrl: 'You must provide a valid URL',
|
||||
validationUrlTrailingSlash: 'URL must not end in a trailing slash',
|
||||
});
|
||||
@@ -183,6 +185,7 @@ const SettingsMain = () => {
|
||||
enableSpecialEpisodes: data?.enableSpecialEpisodes,
|
||||
cacheImages: data?.cacheImages,
|
||||
youtubeUrl: data?.youtubeUrl,
|
||||
versionCheck: data?.versionCheck,
|
||||
}}
|
||||
enableReinitialize
|
||||
validationSchema={MainSettingsSchema}
|
||||
@@ -205,6 +208,7 @@ const SettingsMain = () => {
|
||||
enableSpecialEpisodes: values.enableSpecialEpisodes,
|
||||
cacheImages: values.cacheImages,
|
||||
youtubeUrl: values.youtubeUrl,
|
||||
versionCheck: values?.versionCheck,
|
||||
});
|
||||
mutate('/api/v1/settings/public');
|
||||
mutate('/api/v1/status');
|
||||
@@ -607,6 +611,24 @@ const SettingsMain = () => {
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<div className="form-row">
|
||||
<label htmlFor="versionCheck" className="text-label">
|
||||
{intl.formatMessage(messages.versionCheck)}
|
||||
<span className="label-tip">
|
||||
{intl.formatMessage(messages.versionCheckTip)}
|
||||
</span>
|
||||
</label>
|
||||
<div className="form-input-area">
|
||||
<Field
|
||||
type="checkbox"
|
||||
id="versionCheck"
|
||||
name="versionCheck"
|
||||
onChange={() => {
|
||||
setFieldValue('versionCheck', !values.versionCheck);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="actions">
|
||||
<div className="flex justify-end">
|
||||
<span className="ml-3 inline-flex rounded-md shadow-sm">
|
||||
|
||||
@@ -23,9 +23,12 @@ const StatusChecker = () => {
|
||||
const intl = useIntl();
|
||||
const settings = useSettings();
|
||||
const { hasPermission } = useUser();
|
||||
const { data, error } = useSWR<StatusResponse>('/api/v1/status', {
|
||||
refreshInterval: 60 * 1000,
|
||||
});
|
||||
const { data, error } = useSWR<StatusResponse>(
|
||||
'/api/v1/status?checkUpdateAvailable=false',
|
||||
{
|
||||
refreshInterval: 60 * 1000,
|
||||
}
|
||||
);
|
||||
const [alertDismissed, setAlertDismissed] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
@@ -31,6 +31,7 @@ const defaultSettings = {
|
||||
emailEnabled: false,
|
||||
newPlexLogin: true,
|
||||
youtubeUrl: '',
|
||||
versionCheck: true,
|
||||
plexClientIdentifier: '',
|
||||
};
|
||||
|
||||
|
||||
@@ -920,6 +920,7 @@
|
||||
"components.Settings.SettingsAbout.totalrequests": "Total Requests",
|
||||
"components.Settings.SettingsAbout.uptodate": "Up to Date",
|
||||
"components.Settings.SettingsAbout.version": "Version",
|
||||
"components.Settings.SettingsAbout.versionCheckDisabled": "Version Check Disabled",
|
||||
"components.Settings.SettingsJobsCache.availability-sync": "Media Availability Sync",
|
||||
"components.Settings.SettingsJobsCache.cache": "Cache",
|
||||
"components.Settings.SettingsJobsCache.cacheDescription": "Seerr caches requests to external API endpoints to optimize performance and avoid making unnecessary API calls.",
|
||||
@@ -1045,6 +1046,8 @@
|
||||
"components.Settings.SettingsMain.validationApplicationUrlTrailingSlash": "URL must not end in a trailing slash",
|
||||
"components.Settings.SettingsMain.validationUrl": "You must provide a valid URL",
|
||||
"components.Settings.SettingsMain.validationUrlTrailingSlash": "URL must not end in a trailing slash",
|
||||
"components.Settings.SettingsMain.versionCheck": "Version Check",
|
||||
"components.Settings.SettingsMain.versionCheckTip": "Automatically check for new versions on GitHub.",
|
||||
"components.Settings.SettingsMain.youtubeUrl": "YouTube URL",
|
||||
"components.Settings.SettingsMain.youtubeUrlTip": "Base URL for YouTube videos if a self-hosted YouTube instance is used.",
|
||||
"components.Settings.SettingsNetwork.apiRequestTimeout": "API Request Timeout",
|
||||
|
||||
@@ -261,6 +261,7 @@ CoreApp.getInitialProps = async (initialProps) => {
|
||||
emailEnabled: false,
|
||||
newPlexLogin: true,
|
||||
youtubeUrl: '',
|
||||
versionCheck: true,
|
||||
plexClientIdentifier: '',
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user