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

type: backend

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

api: 1.0.1

version: 1.0.7

search: coverAudio

title: Last.fm

host: last.fm

cover: /cover/lastfm.png

items:
    playlist:
        title: Tracks

validate: ^last.fm

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

TRACK_ID: |
    SET url (URL_REMOVE_PREFIX url)
    IF (EQUAL (START_WITH url "last.fm/") false)
    OR (EQUAL (CONTAIN url "/_/") false)
        RETURN ""
    FI
    RETURN (URL_ELEMENTS url 3 (INDEX_END url "/music/"))

PLAYLIST_INFO: |
    SET url (URL_REMOVE_PREFIX (URL_REMOVE_EXTENSION url))
    IF (EQUAL (START_WITH url "last.fm/") false)
    OR (NOT_EQUAL (COUNT_STRING url '/') 2)
        RETURN false
    FI
    SET type "feed"
    SET id (URL_ELEMENT url (LAST_INDEX_END url '/'))
    RETURN true

URL_TRACK: |
    RETURN (APPEND "https://www.last.fm/music/" id)

URL_PLAYLIST: |
    RETURN (APPEND "https://www.last.fm/music/" id)

QUERY_SOURCE: |
    SET url (URL_REMOVE_PREFIX url)
    IF (EQUAL (START_WITH url "last.fm/") false)
    OR (EQUAL (CONTAIN url "/_/") false)
        RETURN false
    FI
    SET url (URL_ELEMENTS url 3 (INDEX_END url "/music/"))
    SET url (APPEND "https://www.last.fm/music/" url)
    RETURN true

QUERY_TRACK: |
    SET url (URL_REMOVE_PREFIX url)
    IF (EQUAL (START_WITH url "last.fm/") false)
    OR (EQUAL (CONTAIN url "/_/") false)
        RETURN false
    FI
    SET url (URL_ELEMENTS url 3 (INDEX_END url "/music/"))
    SET url (APPEND "https://www.last.fm/music/" url)
    RETURN true

QUERY_PLAYLIST: |
    SET url (URL_REMOVE_PREFIX (URL_REMOVE_EXTENSION url))
    IF (EQUAL (START_WITH url "last.fm/") false)
    OR (NOT_EQUAL (COUNT_STRING url '/') 2)
        RETURN false
    FI
    SET url (URL_ELEMENT url (LAST_INDEX_END url '/'))
    SET url (APPEND "https://www.last.fm/music/" url "/+tracks?date_preset=LAST_7_DAYS")
    RETURN true

CREATE_QUERY: |
    IF (EQUAL method "search")
        SET url (APPEND "https://www.last.fm/search/tracks?q=" q)
        SET id 1
        RETURN
    ELIF (EQUAL method "related")
        SET url (APPEND "https://www.last.fm/music/" q)
        SET id 2
        RETURN
    ELIF (NOT_EQUAL method "cover")
        RETURN
    FI
    SET q (LOWER (SIMPLIFY (REPLACE q (REGEXP "[,.:\\-_(){}\\[\\]]") ' ')))
    SET index (INDEX_OF q (REGEXP "[^0-9]"))
    IF (EQUAL index -1)
        RETURN
    FI
    SET index (INDEX_OF q (REGEXP "[^\s]") index)
    IF (EQUAL index -1)
        RETURN
    FI
    SET q (MID q index (SUB (LAST_INDEX_OF q ' ') index))
    SET url "https://www.last.fm/search/tracks"
    URL_ADD_QUERY url 'q' (URL_ENCODE q)
    SET id 1
    SET label (LOWER (SIMPLIFY (REPLACE label (REGEXP "[,.:\\-_(){}\\[\\]]") ' ')))
    SET queryData (LIST q label)

EXTRACT_SOURCE: |
    SET data (READ data "utf-8")
    SET id (SLICE_IN data "data-youtube-id=\"" '"')
    IF (EQUAL id "")
        RETURN
    FI
    HASH_SET next "backend" "youtube"
    HASH_SET next "url" (APPEND "https://www.youtube.com/watch?v=" id)

