Trouble with selecting the first array element using json_select_array

Here's the code I have, see the bottom of this for the album and selection of the release array and then selecting the name which doesn't work.

In the help file, it doesn't mention whether or they are 0 or 1 based arrays. From my limited knowledge and testing of the JSON methods, I presume they're 1 based.

If anyone knows how to do this without doing a loop on the releases array then I'd greatly appreciate it.

I want to select the first releases array element and get the info from that.

[Name]=beatport.com [v5.0 by steveheroβ„’] (β—£_β—’)
[BasedOn]=https://www.beatport.com
[IndexUrl]=https://www.beatport.com/search/releases?q=%s&per-page=150&sort=release-desc
[AlbumUrl]=
[WordSeparator]=+
[IndexFormat]=% ↓ ID (β—£_β—’)β„’%|% ↓ RELEASE%|% ↓ ARTIST/S%|%_URL%
[Encoding]=url-utf-8

#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::#

[ParserScriptIndex]=...

findline "<!DOCTYPE html>"
findinline "<!DOCTYPE html>"
joinuntil "</html>"
replace "|" "$verticalBar()"
regexpreplace "(?i).*?window\.Playables\s*?=\s*?(\{.+);.*?window\.Sliders\s+=\s+\[.*" "$1"

json "ON" "current"

json_foreach "releases"

json_select "id" # ID
sayrest
say "|"

json_select "name" # RELEASES
sayrest
say "|"

json_select_many "artists" "name" " ● " # ARTIST(S)
sayrest
say "|"

say "https://www.beatport.com/release/" # PREVIEW
json_select "slug"
sayrest
json_select "id"
say "/"
sayrest

saynewline

json_foreach_end

#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::#

[ParserScriptAlbum]=...

findline "<!DOCTYPE html>"
findinline "<!DOCTYPE html>"
joinuntil "</html>"
replace "|" "$verticalBar()"
regexpreplace "(?i).*?window\.Playables\s*?=\s*?(\{.+);.*?window\.Sliders\s+=\s+\[.*" "$1"

debug "on"  "W:\Apps (Portable)\Music Apps\Mp3tag\data\sources\Beatport Pro\debug album BEATPORT.html" 20 # Place before headings to want to debug

json "ON" "current"

outputto "ALBUM"
json_select_array "releases" 1
json_select "name"
sayrest

This works:

outputto "ALBUM"
json_select_many "releases" "name" "|"
sayrest

The json is formatted from beatports pages like so:

