razorwax / Recurbate download

// ==UserScript==
// @name         Recurbate download
// @version      1.2.2
// @description  Adds a download button for each video on recurbate.me
// @author       razorwax
// @updateURL    https://openuserjs.org/meta/razorwax/Recurbate_download.meta.js
// @downloadURL  https://openuserjs.org/install/razorwax/Recurbate_download.user.js
// @match        https://recurbate.me/video*
// @match        https://recu.me/video*
// @license MIT
// ==/UserScript==

function ErrorPrint(errorReason)
{
    var error = "Recurbate Download Error! [reason = " + errorReason + "]";
    console.error(error);
    window.alert(error);
}

function DataErrorPrint(errorReason)
{
    var description;
    if (errorReason == "shall_signin")
    {
        description = "You need to sign in to an account to be able to download.";
    }
    else if (errorReason == "shall_subscribe")
    {
        description = "Your current free downloads have been used today, please upgrade your membership to unlock more downloads.";
    }
    else if (errorReason == "wrong_token")
    {
        description = "Something unexpected has happen, try to reload the site and try again. If it doesn't work then report the error.";
    }
    var error = "Recurbate Download Error! [data_reponse = " + errorReason + "]\n\n" + description;
    console.error(error);
    window.alert(error);
}

function WarnPrint(warnMessage)
{
    var warn = "Warning: " + warnMessage;
    console.warn(warn);
    window.alert(warn);
}

function DownloadVideo(url)
{
    if (!url)
    {
        ErrorPrint("find_video_src_failure");
        return;
    }
    window.open(url, '_blank');
}

function FindSourceFromUnstartedVideo(videoBtn)
{
    // Find token and id
    var token = videoBtn.attr("data-token");
    var id = videoBtn.attr("data-video-id");
    if (token && id)
    {
        // Send video request to server
        var url = "/api/video/" + id + "?token=" + token;
        $.get(url, function(data)
        {
            // Find the src by using jquery selectors
            var sourceElem = $(data).find("video source");
            if (sourceElem.length)
            {
                var src = sourceElem.attr("src");
                if (src)
                {
                    DownloadVideo(src);
                    return;
                }
            }

            // Find the src by using string search
            if (data.includes("<video") && data.includes("src="))
            {
                var src = data.match(/src=".+?"/m);
                if (!!src)
                {
                    // Convert to string
                    src = src[0];
                    // Find the source substring
                    src = src.substring(5, src.length - 1);
                    DownloadVideo(src);
                    return;
                }
            }

            DataErrorPrint(data);
        });
    }
    else
    {
        ErrorPrint("token_and_id_failure");
    }
}

function FindSourceFromStartedVideo()
{
    var foundVideo;
    var searchVideos = $("video");
    if (searchVideos.length == 1)
    {
        // Guess this is the video we are looking for
        foundVideo = searchVideos[0];
    }
    else
    {
        // Multiple videos found, search for the correct one
        var videoIdRegex = /video_\d+/;
        for (var video of searchVideos)
        {
            if (video.id.match(videoIdRegex))
            {
                foundVideo = video;
                break;
            }
        }
    }

    if (foundVideo)
    {
        var source = foundVideo.src;
        if (!source)
        {
            // Try to find video source by source element
            var sourceElem = $(foundVideo).find("source");
            if (sourceElem && sourceElem.length > 0)
            {
                source = sourceElem[0].src;
            }
        }
        DownloadVideo(source);
    }
    else
    {
        ErrorPrint("find_video_failure");
    }
}

function AddDownloadButton(appendToElem)
{
    // Remove official download button
    $("a.download.btn").remove();

    // Add new download button
    var downloadBtn = $("<button style=\"margin-left: 10px;\" class=\"btn btn-warning btn-sm\"><i class=\"fas fa-download\"></i><b style=\"color:#212528\"> Download</b></button>").appendTo(appendToElem);
    downloadBtn.on("click", function()
    {
        // Download button press
        var videoBtns = $("#play_button");
        if (videoBtns.length > 0)
        {
            // Found the unstarted video player, find src from it
            FindSourceFromUnstartedVideo($(videoBtns[0]));
        }
        else
        {
            // Video must have been started
            FindSourceFromStartedVideo();
        }
    });
}

// Create download button
$(function ()
{
    var addTo = $("a.bookmark");
    if (addTo.length == 1)
    {
        addTo = addTo.parent();
    }
    else
    {
        addTo = $("div.video-info").children("div");
    }

    if (addTo.length > 0)
    {
        AddDownloadButton($(addTo[0]));
    }
    else
    {
        ErrorPrint("add_download_btn_failure");
    }
});