### Setting Up Production Environment Variables and Starting Application Source: https://github.com/cyfershepard/jellystat/blob/main/_autodocs/README.md Details the environment variables required for production setup, including database credentials and API keys, followed by build and start commands. Ensure all variables are correctly exported before proceeding. ```bash # 1. Set required environment variables (configuration.md) export POSTGRES_USER=jellystat export POSTGRES_PASSWORD=securepassword export POSTGRES_IP=db.internal export JWT_SECRET=your-secret-key-min-32-chars export JF_HOST=https://jellyfin.example.com export JF_API_KEY=api-key-from-jellyfin # 2. Initialize database npm run build # 3. Start application npm start # 4. Check configuration state (api-reference.md → GET /auth/isConfigured) curl http://localhost:3000/auth/isConfigured ``` -------------------------------- ### Handle Configuration Setup Errors Source: https://github.com/cyfershepard/jellystat/blob/main/_autodocs/error-handling.md Demonstrates a configuration setup request with missing required environment variables. ```http POST /auth/configSetup Body: { JF_HOST: "http://invalid" } Status: 400 Body: "JF_HOST and JF_API_KEY are required for configuration" ``` -------------------------------- ### Example Application Settings Response Source: https://github.com/cyfershepard/jellystat/blob/main/_autodocs/configuration.md Provides an example of the JSON response received when querying the `settings` column from the `app_config` table. This illustrates typical values for runtime configuration parameters. ```json { "EXTERNAL_URL": "https://jellyfin.example.com", "preferred_admin": { "userid": "user123abc", "username": "admin" }, "ExcludedLibraries": ["music-library-id"], "ExcludedUsers": ["test-user-id"], "SyncLibrariesCron": "0 */6 * * *", "AutoSyncEnabled": true, "WebSocketEnabled": true } ``` -------------------------------- ### Setup Application Configuration Source: https://github.com/cyfershepard/jellystat/blob/main/_autodocs/types.md Updates the application configuration, typically used during initial setup. ```APIDOC ## POST /auth/configSetup ### Description Updates the application configuration. ### Method POST ### Endpoint /auth/configSetup ### Request Body - **config** (AppConfig) - Required - The new application configuration object. ``` -------------------------------- ### POST /configSetup Source: https://github.com/cyfershepard/jellystat/blob/main/_autodocs/api-reference.md Configures the connection to a Jellyfin/Emby server during the initial setup. ```APIDOC ## POST /configSetup ### Description Configure Jellyfin/Emby server connection during initial setup. ### Method POST ### Endpoint /auth/configSetup ### Parameters #### Request Body - **JF_HOST** (string) - Required - Jellyfin/Emby server URL - **JF_API_KEY** (string) - Required - API key from Jellyfin/Emby server ### Response #### Success Response (200) - The response includes the updated app_config record. ### Status Codes | Code | Meaning | |------|---------| | 200 | Configuration successful | | 400 | Missing required parameters | | 500 | Validation failed or DB error | ### Request Example ```javascript const response = await fetch('/auth/configSetup', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ JF_HOST: 'http://jellyfin.example.com', JF_API_KEY: 'your-api-key' }) }); ``` ``` -------------------------------- ### systemInfo Source: https://github.com/cyfershepard/jellystat/blob/main/_autodocs/classes-and-modules.md Gets system information from the Jellyfin server. ```APIDOC ## systemInfo() ### Description Gets system information from Jellyfin server. ### Method `async systemInfo(): Promise` ### Returns Server info including Version, Id, ProductName, etc. ### Example ```javascript const info = await API.systemInfo(); console.log(`Jellyfin ${info.Version}`); ``` ``` -------------------------------- ### POST /createuser Source: https://github.com/cyfershepard/jellystat/blob/main/_autodocs/api-reference.md Creates the initial application user during the setup process. ```APIDOC ## POST /createuser ### Description Create initial application user during setup. ### Method POST ### Endpoint /auth/createuser ### Parameters #### Request Body - **username** (string) - Required - Username for the app - **password** (string) - Required - Password (will be SHA3 hashed) ### Status Codes | Code | Meaning | |------|---------| | 200 | User created successfully | | 403 | User already configured | | 500 | Server error | ### Request Example ```javascript const response = await fetch('/auth/createuser', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ username: 'admin', password: 'newPassword' }) }); const { token } = await response.json(); ``` ``` -------------------------------- ### PlaybackFilter Example Usage Source: https://github.com/cyfershepard/jellystat/blob/main/_autodocs/types.md An example demonstrating how to construct a PlaybackFilter array for querying playback activity. It shows filtering by username, client, duration range, and date range. ```javascript [ { field: "UserName", value: "john" }, { field: "Client", in: "Jellyfin Web,Android TV" }, { field: "PlaybackDuration", min: 1000, max: 5000 }, { field: "ActivityDateInserted", min: "2025-01-01", max: "2025-12-31" } ] ``` -------------------------------- ### Instantiate and Get Config Source: https://github.com/cyfershepard/jellystat/blob/main/_autodocs/classes-and-modules.md Instantiate the Config class and retrieve the application configuration. ```javascript const config = new configClass(); const appConfig = await config.getConfig(); ``` -------------------------------- ### Get Library Overview Statistics Source: https://github.com/cyfershepard/jellystat/blob/main/_autodocs/api-reference.md Retrieves an overview of statistics for all libraries, including item count, total plays, and total duration. An example fetch request is provided. ```javascript GET /stats/getLibraryOverview ``` ```javascript [ { "LibraryId": string, "LibraryName": string, "ItemCount": number, "TotalPlays": number, "TotalDuration": number } ] ``` ```javascript const response = await fetch('/stats/getLibraryOverview'); const stats = await response.json(); ``` -------------------------------- ### Get Application Configuration Source: https://github.com/cyfershepard/jellystat/blob/main/_autodocs/types.md Retrieves the current application configuration. ```APIDOC ## GET /api/getconfig ### Description Returns the application configuration object. ### Method GET ### Endpoint /api/getconfig ### Response #### Success Response (200) - **config** (AppConfig) - The application configuration object. ``` -------------------------------- ### Database Configuration Example Source: https://github.com/cyfershepard/jellystat/blob/main/_autodocs/configuration.md Set these environment variables to configure the connection to your PostgreSQL database. Ensure POSTGRES_PASSWORD, POSTGRES_IP, and POSTGRES_PORT are provided. ```bash POSTGRES_USER=jellystat POSTGRES_PASSWORD=securepassword POSTGRES_IP=db.example.com POSTGRES_PORT=5432 POSTGRES_DB=jellystat_prod POSTGRES_SSL_ENABLED=true ``` -------------------------------- ### GET /getconfig Source: https://github.com/cyfershepard/jellystat/blob/main/_autodocs/api-reference.md Retrieve the current application configuration settings. ```APIDOC ## GET /getconfig ### Description Retrieve current application configuration. ### Method GET ### Endpoint /api/getconfig ### Response #### Success Response (200) - **JF_HOST** (string) - The Jellyfin host URL. - **APP_USER** (string) - The application username. - **settings** (object) - Application settings object. - **REQUIRE_LOGIN** (boolean) - Indicates if login is required. - **IS_JELLYFIN** (boolean) - Indicates if the application is using Jellyfin. ### Request Example ```javascript const response = await fetch('/api/getconfig'); const config = await response.json(); ``` ``` -------------------------------- ### Authentication Configuration Example Source: https://github.com/cyfershepard/jellystat/blob/main/_autodocs/configuration.md Set master override username and password for account recovery. Both must be provided together to enable this functionality. ```bash JS_USER=admin_recovery JS_PASSWORD=recovery_password ``` -------------------------------- ### Cron Expression Examples Source: https://github.com/cyfershepard/jellystat/blob/main/_autodocs/configuration.md Examples of standard 5-field cron expressions for scheduling tasks. These define when tasks will run. ```cron 0 0 * * * # Daily at midnight ``` ```cron 0 */6 * * * # Every 6 hours ``` ```cron */5 * * * * # Every 5 minutes ``` ```cron 0 8-20 * * * # Every hour from 8 AM to 8 PM ``` ```cron 0 0 1 * * # Monthly on 1st day ``` -------------------------------- ### GET /keys Source: https://github.com/cyfershepard/jellystat/blob/main/_autodocs/api-reference.md Lists all existing API keys associated with the account. ```APIDOC ## GET /keys ### Description List all API keys. ### Method GET ### Endpoint /api/keys ### Response #### Success Response (200) - **key** (string) - Description of key - **name** (string) - Description of name - **createdAt** (string) - Description of createdAt ### Response Example ```json [ { "key": "string", "name": "string", "createdAt": "string" } ] ``` ``` -------------------------------- ### Import WebSocket Utilities Source: https://github.com/cyfershepard/jellystat/blob/main/_autodocs/websocket-and-realtime.md Imports necessary functions for WebSocket server setup and message broadcasting. ```javascript const { setupWebSocketServer, sendUpdate, sendToAllClients } = require("./ws"); ``` -------------------------------- ### Get System Information Source: https://github.com/cyfershepard/jellystat/blob/main/_autodocs/classes-and-modules.md Retrieves general system information from the Jellyfin server, including version and product details. ```javascript const info = await API.systemInfo(); console.log(`Jellyfin ${info.Version}`); ``` -------------------------------- ### Jellyfin/Emby Server Configuration Example Source: https://github.com/cyfershepard/jellystat/blob/main/_autodocs/configuration.md Provide the host URL and API key for your Jellyfin or Emby server. Configure WebSocket usage and SSL certificate validation as needed. ```bash JF_HOST=http://jellyfin.local:8096 JF_API_KEY=abc123def456ghi789 IS_EMBY_API=false JF_USE_WEBSOCKETS=true REJECT_SELF_SIGNED_CERTIFICATES=false ``` -------------------------------- ### GET /getActivityMonitorSettings Source: https://github.com/cyfershepard/jellystat/blob/main/_autodocs/api-reference.md Retrieves the configuration settings for the activity monitor. ```APIDOC ## GET /getActivityMonitorSettings ### Description Get activity monitor configuration. ### Method GET ### Endpoint /api/getActivityMonitorSettings ### Response #### Success Response (200) - **enabled** (boolean) - Description of enabled - **minPlayDuration** (number) - Description of minPlayDuration - **sessionTimeout** (number) - Description of sessionTimeout ### Response Example ```json { "enabled": boolean, "minPlayDuration": number, "sessionTimeout": number } ``` ``` -------------------------------- ### Playback Tracking Configuration Example Source: https://github.com/cyfershepard/jellystat/blob/main/_autodocs/configuration.md Define the minimum duration in seconds for playback to be recorded and the time threshold in hours for grouping watch events into sessions. ```bash MINIMUM_SECONDS_TO_INCLUDE_PLAYBACK=10 NEW_WATCH_EVENT_THRESHOLD_HOURS=4 ``` -------------------------------- ### Create Initial Application User Source: https://github.com/cyfershepard/jellystat/blob/main/_autodocs/api-reference.md Use this endpoint during the initial setup to create the first user for the application. The provided password will be SHA3 hashed on the server. ```javascript const response = await fetch('/auth/createuser', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ username: 'admin', password: 'newPassword' }) }); const { token } = await response.json(); ``` -------------------------------- ### POST /auth/configSetup Errors Source: https://github.com/cyfershepard/jellystat/blob/main/_autodocs/error-handling.md Outlines potential errors during the initial configuration setup, including missing API keys, invalid credentials, and attempts to reconfigure. ```APIDOC ## POST /auth/configSetup ### Description Outlines potential errors during the initial configuration setup, including missing API keys, invalid credentials, and attempts to reconfigure. ### Method POST ### Endpoint /auth/configSetup ### Parameters #### Request Body - **JF_HOST** (string) - Required - The Jellystat host URL. - **JF_API_KEY** (string) - Required - The Jellystat API key. ### Response #### Success Response (200) - **message** (string) - Confirmation message upon successful configuration. #### Error Responses - **400 Bad Request**: Returned if `JF_HOST` or `JF_API_KEY` are missing in the request body. - **500 Internal Server Error**: Returned if the configuration is already complete and cannot be reconfigured, or if there are issues with server credentials validation. ``` -------------------------------- ### startTask Source: https://github.com/cyfershepard/jellystat/blob/main/_autodocs/classes-and-modules.md Starts an already-registered task with the TaskManager, specifying the task name and the type of trigger. ```APIDOC ## startTask(task, triggerType) ### Description Starts an already-registered task. ### Method startTask ### Parameters #### Path Parameters - **task** (object) - Required - Task identifier. - **task.name** (string) - Required - Task identifier. - **triggerType** (string) - Required - "manual", "cron", or "webhook" ### Request Example ```javascript manager.startTask( { name: 'sync-libs' }, 'cron' ); ``` ``` -------------------------------- ### Setup WebSocket Server Source: https://github.com/cyfershepard/jellystat/blob/main/_autodocs/websocket-and-realtime.md Initializes the Socket.IO server with optional namespace path. Requires an Express HTTP server instance. All connections are authenticated using JWT. ```javascript const http = require('http'); const express = require('express'); const { setupWebSocketServer } = require('./ws'); const app = express(); const server = http.createServer(app); setupWebSocketServer(server, '/api'); server.listen(3000, () => { console.log('WebSocket server listening on port 3000'); }); ``` -------------------------------- ### GET /getTaskSettings Source: https://github.com/cyfershepard/jellystat/blob/main/_autodocs/api-reference.md Retrieves the current settings for the task scheduler. ```APIDOC ## GET /getTaskSettings ### Description Get task scheduler settings. ### Method GET ### Endpoint /api/getTaskSettings ### Response #### Success Response (200) - **SyncLibrariesCron** (string) - Description of SyncLibrariesCron - **SyncUsersCron** (string) - Description of SyncUsersCron - **ActivityMonitorCron** (string) - Description of ActivityMonitorCron ### Response Example ```json { "SyncLibrariesCron": "string", "SyncUsersCron": "string", "ActivityMonitorCron": "string" } ``` ``` -------------------------------- ### Schedule Regular Library Sync via API Source: https://github.com/cyfershepard/jellystat/blob/main/_autodocs/README.md Example of setting up a recurring library synchronization task using the API endpoint. ```javascript // Via API (api-reference.md → POST /setTaskSettings) const response = await fetch('/api/setTaskSettings', { method: 'POST', body: JSON.stringify({ SyncLibrariesCron: '0 */6 * * *' // Every 6 hours }) }); ``` -------------------------------- ### Server Configuration Example Source: https://github.com/cyfershepard/jellystat/blob/main/_autodocs/configuration.md Configure server-specific settings like JWT secret, listen IP, base URL, and timezone. JWT_SECRET is required for secure token signing. ```bash JWT_SECRET=your-super-secret-jwt-key-min-32-chars JS_LISTEN_IP=0.0.0.0 JS_BASE_URL=/jellystat TZ=Etc/UTC ``` -------------------------------- ### GET /isConfigured Source: https://github.com/cyfershepard/jellystat/blob/main/_autodocs/api-reference.md Checks the configuration state of the application and retrieves its current version. ```APIDOC ## GET /isConfigured ### Description Check if the application is configured and retrieve its state. ### Method GET ### Endpoint /auth/isConfigured ### Response #### Success Response (200) - **state** (number) - 0 = not configured, 1 = user set, 2 = fully configured - **version** (string) - Application version #### Response Example ```json { "state": number, "version": string } ``` ### Request Example ```javascript const response = await fetch('/auth/isConfigured'); const { state, version } = await response.json(); ``` ``` -------------------------------- ### GET /getLibraries Source: https://github.com/cyfershepard/jellystat/blob/main/_autodocs/api-reference.md Lists all libraries available in the Jellyfin/Emby server. This endpoint provides a comprehensive overview of all managed libraries. ```APIDOC ## GET /getLibraries ### Description List all libraries in the Jellyfin/Emby server. ### Method GET ### Endpoint /api/getLibraries ### Response #### Success Response (200) - **Id** (string) - Unique identifier for the library - **Name** (string) - Name of the library - **Type** (string) - Type of the library (e.g., movies, shows) - **PrimaryImageHash** (string) - Hash of the primary image for the library - **DateCreated** (string) - Timestamp when the library was created - **ParentId** (string) - ID of the parent library, if applicable - **archived** (boolean) - Indicates if the library is archived ### Response Example ```json [ { "Id": "string", "Name": "string", "Type": "string", "PrimaryImageHash": "string", "DateCreated": "string", "ParentId": "string", "archived": boolean } ] ``` ``` -------------------------------- ### Geolocation Configuration Example Source: https://github.com/cyfershepard/jellystat/blob/main/_autodocs/configuration.md Provide your MaxMind GeoLite2 account ID and license key to enable IP geolocation features. Both are required. ```bash JS_GEOLITE_ACCOUNT_ID=123456 JS_GEOLITE_LICENSE_KEY=abc123XYZ789 ``` -------------------------------- ### Get Complete Application Configuration Source: https://github.com/cyfershepard/jellystat/blob/main/_autodocs/classes-and-modules.md Retrieve the complete application configuration, including server settings and state. Use when the application state needs to be checked. ```javascript const config = await new configClass().getConfig(); if (config.state === 2) { console.log(`Connected to: ${config.JF_HOST}`); } ``` -------------------------------- ### Example PostgreSQL Connection Error Source: https://github.com/cyfershepard/jellystat/blob/main/_autodocs/error-handling.md Illustrates a typical ECONNREFUSED error when the database server is not running. ```javascript Error: connect ECONNREFUSED 127.0.0.1:5432 at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1144:27) ``` -------------------------------- ### Backup Failed: No Write Permissions Source: https://github.com/cyfershepard/jellystat/blob/main/_autodocs/error-handling.md Example error message when the backup process lacks write access to the designated backup folder. ```text "Backup Failed: No write permissions for the folder: [path]" ``` -------------------------------- ### POST /syncPlayback Source: https://github.com/cyfershepard/jellystat/blob/main/_autodocs/api-reference.md Starts the synchronization of playback activity. This allows the system to update playback status across different clients or services. ```APIDOC ## POST /syncPlayback ### Description Trigger playback activity synchronization. ### Method POST ### Endpoint /sync/syncPlayback ``` -------------------------------- ### Get Library Overview Source: https://github.com/cyfershepard/jellystat/blob/main/_autodocs/api-reference.md Fetches an overview of statistics for all libraries, including item counts and total plays. ```APIDOC ## GET /getLibraryOverview ### Description Get overview statistics for all libraries. ### Method GET ### Endpoint /stats/getLibraryOverview ### Response #### Success Response (200) - **LibraryId** (string) - **LibraryName** (string) - **ItemCount** (number) - **TotalPlays** (number) - **TotalDuration** (number) ### Response Example ```json [ { "LibraryId": "string", "LibraryName": "string", "ItemCount": 0, "TotalPlays": 0, "TotalDuration": 0 } ] ``` ``` -------------------------------- ### Check Application Configuration State Source: https://github.com/cyfershepard/jellystat/blob/main/_autodocs/api-reference.md This endpoint retrieves the current configuration state of the application and its version. It is useful for determining if initial setup is required. ```javascript const response = await fetch('/auth/isConfigured'); const { state, version } = await response.json(); ``` -------------------------------- ### TypeScript-like Type Annotation Example Source: https://github.com/cyfershepard/jellystat/blob/main/_autodocs/README.md Illustrates type annotations using TypeScript-like syntax for function parameters and return types. Useful for understanding expected data types. ```javascript function myFunction(name: string, count: number): Promise ``` -------------------------------- ### Get Most Viewed Items by Type Source: https://github.com/cyfershepard/jellystat/blob/main/_autodocs/api-reference.md Fetches the most viewed items (Movies, Series, or Audio) within a specified number of days. The 'type' parameter is required, and 'days' is optional with a default of 30. An example POST request demonstrates usage. ```javascript POST /stats/getMostViewedByType Content-Type: application/json { "days": number, "type": string } ``` ```javascript const response = await fetch('/stats/getMostViewedByType', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ days: 30, type: 'Movie' }) }); const items = await response.json(); ``` -------------------------------- ### Handle Synchronization Progress Updates Source: https://github.com/cyfershepard/jellystat/blob/main/_autodocs/websocket-and-realtime.md Subscribe to 'sync-progress' events to receive real-time updates during library or user synchronization. This example logs messages for 'Update' and 'Complete' event types. ```javascript socket.on('sync-progress', (update) => { if (update.type === 'Update') { console.log(`Syncing: ${update.message}`); } else if (update.type === 'Complete') { console.log('Sync finished'); } }); ``` -------------------------------- ### Task Log Format Example Source: https://github.com/cyfershepard/jellystat/blob/main/_autodocs/error-handling.md Illustrates the structure of error logs stored in the jf_logging table, including task details, execution time, and log messages. ```json { "Id": "uuid-string", "Name": "TaskName", "Type": "Task", "ExecutionType": "cron|manual|webhook", "Duration": 45, // seconds "TimeRun": "2025-06-27T10:30:00Z", "Log": [ { "color": "red", "Message": "Error occurred" }, { "color": "yellow", "Message": "Details here" } ], "Result": "FAILED|SUCCESS|RUNNING" } ``` -------------------------------- ### Code Example with Error Handling Source: https://github.com/cyfershepard/jellystat/blob/main/_autodocs/README.md Demonstrates realistic usage of asynchronous operations with try-catch blocks for error handling. This pattern ensures robustness in API interactions. ```javascript try { const result = await operation(); // Handle success } catch (error) { // Handle error } ``` -------------------------------- ### Get Backup Tables Source: https://github.com/cyfershepard/jellystat/blob/main/_autodocs/api-reference.md Retrieves a list of tables that are available for backup. The response includes table names, labels, and an exclude flag. ```javascript GET /api/getBackupTables ``` -------------------------------- ### Get Excluded Libraries Source: https://github.com/cyfershepard/jellystat/blob/main/_autodocs/classes-and-modules.md Get a list of library IDs that are excluded from tracking. Use to determine which libraries are not being processed. ```javascript const excluded = await config.getExcludedLibraries(); console.log(`Excluded libraries: ${excluded.join(', ')}`); ``` -------------------------------- ### Get Libraries Source: https://github.com/cyfershepard/jellystat/blob/main/_autodocs/types.md Retrieves an array of all media libraries available on the server. Each library object contains details about its ID, name, and type. ```APIDOC ## GET /api/getLibraries ### Description Returns an array of Library objects, representing media collections on the server. ### Method GET ### Endpoint /api/getLibraries ### Response #### Success Response (200) - **Array of Library objects** - Each object contains details like Id, Name, ServerId, IsFolder, Type, CollectionType, ImageTagsPrimary, and archived. #### Response Example { "example": "[\n {\n \"Id\": \"123e4567-e89b-12d3-a456-426614174000\",\n \"Name\": \"Movies\",\n \"ServerId\": \"server-abc\",\n \"IsFolder\": true,\n \"Type\": \"Folder\",\n \"CollectionType\": \"movies\",\n \"ImageTagsPrimary\": \"tag123\",\n \"archived\": false\n }\n]" ``` -------------------------------- ### Create a Backup via API Source: https://github.com/cyfershepard/jellystat/blob/main/_autodocs/README.md Demonstrates how to initiate a backup of specified tables using the backup API endpoint. ```javascript const response = await fetch('/backup/backup', { method: 'POST', body: JSON.stringify({ tables: ['jf_playback_activity', 'jf_libraries', 'jf_users'] }) }); const { file } = await response.json(); ``` -------------------------------- ### setupWebSocketServer Source: https://github.com/cyfershepard/jellystat/blob/main/_autodocs/websocket-and-realtime.md Initializes the Socket.IO server and configures authentication for WebSocket connections. It requires an HTTP server instance and an optional namespace path. ```APIDOC ## setupWebSocketServer(server, namespacePath) ### Description Initializes Socket.IO server and configures authentication. ### Method `setupWebSocketServer` ### Parameters #### Path Parameters - **server** (http.Server) - Required - Express HTTP server instance - **namespacePath** (string) - Optional - Optional namespace path (e.g., "/api") ### Authentication - All WebSocket connections require JWT token. - Token passed via `auth.token` in handshake or query parameter. - Invalid token triggers "Authentication error" and connection rejection. ### Request Example ```javascript const http = require('http'); const express = require('express'); const { setupWebSocketServer } = require('./ws'); const app = express(); const server = http.createServer(app); setupWebSocketServer(server, '/api'); server.listen(3000, () => { console.log('WebSocket server listening on port 3000'); }); ``` ``` -------------------------------- ### Playback Filter Validation Error Response Source: https://github.com/cyfershepard/jellystat/blob/main/_autodocs/error-handling.md Example of a 400 Bad Request response when the filters parameter in the getPlaybackActivity endpoint is invalid JSON. It includes the expected error message and a valid example structure for the filters. ```javascript { "error": "Invalid filters parameter", "example": [ { "field": "UserName", "value": "User" }, { "field": "Client", "in": "Android TV,Web" }, { "field": "PlaybackDuration", "min": 1000, "max": 5000 }, { "field": "PlayMethod", "value": "DirectPlay" }, { "field": "ActivityDateInserted", "min": "2025-01-01", "max": "2025-12-31" }, { "field": "IsPaused", "value": false } ] } ``` -------------------------------- ### Configure Jellyfin/Emby Server Connection Source: https://github.com/cyfershepard/jellystat/blob/main/_autodocs/api-reference.md This endpoint is used during the initial setup to configure the connection to your Jellyfin or Emby server. It requires the server URL and an API key. ```javascript const response = await fetch('/auth/configSetup', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ JF_HOST: 'http://jellyfin.example.com', JF_API_KEY: 'your-api-key' }) }); ``` -------------------------------- ### High-Availability Docker Environment Variables Source: https://github.com/cyfershepard/jellystat/blob/main/_autodocs/configuration.md Extends the production setup for high availability, including database connection pooling tuning. Note that connection pool tuning requires modifying db.js. ```bash # All production settings plus: POSTGRES_IP=postgres-ha.internal POSTGRES_PORT=5432 JS_LISTEN_IP=:: # Connection pool tuning (modify db.js) # max: 50 # idleTimeoutMillis: 60000 ``` -------------------------------- ### Get Activity Monitor Settings Source: https://github.com/cyfershepard/jellystat/blob/main/_autodocs/api-reference.md Retrieves the current configuration for the activity monitor. This includes settings like minimum play duration and session timeout. ```javascript GET /api/getActivityMonitorSettings ``` ```json { "enabled": boolean, "minPlayDuration": number, "sessionTimeout": number } ``` -------------------------------- ### Minimal Docker Environment Variables Source: https://github.com/cyfershepard/jellystat/blob/main/_autodocs/configuration.md Provides essential environment variables for a minimal Jellystat Docker setup. Ensure sensitive values like JWT_SECRET and JF_API_KEY are changed. ```bash POSTGRES_USER=jellystat POSTGRES_PASSWORD=changeme POSTGRES_IP=postgres POSTGRES_PORT=5432 JWT_SECRET=change-this-to-something-secure-32-chars JF_HOST=http://jellyfin:8096 JF_API_KEY=your-api-key TZ=Etc/UTC ``` -------------------------------- ### getUserById Source: https://github.com/cyfershepard/jellystat/blob/main/_autodocs/classes-and-modules.md Gets a specific user by their ID from the Jellyfin server. ```APIDOC ## getUserById(userid) ### Description Gets a specific user by ID. ### Method `async getUserById(userid: string): Promise` ### Parameters #### Path Parameters - **userid** (string) - Required - The ID of the user to retrieve ### Example ```javascript const user = await API.getUserById('user-id-123'); if (user) { console.log(`User: ${user.Name}`); } ``` ``` -------------------------------- ### Handle Library Update Events Source: https://github.com/cyfershepard/jellystat/blob/main/_autodocs/websocket-and-realtime.md Subscribe to 'library-update' events to receive notifications when libraries are synced or modified. This example iterates through the updated libraries and logs their names and item counts. ```javascript socket.on('library-update', (libraries) => { libraries.forEach(lib => { console.log(`${lib.Name}: ${lib.ItemCount} items`); }); }); ``` -------------------------------- ### Production Docker Environment Variables Source: https://github.com/cyfershepard/jellystat/blob/main/_autodocs/configuration.md Configuration for a production Jellystat setup, including database, security, server, and feature settings. Uses environment variables for sensitive data. ```bash # Database POSTGRES_USER=jellystat POSTGRES_PASSWORD=${SECURE_PASSWORD} POSTGRES_IP=db.internal POSTGRES_PORT=5432 POSTGRES_DB=jellystat POSTGRES_SSL_ENABLED=true POSTGRES_SSL_REJECT_UNAUTHORIZED=true # Security JWT_SECRET=${JWT_SECRET_MIN_32_CHARS} JS_LISTEN_IP=0.0.0.0 REJECT_SELF_SIGNED_CERTIFICATES=true # Server JF_HOST=https://jellyfin.example.com JF_API_KEY=${JELLYFIN_API_KEY} JS_BASE_URL=/jellystat TZ=America/New_York # Features JF_USE_WEBSOCKETS=true JS_USE_EXTERNAL_HOST=true MINIMUM_SECONDS_TO_INCLUDE_PLAYBACK=5 # Geolocation (optional) JS_GEOLITE_ACCOUNT_ID=${MAXMIND_ACCOUNT_ID} JS_GEOLITE_LICENSE_KEY=${MAXMIND_LICENSE_KEY} ``` -------------------------------- ### Start a Registered Task Source: https://github.com/cyfershepard/jellystat/blob/main/_autodocs/classes-and-modules.md Initiate the execution of a previously registered task using its name. The triggerType parameter indicates how the task was initiated (e.g., 'cron', 'manual'). ```javascript manager.startTask( { name: 'sync-libs' }, 'cron' ); ``` -------------------------------- ### Initialize WebSocket Server Source: https://github.com/cyfershepard/jellystat/blob/main/_autodocs/classes-and-modules.md Set up the Socket.IO WebSocket server with an HTTP server instance. Ensure the HTTP server is created before calling this function. ```javascript const http = require('http'); const { setupWebSocketServer } = require('./ws'); const server = http.createServer(app); setupWebSocketServer(server); ``` -------------------------------- ### GET /stopTask Source: https://github.com/cyfershepard/jellystat/blob/main/_autodocs/api-reference.md Stops a currently running task identified by its name. ```APIDOC ## GET /stopTask ### Description Stop a running task. ### Method GET ### Endpoint /api/stopTask ### Parameters #### Query Parameters - **task** (string) - Required - Task name to stop ``` -------------------------------- ### Making an Authenticated API Request Source: https://github.com/cyfershepard/jellystat/blob/main/_autodocs/README.md Demonstrates how to log in to obtain a token and then use that token to fetch library data. Ensure you have the correct username and a hashed password for login. ```javascript // Step 1: Login (api-reference.md → POST /login) const response = await fetch('/auth/login', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ username: 'admin', password: 'hashedPassword' }) }); const { token } = await response.json(); // Step 2: Get libraries (api-reference.md → GET /getLibraries) const librariesResponse = await fetch('/api/getLibraries', { headers: { 'Authorization': `Bearer ${token}` } }); const libraries = await librariesResponse.json(); // Step 3: Parse response (types.md → Library schema) libraries.forEach(lib => { console.log(`${lib.Name}: ${lib.Type}`); }); ``` -------------------------------- ### setupWebSocketServer Source: https://github.com/cyfershepard/jellystat/blob/main/_autodocs/classes-and-modules.md Initializes the Socket.IO WebSocket server. This method is used to set up the real-time communication layer for the application. ```APIDOC ## setupWebSocketServer(httpServer) ### Description Initializes Socket.IO WebSocket server. ### Method ```javascript function setupWebSocketServer(httpServer: http.Server): void ``` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```javascript const http = require('http'); const { setupWebSocketServer } = require('./ws'); const server = http.createServer(app); setupWebSocketServer(server); ``` ### Response None ``` -------------------------------- ### GET /api/getRecentlyAdded Source: https://github.com/cyfershepard/jellystat/blob/main/_autodocs/types.md Retrieves a list of recently added media items. ```APIDOC ## GET /api/getRecentlyAdded ### Description Retrieves a list of recently added media items. ### Method GET ### Endpoint /api/getRecentlyAdded ### Response #### Success Response (200) - **Array of RecentlyAddedItem** - A list of recently added media items. #### Response Example [ { "Name": "The Matrix", "SeriesName": null, "Id": "movie-123", "SeriesId": null, "SeasonId": null, "EpisodeId": null, "SeasonNumber": null, "EpisodeNumber": null, "PrimaryImageHash": "abc123xyz", "DateCreated": "2023-10-27T10:00:00Z", "Type": "Movie", "ParentId": "library-abc" } ] ``` -------------------------------- ### GET /api/getTaskSettings Source: https://github.com/cyfershepard/jellystat/blob/main/_autodocs/types.md Retrieves the current task settings for the Jellystat instance. ```APIDOC ## GET /api/getTaskSettings ### Description Retrieves the current task settings for the Jellystat instance. ### Method GET ### Endpoint /api/getTaskSettings ### Response #### Success Response (200) - **SyncLibrariesCron** (string) - Cron expression for library sync schedule - **SyncUsersCron** (string) - Cron expression for user sync schedule - **ActivityMonitorCron** (string) - Cron expression for activity monitor schedule - **AutoSyncEnabled** (boolean) - Whether automatic sync is enabled - **WebSocketEnabled** (boolean) - Whether WebSocket connections are enabled - **MinPlayDuration** (number) - Minimum playback duration in seconds to record - **NewWatchEventThreshold** (number) - Hours threshold for grouping watches as separate sessions #### Response Example { "SyncLibrariesCron": "0 0 * * *", "SyncUsersCron": "0 0 * * *", "ActivityMonitorCron": "0 0 * * *", "AutoSyncEnabled": true, "WebSocketEnabled": true, "MinPlayDuration": 300, "NewWatchEventThreshold": 24 } ``` -------------------------------- ### Create Database Backup Source: https://github.com/cyfershepard/jellystat/blob/main/_autodocs/api-reference.md Initiates a database backup, specifying which tables to include. The response contains the path to the generated backup file. ```javascript POST /backup/backup Content-Type: application/json { "tables": string[] } ``` -------------------------------- ### Get User Details Source: https://github.com/cyfershepard/jellystat/blob/main/_autodocs/types.md Fetches detailed information for a specific user. ```APIDOC ## POST /api/getUserDetails ### Description Returns a single JellyfinUser object with detailed information. ### Method POST ### Endpoint /api/getUserDetails ### Request Body - **userId** (string) - Required - The ID of the user to retrieve details for. ### Response #### Success Response (200) - **user** (JellyfinUser) - The detailed user object. ``` -------------------------------- ### Get Untracked Users Source: https://github.com/cyfershepard/jellystat/blob/main/_autodocs/api-reference.md Retrieves a list of users who are not currently tracked in the system. ```APIDOC ## GET /UntrackedUsers ### Description Get users not currently tracked in the system. ### Method GET ### Endpoint /api/UntrackedUsers ### Response #### Success Response (200) - **Id** (string) - **Name** (string) - **ServerId** (string) - **Policy** (object) ### Response Example ```json [ { "Id": "string", "Name": "string", "ServerId": "string", "Policy": {} } ] ``` ``` -------------------------------- ### List All Libraries Source: https://github.com/cyfershepard/jellystat/blob/main/_autodocs/api-reference.md Fetches a list of all libraries available on the Jellyfin/Emby server. This is useful for understanding the server's structure. ```javascript GET /api/getLibraries ``` ```javascript const response = await fetch('/api/getLibraries'); const libraries = await response.json(); ``` -------------------------------- ### GET /TrackedLibraries Source: https://github.com/cyfershepard/jellystat/blob/main/_autodocs/api-reference.md Retrieves a list of libraries that are currently being tracked or monitored by the system. ```APIDOC ## GET /TrackedLibraries ### Description Get list of tracked (monitored) libraries. ### Method GET ### Endpoint /api/TrackedLibraries ``` -------------------------------- ### POST /backup Source: https://github.com/cyfershepard/jellystat/blob/main/_autodocs/api-reference.md Initiates a database backup process, creating a backup file for the specified tables. The response includes the path to the generated backup file. ```APIDOC ## POST /backup ### Description Create a backup of database tables. ### Method POST ### Endpoint /backup/backup ### Parameters #### Request Body - **tables** (string[]) - Required - An array of table names to include in the backup. ### Request Example ```json { "tables": [ "string" ] } ``` ### Response #### Success Response (200) - **file** (string) - The path to the generated backup file. ### Response Example ```json { "file": "string" } ``` ``` -------------------------------- ### Get Tracked Libraries Source: https://github.com/cyfershepard/jellystat/blob/main/_autodocs/api-reference.md Retrieves a list of libraries that are currently being tracked or monitored. ```javascript GET /api/TrackedLibraries ``` -------------------------------- ### Config Class - getExcludedLibraries Source: https://github.com/cyfershepard/jellystat/blob/main/_autodocs/classes-and-modules.md Gets list of library IDs that are excluded from tracking. ```APIDOC ## getExcludedLibraries() ### Description Gets list of library IDs that are excluded from tracking. ### Signature ```javascript async getExcludedLibraries(): Promise ``` ### Example ```javascript const excluded = await config.getExcludedLibraries(); console.log(`Excluded libraries: ${excluded.join(', ')}`); ``` ``` -------------------------------- ### Backend Directory Structure Source: https://github.com/cyfershepard/jellystat/blob/main/_autodocs/README.md Overview of the backend directories and their primary responsibilities, including server setup, database interaction, API routes, core logic classes, background tasks, database models, and migrations. ```tree backend/ ├── server.js # Express app, routes, middleware ├── db.js # PostgreSQL connection pool ├── ws.js # WebSocket/Socket.IO setup │ ├── routes/ # API endpoint handlers │ ├── auth.js # Login, configuration setup │ ├── api.js # Core API endpoints │ ├── stats.js # Statistics endpoints │ ├── sync.js # Synchronization logic │ ├── backup.js # Backup/restore operations │ ├── proxy.js # Jellyfin/Emby proxy │ ├── logging.js # Task logging │ └── utils.js # Utilities │ ├── classes/ # Core business logic │ ├── config.js # Configuration management │ ├── api-loader.js # Jellyfin/Emby API factory │ ├── jellyfin-api.js # Jellyfin API methods │ ├── emby-api.js # Emby API methods │ ├── task-manager.js # Worker thread management │ ├── task-scheduler.js # Cron scheduling │ ├── backup.js # Database backup │ ├── logging.js # Task logging │ ├── axios.js # HTTP client wrapper │ └── ... │ ├── tasks/ # Background worker tasks │ ├── ActivityMonitor.js # Monitor playback activity │ └── ... │ ├── models/ # Database schemas │ ├── jf_playback_activity.js │ ├── jf_libraries.js │ ├── jf_users.js │ └── ... │ └── migrations/ # Database migrations ├── 001_app_config_table.js ├── 002_jf_activity_watchdog_table.js └── ... ``` -------------------------------- ### Authentication Flow Diagram Source: https://github.com/cyfershepard/jellystat/blob/main/_autodocs/README.md Illustrates the steps involved in user authentication, from input to token generation and storage. ```text User Input ↓ POST /auth/login ↓ [Verify credentials against app_config table] ↓ Generate JWT token ↓ Return token to client ↓ Client stores token in localStorage ↓ Use token in Authorization header for all requests ``` -------------------------------- ### Get Library Synchronization Status Source: https://github.com/cyfershepard/jellystat/blob/main/_autodocs/api-reference.md Retrieves the current status of the library synchronization process. ```javascript GET /sync/getLibrarySync ``` -------------------------------- ### Get Playback Activity Source: https://github.com/cyfershepard/jellystat/blob/main/_autodocs/api-reference.md Retrieves playback activity with support for pagination, filtering, and sorting. ```APIDOC ## GET /getPlaybackActivity ### Description Get playback activity with pagination, filtering, and sorting. ### Method GET ### Endpoint /stats/getPlaybackActivity ### Parameters #### Query Parameters - **size** (number) - Optional - Defaults to 50. Items per page. - **page** (number) - Optional - Defaults to 1. Page number. - **search** (string) - Optional - Search query. - **sort** (string) - Optional - Defaults to "ActivityDateInserted". Sort field. - **desc** (boolean) - Optional - Defaults to true. Descending sort. - **filters** (string) - Optional - Complex filters in JSON format. ### Filter Format Example ```json [ { "field": "UserName", "value": "User" }, { "field": "Client", "in": "Android TV,Web" }, { "field": "PlaybackDuration", "min": 1000, "max": 5000 }, { "field": "PlayMethod", "value": "DirectPlay" }, { "field": "ActivityDateInserted", "min": "2025-01-01", "max": "2025-12-31" }, { "field": "IsPaused", "value": false } ] ``` ``` -------------------------------- ### Get Untracked Users Source: https://github.com/cyfershepard/jellystat/blob/main/_autodocs/types.md Retrieves a list of users from Jellyfin/Emby that are not currently tracked by the application. ```APIDOC ## GET /api/getUntrackedUsers ### Description Returns an array of JellyfinUser objects representing untracked users. ### Method GET ### Endpoint /api/getUntrackedUsers ### Response #### Success Response (200) - **users** (array[JellyfinUser]) - An array of user objects. ``` -------------------------------- ### Import Backup Class Source: https://github.com/cyfershepard/jellystat/blob/main/_autodocs/classes-and-modules.md Import the Backup class to manage database backup and restore operations. ```javascript const Backup = require("./classes/backup"); ``` -------------------------------- ### Query Application Settings from PostgreSQL Source: https://github.com/cyfershepard/jellystat/blob/main/_autodocs/configuration.md Demonstrates how to retrieve the JSON settings object from the `app_config` table in a PostgreSQL database. This query is useful for inspecting or debugging configuration directly. ```sql SELECT settings FROM app_config WHERE "ID" = 1; ``` -------------------------------- ### POST /getHistory Source: https://github.com/cyfershepard/jellystat/blob/main/_autodocs/api-reference.md Get playback history with pagination support, allowing retrieval of records in chunks. ```APIDOC ## POST /getHistory ### Description Get playback history with pagination. ### Method POST ### Endpoint /api/getHistory ### Parameters #### Request Body - **page** (number) - Required - The page number of the history to retrieve. - **size** (number) - Required - The number of records per page. ``` -------------------------------- ### Monitor Library Updates via WebSocket Source: https://github.com/cyfershepard/jellystat/blob/main/_autodocs/README.md Shows how to connect to the WebSocket server and listen for real-time library updates and sync progress. ```javascript const socket = io('http://localhost:3000', { auth: { token } }); socket.on('library-update', (libraries) => { console.log('Libraries updated:', libraries); // Update UI immediately }); socket.on('sync-progress', (progress) => { console.log(`Syncing: ${progress.message}`); updateProgressBar(progress.currentStep / progress.totalSteps); }); ``` -------------------------------- ### Get Most Active Users Source: https://github.com/cyfershepard/jellystat/blob/main/_autodocs/api-reference.md Retrieves a list of the most active users within a specified time period. ```APIDOC ## POST /getMostActiveUsers ### Description Get most active users in time period. ### Method POST ### Endpoint /stats/getMostActiveUsers ### Parameters #### Request Body - **days** (number) - Optional - Defaults to 30. The number of days to look back. ### Request Example ```json { "days": 30 } ``` ``` -------------------------------- ### Creating and Registering a Custom Backend Task Source: https://github.com/cyfershepard/jellystat/blob/main/_autodocs/README.md Illustrates how to create a worker thread for a custom task, register it with the TaskManager, and then schedule its execution. Ensure the task path is correct and the TaskManager/TaskScheduler are available. ```javascript // 1. Create worker thread file (backend/tasks/my-task.js) const { parentPort } = require('worker_threads'); parentPort.on('message', async (message) => { if (message.command === 'start') { try { // Your task logic parentPort.postMessage({ status: 'complete' }); } catch (error) { parentPort.postMessage({ status: 'error', message: error.message }); } } }); // 2. Register task (classes-and-modules.md → TaskManager) const manager = new TaskManager(); manager.addTask({ task: { name: 'my-task', path: './tasks/my-task.js' }, onComplete: () => console.log('Done') }); // 3. Schedule it (classes-and-modules.md → TaskScheduler) const scheduler = new TaskScheduler(); scheduler.scheduleTask('my-task', '0 * * * *', () => { manager.startTask({ name: 'my-task' }, 'cron'); }); ``` -------------------------------- ### Get Most Viewed Libraries Source: https://github.com/cyfershepard/jellystat/blob/main/_autodocs/api-reference.md Retrieves a list of the most viewed libraries within a specified time period. ```APIDOC ## POST /getMostViewedLibraries ### Description Get most viewed libraries in time period. ### Method POST ### Endpoint /stats/getMostViewedLibraries ### Parameters #### Request Body - **days** (number) - Optional - Defaults to 30. The number of days to look back. ### Request Example ```json { "days": 30 } ``` ``` -------------------------------- ### Retrieve Application Configuration Source: https://github.com/cyfershepard/jellystat/blob/main/_autodocs/api-reference.md Use this endpoint to fetch the current configuration settings of the application. The response includes details about the host, user, settings object, and login requirements. ```javascript GET /api/getconfig ``` ```javascript { "JF_HOST": string, "APP_USER": string, "settings": object, "REQUIRE_LOGIN": boolean, "IS_JELLYFIN": boolean } ``` ```javascript const response = await fetch('/api/getconfig'); const config = await response.json(); ``` -------------------------------- ### Get Most Used Client Source: https://github.com/cyfershepard/jellystat/blob/main/_autodocs/api-reference.md Retrieves statistics on the most used playback clients within a specified time period. ```APIDOC ## POST /getMostUsedClient ### Description Get most used playback clients. ### Method POST ### Endpoint /stats/getMostUsedClient ### Parameters #### Request Body - **days** (number) - Optional - Defaults to 30. The number of days to look back. ### Request Example ```json { "days": 30 } ``` ``` -------------------------------- ### GET /api/keys Source: https://github.com/cyfershepard/jellystat/blob/main/_autodocs/types.md Retrieves an array of ApiKey objects, representing registered API keys for programmatic access. ```APIDOC ## GET /api/keys ### Description Retrieves an array of ApiKey objects, representing registered API keys for programmatic access. ### Method GET ### Endpoint /api/keys ### Response #### Success Response (200) - **ApiKey** (array) - An array of API key objects. ### Response Example { "example": [ { "key": "string", "name": "string", "createdAt": "string", "lastUsed": "string | null", "active": true } ] } ```