Files
itunes-vip-convert/convert.go

197 lines
5.3 KiB
Go

package main
import (
"fmt"
"strings"
"strconv"
"os"
"bufio"
"time"
"github.com/beevik/etree"
)
func main() {
// media locations to be replaced
itunes_media := "file://localhost/Z:/Music/usb/" // original location
web_media := "https://dtam.pw/music/tracks/" // final web location
// playlist length counter
playlist_length := 0
// temporary variables to set up and gather information
// next: will toggle so we know on the next loop to save information
name_next := false
artist_next := false
location_next := false
id_next := false
// temp: temporarily store the song information before we insert it into our array
name_temp := ""
artist_temp := ""
location_temp := ""
id_temp := ""
// struct containing a single song and it's information
type Song_Information struct {
name string
artist string
location string
id string
}
// array of the playlist, but only it's ID. when we initially parse the xml,
// it only gives us the playlist in ID form
var playlist_tracks []string
// array of the songs, but not in the correct order
var songlist []Song_Information
// array of the songs, in the correct order
var playlist []Song_Information
// import the playlist
doc := etree.NewDocument()
if err := doc.ReadFromFile("main.xml"); err != nil {
panic(err)
}
// find the playlist in it's ID form
for _, e := range doc.FindElements("./plist/dict/array/dict/array/dict/integer") {
// add track to playlist
playlist_tracks = append(playlist_tracks, e.Text())
}
// get the length of the playlist
for _, e := range doc.FindElements("./plist/dict/dict/*") {
_ = e
playlist_length += 1
}
// cycle through the playlist and grab the song information
for i := 0; i < (playlist_length/2)+1; i++ {
// based on how the xml is formatted from itunes, it has 2 separate elements for each
// key, so we need to mark when we find the key we need and say the next item is the item
for _, e := range doc.FindElements("./plist/dict/dict/dict[" + strconv.Itoa(i) + "]/*") {
// if we find an element with the name "Name", we know the next element is the actual
// name, so mark it so that we know next loop to store it
if(e.Text() == "Name") {
name_next = true
continue
}
if(e.Text() == "Artist") {
artist_next = true
continue
}
if(e.Text() == "Location") {
location_next = true
continue
}
if(e.Text() == "Track ID") {
id_next = true
continue
}
// once we have determined that this should be the information, save it
// to a temporary variable
if(name_next) {
name_temp = e.Text()
name_temp = strings.Replace(name_temp, "&", "&amp;", 5) // make the ampersand xml safe
name_next = false
continue
}
if(artist_next) {
artist_temp = e.Text()
artist_temp = strings.Replace(artist_temp, "&", "&amp;", 5)
artist_next = false
continue
}
if(location_next) {
location_temp = e.Text()
// replace the file name link with the web link
location_temp = strings.Replace(location_temp, itunes_media, web_media, 1)
location_temp = strings.Replace(location_temp, "&", "&amp;", 5)
location_next = false
continue
}
if(id_next) {
id_temp = e.Text()
id_next = false
continue
}
// once we have found all the information we need, put it into a struct and append it
// to our unordered array of songs
if(name_temp != "" && artist_temp != "" && location_temp != "" && id_temp != "") {
songlist = append(songlist, Song_Information{name_temp, artist_temp, location_temp, id_temp})
name_temp = "" // clear our variables again
artist_temp = ""
location_temp = ""
id_temp = ""
continue
}
}
}
// put our tracks in the appropriate order based on the playlist
for _, e := range playlist_tracks {
// loop through our unordered array and find the correct song
for _, f := range songlist {
if(f.id == e) {
// add the correct song to the final playlist
playlist = append(playlist, Song_Information{f.name, f.artist, f.location, f.id})
break
}
}
}
// at this point, our playlist should be sorted
// get date
currentTime := time.Now()
// create the xml file
file, err := os.OpenFile("main_parsed.xml", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
panic(err)
}
// write the initial information for the xml
w := bufio.NewWriter(file)
fmt.Fprintln(w, `<?xml version="1.0" encoding="UTF-8"?>`)
fmt.Fprintln(w, `<playlist xmlns="https://xspf.org/ns/0/" version="1">`)
fmt.Fprintln(w, "<tracklist>")
// print out information at the header
fmt.Fprintln(w, "<track>")
fmt.Fprintln(w, "<creator>dtam playlist</creator>")
fmt.Fprintln(w, "<title>" + strconv.Itoa(len(playlist_tracks)) + " tracks (Last updated: " + currentTime.Format("Jan 02, 2006") + ")</title>")
fmt.Fprintln(w, "<location>https://dtam.pw/music/empty.m4a</location>")
fmt.Fprintln(w, "</track>")
// cycle through our ordered playlist and write it to the file
for _, e := range playlist {
fmt.Fprintln(w, "<track>")
fmt.Fprintln(w, "<creator>" + e.artist + "</creator>")
fmt.Fprintln(w, "<title>" + e.name + "</title>")
fmt.Fprintln(w, "<location>" + e.location+ "</location>")
fmt.Fprintln(w, "</track>")
}
// closing information
fmt.Fprintln(w, "</tracklist>")
fmt.Fprintln(w, "</playlist>")
// write it out
w.Flush()
}