# VBML 1.0.3
#--------------------------------------------------------------------------------------------------
# Properties
#--------------------------------------------------------------------------------------------------

type: backend

source: https://raw.githubusercontent.com/omega-gg/backend/master/bittorrent.vbml

api: 1.0.3

version: 1.0.24

title: BitTorrent

cover: /cover/bittorrent.png

items:
    playlist:
        title: Tracks
    folder:
        title: Torrents & Magnets
        label: all
    folder:
        title: Torrents
    folder:
        title: Magnets

validate: .torrent$|^magnet:?

#--------------------------------------------------------------------------------------------------
# Routines
#--------------------------------------------------------------------------------------------------

TRACK_OUTPUT: |
    SET fragment (URL_FRAGMENT url)
    SET index (INDEX_END fragment '.')
    IF (NOT_EQUAL index -1)
        SET fragment (MID fragment index)
        IF (EXTENSION_IS_AUDIO fragment)
            RETURN "audio"
        FI
    FI
    RETURN "video"

PLAYLIST_INFO: |
    IF (EQUAL (URL_EXTENSION url) "torrent")
    OR (START_WITH url "magnet:?")
        SET type "playlist"
        SET id url
        RETURN true
    FI

URL_PLAYLIST: |
    RETURN id

QUERY_TRACK: |
    IF (START_WITH url "magnet:?")
        SET type "torrent"
    ELIF (NOT_EQUAL (URL_EXTENSION url) "torrent")
        RETURN false
    FI
    SET index (INDEX_END url '#')
    IF (EQUAL index -1)
        SET queryData -1
    ELSE
        SET indexB (INDEX_OF url '.' index)
        IF (EQUAL indexB -1)
            SET queryData (MID url index)
        ELSE
            SET queryData (MID url index (SUB indexB index))
        FI
        SET url (MID url 0 (SUB index 1))
    FI
    RETURN true

QUERY_PLAYLIST: |
    IF (START_WITH url "magnet:?")
        SET type "torrent"
    ELIF (NOT_EQUAL (URL_EXTENSION url) "torrent")
        RETURN false
    FI
    SET index (INDEX_END url '#')
    IF (EQUAL index -1)
        SET queryData -1
    ELSE
        SET indexB (INDEX_OF url '.' index)
        IF (EQUAL indexB -1)
            SET queryData (MID url index)
        ELSE
            SET queryData (MID url index (SUB indexB index))
        FI
        SET url (MID url 0 (SUB index 1))
    FI
    RETURN true

CREATE_QUERY: |
    IF (EQUAL method "search")
        IF (EQUAL label "tracks")
            SET backend "bittorrent"
            SET url "https://html.duckduckgo.com/html"
            SET q (SIMPLIFY q)
            SET queryData q
            IF (EQUAL (START_WITH "torrent ") false)
                SET q (PREPEND q "torrent ")
            FI
            URL_ADD_QUERY url "q" (URL_ENCODE q)
            URL_ADD_QUERY url "kl" "us-en"
            URL_ADD_QUERY url "kp" "-1"
            SET id 3
            SET header true
        ELIF (EQUAL label "all")
            SET backend "bittorrent"
            SET url "https://html.duckduckgo.com/html"
            SET q (SIMPLIFY q)
            IF (EQUAL (START_WITH "torrent ") false)
                SET q (PREPEND q "torrent ")
            FI
            URL_ADD_QUERY url "q" (URL_ENCODE q)
            URL_ADD_QUERY url "kl" "us-en"
            URL_ADD_QUERY url "kp" "-1"
            SET id 1
            SET header true
        ELIF (EQUAL label "torrents")
            SET backend "bittorrent"
            SET url "https://html.duckduckgo.com/html"
            SET q (SIMPLIFY q)
            IF (EQUAL (START_WITH "torrent ") false)
                SET q (PREPEND q "torrent ")
            FI
            URL_ADD_QUERY url "q" (URL_ENCODE q)
            URL_ADD_QUERY url "kl" "us-en"
            URL_ADD_QUERY url "kp" "-1"
            SET id 1
            SET queryData 1
            SET header true
        ELIF (EQUAL label "magnets")
            SET backend "bittorrent"
            SET url "https://html.duckduckgo.com/html"
            SET q (SIMPLIFY q)
            IF (EQUAL (START_WITH "torrent ") false)
                SET q (PREPEND q "torrent ")
            FI
            URL_ADD_QUERY url "q" (URL_ENCODE q)
            URL_ADD_QUERY url "kl" "us-en"
            URL_ADD_QUERY url "kp" "-1"
            SET id 1
            SET queryData 2
            SET header true
        FI
    ELIF (EQUAL method "related")
    AND (EQUAL label "tracks")
        IF (START_WITH q "magnet:?")
            SET type "torrent"
        FI
        SET index (INDEX_OF q '#')
        SET url (MID q 0 index)
        SET id 1
    FI

EXTRACT_TRACK: |
    SET data (READ data "ascii")
    SET data (TORRENT_LIST_AFTER data "info")
    SET name (TORRENT_STRING_AFTER data "name")
    SET items (TORRENT_ITEMS data)
    IF (EQUAL items 0)
        SET string (LATIN_TO_UTF8 name)
        IF (EQUAL (EXTENSION_IS_MEDIA (URL_EXTENSION string)) false)
            RETURN
        FI
        SET author string
    ELSE
        SET index (SUB queryData 1)
        IF (GREATER index 0)
            SET count (SUB (COUNT items) 1)
            IF (GREATER index count)
                SET index count
            FI
        ELSE
            SET index 0
        FI
        SET item (LIST_GET items index)
        SET string (LATIN_TO_UTF8 (HASH_GET item "name"))
        IF (EQUAL (EXTENSION_IS_MEDIA (URL_EXTENSION string)) false)
            RETURN
        FI
        SET author (LATIN_TO_UTF8 name)
    FI
    SET state "cover"
    SET title string
    SET feed url

EXTRACT_PLAYLIST: |
    #IF (EQUAL id 2) # Search urls
    #    SET data (READ data "utf-8")
    #    SET source (SLICE_IN data "initialize('" "'")
    #    HASH_SET next "backend" "bittorrent"
    #    HASH_SET next "url" (APPEND "https://duckduckgo.com" source)
    #    HASH_SET next "id" 3
    #    HASH_SET next "queryData" queryData
    IF (EQUAL id 3) # Extract DuckDuckGo
        # NOTE: Skipping advertisement results.
        SET index (INDEX_OF data "class=\"result results_links results_links_deep web-result")
        SET list (SLICES data "class=\"result__a\"" "</a>" index)
        FOREACH list source
            SET source (HTML_ATTRIBUTE source "href")
            # NOTE: We might get corrupted URL(s) if the 'User-Agent' is invalid.
            IF (CONTAIN source "?uddg=")
                SET source (URL_DECODE (SLICE_IN source "?uddg=" "&amp;"))
            FI
            IF (EQUAL source "")
            OR (LIST_CONTAIN urls source)
                CONTINUE
            FI
            LIST_APPEND urls source
        END
        HASH_SET next "backend" "bittorrent"
        HASH_SET next "url" "https://snowfl.com"
        HASH_SET next "id" 4
        HASH_SET next "queryData" (LIST queryData urls)
        HASH_SET next "skipError" true
    ELIF (EQUAL id 4) # Extract script
        SET index (INDEX_OF data "src=\"b.min")
        SET source (SLICE_IN data '"' '"' index)
        HASH_SET next "backend" "bittorrent"
        HASH_SET next "url" (APPEND "https://snowfl.com/" source)
        HASH_SET next "id" 5
        HASH_SET next "queryData" queryData
        HASH_SET next "skipError" true
    ELIF (EQUAL id 5) # Parse script
        SET index (INDEX_OF data "]}};var")
        SET url (APPEND "https://snowfl.com/" (SLICE_IN data '"' '"' index) '/')
        HASH_SET next "backend" "bittorrent"
        SET query (LIST_TAKE_AT queryData 0)
        SET query (SIMPLIFY (REPLACE query (REGEXP "[',.:\\-_(){}\\[\\]]") ' '))
        SET query (REPLACE query 'é' 'e')
        SET query (REPLACE query 'è' 'e')
        # NOTE: Maybe we should generate a random string instead of 'abcdefgh'.
        HASH_SET next "url" (APPEND url (URL_ENCODE query) "/abcdefgh/0/NONE/NONE/1")
        HASH_SET next "id" 6
        HASH_SET next "queryData" (LIST_TAKE_AT queryData 0)
        HASH_SET next "skipError" true
        HASH_SET next "timeout" 10000
    ELIF (EQUAL id 6) # Extract Torrents
        SET list (JSON_SPLIT data)
        FOREACH list data
            IF (CONTAIN data "\"nsfw\":true")
            OR (CONTAIN data "\"type\":\"NA\"")
                CONTINUE
            FI
            IF (LESSER (ADD (JSON_EXTRACT data "seeder") (JSON_EXTRACT data "leecher")) 4)
                CONTINUE
            FI
            SET source (JSON_EXTRACT_UTF8 data "magnet")
            IF (EQUAL source "")
                CONTINUE
            FI
            SET index (ADD index 1)
            IF (EQUAL index 10)
                BREAK
            FI
            HASH_SET query "type" "torrent"
            HASH_SET query "url" source
            HASH_SET query "id" 8
            HASH_SET query "timeout" 60000 # 1 minute
            LIST_APPEND next query
        END
        FOREACH queryData source
            HASH_SET queryUrl "backend" "bittorrent"
            HASH_SET queryUrl "url" source
            HASH_SET queryUrl "id" 7
            HASH_SET queryUrl "skipError" true
            HASH_SET queryUrl "timeout" 10000
            LIST_APPEND next queryUrl
        END
    ELIF (EQUAL id 7) # Extract sources
        SET data (HTML_EXTRACT data url (LIST "http" "|.torrent" "magnet:?"))
        SET list (HASH_GET data "sources")
        FOREACH list data
            SET data (HASH_GET data "url")
            IF (EQUAL (URL_EXTENSION data) "torrent")
                LIST_APPEND sources data
                SET index (ADD index 1)
                IF (EQUAL index 5)
                    BREAK
                FI
            FI
        END
        IF (NOT_EQUAL index 5)
            FOREACH list data
                SET data (HASH_GET data "url")
                IF (START_WITH data "magnet:?")
                    LIST_APPEND sources data
                    SET index (ADD index 1)
                    IF (EQUAL index 5)
                        BREAK
                    FI
                FI
            END
        FI
        FOREACH sources source
            IF (START_WITH source "magnet:?")
                HASH_SET query "type" "torrent"
                HASH_SET query "timeout" 60000 # 1 minute
            ELSE
                HASH_SET query "type" ""
                HASH_SET query "timeout" 10000
            FI
            HASH_SET query "url" source
            HASH_SET query "id" 8
            HASH_SET query "skipError" true
            LIST_APPEND next query
        END
    ELIF (EQUAL id 8) # Extract torrent
        IF (LENGTH data)
            SET cache data
            SET data (READ data "ascii")
            SET data (TORRENT_LIST_AFTER data "info")
            SET name (TORRENT_STRING_AFTER data "name")
            SET items (TORRENT_ITEMS data)
            IF (EQUAL (COUNT items) 0)
                HASH_SET item "id" 1
                HASH_SET item "name" name
                HASH_SET item "index" -1
                LIST_APPEND items item
            FI
            SET name (LATIN_TO_UTF8 name)
            SET folders (TORRENT_FOLDERS items)
            FOREACH folders data
                FOREACH (HASH_GET data "items") data
                    SET title (LATIN_TO_UTF8 (HASH_GET data "name"))
                    SET extension (URL_EXTENSION title)
                    IF (EXTENSION_IS_MEDIA extension)
                        SET source (APPEND url '#' (HASH_GET data "id") '.' extension)
                        HASH_SET track "source" source
                        HASH_SET track "state" "cover"
                        HASH_SET track "title" title
                        HASH_SET track "author" name
                        HASH_SET track "feed" url
                        LIST_APPEND tracks track
                    FI
                END
            END
            SET clearDuplicate true
        FI
    ELSE
        SET cache data
        SET data (READ data "ascii")
        SET data (TORRENT_LIST_AFTER data "info")
        SET name (TORRENT_STRING_AFTER data "name")
        SET items (TORRENT_ITEMS data)
        IF (EQUAL (COUNT items) 0)
            HASH_SET item "id" 1
            HASH_SET item "name" name
            HASH_SET item "index" -1
            LIST_APPEND items item
        FI
        SET name (LATIN_TO_UTF8 name)
        SET folders (TORRENT_FOLDERS items)
        FOREACH folders data
            FOREACH (HASH_GET data "items") data
                SET title (LATIN_TO_UTF8 (HASH_GET data "name"))
                SET extension (URL_EXTENSION title)
                IF (EXTENSION_IS_MEDIA extension)
                    SET itemId (HASH_GET data "id")
                    SET source (APPEND url '#' itemId '.' extension)
                    HASH_SET track "source" source
                    HASH_SET track "state" "cover"
                    HASH_SET track "title" title
                    HASH_SET track "author" name
                    HASH_SET track "feed" url
                    LIST_APPEND tracks track
                    LIST_APPEND ids itemId
                FI
            END
        END
        SET title name
        IF (EQUAL id 0)
            IF (EQUAL queryData -1)
                RETURN
            FI
            FOREACH ids id
                IF (EQUAL id queryData)
                    SET currentIndex i
                    BREAK
                FI
                SET i (ADD i 1)
            END
        ELSE
            SET clearDuplicate true
        FI
    FI

EXTRACT_FOLDER: |
    #IF (EQUAL id 0) # Search urls
    #    SET data (READ data "utf-8")
    #    SET source (SLICE_IN data "initialize('" "'")
    #    HASH_SET next "backend" "bittorrent"
    #    HASH_SET next "url" (APPEND "https://duckduckgo.com" source)
    #    HASH_SET next "id" 1
    #    HASH_SET next "queryData" queryData
    IF (EQUAL id 1) # Extract DuckDuckGo
        SET id (ADD queryData 2)
        # NOTE: Skipping advertisement results.
        SET index (INDEX_OF data "class=\"result results_links results_links_deep web-result")
        SET list (SLICES data "class=\"result__a\"" "</a>" index)
        FOREACH list source
            SET source (HTML_ATTRIBUTE source "href")
            # NOTE: We might get corrupted URL(s) if the 'User-Agent' is invalid.
            IF (CONTAIN source "?uddg=")
                SET source (URL_DECODE (SLICE_IN source "?uddg=" "&amp;"))
            FI
            IF (EQUAL source "")
            OR (LIST_CONTAIN urls source)
                CONTINUE
            FI
            HASH_SET query "backend" "bittorrent"
            HASH_SET query "url" source
            HASH_SET query "id" id
            HASH_SET query "skipError" true
            HASH_SET query "timeout" 10000
            LIST_APPEND next query
        END
    ELSE # Extract sources
        SET data (HTML_EXTRACT data url (LIST "http" "|.torrent" "magnet:?"))
        IF (EQUAL id 2)
            FOREACH (HASH_GET data "sources") data
                SET url (HASH_GET data "url")
                SET match false
                IF (EQUAL (URL_EXTENSION url) "torrent")
                    HASH_SET item "type" "playlist"
                    HASH_SET item "state" "default"
                    HASH_SET item "source" url
                    HASH_SET item "title" (APPEND "Torrent" " - " (SIMPLIFY url))
                    LIST_APPEND items item
                    SET match true
                FI
                IF (EQUAL match false)
                AND (START_WITH url "magnet:?")
                    HASH_SET item "type" "playlist"
                    HASH_SET item "state" "default"
                    HASH_SET item "source" url
                    HASH_SET item "title" (APPEND "Magnet" " - " (SIMPLIFY url))
                    LIST_APPEND items item
                FI
                IF (match)
                    SET index (ADD index 1)
                    IF (EQUAL index 5)
                        BREAK
                    FI
                FI
            END
        ELIF (EQUAL id 3)
            FOREACH (HASH_GET data "sources") data
                SET url (HASH_GET data "url")
                IF (EQUAL (URL_EXTENSION url) "torrent")
                    HASH_SET item "type" "playlist"
                    HASH_SET item "state" "default"
                    HASH_SET item "source" url
                    HASH_SET item "title" (APPEND "Torrent" " - " (SIMPLIFY url))
                    LIST_APPEND items item
                    SET index (ADD index 1)
                    IF (EQUAL index 5)
                        BREAK
                    FI
                FI
            END
        ELSE # (EQUAL id 4)
            FOREACH (HASH_GET data "sources") data
                SET url (HASH_GET data "url")
                IF (START_WITH url "magnet:?")
                    HASH_SET item "type" "playlist"
                    HASH_SET item "state" "default"
                    HASH_SET item "source" url
                    HASH_SET item "title" (APPEND "Magnet" " - " (SIMPLIFY url))
                    LIST_APPEND items item
                    SET index (ADD index 1)
                    IF (EQUAL index 5)
                        BREAK
                    FI
                FI
            END
        FI
        SET clearDuplicate true
    FI