EXTRACT_TRACK: |
    SET data (READ data "utf-8")
    IF (EQUAL id 0)
        SET title (HTML_TO_UTF8 (SLICE_IN data "data-page-resource-name=\"" '"'))
        SET index (INDEX_END data "property=\"og:image\"")
        SET cover (HTML_ATTRIBUTE_UTF8 data "content" index)
        SET index (INDEX_END data "header-new-crumb")
        SET author (HTML_TO_UTF8 (SLICE_IN data "\"name\">" '<' index))
        SET feed (APPEND "https://www.last.fm" (HTML_ATTRIBUTE data "href" index))
        SET title (APPEND author " - " title)
        SET index (INDEX_END data "\"catalogue-metadata-description\"")
        # NOTE: Sometimes the duration is missing from the page.
        IF (NOT_EQUAL index -1)
            SET duration (SIMPLIFY (SLICE_IN data '>' '<' index))
            SET duration (TIME duration "m:ss")
        FI
        RETURN
    FI
    IF (EQUAL id 2)
        SET index (INDEX_END data "property=\"og:image\"")
        IF (EQUAL index -1)
            RETURN
        FI
        SET cover (HTML_ATTRIBUTE data "content" index)
    ELSE
        SET list (SLICES data "chartlist-row" "</tr>")
        SET listTitle (SPLIT (LIST_GET queryData 0) ' ')
        SET listAuthor (SPLIT (LIST_GET queryData 1) ' ')
        FOREACH list data
            #--------------------------------------------------------------------------------------
            # Match author
            #--------------------------------------------------------------------------------------
            SET index (INDEX_OF data "class=\"chartlist-artist\"")
            SET author (HTML_ATTRIBUTE_UTF8 data "title" index)
            SET author (LOWER (SIMPLIFY (REPLACE author (REGEXP "[,.:\\-_(){}\\[\\]]") ' ')))
            SET list (SPLIT author ' ')
            SET from 0
            FOREACH list valueA
                SET from (LIST_INDEX listAuthor valueA from)
                IF (EQUAL from -1)
                    SET from 0
                    FOREACH listAuthor valueB
                        SET from (LIST_INDEX list valueB from)
                        IF (EQUAL from -1)
                            BREAK
                        FI
                    END
                    BREAK
                FI
            END
            IF (EQUAL from -1)
                CONTINUE
            FI
            #--------------------------------------------------------------------------------------
            # Match title
            #--------------------------------------------------------------------------------------
            SET index (INDEX_OF data "class=\"chartlist-name\"")
            SET string (HTML_ATTRIBUTE_UTF8 data "title" index)
            SET string (LOWER (SIMPLIFY (REPLACE string (REGEXP "[,.:\\-_(){}\\[\\]]") ' ')))
            SET list (SPLIT string ' ')
            SET from 0
            FOREACH list valueA
                SET from (LIST_INDEX listTitle valueA from)
                IF (EQUAL from -1)
                    SET from 0
                    FOREACH listTitle valueB
                        SET from (LIST_INDEX list valueB from)
                        IF (EQUAL from -1)
                            BREAK
                        FI
                    END
                    BREAK
                FI
            END
            IF (EQUAL from -1)
                CONTINUE
            FI
            #--------------------------------------------------------------------------------------
            SET source (HTML_ATTRIBUTE_UTF8 data "href" index)
            HASH_SET next "url" (APPEND "https://www.last.fm" source)
            HASH_SET next "id" 2
            RETURN
        END
    FI

EXTRACT_PLAYLIST: |
    SET data (READ data "utf-8")
    IF (EQUAL id 0) # Feed
        SET title (HTML_TO_UTF8 (SLICE_IN data "data-page-resource-name=\"" '"'))
        SET index (INDEX_END data "property=\"og:image\"")
        SET cover (HTML_ATTRIBUTE_UTF8 data "content" index)
        SET list (SLICES_IN data "chartlist-play-button" "</div")
    ELIF (EQUAL id 1) # Search
        SET list (SLICES_IN data "chartlist-play-button" "</div")
    ELIF (EQUAL id 2) # Related
        SET list (SLICES_IN data "<div class=\"media-item" "</div")
    FI
    FOREACH list data
        SET source (SLICE_IN data "data-track-url=\"" '"')
        IF (EQUAL source "")
        OR (LIST_CONTAIN urls source)
            CONTINUE
        FI
        LIST_APPEND urls source
        SET name (HTML_TO_UTF8 (SLICE_IN data "data-track-name=\"" '"'))
        SET author (HTML_TO_UTF8 (SLICE_IN data "data-artist-name=\"" '"'))
        SET url (REPLACE (SLICE_IN data "src=\"" '"') (REGEXP "/300x300/|/64s/") "/ar0/")
        HASH_SET track "state" "default"
        HASH_SET track "source" (APPEND "https://www.last.fm" (HTML_TO_UTF8 source))
        HASH_SET track "title" (APPEND author " - " name)
        HASH_SET track "cover" url
        HASH_SET track "author" author
        LIST_APPEND tracks track
    END
