Pe8er / Playbox.widget

93 stars 25 forks source link

issue on big sur #40

Open Gtocss opened 3 years ago

Gtocss commented 3 years ago

stylus:99:27 95| left 0 96| margin 0 97| color fColor1 98| background-color white 99| width mainDimension * Scale ---------------------------------^ 100| max-width @width 101| padding 8px 102| border-radius 0 0 5px 5px cannot coerce Scale to unit at ".text" (stylus:90:3) at "#Playbox-widget-Playbox-widget-index-coffee" (stylus:177:45) while parsing file: /Users/gtocs/Library/Application Support/Übersicht/widgets/Playbox.widget/Playbox.widget/index.coffee ![Uploading Screenshot 2021-10-17 at 12.01.40 PM.png…]()

not-alaris commented 2 years ago

I have the same issue.

Soft-Bred commented 2 years ago

same here

ItsFoxDev commented 1 year ago

This isn't working because iTunes.app has been renamed to Music.app, but this fixes it:

Replace the entire lib/get current track.applescript file with this:

global artistName, songName, albumName, songRating, songDuration, currentPosition, musicapp, apiKey, songMetaFile, mypath, currentCoverURL, isLoved
set metaToGrab to {"artistName", "songName", "albumName", "songDuration", "currentPosition", "coverURL", "songChanged", "isLoved"}
property enableLogging : false --- options: true | false

