diff --git a/src/utils/config/service-helpers.js b/src/utils/config/service-helpers.js index 41fe263a..c63fa8f2 100644 --- a/src/utils/config/service-helpers.js +++ b/src/utils/config/service-helpers.js @@ -63,10 +63,10 @@ export async function servicesFromDocker() { const serviceServers = await Promise.all( Object.keys(servers).map(async (serverName) => { try { + const isSwarm = !!servers[serverName].swarm; const docker = new Docker(getDockerArguments(serverName).conn); - const containers = await docker.listContainers({ - all: true, - }); + const listProperties = { all: true }; + const containers = await ((isSwarm) ? docker.listServices(listProperties) : docker.listContainers(listProperties)); // bad docker connections can result in a object? // in any case, this ensures the result is the expected array @@ -76,17 +76,19 @@ export async function servicesFromDocker() { const discovered = containers.map((container) => { let constructedService = null; + const containerLabels = isSwarm ? shvl.get(container, 'Spec.Labels') : container.Labels; + const containerName = isSwarm ? shvl.get(container, 'Spec.Name') : container.Names[0]; - Object.keys(container.Labels).forEach((label) => { + Object.keys(containerLabels).forEach((label) => { if (label.startsWith("homepage.")) { if (!constructedService) { constructedService = { - container: container.Names[0].replace(/^\//, ""), + container: containerName.replace(/^\//, ""), server: serverName, type: 'service' }; } - shvl.set(constructedService, label.replace("homepage.", ""), substituteEnvironmentVars(container.Labels[label])); + shvl.set(constructedService, label.replace("homepage.", ""), substituteEnvironmentVars(containerLabels[label])); } }); diff --git a/src/utils/proxy/use-widget-api.js b/src/utils/proxy/use-widget-api.js index 52e986e1..e4744038 100644 --- a/src/utils/proxy/use-widget-api.js +++ b/src/utils/proxy/use-widget-api.js @@ -7,7 +7,11 @@ export default function useWidgetAPI(widget, ...options) { if (options && options[1]?.refreshInterval) { config.refreshInterval = options[1].refreshInterval; } - const { data, error, mutate } = useSWR(formatProxyUrl(widget, ...options), config); + let url = formatProxyUrl(widget, ...options) + if (options[0] === "") { + url = null + } + const { data, error, mutate } = useSWR(url, config); // make the data error the top-level error return { data, error: data?.error ?? error, mutate } } diff --git a/src/widgets/lidarr/component.jsx b/src/widgets/lidarr/component.jsx index a6aa82c7..77d831f8 100644 --- a/src/widgets/lidarr/component.jsx +++ b/src/widgets/lidarr/component.jsx @@ -9,7 +9,9 @@ export default function Component({ service }) { const { widget } = service; - const { data: albumsData, error: albumsError } = useWidgetAPI(widget, "album"); + // album API endpoint can get massive, so we prevent calling if not included in fields see https://github.com/benphelps/homepage/discussions/1577 + const showAlbums = widget.fields?.includes('albums') || !widget.fields; + const { data: albumsData, error: albumsError } = useWidgetAPI(widget, showAlbums ? "album" : ""); const { data: wantedData, error: wantedError } = useWidgetAPI(widget, "wanted/missing"); const { data: queueData, error: queueError } = useWidgetAPI(widget, "queue/status"); @@ -18,7 +20,7 @@ export default function Component({ service }) { return ; } - if (!albumsData || !wantedData || !queueData) { + if ((showAlbums && !albumsData) || !wantedData || !queueData) { return ( @@ -32,7 +34,7 @@ export default function Component({ service }) { - + {showAlbums && } ); }