Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 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
18 changes: 18 additions & 0 deletions docs/widgets/services/jellystat.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
---
title: Jellystat
description: Jellystat Widget Configuration
---

Learn more about [Jellystat](https://github.com/CyferShepard/Jellystat). The widget supports (at least) Jellystat version 1.1.6

You can create an API key from inside Jellystat at `Settings > API Key`.

Allowed fields: `["songs", "movies", "episodes", "other"]`.

```yaml
widget:
type: jellystat
url: http://jellystat.host.or.ip
key: apikeyapikeyapikeyapikeyapikey
days: 30 # optional, defaults to 30
```
6 changes: 6 additions & 0 deletions public/locales/en/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -1042,5 +1042,11 @@
"downloads": "Downloads",
"uploads": "Uploads",
"sharedFiles": "Files"
},
"jellystat": {
"songs": "Songs",
"movies": "Movies",
"episodes": "Episodes",
"other": "Other"
}
}
6 changes: 6 additions & 0 deletions src/utils/config/service-helpers.js
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should be inserted alphabetical (ish) by widget name

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried to apply this suggestion, but honestly there are far too many widgets in the wrong order to be sure this is what you meant.

833db71b8770678c3c3efffe62286bef034c632e

Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,9 @@ export function cleanServiceGroups(groups) {
referrerPolicy,
src,

// jellystat
days,

// kopia
snapshotHost,
snapshotPath,
Expand Down Expand Up @@ -563,6 +566,9 @@ export function cleanServiceGroups(groups) {
if (type === "spoolman") {
if (spoolIds !== undefined) widget.spoolIds = spoolIds;
}
if (type === "jellystat") {
if (days !== undefined) widget.days = parseInt(days, 10);
}
return widget;
});
return cleanedService;
Expand Down
2 changes: 1 addition & 1 deletion src/utils/proxy/handlers/credentialed.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ export default async function credentialedProxyHandler(req, res, map) {
} else if (widget.type === "proxmoxbackupserver") {
delete headers["Content-Type"];
headers.Authorization = `PBSAPIToken=${widget.username}:${widget.password}`;
} else if (widget.type === "autobrr") {
} else if (["autobrr", "jellystat"].includes(widget.type)) {
headers["X-API-Token"] = `${widget.key}`;
} else if (widget.type === "tubearchivist") {
headers.Authorization = `Token ${widget.key}`;
Expand Down
1 change: 1 addition & 0 deletions src/widgets/components.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ const components = {
jdownloader: dynamic(() => import("./jdownloader/component")),
jellyfin: dynamic(() => import("./emby/component")),
jellyseerr: dynamic(() => import("./jellyseerr/component")),
jellystat: dynamic(() => import("./jellystat/component")),
kavita: dynamic(() => import("./kavita/component")),
komga: dynamic(() => import("./komga/component")),
kopia: dynamic(() => import("./kopia/component")),
Expand Down
42 changes: 42 additions & 0 deletions src/widgets/jellystat/component.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import Block from "components/services/widget/block";
import Container from "components/services/widget/container";

import useWidgetAPI from "utils/proxy/use-widget-api";

export default function Component({ service }) {
const { widget } = service;

// Days validation
if (!(Number.isInteger(widget.days) && 0 < widget.days)) widget.days = 30;

if (!widget.fields) {
widget.fields = [];
}

const { data: viewsData, error: viewsError } = useWidgetAPI(widget, "getViewsByLibraryType", { days: widget.days });

const error = viewsError || viewsData?.message;
if (error) {
return <Container service={service} error={error} />;
}

if (!viewsData) {
return (
<Container service={service}>
<Block label="jellystat.songs" />
<Block label="jellystat.movies" />
<Block label="jellystat.episodes" />
<Block label="jellystat.other" />
</Container>
);
}

return (
<Container service={service}>
<Block label="jellystat.songs" value={viewsData.Audio} />
<Block label="jellystat.movies" value={viewsData.Movie} />
<Block label="jellystat.episodes" value={viewsData.Series} />
<Block label="jellystat.other" value={viewsData.Other} />
</Container>
);
}
15 changes: 15 additions & 0 deletions src/widgets/jellystat/widget.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import credentialedProxyHandler from "utils/proxy/handlers/credentialed";

const widget = {
api: "{url}/{endpoint}",
proxyHandler: credentialedProxyHandler,

mappings: {
getViewsByLibraryType: {
endpoint: "stats/getViewsByLibraryType",
params: ["days"],
},
},
};

export default widget;
2 changes: 2 additions & 0 deletions src/widgets/widgets.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ import immich from "./immich/widget";
import jackett from "./jackett/widget";
import jdownloader from "./jdownloader/widget";
import jellyseerr from "./jellyseerr/widget";
import jellystat from "./jellystat/widget";
import karakeep from "./karakeep/widget";
import kavita from "./kavita/widget";
import komga from "./komga/widget";
Expand Down Expand Up @@ -190,6 +191,7 @@ const widgets = {
jdownloader,
jellyfin: emby,
jellyseerr,
jellystat,
kavita,
komga,
kopia,
Expand Down
Loading