set apiKey to "2e8c49b69df3c1cf31aaa36b3ba1d166"
try
    set mypath to POSIX path of (path to me)
    set AppleScript's text item delimiters to "/"
    set mypath to (mypath's text items 1 thru -2 as string) & "/"
    set AppleScript's text item delimiters to ""
on error e
    logEvent(e)
    return
end try

set songMetaFile to (mypath & "songMeta.plist" as string)

if isMusicPlaying() is true then
    my pruneCovers()
    getSongMeta()
    writeSongMeta({"currentPosition" & "##" & currentPosition})

    if didSongChange() is true then
        delay 1
        writeSongMeta({¬
            "artistName" & "##" & artistName, ¬
            "songName" & "##" & songName, ¬
            "songDuration" & "##" & songDuration, ¬
            "isLoved" & "##" & isLoved, ¬
            "songChanged" & "##" & ¬
            true})
        if didCoverChange() is true then
            set savedCoverURL to my readSongMeta({"coverURL"})
            set currentCoverURL to grabCover()
            if savedCoverURL is not currentCoverURL then writeSongMeta({"coverURL" & "##" & currentCoverURL})
        end if
        writeSongMeta({"albumName" & "##" & albumName})
    else
        writeSongMeta({¬
            "songChanged" & "##" & false, ¬
            "isLoved" & "##" & isLoved})
    end if
else
    return
end if

spitOutput(metaToGrab) as string

------------------------------------------------
---------------SUBROUTINES GALORE---------------
------------------------------------------------

on isMusicPlaying()
    set apps to {"Music", "Spotify"}
    set answer to false
    repeat with anApp in apps
        tell application "System Events" to set isRunning to (name of processes) contains anApp
        if isRunning is true then
            try
                using terms from application "Music"
                    tell application anApp
                        if player state is playing then
                            set musicapp to (anApp as string)
                            set answer to true
                        end if
                    end tell
                end using terms from
            on error e
                my logEvent(e)
            end try
        end if
    end repeat
    return answer
end isMusicPlaying

on getSongMeta()
    try
        set musicAppReference to a reference to application musicapp
        using terms from application "Music"
            try
                tell musicAppReference
                    set {artistName, songName, albumName, songDuration} to {artist, name, album, duration} of current track
                    if musicapp is "Music" then
                        set isLoved to loved of current track as string
                    else if musicapp is "Spotify" then
                        try
                            set isLoved to starred of current track as string
                        on error
                            set isLoved to "false"
                        end try
                        set songDuration to my comma_delimit(songDuration)
                    end if
                    set currentPosition to my formatNum(player position as string)
                    set songDuration to my formatNum(songDuration as string)
                end tell
            on error e
                my logEvent(e)
            end try
        end using terms from
    on error e
        my logEvent(e)
    end try
    return songDuration
end getSongMeta

on didSongChange()
    set answer to false
    try
        set currentSongMeta to artistName & songName
        set savedSongMeta to (readSongMeta({"artistName"}) & readSongMeta({"songName"}) as string)
        if currentSongMeta is not savedSongMeta then set answer to true
    on error e
        my logEvent(e)
    end try
    return answer
end didSongChange

on didCoverChange()
    set answer to false
    try
        set currentSongMeta to artistName & albumName
        set savedSongMeta to (readSongMeta({"artistName"}) & readSongMeta({"albumName"}) as string)
        if currentSongMeta is not savedSongMeta then set answer to true
        if readSongMeta({"coverURL"}) is "NA" then set answer to true
    on error e
        my logEvent(e)
    end try
    return answer
end didCoverChange

on grabCover()
    try
        if musicapp is "Music" then
            tell application "Music" to tell current track
                if exists (every artwork) then
                    my getLocaliTunesArt()
                else
                    my getLastfmArt()
                end if
            end tell
        else if musicapp is "Spotify" then
            my getSpotifyArt()
        end if
    on error e
        logEvent(e)
        set currentCoverURL to getPathItem(mypath) & "default.png"
    end try
    return currentCoverURL
end grabCover

on getLocaliTunesArt()
    tell application "Music" to tell artwork 1 of current track -- get the raw bytes of the artwork into a var
        set srcBytes to raw data
        if format is «class PNG » then -- figure out the proper file extension
            set ext to ".png"
        else
            set ext to ".jpg"
        end if
    end tell
    set fileName to (mypath as POSIX file) & "cover" & (random number from 0 to 9) & ext as string -- get the filename to ~/my path/cover.ext
    set outFile to open for access file fileName with write permission -- write to file
    set eof outFile to 0 -- truncate the file
    write srcBytes to outFile -- write the image bytes to the file
    close access outFile
    set currentCoverURL to POSIX path of fileName
    writeSongMeta({"oldFilename" & "##" & currentCoverURL})
    set currentCoverURL to getPathItem(currentCoverURL)
end getLocaliTunesArt

on getSpotifyArt()
    try
        tell application "Spotify" to set currentCoverURL to artwork url of current track
    on error e
        my logEvent(e)
        set coverDownloaded to false
        set rawXML to ""
        set currentCoverURL to "NA"
        repeat 5 times
            try
                set rawXML to (do shell script "curl 'http://ws.audioscrobbler.com/2.0/?method=album.getinfo&artist=" & my textReplace(artistName, space, "+") & "&album=" & my textReplace(albumName, space, "+") & "&api_key=" & apiKey & "'")
                delay 1
            on error e
                my logEvent(e & return & rawXML)
            end try
            if rawXML is not "" then
                try
                    set AppleScript's text item delimiters to "extralarge\">"
                    set processingXML to text item 2 of rawXML
                    set AppleScript's text item delimiters to "</image>"
                    set currentCoverURL to text item 1 of processingXML
                    set AppleScript's text item delimiters to ""
                    if currentCoverURL is "" then
                        my logEvent("Cover art unavailable." & return & rawXML)
                        set currentCoverURL to "NA"
                        set coverDownloaded to true
                    end if
                on error e
                    my logEvent(e & return & rawXML)
                end try
                set coverDownloaded to true
            end if
            if coverDownloaded is true then exit repeat
        end repeat
    end try
end getSpotifyArt

on pruneCovers()
    try
        do shell script "rm '" & readSongMeta({"oldFilename"}) & "'"
    on error e
        my logEvent(e)
    end try
end pruneCovers

on getPathItem(aPath)
    set AppleScript's text item delimiters to "/"
    set countItems to count text items of aPath
    set start to countItems - 2
    set outputPath to "/" & text items start thru -1 of aPath as string
    set AppleScript's text item delimiters to ""
    return outputPath
end getPathItem

on readSongMeta(keyNames)
    set valueList to {}
    tell application "System Events" to tell property list file songMetaFile to tell contents
        repeat with keyName in keyNames
            try
                set keyValue to value of property list item keyName
            on error e
                my logEvent("Reading song metadata" & space & e)
                my writeSongMeta({keyName & "##" & "NA"})
                set keyValue to value of property list item keyName
            end try

            copy keyValue to the end of valueList
        end repeat
    end tell
    return valueList
end readSongMeta

on writeSongMeta(keys)
    tell application "System Events"
        if my checkFile(songMetaFile) is false then
            -- create an empty property list dictionary item
            set the parent_dictionary to make new property list item with properties {kind:record}
            -- create new property list file using the empty dictionary list item as contents
            set this_plistfile to ¬
                make new property list file with properties {contents:parent_dictionary, name:songMetaFile}
        end if
        try
            repeat with aKey in keys
                set AppleScript's text item delimiters to "##"
                set keyName to text item 1 of aKey
                set keyValue to text item 2 of aKey
                set AppleScript's text item delimiters to ""
                make new property list item at end of property list items of contents of property list file songMetaFile ¬
                    with properties {kind:string, name:keyName, value:keyValue}
            end repeat
        on error e
            my logEvent(e)
        end try
    end tell
end writeSongMeta

on spitOutput(metaToGrab)
    set valuesList to {}
    repeat with metaPiece in metaToGrab
        set valuesList to valuesList & readSongMeta({metaPiece}) & " @ "
    end repeat
    set output to items 1 thru -2 of valuesList
    return output
end spitOutput

on formatNum(aNumber)
    set delimiters to {",", "."}
    repeat with aDelimiter in delimiters
        if aNumber contains aDelimiter then
            set AppleScript's text item delimiters to aDelimiter
            set outValue to text item 1 of aNumber
            set AppleScript's text item delimiters to ""
            return outValue
        end if
    end repeat
    if aNumber does not contain delimiters then return aNumber
end formatNum

on comma_delimit(this_number)
    set this_number to this_number as string
    if this_number contains "E" then set this_number to number_to_string(this_number)
    set the num_length to the length of this_number
    set the this_number to (the reverse of every character of this_number) as string
    set the new_num to ""
    repeat with i from 1 to the num_length
        if i is the num_length or (i mod 3) is not 0 then
            set the new_num to (character i of this_number & the new_num) as string
        else
            set the new_num to ("." & character i of this_number & the new_num) as string
        end if
    end repeat
    return the new_num
end comma_delimit

on number_to_string(this_number)
    set this_number to this_number as string
    if this_number contains "E+" then
        set x to the offset of "." in this_number
        set y to the offset of "+" in this_number
        set z to the offset of "E" in this_number
        set the decimal_adjust to characters (y - (length of this_number)) thru ¬
            -1 of this_number as string as number
        if x is not 0 then
            set the first_part to characters 1 thru (x - 1) of this_number as string
        else
            set the first_part to ""
        end if
        set the second_part to characters (x + 1) thru (z - 1) of this_number as string
        set the converted_number to the first_part
        repeat with i from 1 to the decimal_adjust
            try
                set the converted_number to ¬
                    the converted_number & character i of the second_part
            on error
                set the converted_number to the converted_number & "0"
            end try
        end repeat
        return the converted_number
    else
        return this_number
    end if
end number_to_string

on textReplace(sourceText, searchText, replaceText)
    set {TID, AppleScript's text item delimiters} to {AppleScript's text item delimiters, searchText}
    set textItems to every text item of sourceText
    set AppleScript's text item delimiters to replaceText
    set changedText to textItems as string
    set AppleScript's text item delimiters to TID
    return changedText
end textReplace

on encodeText(this_text, encode_URL_A, encode_URL_B, method)
    --http://www.macosxautomation.com/applescript/sbrt/sbrt-08.html
    set the standard_characters to "abcdefghijklmnopqrstuvwxyz0123456789"
    set the URL_A_chars to "$+!'/?;&@=#%><{}[]\"~`^\\|*"
    set the URL_B_chars to ".-_:"
    set the acceptable_characters to the standard_characters
    if encode_URL_A is false then set the acceptable_characters to the acceptable_characters & the URL_A_chars
    if encode_URL_B is false then set the acceptable_characters to the acceptable_characters & the URL_B_chars
    set the encoded_text to ""
    repeat with this_char in this_text
        if this_char is in the acceptable_characters then
            set the encoded_text to (the encoded_text & this_char)
        else
            set the encoded_text to (the encoded_text & encode_char(this_char, method)) as string
        end if
    end repeat
    return the encoded_text
end encodeText

on encode_char(this_char, method)
    set the ASCII_num to (the ASCII number this_char)
    set the hex_list to {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"}
    set x to item ((ASCII_num div 16) + 1) of the hex_list
    set y to item ((ASCII_num mod 16) + 1) of the hex_list
    if method is 1 then
        return ("%" & x & y) as string
    else if method is 2 then
        return "_" as string
    end if
end encode_char

on checkFile(myfile)
    try
        POSIX file myfile as alias
        return true
    on error
        return false
    end try
end checkFile

on logEvent(e)
    if enableLogging is true then
        set e to e as string
        do shell script "echo '" & (current date) & space & e & "' >> ~/Library/Logs/CurrentTrack.log"
    else
        return
    end if
end logEvent