Fixed duplicate IDs in languages profile items

pull/2683/head v1.4.5-beta.5
morpheus65535 2 months ago committed by GitHub
parent 9d8d995d3a
commit c11bdf34fa
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -528,3 +528,32 @@ def upgrade_languages_profile_hi_values():
.values({"items": json.dumps(items)}) .values({"items": json.dumps(items)})
.where(TableLanguagesProfiles.profileId == languages_profile.profileId) .where(TableLanguagesProfiles.profileId == languages_profile.profileId)
) )
def fix_languages_profiles_with_duplicate_ids():
languages_profiles = database.execute(
select(TableLanguagesProfiles.profileId, TableLanguagesProfiles.items, TableLanguagesProfiles.cutoff)).all()
for languages_profile in languages_profiles:
if languages_profile.cutoff:
# ignore profiles that have a cutoff set
continue
languages_profile_ids = []
languages_profile_has_duplicate = False
languages_profile_items = json.loads(languages_profile.items)
for items in languages_profile_items:
if items['id'] in languages_profile_ids:
languages_profile_has_duplicate = True
break
else:
languages_profile_ids.append(items['id'])
if languages_profile_has_duplicate:
item_id = 0
for items in languages_profile_items:
item_id += 1
items['id'] = item_id
database.execute(
update(TableLanguagesProfiles)
.values({"items": json.dumps(languages_profile_items)})
.where(TableLanguagesProfiles.profileId == languages_profile.profileId)
)

@ -35,7 +35,8 @@ else:
# there's missing embedded packages after a commit # there's missing embedded packages after a commit
check_if_new_update() check_if_new_update()
from app.database import System, database, update, migrate_db, create_db_revision, upgrade_languages_profile_hi_values # noqa E402 from app.database import (System, database, update, migrate_db, create_db_revision, upgrade_languages_profile_hi_values,
fix_languages_profiles_with_duplicate_ids) # noqa E402
from app.notifier import update_notifier # noqa E402 from app.notifier import update_notifier # noqa E402
from languages.get_languages import load_language_in_db # noqa E402 from languages.get_languages import load_language_in_db # noqa E402
from app.signalr_client import sonarr_signalr_client, radarr_signalr_client # noqa E402 from app.signalr_client import sonarr_signalr_client, radarr_signalr_client # noqa E402
@ -50,6 +51,7 @@ if args.create_db_revision:
else: else:
migrate_db(app) migrate_db(app)
upgrade_languages_profile_hi_values() upgrade_languages_profile_hi_values()
fix_languages_profiles_with_duplicate_ids()
configure_proxy_func() configure_proxy_func()

@ -1,7 +1,9 @@
# coding=utf-8 # coding=utf-8
import json
from app.config import settings from app.config import settings
from app.database import TableShowsRootfolder, TableMoviesRootfolder, database, select from app.database import TableShowsRootfolder, TableMoviesRootfolder, TableLanguagesProfiles, database, select
from app.event_handler import event_stream from app.event_handler import event_stream
from .path_mappings import path_mappings from .path_mappings import path_mappings
from sonarr.rootfolder import check_sonarr_rootfolder from sonarr.rootfolder import check_sonarr_rootfolder
@ -47,4 +49,21 @@ def get_health_issues():
health_issues.append({'object': path_mappings.path_replace_movie(item.path), health_issues.append({'object': path_mappings.path_replace_movie(item.path),
'issue': item.error}) 'issue': item.error})
# get languages profiles duplicate ids issues when there's a cutoff set
languages_profiles = database.execute(
select(TableLanguagesProfiles.items, TableLanguagesProfiles.name, TableLanguagesProfiles.cutoff)).all()
for languages_profile in languages_profiles:
if not languages_profile.cutoff:
# ignore profiles that don't have a cutoff set
continue
languages_profile_ids = []
for items in json.loads(languages_profile.items):
if items['id'] in languages_profile_ids:
health_issues.append({'object': languages_profile.name,
'issue': 'This languages profile has duplicate IDs. You need to edit this profile'
' and make sure to select the proper cutoff if required.'})
break
else:
languages_profile_ids.append(items['id'])
return health_issues return health_issues

@ -270,6 +270,7 @@ function useRoutes(): CustomRouteObject[] {
{ {
path: "status", path: "status",
name: "Status", name: "Status",
badge: data?.status,
element: ( element: (
<Lazy> <Lazy>
<SystemStatusView></SystemStatusView> <SystemStatusView></SystemStatusView>
@ -309,6 +310,7 @@ function useRoutes(): CustomRouteObject[] {
data?.sonarr_signalr, data?.sonarr_signalr,
data?.radarr_signalr, data?.radarr_signalr,
data?.announcements, data?.announcements,
data?.status,
radarr, radarr,
sonarr, sonarr,
], ],

@ -2,7 +2,7 @@ import { FunctionComponent, useCallback, useMemo } from "react";
import { Badge, Button, Group } from "@mantine/core"; import { Badge, Button, Group } from "@mantine/core";
import { faTrash, faWrench } from "@fortawesome/free-solid-svg-icons"; import { faTrash, faWrench } from "@fortawesome/free-solid-svg-icons";
import { ColumnDef } from "@tanstack/react-table"; import { ColumnDef } from "@tanstack/react-table";
import { cloneDeep } from "lodash"; import { cloneDeep, includes, maxBy } from "lodash";
import { Action } from "@/components"; import { Action } from "@/components";
import { import {
anyCutoff, anyCutoff,
@ -79,10 +79,10 @@ const Table: FunctionComponent = () => {
}) => { }) => {
return ( return (
<Group gap="xs" wrap="nowrap"> <Group gap="xs" wrap="nowrap">
{items.map((v) => { {items.map((v, i) => {
const isCutoff = v.id === cutoff || cutoff === anyCutoff; const isCutoff = v.id === cutoff || cutoff === anyCutoff;
return ( return (
<ItemBadge key={v.id} cutoff={isCutoff} item={v}></ItemBadge> <ItemBadge key={i} cutoff={isCutoff} item={v}></ItemBadge>
); );
})} })}
</Group> </Group>
@ -148,9 +148,45 @@ const Table: FunctionComponent = () => {
icon={faWrench} icon={faWrench}
c="gray" c="gray"
onClick={() => { onClick={() => {
const lastId = maxBy(profile.items, "id")?.id || 0;
// We once had an issue on the past where there were duplicated
// item ids that needs to become unique upon editing.
const sanitizedProfile = {
...cloneDeep(profile),
items: profile.items.reduce(
(acc, value) => {
const { ids, duplicatedIds, items } = acc;
// We once had an issue on the past where there were duplicated
// item ids that needs to become unique upon editing.
if (includes(ids, value.id)) {
duplicatedIds.push(value.id);
items.push({
...value,
id: lastId + duplicatedIds.length,
});
return acc;
}
ids.push(value.id);
items.push(value);
return acc;
},
{
ids: [] as number[],
duplicatedIds: [] as number[],
items: [] as typeof profile.items,
},
).items,
tag: profile.tag || undefined,
};
modals.openContextModal(ProfileEditModal, { modals.openContextModal(ProfileEditModal, {
languages, languages,
profile: cloneDeep(profile), profile: sanitizedProfile,
onComplete: updateProfile, onComplete: updateProfile,
}); });
}} }}

Loading…
Cancel
Save