Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed duplicate IDs in languages profile items #2667

Merged
merged 4 commits into from
Sep 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions bazarr/app/database.py
Original file line number Diff line number Diff line change
Expand Up @@ -528,3 +528,32 @@ def upgrade_languages_profile_hi_values():
.values({"items": json.dumps(items)})
.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)
)
4 changes: 3 additions & 1 deletion bazarr/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@
# there's missing embedded packages after a commit
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 languages.get_languages import load_language_in_db # noqa E402
from app.signalr_client import sonarr_signalr_client, radarr_signalr_client # noqa E402
Expand All @@ -50,6 +51,7 @@
else:
migrate_db(app)
upgrade_languages_profile_hi_values()
fix_languages_profiles_with_duplicate_ids()

configure_proxy_func()

Expand Down
21 changes: 20 additions & 1 deletion bazarr/utilities/health.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
# coding=utf-8

import json

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 .path_mappings import path_mappings
from sonarr.rootfolder import check_sonarr_rootfolder
Expand Down Expand Up @@ -47,4 +49,21 @@ def get_health_issues():
health_issues.append({'object': path_mappings.path_replace_movie(item.path),
'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
2 changes: 2 additions & 0 deletions frontend/src/Router/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,7 @@ function useRoutes(): CustomRouteObject[] {
{
path: "status",
name: "Status",
badge: data?.status,
element: (
<Lazy>
<SystemStatusView></SystemStatusView>
Expand Down Expand Up @@ -309,6 +310,7 @@ function useRoutes(): CustomRouteObject[] {
data?.sonarr_signalr,
data?.radarr_signalr,
data?.announcements,
data?.status,
radarr,
sonarr,
],
Expand Down
44 changes: 40 additions & 4 deletions frontend/src/pages/Settings/Languages/table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { FunctionComponent, useCallback, useMemo } from "react";
import { Badge, Button, Group } from "@mantine/core";
import { faTrash, faWrench } from "@fortawesome/free-solid-svg-icons";
import { ColumnDef } from "@tanstack/react-table";
import { cloneDeep } from "lodash";
import { cloneDeep, includes, maxBy } from "lodash";
import { Action } from "@/components";
import {
anyCutoff,
Expand Down Expand Up @@ -79,10 +79,10 @@ const Table: FunctionComponent = () => {
}) => {
return (
<Group gap="xs" wrap="nowrap">
{items.map((v) => {
{items.map((v, i) => {
const isCutoff = v.id === cutoff || cutoff === anyCutoff;
return (
<ItemBadge key={v.id} cutoff={isCutoff} item={v}></ItemBadge>
<ItemBadge key={i} cutoff={isCutoff} item={v}></ItemBadge>
);
})}
</Group>
Expand Down Expand Up @@ -148,9 +148,45 @@ const Table: FunctionComponent = () => {
icon={faWrench}
c="gray"
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, {
languages,
profile: cloneDeep(profile),
profile: sanitizedProfile,
onComplete: updateProfile,
});
}}
Expand Down