### CentOS/RedHat: Install and Configure Headphones Service Source: https://github.com/rembo10/headphones/wiki/Install-as-a-daemon This section details the installation and setup of Headphones on CentOS and RedHat systems using systemd. It involves creating a user, cloning the repository, setting up the service file, and configuring necessary directories and permissions. ```shell sudo adduser --system sabnzbd mkdir /home/sabnzbd mkdir /etc/headphones cd /home/sabnzbdgit clone https://github.com/rembo10/headphones.git sudo cp /home/sabnzbd/headphones/init-scripts/init.fedora.centos.systemd /home/sabnzbd/headphones/init-scripts/headphones.service sudo chmod +x /home/sabnzbd/headphones/init-scripts/headphones.service sudo touch /etc/headphones/headphones.ini sudo chown -R sabnzbd:sabnzbd /home/sabnzbd sudo chown sabnzbd:sabnzbd /etc/headphones/headphones.ini sudo cp /home/sabnzbd/headphones/init-scripts/headphones.service /lib/systemd/system/headphones.service sudo systemctl daemon-reload sudo systemctl enable headphones.service sudo service headphones [start | stop | reload | restart] ``` -------------------------------- ### Install Headphones on Linux using Git Source: https://github.com/rembo10/headphones/wiki/Installation This snippet outlines the process of installing Headphones on a Linux system using Git. It involves cloning the repository from GitHub and then executing the main Python script. Ensure Git and Python 3 are installed beforehand. ```bash sudo apt-get install git-core cd /opt git clone https://github.com/rembo10/headphones.git cd headphones python3 Headphones.py ``` -------------------------------- ### Command-Line Options for Headphones Source: https://github.com/rembo10/headphones/wiki/Troubleshooting Demonstrates how to start Headphones directly from the command line with help information. This is useful for verifying installation and understanding available options. ```bash python Headphones.py -h ``` -------------------------------- ### Ubuntu: Install and Configure Headphones Service Source: https://github.com/rembo10/headphones/wiki/Install-as-a-daemon This snippet outlines the steps to install and configure the Headphones service on Ubuntu. It includes creating a default configuration file, setting permissions, linking the init script, and managing the service. It also details how to configure the WebGUI to be accessible from other machines. ```shell cd /opt/headphones sudo touch /etc/default/headphones sudo adduser --system --no-create-home headphones sudo chown headphones:nogroup -R /opt/headphones sudo chmod +x /opt/headphones/init-scripts/init.ubuntu sudo ln -s /opt/headphones/init-scripts/init.ubuntu /etc/init.d/headphones sudo update-rc.d headphones defaults sudo update-rc.d headphones enable sudo service headphones [start | stop | reload | restart | status] # To allow Headphones WebGUI access from another machine: sudo service headphones stop # Modify '/opt/headphones/config.ini' changing 'localhost' to '0.0.0.0' sudo service headphones start ``` -------------------------------- ### Synology: Install Headphones Service Source: https://github.com/rembo10/headphones/wiki/Install-as-a-daemon Instructions for installing Headphones on a Synology NAS. This involves creating a dedicated user, setting directory permissions, downloading and enabling the init script. ```shell chown -R headphones:users /volume1/@appstore/headphones wget -O /opt/etc/init.d/S99headphones.sh http://dl.dropbox.com/u/5653370/syn_files/headphones/S99headphones.sh chmod a+x /opt/etc/init.d/S99headphones.sh /opt/etc/init.d/S99headphones.sh [start | stop | restart | update] ``` -------------------------------- ### Install Headphones on FreeBSD using Git and Python Source: https://github.com/rembo10/headphones/wiki/Installation This snippet details the installation of Headphones on a FreeBSD system. It requires Git, Python 3.6+, and SQLite3. The process involves cloning the repository and running the Python script. ```bash sudo pkg install git sudo pkg install python3 sudo pkg install sqlite3 cd /usr/local git clone https://github.com/rembo10/headphones.git cd headphones python2.7 Headphones.py ``` -------------------------------- ### Manage Headphones systemd User Service Source: https://github.com/rembo10/headphones/wiki/Install-as-a-daemon These are the shell commands used to manage the Headphones systemd user service. They include reloading the daemon after configuration changes, starting the service, enabling it to start on boot, and checking its status via journalctl. ```bash loginctl enable-linger $USER ``` ```bash systemctl --user daemon-reload ``` ```bash systemctl --user start headphones.service ``` ```bash systemctl --user enable --now headphones.service ``` ```bash journalctl --user -u headphones.service ``` -------------------------------- ### Download Headphones zip for Windows and MacOS Source: https://github.com/rembo10/headphones/wiki/Installation This provides the direct download link for the Headphones application as a ZIP archive from GitHub, suitable for manual installation on Windows and MacOS. After downloading, the archive needs to be extracted to the desired location. ```bash https://github.com/rembo10/headphones/zipball/master ``` -------------------------------- ### Run Headphones on Windows Source: https://github.com/rembo10/headphones/wiki/Installation This snippet describes how to run Headphones on a Windows system after downloading and extracting it from GitHub. It involves double-clicking the main Python script. Ensure Python 3.6+ is installed. ```batch Headphones.py ``` -------------------------------- ### Windows: Schedule Headphones to Run at Startup Source: https://github.com/rembo10/headphones/wiki/Install-as-a-daemon This guide explains how to configure Headphones to run automatically at system startup on Windows using the Task Scheduler. It outlines the specific settings required for the task, including user account, triggers, actions, conditions, and settings. ```batch "C:\Path\To\Your\headphones.py" ``` -------------------------------- ### Install Headphones on MacOS using Git Source: https://github.com/rembo10/headphones/wiki/Installation This method for installing Headphones on MacOS utilizes Git for cloning the repository. It requires Python 3 to be installed. After cloning, navigate to the directory and run the Python script. ```bash xcode-select --install cd /Applications git clone https://github.com/rembo10/headphones.git Headphones cd /Applications/Headphones python3 Headphones.py ``` -------------------------------- ### Create systemd User Service for Headphones Source: https://github.com/rembo10/headphones/wiki/Install-as-a-daemon This snippet shows the configuration for a systemd user service file to run the Headphones application. It specifies the service's description, dependencies, execution command, working directory, and restart behavior. Ensure `YOUR_USERNAME` is replaced with your actual username. ```systemd unit file [Unit] Description=Headphones Service After=network.target [Service] Type=simple ExecStart=python3 Headphones.py --datadir userdata/ WorkingDirectory=/home/YOUR_USERNAME/headphones Restart=on-failure [Install] WantedBy=default.target ``` -------------------------------- ### Enable Headphones Service for Startup (Ubuntu/Debian) Source: https://github.com/rembo10/headphones/wiki/Troubleshooting This command enables the Headphones service to start automatically on system boot for Ubuntu/Debian-based systems. It uses `update-rc.d` to set the default runlevels for the service. Ensure the service is properly installed before running this command. ```bash sudo update-rc.d headphones defaults ``` -------------------------------- ### Example Error Message for MusicBrainz Server Source: https://github.com/rembo10/headphones/wiki/Troubleshooting An example of a warning message that indicates Headphones is unable to connect to the MusicBrainz server. This helps users identify the specific problem when troubleshooting. ```log WARNING Attempt to query MusicBrainz for XXXX failed (retried 3 times, caused by: HTTP Error 502: Bad Gateway) ``` -------------------------------- ### Get Version Information Source: https://github.com/rembo10/headphones/blob/master/API.md Retrieves detailed version information about the Headphones installation, including paths, installation type, current and installed versions, and the number of commits behind the latest version. ```HTTP /getVersion ``` -------------------------------- ### Manual Update of Headphones using Git Source: https://github.com/rembo10/headphones/wiki/Troubleshooting A step-by-step guide to manually update Headphones using Git. This process involves resetting the repository, fetching remote updates, and pulling the latest changes from the master or develop branch. Ensure Git is installed and accessible. ```bash cd /path/to/headphones git branch git remote show origin git reset --hard git remote update git pull origin master # or git pull origin develop ``` -------------------------------- ### Mac OS X: Configure Headphones Launch Agent Source: https://github.com/rembo10/headphones/wiki/Install-as-a-daemon This snippet details how to set up Headphones to run as a launch agent on Mac OS X. It involves copying the init script to the user's LaunchAgents directory and using launchctl to load or unload the agent. ```shell cp /Applications/Headphones/init-scripts/init.osx ~/Library/LaunchAgents/com.rembo10.headphones.plist launchctl [load | unload] ~/Library/LaunchAgents/com.rembo10.headphones.plist ``` -------------------------------- ### Debug Headphones Daemon Startup Script Source: https://github.com/rembo10/headphones/wiki/Troubleshooting This example demonstrates how to modify a Headphones init script (specifically for Ubuntu) to debug startup issues. By removing `--daemon` and `--quiet` and adding `--verbose`, the script will run in the foreground, printing errors to the console or log file. This helps identify startup failures. ```bash # Example modification of launch options in an init script # Original: exec start-stop-daemon --quiet --pidfile /var/run/headphones.pid --make-pidfile --background --start --chuid headphones:headphones --exec /usr/bin/python -- /opt/headphones/Headphones.py --daemon --pidfile=/var/run/headphones.pid --datadir=/var/lib/headphones # Modified for debugging: exec start-stop-daemon --pidfile /var/run/headphones.pid --make-pidfile --start --chuid headphones:headphones --exec /usr/bin/python -- /opt/headphones/Headphones.py --pidfile=/var/run/headphones.pid --datadir=/var/lib/headphones --verbose ``` -------------------------------- ### Test XLD Command-Line Interface Source: https://github.com/rembo10/headphones/wiki/XLD-Re-Encoding-on-OSX This command tests the XLD command-line executable to ensure it's installed correctly and accessible. It should display a list of available options, confirming the CLI is functional. No specific inputs are required, and the output shows the program's capabilities. ```bash /Applications/xld ``` -------------------------------- ### Downgrade Headphones using contrib script Source: https://github.com/rembo10/headphones/wiki/Troubleshooting An alternative method for downgrading Headphones to the last successfully started version using a provided script. This requires Git to be installed and is a Unix-only solution. The script needs the path to the data folder as an argument. ```bash contrib/downgrade.sh ``` -------------------------------- ### Reinstall Headphones using Git Clone Source: https://github.com/rembo10/headphones/wiki/Troubleshooting Steps to completely reinstall Headphones, which can resolve issues that prevent normal updates. This involves backing up configuration and database files, removing the existing installation, cloning a fresh copy, and ensuring correct file ownership. ```bash cd /path/to/headphones cp headphones.db* ../ cp config.ini ../ cd .. rm -rf /path/to/headphones git clone https://github.com/rembo10/headphones /path/to/headphones chown -R headphones:headphones /path/to/headphones ``` -------------------------------- ### Get MusicBrainz Link (Python/Mako) Source: https://github.com/rembo10/headphones/blob/master/data/interfaces/default/album.html Constructs a MusicBrainz release URL using the provided ReleaseID. This link is displayed to allow users to view the release details on MusicBrainz. ```python mb_link = "http://musicbrainz.org/release/" + alternate_album['ReleaseID'] ``` -------------------------------- ### Toggle Verbose Logging in Headphones Source: https://github.com/rembo10/headphones/wiki/Troubleshooting This snippet explains how to enable verbose logging in Headphones, which is crucial for diagnosing problems. It can be done by starting the application with a command-line argument or by accessing a specific URL. ```text Start Headphones with the --verbose option. Toggle verbose mode temporary via http://ip:port/toggleVerbose. ``` -------------------------------- ### Display Headphones Version Information (Python Template) Source: https://github.com/rembo10/headphones/blob/master/data/interfaces/default/base.html This snippet uses Python templating to display the current version of Headphones, along with checks for updates against GitHub. It handles cases for unknown versions, newer versions available, and the number of commits behind. It also supports different installation types and Git branches. ```python <% import headphones from headphones import version %> Headphones - ${title} ${next.headIncludes()} % if headphones.CONFIG.CHECK_GITHUB and not headphones.CURRENT_VERSION: You're running an unknown version of Headphones. [Update](update) or [Close](javascript:void(0)) % elif headphones.CONFIG.CHECK_GITHUB and headphones.CURRENT_VERSION != headphones.LATEST_VERSION and headphones.COMMITS_BEHIND > 0 and headphones.INSTALL_TYPE != 'win': A [newer version](https://github.com/${headphones.CONFIG.GIT_USER}/headphones/compare/${headphones.CURRENT_VERSION}...${headphones.LATEST_VERSION}) is available. You're ${headphones.COMMITS_BEHIND} commits behind. [Update](update) or [Close](javascript:void(0)) % endif [![headphones](images/headphoneslogo.png)](home) * [wanted](upcoming) * [extras](extras) * [manage](manage) * [history](history) * [logs](logs) * [](config) Artist Album Series ${next.headerIncludes()} ${next.body()} [Website](https://github.com/rembo10/headphones) | %if headphones.CONFIG.GIT_USER != 'rembo10': [GitHub](https://github.com/${headphones.CONFIG.GIT_USER}/headphones "Open this fork on github") | %endif [Help](https://github.com/rembo10/headphones/wiki/TroubleShooting) [Shutdown](shutdown) | [Restart](restart) | [Check for new version](javascript:void(0)) Version: _${headphones.CURRENT_VERSION}_ %if version.HEADPHONES_VERSION != 'master': (${version.HEADPHONES_VERSION}) %endif %if headphones.CONFIG.GIT_BRANCH != 'master': (${headphones.CONFIG.GIT_BRANCH}) %endif [Back to top](#main) ${next.javascriptIncludes()} $(document).ready(function() { $('form:first *:input[type!=hidden]:first').focus(); try{ var type = window.localStorage.getItem('search_type') || "artist"; $("#search_type").val(type); } catch(e) { } }); $("select[id=search_type]").change(function() { var type = $(this).val() try{ window.localStorage.setItem('search_type', type); } catch(e) { } }); <%def name="javascriptIncludes()"> <%def name="headIncludes()"> <%def name="headerIncludes()"> ``` -------------------------------- ### Get Album Summary and Content Source: https://github.com/rembo10/headphones/blob/master/API.md Fetches detailed information about an album, including a summary and content, both formatted in HTML. This provides comprehensive details about the album. ```HTTP /getAlbumInfo&id=$albumid ``` -------------------------------- ### Compile Less to CSS using Less Compiler Source: https://github.com/rembo10/headphones/blob/master/data/interfaces/default/css/README.md This command compiles a Less stylesheet (style.less) into a CSS stylesheet (style.css) using the 'lessc' utility. Ensure you have Less installed before running this command. The output is a standard CSS file. ```bash lessc style.less > style.css ``` -------------------------------- ### Add Torznab Provider Dynamically - JavaScript Source: https://github.com/rembo10/headphones/blob/master/data/interfaces/default/config.html This JavaScript function dynamically adds a new 'Torznab' provider configuration form. It creates fields for host, API key, and seed ratio, along with a 'Remove' button. Each added provider gets a unique ID, and the 'Remove' button is configured to delete its parent element and update a counter for removed providers. ```javascript $("#add_torznab").click(function() { var intId = $("#torznab_providers > div").size() + deletedTorznabs + 1; var formfields = $("
%for newznab in config['extra_newznabs']: <% if newznab[2] == '1' or newznab[2] == 1: newznab_enabled = "checked" else: newznab_enabled = "" %> Newznab Host Newznab API Enabled <% newznab_number += 1 %> %endfor ``` -------------------------------- ### Get Album Thumbnail Image Source: https://github.com/rembo10/headphones/blob/master/API.md Retrieves a thumbnail image for a specified album. It returns either a relative path to the cached thumbnail or an HTTP URL if the cache directory is not writable. ```HTTP /getAlbumThumb&id=$albumid ``` -------------------------------- ### Get Artist Thumbnail Image Source: https://github.com/rembo10/headphones/blob/master/API.md Retrieves a thumbnail image for a specified artist. It returns either a relative path to the cached thumbnail or an HTTP URL if the cache directory is not writable. ```HTTP /getArtistThumb&id=$artistid ``` -------------------------------- ### Dynamic HTML Rendering with Jinja2 (Template) Source: https://github.com/rembo10/headphones/blob/master/data/interfaces/default/artist.html This is a template snippet using a Jinja2-like syntax (indicated by `<% %>` and `${ }`) to dynamically render HTML content. It iterates through albums, displays artist and album information, and includes conditional logic for status updates and download actions. It relies on Python variables like `artist`, `albums`, `db`, and `string`. ```html <%inherit file="base.html"/> <%! from headphones import db import headphones import string %> <%def name="headerIncludes()"> [Refresh Artist](javascript:void(0)) [Delete Artist](deleteArtist?ArtistID=${artist['ArtistID']}) [Scan Artist](javascript:void(0)) %if artist['Status'] == 'Paused': [Resume Artist](javascript:void(0)) %else: [Pause Artist](javascript:void(0)) %endif %if artist['IncludeExtras']: [Remove Extras](javascript:void(0)) [Modify Extras](javascript:void(0)) %else: [Get Extras](javascript:void(0)) %endif %for extra in extras: ${string.capwords(extra)} %endfor [« Back to overview](home) <%def name="body()"> ![](artwork/artist/${artist['ArtistID']}) [${artist['ArtistName']}](http://musicbrainz.org/artist/${artist['ArtistID']}) ================================================================================ Mark selected albums as Choose... Wanted Wanted (new only) Skipped Ignored Downloaded %for album in albums: <% if album['Status'] == 'Skipped': grade = 'Z' elif album['Status'] == 'Wanted': grade = 'X' elif album['Status'] == 'Snatched': grade = 'C' elif album['Status'] == 'Ignored': grade = 'I' else: grade = 'A' myDB = db.DBConnection() totaltracks = len(myDB.select('SELECT TrackTitle from tracks WHERE AlbumID=?', [album['AlbumID']])) havetracks = len(myDB.select('SELECT TrackTitle from tracks WHERE AlbumID=? AND Location IS NOT NULL', [album['AlbumID']])) + len(myDB.select('SELECT TrackTitle from have WHERE ArtistName like ? AND AlbumTitle LIKE ? AND Matched = "Failed"', [album['ArtistName'], album['AlbumTitle']])) try: percent = (havetracks*100.0)/totaltracks if percent > 100: percent = 100 except (ZeroDivisionError, TypeError): percent = 0 totaltracks = '?' avgbitrate = myDB.action("SELECT AVG(BitRate) FROM tracks WHERE AlbumID=?", [album['AlbumID']]).fetchone()[0] if avgbitrate: bitrate = str(int(avgbitrate)/1000) + ' kbps' else: bitrate = '' albumformatcount = myDB.action("SELECT COUNT(DISTINCT Format) FROM tracks WHERE AlbumID=?", [album['AlbumID']]).fetchone()[0] if albumformatcount == 1: albumformat = myDB.action("SELECT DISTINCT Format FROM tracks WHERE AlbumID=?", [album['AlbumID']]).fetchone()[0] elif albumformatcount > 1: albumformat = 'Mixed' else: albumformat = '' lossy_formats = [str.upper(fmt) for fmt in headphones.LOSSY_MEDIA_FORMATS] %> %endfor Name Date Type Metacritic Status Have Bitrate Format ![](artwork/thumbs/album/${album['AlbumID']}) [${album['AlbumTitle']}](albumPage?AlbumID=${album['AlbumID']}) ${album['ReleaseDate']} ${album['Type']} ${album['CriticScore']}/${album['UserScore']} ${album['Status']} %if album['Status'] == 'Skipped' or album['Status'] == 'Ignored': [[want](javascript:void(0))] %elif (album['Status'] == 'Wanted' or album['Status'] == 'Wanted Lossless'): [[skip](javascript:void(0))] [[search](javascript:void(0) "Search if available for download")] %else: [[retry](javascript:void(0) "Retry the same download again")][[new](javascript:void(0) "Try a new download, skipping all previously tried nzbs")] %endif %if albumformat in lossy_formats and album['Status'] == 'Skipped': [[want lossless](javascript:void(0))] %elif albumformat in lossy_formats and (album['Status'] == 'Snatched' or album['Status'] == 'Downloaded'): [[retry lossless](javascript:void(0))] %endif ${havetracks}/${totaltracks} ${bitrate} ${albumformat} ``` -------------------------------- ### Get Total Album Duration (Python/Mako) Source: https://github.com/rembo10/headphones/blob/master/data/interfaces/default/album.html Calculates the total duration of all tracks within an album by summing the 'TrackDuration' from the 'tracks' table. The result is then converted to a human-readable format. ```python totalduration = myDB.action("SELECT SUM(TrackDuration) FROM tracks WHERE AlbumID=?", [album['AlbumID']]).fetchone()[0] ``` -------------------------------- ### JavaScript Initialization and Event Handlers Source: https://github.com/rembo10/headphones/blob/master/data/interfaces/default/config.html This comprehensive function initializes the page by setting the initial visibility of various options based on checkbox states and attaches event listeners for UI interactions. It handles API key generation, authentication settings, HTTPS, encoding, album art, file moving, and notifications. ```javascript function initThisPage() { if ($("#api_enabled").is(":checked")) { $("#apioptions").show(); } else { $("#apioptions").hide(); } $("#api_enabled").click(function(){ if ($("#api_enabled").is(":checked")) { $("#apioptions").slideDown(); } else { $("#apioptions").slideUp(); } }); $('#api_key').click(function(){ $('#api_key').select() }); $("#generate_api").click(function(){ $.get('generateAPI', function(data){ if (data.error != undefined) { alert(data.error); return; } $('#api_key').val(data); }); }); if ($("#customauth").is(":checked")) { $("#customauth_options").show(); } else { $("#customauth_options").hide(); } $("#customauth").click(function(){ if ($("#customauth").is(":checked")) { $("#customauth_options").slideDown(); } else { $("#customauth_options").slideUp(); } }); if ($("#enable_https").is(":checked")) { $("#https_options").show(); } else { $("#https_options").hide(); } $("#enable_https").click(function(){ if ($("#enable_https").is(":checked")) { $("#https_options").slideDown(); } else { $("#https_options").slideUp(); } }); if ($("#music_encoder").is(":checked")) { $("#encoderoptions").show(); } else { $("#encoderoptions").hide(); } $("#music_encoder").click(function(){ if ($("#music_encoder").is(":checked")) { $("#encoderoptions").slideDown(); } else { $("#encoderoptions").slideUp(); } }); if ($("#embed_album_art").is(":checked")) { $("#album_art_size_options").show(); } else { if (!$("#add_album_art").is(":checked")) { $("#album_art_size_options").hide(); } } $("#embed_album_art").click(function(){ if ($("#embed_album_art").is(":checked")) { $("#album_art_size_options").slideDown(); } else { if (!$("#add_album_art").is(":checked")) { $("#album_art_size_options").slideUp(); } } }); if ($("#add_album_art").is(":checked")) { $("#album_art_options").show(); $("#album_art_size_options").show(); } else { $("#album_art_options").hide(); } $("#add_album_art").click(function(){ if ($("#add_album_art").is(":checked")) { $("#album_art_options").slideDown(); $("#album_art_size_options").slideDown(); } else { $("#album_art_options").slideUp(); if (!$("#embed_album_art").is(":checked")) { $("#album_art_size_options").slideUp(); } } }); if ($("#move_files").is(":checked")) { $("#move_files_options").show(); } else { $("#move_files_options").hide(); } $("#move_files").click(function(){ if ($("#move_files").is(":checked")) { $("#move_files_options").slideDown(); } else { $("#move_files_options").slideUp(); } }); if ($("#growl").is(":checked")) { $("#growloptions").show(); } else { $("#growloptions").hide(); } $("#growl").click(function(){ if ($("#growl").is(":checked")) { $("#growloptions").slideDown(); } else { $("#growloptions").slideUp(); } }); if ($("#prowl").is(":checked")) { $("#prowloptions").show(); } else { $("#prowloptions").hide(); } $("#prowl").click(function(){ if ($("#prowl").is(":checked")) { $("#prowloptions").slideDown(); } else { $("#prowloptions").slideUp(); } }); if ($("#xbmc").is(":checked")) { $("#xbmcoptions").show(); } else { $("#xbmcoptions").hide(); } $("#xbmc").click(function(){ if ($("#xbmc").is(":checked")) { $("#xbmcoptions").slideDown(); } else { $("#xbmcoptions").slideUp(); } }); if ($("#lms").is(":checked")) { $("#lmsoptions").show(); } else { $("#lmsoptions").hide(); } $("#lms").click(function(){ if ($("#lms").is(":checked")) { $("#lmsoptions").slideDown(); } else { $("#lmsoptions").slideUp(); } }); if ($("#plex").is(":checked")) { $("#plexoptions").show(); } else { $("#plexoptions").hide(); } $("#plex").click(function(){ if ($("#plex").is(":checked")) { $("#plexoptions").slideDown(); } else { $("#plexoptions").slideUp(); } }); if ($( ``` -------------------------------- ### Get Total Track Count (Python/Mako) Source: https://github.com/rembo10/headphones/blob/master/data/interfaces/default/album.html Counts the total number of tracks for a given album by querying the 'tracks' table based on AlbumID. This is displayed as part of the album's summary information. ```python totaltracks = len(myDB.select("SELECT TrackTitle from tracks WHERE AlbumID=?", [album['AlbumID']])) ``` -------------------------------- ### Configure Synology NAS Integration in Python Source: https://github.com/rembo10/headphones/blob/master/data/interfaces/default/config.html This Python snippet is a placeholder for Synology NAS integration settings. No specific parameters are detailed. ```python Synology NAS ``` -------------------------------- ### Clone Repository with Feature Branch (Git) Source: https://github.com/rembo10/headphones/blob/master/CONTRIBUTING.md This command clones the Headphones repository and checks out a new feature branch from the 'develop' branch. It's the recommended way to start developing new features to minimize merge conflicts. ```bash git clone origin/develop -b FEATURE_NAME ``` -------------------------------- ### Get Album Average Bitrate (Python) Source: https://github.com/rembo10/headphones/blob/master/data/interfaces/default/artist.html This Python snippet retrieves the average bitrate for all tracks within a specific album using a database query. It formats the result into 'kbps'. It requires the `AlbumID` and uses `db.DBConnection` for data retrieval. ```python avgbitrate = myDB.action("SELECT AVG(BitRate) FROM tracks WHERE AlbumID=?", [album['AlbumID']]).fetchone()[0] if avgbitrate: bitrate = str(int(avgbitrate)/1000) + ' kbps' else: bitrate = '' ``` -------------------------------- ### Initialize UI Components and Event Handlers Source: https://github.com/rembo10/headphones/blob/master/data/interfaces/default/config.html Initializes various UI components and sets up event handlers for user interactions. This includes tabbed interfaces, input field synchronization, and checkbox initialization for different configuration options. It also handles adding and removing 'torznab' settings dynamically. ```javascript var deletedTorznabs = 0; $(document).ready(function() { initThisPage(); }); function initThisPage() { $("#add_torznab").click(function() { var intId = $(".torznab").length + 1; var formfields = $("
"); var removeTorznabButton = $("
"); removeTorznabButton.click(function() { $(this).parent().remove(); deletedTorznabs = deletedTorznabs + 1; }); formfields.append(removeTorznabButton); formfields.append("
"); $("#add_torznab").before(formfields); }); $(".hpuser").keyup(function() { $(".hpuser").val($(this).val()); }); $(".hppass").keyup(function() { $(".hppass").val($(this).val()); }); $(function() { $("#tabs").tabs(); }); initActions(); initConfigCheckbox("#headphones_indexer"); initConfigCheckbox("#use_newznab"); initConfigCheckbox("#use_nzbsorg"); initConfigCheckbox("#use_omgwtfnzbs"); initConfigCheckbox("#use_torznab"); initConfigCheckbox("#use_piratebay"); initConfigCheckbox("#use_rutracker"); initConfigCheckbox("#use_orpheus"); initConfigCheckbox("#use_redacted"); initConfigCheckbox("#api_enabled"); initConfigCheckbox("#enable_https"); initConfigCheckbox("#customauth"); initConfigCheckbox("#mb_ignore_age_missing"); } ``` -------------------------------- ### Check File Permissions on Linux Source: https://github.com/rembo10/headphones/wiki/Troubleshooting Provides a command to list files and their permissions in the current directory on a Linux system. This helps in verifying that Headphones has the necessary read/write access. ```bash ls -al ``` -------------------------------- ### Get Album Format Count and Type (Python) Source: https://github.com/rembo10/headphones/blob/master/data/interfaces/default/artist.html This Python code determines the number of distinct formats for tracks within an album and identifies the format(s). If there's only one format, it's specified; otherwise, it's marked as 'Mixed'. It uses `db.DBConnection` and requires the `AlbumID`. ```python albumformatcount = myDB.action("SELECT COUNT(DISTINCT Format) FROM tracks WHERE AlbumID=?", [album['AlbumID']]).fetchone()[0] if albumformatcount == 1: albumformat = myDB.action("SELECT DISTINCT Format FROM tracks WHERE AlbumID=?", [album['AlbumID']]).fetchone()[0] elif albumformatcount > 1: albumformat = 'Mixed' else: albumformat = '' ``` -------------------------------- ### Force Legacy Actions Source: https://github.com/rembo10/headphones/blob/master/data/interfaces/default/manage.html Presents options for comprehensive, time-consuming legacy actions. These include a full artist update and a complete library re-scan, with a warning about resetting manual matching. ```html Please note that these functions will take a significant amount of time to complete. [Force Update Active Artists [Comprehensive]](javascript:void(0)) [Force Re-scan Library [Comprehensive]](javascript:void(0)) *Warning: If you choose [Force Re-scan Library], any manually ignored/matched artists/albums will be reset to "unmatched". ``` -------------------------------- ### OS X Notification Registration via AJAX Source: https://github.com/rembo10/headphones/blob/master/data/interfaces/default/config.html Handles the registration of an application for OS X notifications using an AJAX GET request. It sends the application name to the server and displays a success message or error feedback to the user. The function includes a delay for fading out the message. ```javascript $('#osxnotifyregister').click(function () { var osx_notify_app = $("#osx_notify_reg").val(); $.get("/osxnotifyregister", {'app': osx_notify_app}, function (data) { $('#ajaxMsg').html("
"+data+"
"); }); $('#ajaxMsg').addClass('success').fadeIn().delay(3000).fadeOut() }) ``` -------------------------------- ### Initialize Album Data Table with Options (JavaScript) Source: https://github.com/rembo10/headphones/blob/master/data/interfaces/default/managealbums.html This JavaScript function initializes a DataTables instance for the album table. It configures sorting, filtering, and display options, including custom language settings and column definitions. The function also includes a callback to reset filters and scroll to the top. ```javascript function initThisPage() { $('#album_table').dataTable({ "bDestroy": true, "aoColumns": [ null, null, null, null, null, null, {"sType": "title-numeric"}, null, null ], "aoColumnDefs": [ { 'bSortable': false, 'aTargets': [0] } ], "oLanguage": { "sLengthMenu":"Show _MENU_ albums per page", "sEmptyTable": "No album information available", "sInfo":"Showing _TOTAL_ albums", "sInfoEmpty":"Showing 0 to 0 of 0 albums", "sInfoFiltered":"(filtered from _MAX_ total albums)", "sSearch": "" }, "bPaginate": false, "aaSorting": [[5, 'desc']], "fnDrawCallback": function (o) { // Jump to top of page $('html,body').scrollTop(0); } }); resetFilters("albums"); } $(document).ready(function() { initThisPage(); }); ``` -------------------------------- ### Check Headphones Process Status (Linux/macOS) Source: https://github.com/rembo10/headphones/wiki/Troubleshooting This command checks if the Headphones process is currently running on a Linux or macOS system. It uses `ps` to list running processes and `grep` to filter for 'Headphones'. This is useful for diagnosing issues where Headphones may not be running as expected, especially when installed as a daemon. ```bash ps awx | grep Headphones ``` -------------------------------- ### JavaScript Data Table Initialization and Customization Source: https://github.com/rembo10/headphones/blob/master/data/interfaces/default/manageunmatched.html This JavaScript code initializes a DataTables instance for an artist table, configuring pagination, search, and display options. It includes a callback function to ensure the user scrolls to the top of the page after each table redraw. ```javascript $(document).ready(function() { $('#artist_table').dataTable({ "bStateSave": true, "bPaginate": true, "oLanguage": { "sSearch": "", "sLengthMenu":"Show _MENU_ albums per page", "sInfo":"Showing _START_ to _END_ of _TOTAL_ albums", "sInfoEmpty":"Showing 0 to 0 of 0 albums", "sInfoFiltered":"(filtered from _MAX_ total albums)", "sEmptyTable": " ", }, "sPaginationType": "full_numbers", "fnDrawCallback": function (o) { // Jump to top of page $('html,body').scrollTop(0); } }); initActions(); }); ``` -------------------------------- ### Render Download History Table Source: https://github.com/rembo10/headphones/blob/master/data/interfaces/default/history.html This Jinja2 template code iterates through a list of history items, determining a 'grade' based on status and identifying the file type from the URL. It then formats and displays various details including date, title, file ID, album page link, size, status, and action buttons for each item. It relies on the 'headphones.helpers' module for byte conversion to MB. ```Jinja2 <%inherit file="base.html"/> <%! from headphones import helpers from html import escape as html_escape %> <%def name="headerIncludes()"> [Clear All History](javascript:void(0)) [Clear Processed](javascript:void(0)) [Clear Unprocessed](javascript:void(0)) [Clear Frozen](javascript:void(0)) [Clear Snatched](javascript:void(0)) <%def name="body()"> History ======= %for item in history: <% if item['Status'] == 'Processed': grade = 'A' elif item['Status'] == 'Snatched': grade = 'C' elif item['Status'] == 'Unprocessed': grade = 'X' elif item['Status'] == 'Frozen': grade = 'X' else: grade = 'U' fileid = 'unknown' if item['URL'].find('nzb') != -1: fileid = 'nzb' if item['URL'].find('torrent') != -1: fileid = 'torrent' if item['URL'].find('magnet:') != -1: fileid = 'torrent' if item['URL'].find('rutracker') != -1: fileid = 'torrent' if item['URL'].find('codeshy') != -1: fileid = 'nzb' if item['URL'].find('bandcamp') != -1: fileid = 'bandcamp' folder = 'Folder: ' + item['FolderName'] %> %endfor Date Added File Name Size Status ${item['DateAdded']} ${html_escape(item['Title'], quote=True)} [[${fileid}](${item['URL']})][[album page]](albumPage?AlbumID=${item['AlbumID']}) ${helpers.bytes_to_mb(item['Size'])} ${item['Status']} [[retry]](javascript:void(0))[[new]](javascript:void(0)) [![](interfaces/default/images/trashcan.png "Clear this item from the history")](javascript:void(0)) <%def name="headIncludes()"> <%def name="javascriptIncludes()"> ```