-
-
Save bonelifer/b0236f57280489f35caebcec58e21bac to your computer and use it in GitHub Desktop.
Add SomaFM channels as individual playlists in specified directories. Supports multiple playlist types (highestpls-aac, fastpls-mp3, fastpls-aacp, slowpls-aacp). Will delete existing playlists before creating new ones. Requires curl, awk, grep, and basic shell tools. You can specify which playlist types to create by passing arguments, or leave b…
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
# Script to create SomaFM playlists based on XML channel data | |
# The script will create playlists in directories named after the playlist type (e.g., fastpls-mp3). | |
# It can handle multiple types of playlists, and will clean up existing playlists before creating new ones. | |
# Base directory for all playlists | |
BASE_DIR="./playlists" | |
# Define valid playlist types and their mappings using an associative array | |
# This maps playlist types to XML tags and format attributes in the SomaFM channel data | |
declare -A TYPES=( | |
["highestpls-aac"]="highestpls aac" # Highest quality AAC format | |
["fastpls-mp3"]="fastpls mp3" # Fast MP3 format | |
["fastpls-aacp"]="fastpls aacp" # Fast AAC+ format | |
["slowpls-aacp"]="slowpls aacp" # Slow AAC+ format | |
) | |
# Function to remove all directories and their contents within BASE_DIR | |
# This is useful to clean up before creating new playlists | |
cleanup_all_playlists() { | |
if [[ -d "$BASE_DIR" ]]; then | |
# Delete all files and subdirectories in the BASE_DIR | |
find "$BASE_DIR" -mindepth 1 -delete || { | |
echo "Error removing directories and files in $BASE_DIR: $?" | |
return 1 | |
} | |
fi | |
} | |
# Function to create playlists for a given type | |
# This function processes the channel XML data, extracts the playlist URL based on type, | |
# and saves it as a .m3u file in the appropriate directory | |
create_playlists() { | |
local type="$1" | |
# Look up the type from the TYPES array and ensure it's valid | |
local type_name="${TYPES[$type]}" || { echo "Error: Invalid type $type"; return 1; } | |
local type_name_parts=(${type_name// / }) | |
local type_name_main="${type_name_parts[0]}" # The XML tag (e.g., fastpls, highestpls) | |
local type_name_format="${type_name_parts[1]}" # The format (e.g., mp3, aac) | |
# Create the directory for this type of playlist | |
mkdir -p "$BASE_DIR/$type" || { echo "Error creating directory $BASE_DIR/$type: $?" ; return 1; } | |
# More robust XML handling with error checking | |
# Fetch the channel XML, process each channel, and extract relevant playlist URLs | |
if ! curl -s https://somafm.com/channels.xml | \ | |
awk 'BEGIN { RS="</channel>"; ORS="</channel>\n" } { gsub("\n", " "); print }' | \ | |
grep -Po '(<channel id="[^"]+">.*?</channel>)' | while read -r channel; do | |
# Extract the channel name (title) and URL based on the requested playlist type | |
CHANNEL_NAME=$(echo "$channel" | grep -Po '(?<=<title><!\[CDATA\[).+?(?=\]\]></title>)') || continue | |
URL=$(echo "$channel" | grep -Po "(?<=<${type_name_main} format=\"${type_name_format}\">).+?(?=</${type_name_main}>)") | |
# If no URL is found for the given type, skip this channel | |
if [[ -z "$URL" ]]; then | |
echo "No ${type_name_main} (${type_name_format}) URL found for channel: ${CHANNEL_NAME}" | |
continue | |
fi | |
# Create the playlist file for the channel | |
PLAYLIST_FILE="$BASE_DIR/$type/${CHANNEL_NAME}.m3u" | |
echo "$URL" > "$PLAYLIST_FILE" || { echo "Error writing to file $PLAYLIST_FILE: $?" ; rm -rf "$BASE_DIR/$type"; return 1; } | |
echo "Created playlist: $PLAYLIST_FILE" | |
done; then | |
# If there was an error fetching or processing the XML, clean up and return an error | |
echo "Error fetching or processing SomaFM channel data." | |
rm -rf "$BASE_DIR/$type" | |
return 1 | |
fi | |
} | |
# Main script logic: First, clean everything; then create playlists. | |
cleanup_all_playlists | |
# If no arguments are provided, create playlists for all types | |
if [[ "$#" -eq 0 ]]; then | |
for type in "${!TYPES[@]}"; do | |
create_playlists "$type" || exit 1 | |
done | |
else | |
# If arguments are provided, create only the specified playlist types | |
for arg in "$@"; do | |
# Check if the argument matches a valid type from the TYPES array | |
if [[ -v "TYPES[$arg]" ]]; then | |
create_playlists "$arg" || exit 1 | |
else | |
echo "Invalid type: $arg. Valid types: ${!TYPES[@]}" | |
exit 1 | |
fi | |
done | |
fi | |
# Exit the script successfully | |
exit 0 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add SomaFM channels as individual playlists in specified directories. Supports multiple playlist types (highestpls-aac, fastpls-mp3, fastpls-aacp, slowpls-aacp). Will delete existing playlists before creating new ones. Requires curl, awk, grep, and basic shell tools. You can specify which playlist types to create by passing arguments, or leave blank to create all playlist types.