Unverified Commit 92f5c175 authored by TheTechRobo's avatar TheTechRobo
Browse files

Add new API version (3) and allow selecting the API version you use

v1 is no longer supported, but you can still use v2 (in fact for now
/find/:videoid uses v2)
parent 805fcb20
Loading
Loading
Loading
Loading
+8 −9
Original line number Diff line number Diff line
@@ -5,23 +5,22 @@ from flask import Flask, render_template, request, abort

app = Flask(__name__)

@app.route("/find/<id>")
async def youtube(id):
    if not re.match(r"^[A-Za-z0-9_-]{10}[AEIMQUYcgkosw048]$", id):
        return {"status": "bad.id", "true": True, "id": None}, 400
@app.route("/api/v2/<id>")
async def youtubev2(id, site="youtube"):
    return (await lostmediafinder.YouTubeResponse.generateAsync(id)).json()

async def wrapperYT(id):
    return await lostmediafinder.YouTubeResponse.generateAsync(id)

@app.route("/api/v<int:v>/<site>/<id>")
@app.route("/api/v<int:v>/<id>")
async def findapi(v, id, site="query"):
async def youtube(v, id, site="youtube"):
    if v == 1:
        return "This API version is no longer supported.", 410
    if v != 2:
    if v not in (2, 3):
        return "Unrecognised API version", 404
    if site == "query":
        site = request.args.get("site") or abort(400)
    if site == "youtube":
        return await youtube(id)
        return (await wrapperYT(id)).coerce_to_api_version(v).json()
    return "Unrecognised site", 404

@app.route("/")
+1 −1
Original line number Diff line number Diff line
@@ -159,7 +159,7 @@ class Filmot(YouTubeService):
        capcount = int(archived)
        available = f"https://filmot.com/video/{id}" if archived else None
        return cls(
                archived=archived, capcount=capcount, error=False,
                archived=archived, capcount=capcount, error=None,
                lastupdated=lastupdated, name=cls.getName(), note="",
                rawraw=rawraw, metaonly=True, comments=False,
                available=available
+49 −5
Original line number Diff line number Diff line
@@ -46,6 +46,10 @@ class Service(JSONDataclass):
        rawraw (Any): The data used to check whether the video is archived on that particular service. For example, for GhostArchive, it would be the HTTP status code.
        metaonly (bool): True if only the metadata is archived. This value should not be relied on!
        comments (bool): True if the comments are archived. This value should not be relied on!

        =Changelog=
        API VERSION 2 -> 3:
            - The `error` attribute is now no longer a boolean; it contains an error message if an error occured and null if no error occured
    """
    archived: bool
    capcount: int
@@ -58,7 +62,7 @@ class Service(JSONDataclass):

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

    @staticmethod
    def _getFromConfig(key, key1=None):
@@ -89,11 +93,11 @@ class Service(JSONDataclass):
        except Exception as ename: # pylint: disable=broad-except
            note = f"An error occured while retrieving data from {cls.getName()}."
            print(ename)
            rawraw = f"{type(ename)}{repr(ename)}" if includeRaw else None
            rawraw = f"{type(ename)}: {repr(ename)}"
            return cls(
                    archived=False, capcount=0, error=True,
                    archived=False, capcount=0, error=rawraw,
                    lastupdated=time.time(), name=cls.getName(), note=note,
                    rawraw=rawraw, metaonly=False, comments=False,
                    rawraw=None, metaonly=False, comments=False,
                    available=None
            )

@@ -139,7 +143,47 @@ class YouTubeResponse(JSONDataclass):
    id: str
    status: str
    keys: list[YouTubeService]
    api_version: int = 2
    api_version: int = 3

    def coerce_to_api_version(self, target):
        """
        Downgrades the API version to one of your choice, then returns self.
        PLEASE NOTE! While it returns the coerced response, it itself is also downgraded.
        So:
            >>> original_response = Response(...)
            >>> original_response.api_version
            3
            >>> coerced = original_response.coerce_to_api_version(2)
            >>> coerced.api_version
            2
            >>> original_response.api_version
            2

        Arguments:
            target (int): The target API version. Must be lower than self.api_version
        """
        currentApiVersion = self.api_version
        if currentApiVersion < target:
            raise ValueError("cannot upgrade api version")
        while self.api_version != target:
            fname = f"_convert_v{self.api_version}_to_v{self.api_version-1}"
            if not hasattr(self, fname):
                raise ValueError("cannot downgrade any further")
            getattr(self, fname)()
        assert self.api_version == target
        return self

    def _convert_v3_to_v2(self):
        assert self.api_version == 3
        self.api_version = 2
        for index, service in enumerate(self.keys):
            if service.error is None:
                service.error = False
            else:
                service.rawraw = service.error
                service.error = True
            self.keys[index] = service
        return self

    @classmethod
    def _get_services(cls):