Skip to content

Instantly share code, notes, and snippets.

@jasantunes
Created February 7, 2019 07:59
Show Gist options
  • Save jasantunes/8d6dbe9ec1d7037fa48f4e49a401363e to your computer and use it in GitHub Desktop.
Save jasantunes/8d6dbe9ec1d7037fa48f4e49a401363e to your computer and use it in GitHub Desktop.
iTunes sync ratings (deprecated)
(*
Author: Joao Antunes
Version: 0.1
*)
property database_file : "Library:iTunes:Scripts:index_ratings.txt"
property SET_ENCODING : "export LANG=en_US.UTF-8; "
on run
set FILEDB to POSIX path of ((path to home folder as string) & database_file)
set FILETMP to POSIX path of "/tmp/tmp.file"
set global_dirty to false
tell application "iTunes"
set lib to a reference to library playlist 1
set total_tracks to (count of every track of lib)
-- DEBUG ONLY SELECTED
--set sel to selection
--repeat with t in sel
-- DEBUG ONLY SELECTED
repeat with i from 1 to total_tracks
set t to track i of lib
try
set dirty to false
set search_string to (t's artist & tab & t's album & tab & t's track number & tab) as «class utf8»
--set match to (do shell script SET_ENCODING & "egrep -in '^" & search_string & "' " & quoted form of FILEDB) as «class utf8»
set match to (do shell script SET_ENCODING & "sed -n '/" & search_string & "/{=;p;}' " & quoted form of FILEDB & " | sed '$!N;s/\\n/:/'") as «class utf8»
if match is equal to "" then
error
end if
set remote_ratings to my getRatings(match)
if remote_ratings is not equal to t's rating then set dirty to true
if dirty is true then
set remote_timestamp to my text2date(my getTimestampDate(match))
log "CHECKING: " & t's name & " (" & t's rating & ") " & tab & "date: " & remote_timestamp
-- get local timestamp
set local_timestamp to t's played date
--set local_skipped to t's skipped date
--if local_skipped is missing value then set local_skipped to local_timestamp
--if local_timestamp is missing value or local_timestamp < local_skipped then set local_timestamp to local_skipped
if t's rating is equal to 0 or local_timestamp is missing value or local_timestamp < remote_timestamp then
-- REMOTE is newer
-- update local version
log "UPDATE LOCAL: " & t's name & tab & t's rating & " -> " & remote_ratings
set t's rating to remote_ratings
set t's played date to remote_timestamp
else
-- REMOTE is older
-- update filedb info
--set t's played date to local_timestamp
log "UPDATE REMOTE: " & t's name & tab & remote_ratings & " -> " & t's rating
my updateTrackLine(FILEDB, FILETMP, match, search_string, t's name & tab & t's rating & tab & my date2text(local_timestamp))
set global_dirty to true
end if
end if
on error errMsg
log errMsg
-- append track to filedb
if t's rating > 0 then
log "REMOTE: CREATING " & t's name & " Ratings to " & t's rating
if t's played date is equal to missing value then set t's played date to current date
set newline to t's artist & tab & t's album & tab & t's track number & tab & t's name & tab & t's rating & tab & my date2text(t's played date)
if global_dirty is equal to false then
set global_dirty to true
try
do shell script SET_ENCODING & "cp " & quoted form of FILEDB & " " & quoted form of FILETMP
end try
end if
do shell script SET_ENCODING & "echo " & quoted form of newline & " >> " & quoted form of FILETMP
set global_dirty to true
end if
end try
end repeat
if global_dirty is equal to true then
-- backup old and update new
do shell script ¬
"mv " & quoted form of FILEDB & " '" & FILEDB & ".bak'; " & ¬
"mv " & quoted form of FILETMP & " " & quoted form of FILEDB
end if
display dialog "All Ratings Synchronized" buttons "OK" default button "OK"
end tell
end run
on getRatings(track_line)
set the_command to "echo " & quoted form of track_line & " | cut -f5"
return (do shell script the_command) as integer
end getRatings
on getTimestampDate(track_line)
set output to (do shell script "echo " & quoted form of track_line & " | cut -f6") as text
return output
end getTimestampDate
on date2text(the_date)
--log "CONVERTING " & the_date & " to TEXT"
set text item delimiters to ""
set yy to (year of the_date as integer)
set mm to (month of the_date as integer)
set dd to (day of the_date as integer)
set h to (hours of the_date as integer)
set m to (minutes of the_date as integer)
set s to (seconds of the_date as integer)
return yy & "." & mm & "." & dd & "." & h & "." & m & "." & s as text
end date2text
--my text2dateDate("1/2/34") --> date "Monday, January 2, 0034 12:00:00 AM"
on text2date(theDateStr)
set text item delimiters to "."
set {yy, mm, dd, h, m, s} to every text item in theDateStr
set t to current date
set {t's year, t's month, t's day, t's hours, t's minutes, t's seconds} to {yy, mm, dd, h, m, s}
set text item delimiters to ""
return t
end text2date
on updateTrackLine(FILEDB, FILETMP, match, common_data, append_data)
-- log "updateTrackLine"
-- log "MATCH: " & match
-- log "COMMON: " & common_data
-- log "APPEND: " & append_data
set line_number to (do shell script "echo " & quoted form of match & " | cut -f1 -d ':'") as integer
set the_command to "sed \"" & line_number & "s/^\\(" & common_data & "\\).*$/\\1" & append_data & "/\" " & quoted form of FILEDB & " > " & quoted form of FILETMP
set res to (do shell script SET_ENCODING & the_command) as text
log res
end updateTrackLine
on sanitize(txt)
-- set the_string to my replace_chars(the_string, "/", "\\/")
-- set the_string to my replace_chars(the_string, "&", "\\&")
set txt to my replace_chars(txt, "(", "\\(")
set txt to my replace_chars(txt, ")", "\\)")
return txt
end sanitize
on replace_chars(txt, srch, repl)
set AppleScript's text item delimiters to the srch
set the item_list to every text item of txt
set AppleScript's text item delimiters to the repl
set txt to the item_list as string
set AppleScript's text item delimiters to ""
return txt
end replace_chars
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment