# VBML 1.0.1
#--------------------------------------------------------------------------------------------------
# Properties
#--------------------------------------------------------------------------------------------------

type: backend

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

api: 1.0.1

version: 1.0.11

title: SoundCloud

host: soundcloud.com

cover: /cover/soundcloud.png

items:
    playlist:
        title: Tracks
    folder:
        title: People
    folder:
        title: Playlists

validate: ^soundcloud.com

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

TRACK_ID: |
    SET url (URL_REMOVE_PREFIX url)
    IF (EQUAL (START_WITH url "soundcloud.com/") false)
    OR (CONTAIN url (REGEXP "/tracks/|/sets/|/albums/|/reposts/|/tags/|/popular/"))
        RETURN ""
    FI
    SET url (URL_ELEMENTS url 2 15)
    IF (EQUAL (COUNT_STRING url '/') 1)
        RETURN url
    ELSE
        RETURN ""
    FI

TRACK_OUTPUT: |
    RETURN "audio"

PLAYLIST_INFO: |
    SET url (URL_REMOVE_PREFIX url)
    IF (EQUAL (START_WITH url "soundcloud.com/") false)
        RETURN false
    FI
    SET url (MID url 15)
    IF (CONTAIN url (REGEXP "[.\\?#]"))
        RETURN false
    ELIF (COUNT_STRING url '/')
        IF (CONTAIN url "/sets/")
            SET type "playlist"
            SET id url
        ELSE
            RETURN false
        FI
    ELSE
        SET type "feed"
        SET id url
    FI
    RETURN true

URL_TRACK: |
    RETURN (APPEND "https://soundcloud.com/" id)

URL_PLAYLIST: |
    RETURN (APPEND "https://soundcloud.com/" id)

QUERY_SOURCE: |
    IF (EQUAL global "")
        SET id -1
        SET queryData url 0
        SET url "https://soundcloud.com"
    ELSE
        SET queryData global
    FI
    RETURN true

QUERY_TRACK: |
    RETURN true

QUERY_PLAYLIST: |
    SET source url
    SET source (URL_REMOVE_PREFIX source)
    IF (EQUAL (START_WITH source "soundcloud.com/") false)
        RETURN false
    FI
    SET source (MID source 15)
    IF (CONTAIN source (REGEXP "[.\\?#]"))
        RETURN false
    ELIF (COUNT_STRING source '/')
        IF (CONTAIN source "/sets/")
            IF (EQUAL global "")
                SET id -1
                SET queryData url 1
                SET url "https://soundcloud.com"
            ELSE
                SET id 1
                SET queryData global
            FI
        ELSE
            RETURN false
        FI
    ELSE
        IF (EQUAL global "")
            SET id -1
            SET queryData url 2
            SET url "https://soundcloud.com"
        ELSE
            SET id 2
            SET queryData global
        FI
    FI
    RETURN true

CREATE_QUERY: |
    IF (EQUAL method "search")
        IF (EQUAL label "tracks")
            SET source (APPEND "https://api-v2.soundcloud.com/search/tracks?q=" (URL_ENCODE q) \
                               "&limit=50")
            IF (EQUAL global "")
                SET url "https://soundcloud.com"
                SET id -1
                SET queryData source 0
            ELSE
                SET backend "soundcloud"
                SET url (URL_ADD_QUERY source "client_id" id)
                SET queryData global
            FI
        ELIF (EQUAL label "people")
            SET source (APPEND "https://api-v2.soundcloud.com/search/users?q=" (URL_ENCODE q) \
                               "&limit=50")
            IF (EQUAL global "")
                SET url "https://soundcloud.com"
                SET id -1
                SET queryData source 0
            ELSE
                SET backend "soundcloud"
                SET url (URL_ADD_QUERY source "client_id" id)
                SET queryData global
            FI
        ELIF (EQUAL label "playlists")
            SET source (APPEND "https://api-v2.soundcloud.com/search/playlists?q=" q \
                               "&limit=50")
            IF (EQUAL global "")
                SET url "https://soundcloud.com"
                SET id -1
                SET queryData source 1
            ELSE
                SET backend "soundcloud"
                SET url (URL_ADD_QUERY source "client_id" id)
                SET id 1
                SET queryData global
            FI
        FI
    ELIF (EQUAL method "related")
    AND (EQUAL label "tracks")
        SET source (APPEND "https://soundcloud.com/" q)
        IF (EQUAL global "")
            SET url "https://soundcloud.com"
            SET id -1
            SET queryData source 3
        ELSE
            SET url source
            SET id 3
            SET queryData global
        FI
    FI

EXTRACT_SOURCE: |
    SET data (READ data "utf-8")
    IF (EQUAL id -1)
        SET index (LAST_INDEX_OF data "<script crossorigin src=")
        HASH_SET next "backend" "soundcloud"
        HASH_SET next "url" (HTML_ATTRIBUTE_AT data (ADD index 25))
        HASH_SET next "id" -2
        HASH_SET next "queryData" queryData
    ELIF (EQUAL id -2)
        SET index (INDEX_OF data "client_id")
        SET id (HTML_ATTRIBUTE_AT data (ADD index 11))
        SET string (LIST_GET queryData 0)
        IF (START_WITH string "https://api")
            URL_ADD_QUERY string "client_id" id
        FI
        HASH_SET next "backend" "soundcloud"
        HASH_SET next "url" string
        HASH_SET next "id" (LIST_GET queryData 1)
        HASH_SET next "queryData" id
        SET backup id
    ELIF (EQUAL id 0)
        SET index (INDEX_END data "hydratable\":\"sound\"")
        SET string (JSON_EXTRACT data "data" index)
        SET id (JSON_EXTRACT_UTF8 string "id")
        HASH_SET next "backend" "soundcloud"
        HASH_SET next "url" (APPEND "https://api-v2.soundcloud.com/tracks/" id \
                                    "?client_id=" queryData)
        HASH_SET next "id" 1
        HASH_SET next "queryData" queryData
    ELIF (EQUAL id 1)
        SET url (JSON_EXTRACT data "url")
        SET url (APPEND url "?client_id=" queryData)
        SET url (APPEND url "&track_authorization=" (JSON_EXTRACT data "track_authorization"))
        HASH_SET next "backend" "soundcloud"
        HASH_SET next "url" url
        HASH_SET next "id" 2
    ELSE
        HASH_SET medias "480" (JSON_EXTRACT data "url")
    FI

EXTRACT_TRACK: |
    SET data (READ data "utf-8")
    SET index (INDEX_END data "hydratable\":\"sound\"")
    SET string (JSON_EXTRACT data "data" index)
    SET title (JSON_EXTRACT_UTF8 string "title")
    SET cover (JSON_EXTRACT string "artwork_url")
    IF (EQUAL cover "null")
        SET cover (JSON_EXTRACT string "avatar_url")
    FI
    SET cover (REPLACE cover "-large." "-t500x500.")
    SET author (JSON_EXTRACT string "user")
    SET feed (APPEND "https://soundcloud.com/" (JSON_EXTRACT author "permalink"))
    SET author (JSON_EXTRACT_UTF8 author "username")
    SET duration (JSON_EXTRACT string "duration")
    SET date (JSON_EXTRACT string "created_at")
    SET date (MID date 0 19)
    IF (CONTAIN date ' ')
        SET date (DATE date "yyyy/MM/dd hh:mm:ss")
    ELSE
        SET date (DATE date "yyyy-MM-ddThh:mm:ss")
    FI

EXTRACT_PLAYLIST: |
    SET data (READ data "utf-8")
    IF (EQUAL id -1)
        SET index (LAST_INDEX_OF data "<script crossorigin src=")
        HASH_SET next "backend" "soundcloud"
        HASH_SET next "url" (HTML_ATTRIBUTE_AT data (ADD index 25))
        HASH_SET next "id" -2
        HASH_SET next "queryData" queryData
    ELIF (EQUAL id -2)
        SET index (INDEX_OF data "client_id")
        SET id (HTML_ATTRIBUTE_AT data (ADD index 11))
        SET string (LIST_GET queryData 0)
        IF (START_WITH string "https://api")
            URL_ADD_QUERY string "client_id" id
        FI
        HASH_SET next "backend" "soundcloud"
        HASH_SET next "url" string
        HASH_SET next "id" (LIST_GET queryData 1)
        HASH_SET next "queryData" id
        SET backup id
    ELIF (EQUAL id 1) # playlist
        SET index (INDEX_END data "hydratable\":\"playlist\"")
        SET string (JSON_EXTRACT data "data" index)
        SET source (REPLACE (JSON_EXTRACT_UTF8 string "uri") "api." "api-v2.")
        SET title (JSON_EXTRACT_UTF8 string "title")
        SET index (INDEX_OF string "<img")
        SET cover (HTML_ATTRIBUTE string "src" index)
        SET cover (REPLACE cover "-large." "-t500x500.")
        # FIXME: We can't seem to be able to retrieve playlist tracks directly.
        #HASH_SET next "url" (APPEND source "?client_id=" queryData)
    ELIF (EQUAL id 2) # feed
        SET index (INDEX_END data "hydratable\":\"user\"")
        SET string (JSON_EXTRACT data "data" index)
        SET source (REPLACE (JSON_EXTRACT_UTF8 string "uri") "api." "api-v2.")
        SET title (JSON_EXTRACT_UTF8 string "username")
        SET cover (JSON_EXTRACT_UTF8 string "avatar_url")
        SET cover (REPLACE cover "-large." "-t500x500.")
        HASH_SET next "backend" "soundcloud"
        HASH_SET next "url" (APPEND source "/tracks?limit=50&client_id=" queryData)
    ELIF (EQUAL id 3) # related
        SET index (INDEX_END data "hydratable\":\"sound\"")
        SET string (JSON_EXTRACT data "data" index)
        SET id (JSON_EXTRACT_UTF8 string "id")
        HASH_SET next "backend" "soundcloud"
        HASH_SET next "url" (APPEND "https://api-v2.soundcloud.com/tracks/" id \
                                    "/related?limit=50&client_id=" queryData)
     ELSE
         SET data (JSON_EXTRACT data "collection")
         FOREACH (JSON_SPLIT data) data
             SET source (JSON_EXTRACT data "permalink")
             SET user (JSON_EXTRACT data "user")
             SET feed (APPEND "https://soundcloud.com/" (JSON_EXTRACT user "permalink"))
             HASH_SET track "source" (APPEND feed '/' source)
             HASH_SET track "title" (JSON_EXTRACT_UTF8 data "title")
             SET cover (JSON_EXTRACT data "artwork_url")
             IF (EQUAL cover "null")
                 SET cover (JSON_EXTRACT data "avatar_url")
             FI
             HASH_SET track "cover" (REPLACE cover "-large." "-t500x500.")
             HASH_SET track "feed" feed
             HASH_SET track "author" (JSON_EXTRACT_UTF8 user "username")
             HASH_SET track "duration" (JSON_EXTRACT data "duration")
             SET date (JSON_EXTRACT data "created_at")
             SET date (MID date 0 19)
             IF (CONTAIN date ' ')
                 HASH_SET track "date" (DATE date "yyyy/MM/dd hh:mm:ss")
             ELSE
                 HASH_SET track "date" (DATE date "yyyy-MM-ddThh:mm:ss")
             FI
             LIST_APPEND tracks track
         END
    FI

EXTRACT_FOLDER: |
    SET data (READ data "utf-8")
    IF (EQUAL id -1)
        SET index (LAST_INDEX_OF data "<script crossorigin src=")
        HASH_SET next "backend" "soundcloud"
        HASH_SET next "url" (HTML_ATTRIBUTE_AT data (ADD index 25))
        HASH_SET next "id" -2
        HASH_SET next "queryData" queryData
    ELIF (EQUAL id -2)
        SET index (INDEX_OF data "client_id")
        SET id (HTML_ATTRIBUTE_AT data (ADD index 11))
        SET string (LIST_GET queryData 0)
        IF (START_WITH string "https://api")
            URL_ADD_QUERY string "client_id" id
        FI
        HASH_SET next "backend" "soundcloud"
        HASH_SET next "url" string
        HASH_SET next "id" (LIST_GET queryData 1)
        HASH_SET next "queryData" id
        SET backup id
    ELSE
        SET data (JSON_EXTRACT data "collection")
        IF (EQUAL id 0) # people
            FOREACH (JSON_SPLIT data) data
                HASH_SET item "type" "feed"
                HASH_SET item "state" "default"
                HASH_SET item "source" (APPEND "https://soundcloud.com/" \
                                               (JSON_EXTRACT data "permalink"))
                HASH_SET item "title" (JSON_EXTRACT_UTF8 data "username")
                SET cover (JSON_EXTRACT data "avatar_url")
                HASH_SET item "cover" (REPLACE cover "-large." "-t500x500.")
                LIST_APPEND items item
            END
        ELSE # playlists
            FOREACH (JSON_SPLIT data) data
                HASH_SET item "type" "playlist"
                HASH_SET item "state" "default"
                HASH_SET item "source" (JSON_EXTRACT data "permalink_url")
                HASH_SET item "title" (JSON_EXTRACT_UTF8 data "permalink")
                SET cover (JSON_EXTRACT data "artwork_url")
                IF (EQUAL cover "null")
                    SET cover (JSON_EXTRACT data "avatar_url")
                FI
                HASH_SET item "cover" (REPLACE cover "-large." "-t500x500.")
                LIST_APPEND items item
            END
        FI
    FI

QUERY_FAILED: |
    SET global ""