{
  "charts": [],
  "packs": [],
  "releases": [{
    "active": true,
    "artists": [{
      "id": 2940,
      "name": "Tom Sawyer",
      "slug": "tom-sawyer"
    }],
    "audio_format": "mp3",
    "catalog": "ATSUO017",
    "component": "Release Detail",
    "component_type": null,
    "date": {
      "published": "2007-03-15",
      "released": "2007-03-15"
...

With their new website the result is actually a json data packet without the header.
Have you tried reconstructing the full json packet inserting data-json=' in front of the packet ?

Needless to say both main and classic sites are down at the moment, worth working on traxsource nowadays . Beatport behaviour handling their server downtime is baffling . Seeing so many Djs losing profit with those issues will surely create a migrating trend towards tracksource and juno I guess.

Would have help you more with your scripts but I developed my own software to automate all searches and months after months I made it almost fully independent from mp3tag. I am a former hardcore 68k programmer and hate correcting other people's bugs so I get only myself to blame. ( tag reader, json paser and so on..) it tags a track in about 5 seconds on average :slight_smile:

It's valid JSON in parsing. I've regexp'd the html stuff out beforehand. The release is an array.

I want to get the 1st index.

Is your program available to the public?

Sorry for the late reply. I was looking into the issue and so far json_select_array was assuming string elements. In you example, beatport is returning objects as array elements.

A possible solution would be to automatically select the object to the current input so that json_select would operate on the properties of this object. A call to json_unselect_object would be necessary if you want to continue operating outside of this object.

What do you think?

No worries, I don't know how you would apply that as code.

I've tried again and this works if I use json_foreach and omit the json_foreach_end but I cannot get it to work any other way.

See line 131 to 135.

[Name]=beatport.com [v5.0 by steveheroβ„’] (β—£_β—’)
[BasedOn]=https://www.beatport.com
[IndexUrl]=https://www.beatport.com/search/releases?q=
[AlbumUrl]=
[WordSeparator]=+
[IndexFormat]=% ↓ TYPE%|% ↓ EXCLUSIVE%|% ↓ ID (β—£_β—’)β„’%|% ↓ PRICE%|% ↓ RECORD LABEL%|% ↓ RELEASED%|% ↓ CATALOG%|% ↓ RELEASE%|% ↓ GENRE/S%|% ↓ R #%|% ↓ REMIXER/S%|% ↓ A #%|% ↓ ARTIST/S%|%_URL%
[Encoding]=url-utf-8

#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::#

[ParserScriptIndex]=...

findline "<!DOCTYPE html>"
findinline "<!DOCTYPE html>"
joinuntil "</html>"
replace "|" "$verticalBar()"
regexpreplace "(?i).*?window\.Playables\s*?=\s*?(\{.+);.*?window\.Sliders\s+=\s+\[.*" "$1"
regexpreplace "(\"exclusive\":\s+)(true\,)" "$1 "βœ“","
regexpreplace "(\"exclusive\":\s+)(false\,)" "$1 "β•³","
regexpreplace "(\"type\":\s+\")([^\"]+)" "$1\u$2" # Upper case first letter for release type

debug "on"  "W:\Apps (Portable)\Music Apps\Mp3tag\data\sources\Beatport Pro\debug index BEATPORT.html" 20 # Place before headings to want to debug

json "ON" "current"

json_foreach "releases"

json_select "type" # TYPE
sayrest
say "|"

json_select "exclusive" # EXCLUSIVE
sayrest
say "|"

json_select "id" # ID
sayrest
say "|"

json_select_object "price" # PRICE
json_select "display"
sayrest
json_unselect_object
say "|"

json_select_object "label" # LABEL
json_select "name"
sayrest
json_unselect_object
say "|"

json_select_object "date" # RELEASED
json_select "released"
sayrest
json_unselect_object
say "|"

json_select "catalog" # CATALOG
sayrest
say "|"

json_select "name" # RELEASES
sayrest
say "|"

json_select_many "genres" "name" " ● " # GENRES/S
sayrest
say "|"

json_foreach "remixers" # REMIXERS COUNT
ifnot "0"
sayrest
else
say "-"
endif
json_foreach_end
say "|"

json_select_many "remixers" "name" " ● " # REMIXERS/S
ifnot ""
sayrest
else
say "-"
endif
say "|"

json_foreach "artists" # ARTIST COUNT
sayrest
json_foreach_end
say "|"

json_select_many "artists" "name" " ● " # ARTIST/S
sayrest
say "|"

say "https://www.beatport.com/release/" # _URL
json_select "slug"
sayrest
json_select "id"
say "/"
sayrest

saynewline

json_foreach_end

#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::#

[ParserScriptAlbum]=...

findline "<!DOCTYPE html>"
findinline "<!DOCTYPE html>"
joinuntil "</html>"
replace "|" "$verticalBar()"
regexpreplace "(?i).*?window\.Playables\s*?=\s*?(\{.+);.*?window\.Sliders\s+=\s+\[.*" "$1"
regexpreplace "(?i)(\"exclusive\":\s+)(true\,)" "$1 "","
regexpreplace "(\"exclusive\":\s+)(true\,)" "$1 "βœ“","
regexpreplace "(\"exclusive\":\s+)(false\,)" "$1 "β•³","
regexpreplace "(\"type\":\s+\")([^\"]+)" "$1\u$2" # Upper case first letter for release type

debug "on"  "W:\Apps (Portable)\Music Apps\Mp3tag\data\sources\Beatport Pro\debug album BEATPORT.html" 20 # Place before headings to want to debug

json "ON" "current"

outputto "ALBUM"
json_foreach "releases"
json_select "name"
sayrest

# Adding this below will output all the albums but if omitted it will only get the first array.
# json_foreach_end

Surely:

json_select_array "releases" 0
json_select "name"
sayrest

should behave the same as what the foreach loop does. This is truly confusing me.

Are arrays 0 or 1 based?

You can try the latest development build Mp3tag v2.99d where I've changed the behavior of json_select_array as outlined above. A call to json_unselect_object is then necessary if you want to continue operating outside of the selected object.

json_select_array "releases" 1
json_select "name"
sayrest
json_unselect_object

The arrays are 1-based.

1 Like

Thanks, that works now. I thought it was something I was doing all along.

Ps, can you update the help page for WSS with this info along with my intial queries solution. Thanks.

1 Like