Commit 21f5efa4 authored by TheTechRobo's avatar TheTechRobo
Browse files

Add noscript version; also fix major bug

Fixes #37
parent ca8b02d0
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -4,3 +4,4 @@ switch
nest_asyncio
cachetools
click
asyncache
+61 −3
Original line number Diff line number Diff line
from flask import Flask, render_template, request
from flask import Flask, render_template, request, Response

import re, urllib.parse

import lostmediafinder

@@ -7,6 +9,7 @@ app = Flask(__name__)
@app.route("/robots.txt")
async def robots():
    return """
# I'm 100% fine with crawlers, just don't fuck up my servers.
User-Agent: *
Crawl-delay: 2
Disallow:
@@ -27,7 +30,7 @@ async def wrapperYT(id):

@app.route("/api/v<int:v>/<site>/<id>")
@app.route("/api/v<int:v>/<id>")
async def youtube(v, id, site="youtube"):
async def youtube(v, id, site="youtube", json=True):
    """
    Wrapper around lostmediafinder
    """
@@ -36,9 +39,64 @@ async def youtube(v, id, site="youtube"):
    if v not in (2, 3):
        return "Unrecognised API version", 404
    if site == "youtube":
        return (await wrapperYT(id)).coerce_to_api_version(v).json()
        r = (await wrapperYT(id)).coerce_to_api_version(v)
        if json:
            return r.json()
        return r
    return "Unrecognised site", 404

@app.route("/noscript_init.html")
async def noscript_init():
    return """
    <!DOCTYPE html>
    <html>
      <body style="text-align:center;align-items:center">
        <p>Awaiting input...</p>
      </body>
    </html>
    """

ID_PATTERN = re.compile(r'^[A-Za-z0-9_-]{10}[AEIMQUYcgkosw048]$')
PATTERNS = [
    re.compile(r'(?:https?://)?(?:\w+\.)?youtube\.com/watch/?\?v=([A-Za-z0-9_-]{10}[AEIMQUYcgkosw048])(?:[\/&].*)?', re.IGNORECASE),
    re.compile(r'(?:https?://)?(?:\w+\.)?youtube.com/(?:v|embed|shorts|video)/([A-Za-z0-9_-]{10}[AEIMQUYcgkosw048])(?:[\/&].*)?', re.IGNORECASE),
    re.compile(r'(?:https?://)?youtu.be/([A-Za-z0-9_-]{10}[AEIMQUYcgkosw048])(?:\?.*)?', re.IGNORECASE),
    re.compile(r'(?:https?://)?filmot.com/video/([A-Za-z0-9_-]{10}[AEIMQUYcgkosw048])(?:\?.*)?', re.IGNORECASE)
]

def coerce_to_id(vid):
    if re.match(ID_PATTERN, vid):
        return vid

    for pattern in PATTERNS:
        newVid = re.sub(pattern, lambda match: match.group(1), vid)
        if re.match(ID_PATTERN, newVid):
            return newVid
    return None

@app.route("/noscript_load.html")
async def noscript_load():
    if not request.args.get("d"):
        return "No d param provided - It should be the video id or url", 400
    id = coerce_to_id(request.args['d'])
    response = Response("""
    <!DOCTYPE html>
    <html>
    <head><meta http-equiv="refresh" content="0; url=/noscript_load_thing.html?id=%s" />
    <body>
    <img src="/static/ab79a231234507.564a1d23814ef.gif" width="25" height="25" />Loading could take up to 45 seconds.</img>
    </body>
    </html>
    """ % id, headers=(("FinUrl", f"/noscript_load_thing.html?id={id}"),))
    return response, 302

@app.route("/noscript_load_thing.html")
async def load_thing():
    if not request.args.get("id"):
        return "Missing id parameter", 400
    t = await youtube(3, request.args['id'], "youtube", json=False)
    return render_template("fid.html", resp=t)

@app.route("/")
async def index():
    """
+3 −6
Original line number Diff line number Diff line
@@ -7,7 +7,8 @@ import time
import typing
import re

