Commit 3c1ff520 authored by TheTechRobo's avatar TheTechRobo
Browse files

Stream results to frontend

Fixes #66
Fixes #83
parent dd167daf
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -39,7 +39,7 @@ class Service(JSONDataclass):
    """
    archived: bool
    capcount: int
    lastupdated: int
    lastupdated: float
    name: str
    note: str
    rawraw: typing.Any
@@ -49,7 +49,7 @@ class Service(JSONDataclass):

    available: typing.Optional[str] = None
    suppl: str = ""
    error: typing.Optional[bool] = None
    error: typing.Optional[typing.Any] = None

    configId = None

@@ -85,7 +85,7 @@ class Service(JSONDataclass):
                    archived=False, capcount=0, error=rawraw,
                    lastupdated=time.time(), name=cls.getName(), note=note,
                    rawraw=None, metaonly=False, comments=False,
                    available=None, classname="Error"
                    available=None, classname=cls.__name__
            )

    @classmethod
+112 −34
Original line number Diff line number Diff line
@@ -26,6 +26,47 @@ function getVideoId(videoInput) {
    return false;
}

function makeServiceEntry(result) {
    var colour;
    if (result.error) {
        colour = "white";
    } else if (result.archived && result.metaonly) {
        colour = "yellow";
    } else if (result.archived) {
        colour = "green";
    } else {
        colour = "red";
    }
    var isarchived = result.archived ? "Available" : "Not Available";
    if (result.error !== null) {
        isarchived = "Unknown";
        result.note = result.note + result.error;
    }

    let archived = `<span class='${colour}'>${isarchived}</span>`;
    let metaonly = (result.metaonly && result.archived) ? " (metadata only) " : " ";
    let comments = (result.archived && result.comments) ? " (incl. comments) " : " ";
    let lien = result.available ? `<a href="${result.available}">(link)</a>` : ""
    return `${archived}${metaonly}${comments}${lien}<br />${result.note}`
}

// https://stackoverflow.com/a/48054293/9654083
function escapeHTML(unsafeText) {
    let div = document.createElement('div');
    div.innerText = unsafeText;
    return div.innerHTML;
}

function makeLoadingElement(title) {
    const li = document.createElement("li");
    li.innerHTML = `
        <b>${escapeHTML(title)}</b>:
        <span class="result"><img src="/static/loading.gif" style="height: 1em;" /> Loading...</span>
    `;
    li.setAttribute("data-status", "loading");
    return li;
}

function finish(vid1) {
    const dataDiv = getDataDiv()
    const submitBtn = getSubmitBtn()
@@ -49,7 +90,7 @@ function finish(vid1) {

    // https://www.behance.net/gallery/31234507/Open-source-Loading-GIF-Icons-Vol-1
    dataDiv.innerHTML += `<div style="display: flex; gap: 12px;"><img src="/static/loading.gif" width="25" height="25" /> Loading could take up to 30 seconds.</div>`;
    fetch(`api/v4/youtube/${vid}`)
    fetch(`api/v4/youtube/${vid}?stream`)
        .then((response) => {
            if (response.status === 410 || response.status === 404) {
                dataDiv.innerHTML = `<span style="color: red;">API version is not supported - this should never happen</span>`;
@@ -63,45 +104,82 @@ function finish(vid1) {
                dataDiv.innerHTML = `<span style="color: red;">You have been rate limited - please slow down</span>`;
                return null;
            }
            return response.json();
            return response.body.getReader();
        })
        .then((data) => {
        .then((stream) => {
            if (stream === null) {
                return;
            }
            const possible_states = Object.freeze({
                Preparation: "Preparation",
                Generation: "Generation",
                Verdict: "Verdict"
            });
            let ul = document.createElement("ul");
            dataDiv.innerHTML = "";
            dataDiv.appendChild(ul);
            let state = possible_states.Preparation;
            let currentline = "";
            let elements = {};
            function processLine(line) {
                if (line === "" || line === "\n") {
                    return;
                }
                let data = JSON.parse(line);
                switch(state) {
                    case possible_states.Preparation: {
                        for (const [key, value] of Object.entries(data)) {
                            elements[key] = makeLoadingElement(value);
                            ul.appendChild(elements[key]);
                        }
                        state = possible_states.Generation;
                        break;
                    }
                    case possible_states.Generation: {
                        if (data === null) {
                            state = possible_states.Verdict;
                            return;
                        }
            console.log(`Data: ${data}`)
            let write = "<ul>";
            let keys = data.keys;
            keys.forEach((wbm) => {
                var colour;
                if (wbm.error) {
                    colour = "white";
                } else if (wbm.archived && wbm.metaonly) {
                    colour = "yellow";
                } else if (wbm.archived) {
                    colour = "green";
                } else {
                    colour = "red";
                        const cln = data.classname;
                        elements[cln].querySelector(".result").innerHTML = makeServiceEntry(data);
                        elements[cln].setAttribute("data-status", "done");
                        break;
                    }
                var isarchived = wbm.archived ? "Available" : "Not Available";
                if (wbm.error !== null) {
                    isarchived = "Unknown";
                    wbm.note = wbm.note + wbm.error;
                    case possible_states.Verdict: {
                        return;
                    }
                    default: {
                        throw new Error("unexpected state")
                    }
                }
            }
            function pump() {
                return stream.read().then(({ done, value }) => {
                    if (done) {
                        return;
                    }
                    let text = new TextDecoder().decode(value);
                    for (const c of text) {
                        currentline += c
                        if (c === "\n") {
                            processLine(currentline);
                            currentline = "";
                        }
                    }
                    return pump();
                }).catch((e) => {
                    console.log(`! CONNECTION ERROR ! (${e})`);
                    Object.values(elements).forEach((i) => {
                        if (i.getAttribute("data-status") == "loading") {
                            i.querySelector(".result").innerHTML = '<span class="white">Error</span><br />A connection error occured while receiving data. Please try again; if it persists, contact me (details are at the bottom of "How do I use this?") and provide console output and a way to reproduce if possible.';
                        }
                let archived = `<span class='${colour}'>${isarchived}</span>`;
                let metaonly = (wbm.metaonly && wbm.archived) ? " (metadata only) " : " ";
                let comments = (wbm.archived && wbm.comments) ? " (incl. comments) " : " ";
                let lien = wbm.available ? `<a href="${wbm.available}">(link)</a>` : ""
                write += `<li><b>${wbm.name}:</b> ${archived}${metaonly}${comments}${lien}<br>`
                write += `${wbm.note}</li>`;

                    });
            let elm = document.getElementById("data");
            elm.innerHTML = write;
            submitBtn.innerHTML = "Search for Captures";
                });
            }
            return pump();
        })
        .catch((e) => {
            dataDiv.innerHTML = '<span class="red" style="background-color: #FFFFFF;">An error occurred, check your internet connection</span>';
            dataDiv.innerHTML = '<span class="red" style="background-color: #fff;">An error occurred, check your internet connection</span>';
            throw (e);
        })
        .finally(() => {
@@ -120,6 +198,6 @@ function finishWrpa(data) {
        return finish(data);
    } catch (err) {
        console.error(err)
        dataDiv.innerHTML = "<span class='red'>This should be unreachable. Please report this issue and provide a way to reproduce.</span>";
        dataDiv.innerHTML = "<span class='red'>An unknown error occured. Please report this. If possible, provide console output and a way of reproducing.</span>";
    }
}
+0 −1
Original line number Diff line number Diff line
@@ -87,7 +87,6 @@
<div class="container" id="footer-section">
    <p style="text-align: center;"><i>Website created by <a href="https://thetechrobo.ca">TheTechRobo</a></i></p>
</div>
<script>initDarkMode()</script>
{% if default %}
  <script>finishWrpa("{{default}}");</script>
{% endif %}