gaspar_schot / Librivox.org Playlists

// ==UserScript==
// @name         Librivox.org Playlists
// @namespace    https://openuserjs.org/users/gaspar_schot
// @version      1.0
// @description  Adds a link to download an m3u playlist of the mp3 files in the current librivox.org page.
// @author       gaspar_schot
// @copyright    2019, gaspar_schot (https://openuserjs.org/users/gaspar_schot)
// @updateURL    https://openuserjs.org/meta/gaspar_schot/Librivox.org_Playlists.meta.js
// @license      MIT
// @match        https://librivox.org/*
// @require      http://code.jquery.com/jquery-latest.min.js

// ==/UserScript==

(function() {
    'use strict';
    const $ = window.jQuery;

 	function decodeURIComponentSafe(s) {
 		if ( !s ) { return s; }
        return decodeURIComponent(s.replace(/%(?![0-9a-fA-F]{2})/g, '%25') ); // replace % with %25 if not followed by two a-f/number
 	}
    const $download_cont = $('.book-page-sidebar').last();
    const $download_button = '<p><a href="" id="download_button">M3U Playlist</a></p>';
          $download_cont.find('p').last().after($download_button);
    const $mp3_cont = $('.chapter-download');

    if ( $mp3_cont.length ) {
        let $mp3_links_list = '#EXTM3U\n';
        let $mp3_item = $mp3_cont.find('tbody tr');
        let $mp3_link;
        let $mp3_chapter_name = '';
        let $mp3_author = '';
        let $mp3_reader = '';
        let $mp3_time, time;

        let chapter_index = $mp3_cont.find('th:contains("Chapter")').index();
        let author_index = $mp3_cont.find('th:contains("Author")').index();
        let reader_index = $mp3_cont.find('th:contains("Reader")').index();
        let time_index = $mp3_cont.find('th:contains("Time")').index();

        $mp3_item.each(function() {
            $mp3_link = $(this).find('td').eq(1).find('a').attr('href');
            $mp3_chapter_name = $(this).find('td').eq(chapter_index).text();
            $mp3_author = $(this).find('td').eq(author_index).text();
            $mp3_reader = $(this).find('td').eq(reader_index).text();
            $mp3_time = $(this).find('td').eq(time_index).text();
            if ( $mp3_author.length > 0 ) { $mp3_author = ', '+ $mp3_author }
            if ( $mp3_reader.length > 0 ) { $mp3_reader = ' (Reader: '+ $mp3_reader +')' }
            if ( $mp3_time.length !== -1 ) {
                $mp3_time = $mp3_time.split(':').reverse(); // 00:26:50
                time = Number.parseInt($mp3_time[0]) + Number.parseInt($mp3_time[1]*60) + Number.parseInt($mp3_time[2]*60*60);
            } else {
                time = '';
            }
            $mp3_links_list += '#EXTINF:' + time + ',' + decodeURIComponentSafe($mp3_chapter_name) + decodeURIComponentSafe($mp3_author) + decodeURIComponentSafe($mp3_reader) + '\n' + $mp3_link + '\n';
        });

        $('#download_button').on('click',function() {
            download($mp3_links_list, $('.book-page-book-cover + h1').text() +'.m3u', 'text/plain');
        });
    }

    // create download link
    function download(text, name, type) {
        var $download_button = document.getElementById("download_button");
        var file = new Blob([text], {type: type});
        $download_button.href = URL.createObjectURL(file);
        $download_button.download = name;
        URL.revokeObjectURL(file);
    }

})();