import cachetools.func
import cachetools
import asyncache

from snscrape.base import _JSONDataclass as JSONDataclass

@@ -72,11 +73,7 @@ class Service(JSONDataclass):
        raise NotImplementedError("Subclass Service and impl the _run function")

    @classmethod
    # cache has a max of 128 items; items are cached for 600 seconds (10min)
    # important settings:
    #   maxsize=128, ttl=600
    # might add this to config.py later
    @cachetools.func.ttl_cache
    @asyncache.cached(cachetools.TTLCache(1024, 600))
    async def run(cls, id: str, includeRaw=True, **kwargs):
        """
        Retrieves the data from the service.
+34 −4
Original line number Diff line number Diff line
@@ -5,12 +5,42 @@
body {
  font-family: Ubuntu, Arial, sans-serif;
}
span > a {
  color: cyan;
}
span > a:visited {
  color: pink;
}
</style>
  </head>
  <body>
    <h1>fid is deprecated</h1>
    <i>Well, it wasn't actually ever supported, so...</i>
    <p>While I don't <i>like</i> using JavaScript for the basic site functionality, it makes stuff a lot easier and more modern-feeling.</p>
    <p>If you want to use the data in your own project, and that's why you're looking at this, the API is publicly documented. Please don't spam my servers, though - anyone that spams too much may be banned. Contact me on Discord (TheTechRobo#7420) or IRC (TheTechRobo on hackint) to discuss.</p>
    <h1>Results of id {{ resp.id }}</h1>
    {% if resp['status'] != "ok" %}
      <p>STATUS FAILED. {{resp['status']}}</p>
      {%endif%}
    <ul>
    {% for result in resp['keys'] %}
    <li>{{ result['name'] }} :
      {% if result['archived'] %}
        <span style="background-color: black;color: {{'yellow' if result.metaonly else 'green'}};">Archived {{'(metadata only)' if result.metaonly else ''}}
          {{ '(incl. comments)' if result.comments else '' }}
          {% if result['available'] %}<a href="{{result['available']}}">(link)</a>
          {% endif %}
        </span>
      {% elif result['error'] %}
        <span style="background-color: black;color: white;">Error</span>
      {% elif not result['archived'] %}
        <span style="background-color: black;color: red;">Not Archived</span>
      {% else %}
        <span style="background-color: black;color: white;">Unknown</span>
      {% endif %}
      <br>
      {{ result['note'] | safe }}
    </li>
    {%endfor%}
    </ul>
    <details><summary>Raw json</summary>
      {{resp.json()}}
    </details>
  </body>
</html>
+8 −13
Original line number Diff line number Diff line
@@ -271,25 +271,20 @@ button[disabled] {
    </script>
  </head>
  <body>
    <noscript>
<style>
.contenu, .data {
  width: 100%;
  display: none;
}
</style>
  This website requires JavaScript to function correctly.
  <br>
  I am sorry for any inconvenience this causes you.
    </noscript>
    <div id="contenu">
      <form onsubmit="finishWrpa(document.getElementById('texting').value); return false;">
        <input type="text" id="texting" placeholder="Enter video ID here..." value="{{default}}"/>
      <form onsubmit="finishWrpa(document.getElementById('texting').value); return false;" target="data-frame" action="/noscript_load.html">
        <input name="d" type="text" id="texting" placeholder="Enter video ID here..." value="{{default}}"/>
        <button action="submit" id="but" class="btn btn-primary">Search for Captures</button>
      </form>
      <span id="int"></span>
    </div>
    <div id="data">
      <noscript>
        <iframe name="data-frame" src="/noscript_init.html" style="height:100%;width:100%;">
          Your browser doesn't support JavaScript or iframes.<br />
          This website requires at least one of them.
        </iframe>
      </noscript>
      <p style="text-align: center;"><i>website created by <a href="https://thetechrobo.ca">TheTechRobo</a></i></p>
    </div>
    <div id="warning">