Fetcharr

repository·main·Indexed 43 days ago

https://github.com/egg82/fetcharr

A containerized CLI tool that automates searching for and upgrading media content by interacting with *arr applications, including Radarr, Sonarr, Lidarr, Readarr/Bookshelf, and Whisparr. It periodically scans connected media managers to find better quality versions or missing content, forcing updates through configured indexers to bypass unreliable RSS feeds.

Tokens
9.9K
Snippets
10
Records
18
Agent score
53%

What's inside Fetcharr

  1. What is Fetcharr?

    main

    Fetcharr is a CLI-based containerized application designed to scan and upgrade media by interacting with various '*arr' applications. It periodically searches your connected media managers to find better quality versions or missing content, forcing the applications to update through their configured indexers. This bypasses limitations where RSS feeds might be unreliable or outdated.

    Supported Applications:

    • Radarr
    • Sonarr
    • Lidarr
    • Readarr/Bookshelf
    • Whisparr
  2. Expose an API to other plugins

    main

    To allow other plugins to consume your custom API, follow these two steps:

    1. Export your classes: Add the relevant classes or packages to the exports list in your plugin's plugin.yaml. This makes them available in other plugins' ClassLoaders.
    2. Register your API: Use the me.egg82.fetcharr.api.model.registry.Registry class via the FetcharrAPIProvider to register your service.

    Consuming an API: Other plugins can retrieve your registered API using:

    • FetcharrAPIProvider.instance().registry().getFirst()
    • FetcharrAPIProvider.instance().registry().getAll()

    Best Practice: Only export necessary API interfaces to avoid namespace pollution; do not export implementation details.

    // Registering an API
    FetcharrAPIProvider.instance().registry().register(yourApiInstance);
    
    // Consuming an API (in another plugin)
    var api = FetcharrAPIProvider.instance().registry().getFirst();
  3. Understand Fetcharr caching behavior

    main

    Fetcharr supports both file-based and in-memory caching. You can control this using USE_FILE_CACHE and USE_MEMORY_CACHE with values auto, true, or false.

    Automatic Configuration (auto mode)

    • USE_FILE_CACHE=auto: Fetcharr checks if the configured CACHE_DIR is writable. If writable, file caching is enabled; otherwise, it is disabled.
    • USE_MEMORY_CACHE=auto: Fetcharr checks if file caching is usable. If file caching is active, in-memory caching is disabled to save RAM. If file caching is unavailable, in-memory caching is enabled.

    Key Considerations

    • Preference: File caching is preferred over in-memory caching because in-memory caching can consume significant amounts of RAM.
    • Persistence: If you use purely in-memory caching, your cache will be lost whenever the container restarts.
    • Impact: Disabling or clearing the cache will not break the program, but it will result in more API calls and slower execution speeds.
  4. Install Fetcharr via Docker Compose

    main

    Use this docker-compose.yml structure to manage your Fetcharr deployment. Ensure you provide the necessary environment variables for your specific '*arr' instances and map the required volumes.

    services:
      fetcharr:
        image: egg82/fetcharr:latest
        container_name: fetcharr
        hostname: fetcharr
        environment:
          - VERIFY_CERTS=true
          - SSL_PATH=/etc/ssl/certs/ca-bundle.crt
          - SEARCH_AMOUNT=5
          - SEARCH_INTERVAL=1hour
          - RADARR_0_URL=https://radarr.home.lab
          - RADARR_0_API_KEY=e8ea891d72ff973fa6db0d34369a60a7
          - SONARR_0_URL=https://sonarr.home.lab
          - SONARR_0_API_KEY=71730b5dfaa4293fe0c050844c10df66
          - SONARR_1_URL=https://anime.home.lab
          - SONARR_1_API_KEY=bdb84dc8e4b787c76be8aae2dfe9bd19
        volumes:
          - ./config:/app/config
          - ./cache:/app/cache
          - ./logs:/app/logs
          - ./plugins:/app/plugins
        restart: unless-stopped
  5. Run Fetcharr as a different user

    main

    By default, Fetcharr runs as UID 1000 and GID 1000. You have two methods for changing the user:

    1. Runtime User Setting: Set the user directly via the --user flag in Docker or the user key in Compose. Note: Fetcharr will not attempt to change volume ownership for your data directories using this method.

    2. Remap User (Root Start): Start the container as root (--user 0:0) and provide PUID and PGID environment variables. Fetcharr will start as root to modify volume mount ownership and then drop privileges. This is more flexible but considered less secure.

    Unraid Users: Unraid typically uses 99:100 (nobody:users). Use one of the methods above, adding the flag to the 'Extra Parameters' field in the container template (ensure 'Advanced View' is enabled).

    # Method 1: Runtime User Setting (Docker)
    docker run --user 99:100 ... egg82/fetcharr:latest
    
    # Method 2: Remap User (Docker)
    docker run --user 0:0 -e PUID=99 -e PGID=100 ... egg82/fetcharr:latest
  6. Install Fetcharr via Docker

    main

    You can run Fetcharr using the latest tag for production or the dev tag for development. Use the following command to start a container with example environment variables for Radarr and Sonarr, and local volume mounts for configuration, cache, logs, and plugins.

    docker run \
      -e VERIFY_CERTS=true \
      -e SSL_PATH=/etc/ssl/certs/ca-bundle.crt \
      -e SEARCH_AMOUNT=5 \
      -e SEARCH_INTERVAL=1hour \
      -e RADARR_0_URL=https://radarr.home.lab \
      -e RADARR_0_API_KEY=e8ea891d72ff973fa6db0d34369a60a7 \
      -e SONARR_0_URL=https://sonarr.home.lab \
      -e SONARR_0_API_KEY=71730b5dfaa4293fe0c050844c10df66 \
      -e SONARR_1_URL=https://anime.home.lab \
      -e SONARR_1_API_KEY=bdb84dc8e4b787c76be8aae2dfe9bd19 \
      -v ./config:/app/config \
      -v ./cache:/app/cache \
      -v ./logs:/app/logs \
      -v ./plugins:/app/plugins \
      egg82/fetcharr:latest
  7. Develop a Fetcharr plugin

    main

    To create a plugin, your code must implement the me.egg82.fetcharr.api.plugin.Plugin interface. You must also include a plugin.yaml file in your resources to define the plugin's metadata.

    plugin.yaml Schema

    • id (REQUIRED): A unique plugin ID.
    • name (REQUIRED): A friendly name.
    • version (REQUIRED): The version string.
    • class (REQUIRED): The fully qualified name of the main class implementing me.egg82.fetcharr.api.plugin.Plugin.
    • description (Optional): A description of the plugin.
    • authors (Optional): A list of authors.
    • exports (Optional): A list of classes or packages to expose to other plugins via their ClassLoader.
    id: unique-id
    name: Some name
    version: Any version number
    description: Whatever description
    authors: [some, authors]
    class: your.package.path.MainClass
    exports:
      - another.package.path.to.api
      - maybe.some.path.to.Class
  8. Configure Fetcharr for Kubernetes

    main

    The following manifest sets up a Fetcharr deployment in Kubernetes, including PersistentVolumeClaims (PVCs) for config (1Gi), cache (5Gi), logs (10Gi), and plugins (5Gi). It also includes a security context for running as a non-root user (UID 1000).

    apiVersion: v1
    kind: Namespace
    metadata:
      name: fetcharr
    ---
    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: config
      namespace: fetcharr
    spec:
      accessModes:
        - ReadWriteMany
      resources:
        requests:
          storage: 1Gi
    ---
    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: cache
      namespace: fetcharr
    spec:
      accessModes:
        - ReadWriteMany
      resources:
        requests:
          storage: 5Gi
    ---
    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: logs
      namespace: fetcharr
    spec:
      accessModes:
        - ReadWriteMany
      resources:
        requests:
          storage: 10Gi
    ---
    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: plugins
      namespace: fetcharr
    spec:
      accessModes:
        - ReadWriteMany
      resources:
        requests:
          storage: 5Gi
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      labels:
        app.kubernetes.io/name: fetcharr
      name: fetcharr
      namespace: fetcharr
    spec:
      replicas: 1
      selector:
        matchLabels:
          app.kubernetes.io/name: fetcharr
      template:
        metadata:
          labels:
            app.kubernetes.io/name: fetcharr
        spec:
          securityContext:
            fsGroup: 1000
            fsGroupChangePolicy: OnRootMismatch
            seccompProfile:
              type: RuntimeDefault
          containers:
            - image: egg82/fetcharr:<use-real-version>
              name: fetcharr
              securityContext:
                runAsUser: 1000
                runAsGroup: 1000
                allowPrivilegeEscalation: false
                runAsNonRoot: true
                capabilities:
                  drop: ["ALL"]
              resources:
                requests:
                  cpu: 50m
                  memory: 150Mi
                limits:
                  cpu: 500m
                  memory: 1Gi
              env:
                - name: VERIFY_CERTS
                  value: "true"
                - name: SSL_PATH
                  value: /etc/ssl/certs/ca-bundle.crt
                - name: SEARCH_AMOUNT
                  value: "5"
                - name: SEARCH_INTERVAL
                  value: 1hour
                - name: RADARR_0_URL
                  value: https://radarr.home.lab
                - name: RADARR_0_API_KEY
                  value: e8ea891d72ff973fa6db0d34369a60a7
                - name: SONARR_0_URL
                  value: https://sonarr.home.lab
                - name: SONARR_0_API_KEY
                  value: 71730b5dfaa4293fe0c050844c10df66
                - name: SONARR_1_URL
                  value: https://anime.home.lab
                - name: SONARR_1_API_KEY
                  value: bdb84dc8e4b787c76be8aae2dfe9bd19
              volumeMounts:
                - mountPath: /app/config
                  name: config
                - mountPath: /app/cache
                  name: cache
                - mountPath: /app/logs
                  name: logs
                - mountPath: /app/plugins
                  name: plugins
          volumes:
            - name: config
              persistentVolumeClaim:
                claimName: config
            - name: cache
              persistentVolumeClaim:
                claimName: cache
            - name: logs
              persistentVolumeClaim:
                claimName: logs
            - name: plugins
              persistentVolumeClaim:
                claimName: plugins
  9. Install and manage plugins

    main

    Plugins are .jar files loaded from the directory specified by PLUGIN_DIR. They are loaded in natural sort order (e.g., 00-plugin.jar loads before 10-plugin.jar).

    Manual Installation

    Drop .jar files into the plugin directory and restart Fetcharr.

    Automatic Installation via plugins.yaml

    You can automate plugin downloads by creating a plugins.yaml file in your configuration directory. This file supports direct downloads and manifest references.

    Direct Download Options:

    • url: The download URL.
    • filename: The name to save the file as in the plugin directory.
    • sha256: (Recommended) The SHA256 checksum for verification.

    Manifest Reference:

    • manifest: A URL to another YAML-formatted plugin list. Manifests can be recursive, but Fetcharr detects and ignores loops.
    plugins:
      - url: https://some.web.domain/some/path/some-plugin-1.0.0.jar
        filename: 01-some-plugin.jar
    
      - url: https://another.web.domain/another/path/v1.2.3/another-plugin.jar
        filename: 02-another-plugin.jar
        sha256: 396d448073cf44195508216fca8668cfd6ab395bb447a077227b17d521dec80b
    
      - manifest: https://some.web.domain/whatever/path/manifest.yaml
  10. Configure plugin environment variables

    main

    Fetcharr provides two environment variables to control plugin behavior and directory location:

    • PLUGIN_DIR: Specifies the directory where plugins are loaded from. Defaults to /app/plugins.
    • PROVIDE_RAW_API_OBJ: A boolean (true or false). When set to true, raw API objects are provided to plugins, which allows for more flexibility but increases memory usage. Defaults to false.
  11. Configure Unirest proxy and SSL settings

    main

    Fetcharr uses Unirest for HTTP requests. You can configure proxy settings and SSL/TLS behavior via environment variables.

    Supported configurations include:

    • Proxy: Set PROXY_HOST and PROXY_PORT to route requests through a proxy.
    • Timeouts: Configure CONNECT_TIMEOUT, REQUEST_TIMEOUT, and CONNECT_TTL (in milliseconds).
    • SSL/TLS:
      • Use VERIFY_CERTS (boolean) to enable or disable certificate verification.
      • Use SSL_PATH to provide a file containing X.509 certificates. If provided, these certificates are loaded into a custom trust store for the application.
  12. Configure Arr instance connections

    main

    Fetcharr connects to multiple instances of various 'Arr' services. For each service type, you must provide a URL and an API key. The application supports multiple instances of the same service type using indexed environment variables.

    Supported service types (ArrType):

    • RADARR
    • SONARR
    • LIDARR
    • READARR
    • WHISPARR

    For each instance i, you need to set:

    • URL_{TYPE}_{i}
    • API_KEY_{TYPE}_{i}

    Note: The application attempts to validate the connection using the provided credentials. If authentication fails, it will log a warning but may still attempt to add the instance.