--- # beets: the tag fixer that runs BEFORE Navidrome sees anything. # # Navidrome has no metadata fetcher and no tag editor by design - it trusts the # tags on disk completely. That is the right call, but it means a library with # bad tags renders as a bad library and there is nothing in Navidrome to fix it # with. beets is the fix, and it belongs on this box because that is where the # files are. # # There is no unit and no timer here on purpose: `beet import` is interactive, # it MOVES and RENAMES files, and a cron job that reorganises a music library # unattended is a way to lose one. - name: Install beets and its fingerprinting dependencies apt: name: - beets # fpcalc. Without it the chroma plugin cannot acoustically identify a # file whose tags are too mangled to match, which is exactly the case # beets is most useful for. - libchromaprint-tools - python3-acoustid # lastgenre imports pylast, and Debian's beets package does NOT depend on # it. Without this the plugin fails to load and every single `beet` # invocation prints a ModuleNotFoundError traceback while genres are # silently never fetched - configured, listed in `plugins:`, and inert. - python3-pylast state: present update_cache: true when: navidrome_beets_enabled | bool - name: Create the beets state directory ansible.builtin.file: path: "{{ navidrome_beets_dir }}" state: directory owner: "{{ navidrome_curator_user }}" group: "{{ navidrome_curator_user }}" mode: '0750' when: navidrome_beets_enabled | bool # Both levels explicitly, parent first. The file module creates missing parents # like `mkdir -p`, but it creates them owned by ROOT - which would leave # ~/.config root-owned on a fresh cloud-init box and break every other # user-level tool that wants to write there later. - name: Create the curator's XDG config directory ansible.builtin.file: path: "{{ navidrome_beets_config | dirname | dirname }}" state: directory owner: "{{ navidrome_curator_user }}" group: "{{ navidrome_curator_user }}" mode: '0755' when: navidrome_beets_enabled | bool - name: Create the beets config directory ansible.builtin.file: path: "{{ navidrome_beets_config | dirname }}" state: directory owner: "{{ navidrome_curator_user }}" group: "{{ navidrome_curator_user }}" mode: '0755' when: navidrome_beets_enabled | bool - name: Write the beets configuration ansible.builtin.template: src: beets-config.yaml.j2 dest: "{{ navidrome_beets_config }}" owner: "{{ navidrome_curator_user }}" group: "{{ navidrome_curator_user }}" mode: '0644' when: navidrome_beets_enabled | bool