chylld
14-11-2006, 08:33 PM
Hi all
This is a little program i wrote that parses the iTunes library and copies all 4-star and 5-star songs out into another folder, sorted into further folders for each artist. It also renames the copied files so that they don't include characters which error (underscore) on our HU displays, like ?, *, & etc.
I wrote this because the default itunes way to burn mp3 cd's is either flat or double-nested by artist then album, which i felt didn't work well with my 06 civic HU which only has prev/next folder and prev/next track.
If you burn the resulting folder structure to cdr (or better, cdrw) you can (if ur HU operates similar to the one on my 06 civic) then use the "folder" knob to scroll through artists, and then the prev/next track buttons on the HU or on the steering wheel to scroll through songs for that artist. just seems to make better sense to me than going flat or scrolling to the "unknown album" folder all the time :)
feel free to use and/or modify the code at your own will; i trust if you know how to compile and run it, then you'll know how to change it! i've highlighted the 2 bits you'll probably need to change though.
package crumpet;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.net.URI;
import java.net.URLDecoder;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
public class Crumpet {
public static void main(String[] args) throws Exception {
new Crumpet();
}
public Crumpet() throws Exception {
parseXML("C:\\Documents and Settings\\username\\My Documents\\"+
"My Music\\iTunes\\iTunes Music Library.xml");
}
private void parseXML(String xmlFile) throws Exception {
parseTracks(getElementNodeByKey(
DocumentBuilderFactory
.newInstance()
.newDocumentBuilder()
.parse(new File(xmlFile))
.getDocumentElement()
.getElementsByTagName("dict")
.item(0),"Tracks"));
}
private void parseTracks(Node tracks) throws Exception {
NodeList children = tracks.getChildNodes();
for(int i=0;i<children.getLength();i++) {
Node n = children.item(i);
if(n.getNodeName().equals("dict")) {
parseTrack(n);
}
}
}
private void parseTrack(Node track) throws Exception {
String artist = getTextValue(getElementNodeByKey(track,"Artist"));
String name = getTextValue(getElementNodeByKey(track,"Name"));
String location = getTextValue(getElementNodeByKey(track,"Location"));
String rating = getTextValue(getElementNodeByKey(track,"Rating"));
if(rating.equals("80") || rating.equals("100")) {
String dest = "Y:\\songs\\"+artist+"\\"+name+".mp3";
fileCopy(URLDecoder.decode(location.substring(17),"UTF-8"),fileSafe(dest));
}
}
private Node getElementNodeByKey(Node node, String key) {
Node ret = null;
NodeList children = node.getChildNodes();
for(int i=0;i<children.getLength();i++) {
Node n = children.item(i);
if(n.getNodeName().equals("key") && getTextValue(n).equals(key)) {
ret = n.getNextSibling();
while(ret.getNodeType()!=Node.ELEMENT_NODE) {
ret = ret.getNextSibling();
}
}
}
return ret;
}
private String getTextValue(Node n) {
String ret = "";
if(n!=null) {
NodeList children = n.getChildNodes();
for(int i=0;i<children.getLength();i++) {
if(children.item(i).getNodeType()==Node.TEXT_NODE) {
ret += children.item(i).getNodeValue().trim();
}
}
}
return ret;
}
private void fileCopy(String src, String dest) throws Exception {
File fSrc = new File(src);
File fDest = new File(dest);
System.out.println(src+" => "+dest);
new File(dest.substring(0,dest.lastIndexOf("\\"))).mkdirs();
FileChannel in = null, out = null;
in = new FileInputStream(fSrc).getChannel();
out = new FileOutputStream(fDest).getChannel();
long size = in.size();
MappedByteBuffer buf = in.map(FileChannel.MapMode.READ_ONLY, 0, size);
out.write(buf);
in.close();
out.close();
}
private String fileSafe(String name) {
return name.replace("?","")
.replace("*","-")
.replace("(","")
.replace(")","")
.replace("'","")
.replace(",","")
.replace("&","-");
}
}
This is a little program i wrote that parses the iTunes library and copies all 4-star and 5-star songs out into another folder, sorted into further folders for each artist. It also renames the copied files so that they don't include characters which error (underscore) on our HU displays, like ?, *, & etc.
I wrote this because the default itunes way to burn mp3 cd's is either flat or double-nested by artist then album, which i felt didn't work well with my 06 civic HU which only has prev/next folder and prev/next track.
If you burn the resulting folder structure to cdr (or better, cdrw) you can (if ur HU operates similar to the one on my 06 civic) then use the "folder" knob to scroll through artists, and then the prev/next track buttons on the HU or on the steering wheel to scroll through songs for that artist. just seems to make better sense to me than going flat or scrolling to the "unknown album" folder all the time :)
feel free to use and/or modify the code at your own will; i trust if you know how to compile and run it, then you'll know how to change it! i've highlighted the 2 bits you'll probably need to change though.
package crumpet;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.net.URI;
import java.net.URLDecoder;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
public class Crumpet {
public static void main(String[] args) throws Exception {
new Crumpet();
}
public Crumpet() throws Exception {
parseXML("C:\\Documents and Settings\\username\\My Documents\\"+
"My Music\\iTunes\\iTunes Music Library.xml");
}
private void parseXML(String xmlFile) throws Exception {
parseTracks(getElementNodeByKey(
DocumentBuilderFactory
.newInstance()
.newDocumentBuilder()
.parse(new File(xmlFile))
.getDocumentElement()
.getElementsByTagName("dict")
.item(0),"Tracks"));
}
private void parseTracks(Node tracks) throws Exception {
NodeList children = tracks.getChildNodes();
for(int i=0;i<children.getLength();i++) {
Node n = children.item(i);
if(n.getNodeName().equals("dict")) {
parseTrack(n);
}
}
}
private void parseTrack(Node track) throws Exception {
String artist = getTextValue(getElementNodeByKey(track,"Artist"));
String name = getTextValue(getElementNodeByKey(track,"Name"));
String location = getTextValue(getElementNodeByKey(track,"Location"));
String rating = getTextValue(getElementNodeByKey(track,"Rating"));
if(rating.equals("80") || rating.equals("100")) {
String dest = "Y:\\songs\\"+artist+"\\"+name+".mp3";
fileCopy(URLDecoder.decode(location.substring(17),"UTF-8"),fileSafe(dest));
}
}
private Node getElementNodeByKey(Node node, String key) {
Node ret = null;
NodeList children = node.getChildNodes();
for(int i=0;i<children.getLength();i++) {
Node n = children.item(i);
if(n.getNodeName().equals("key") && getTextValue(n).equals(key)) {
ret = n.getNextSibling();
while(ret.getNodeType()!=Node.ELEMENT_NODE) {
ret = ret.getNextSibling();
}
}
}
return ret;
}
private String getTextValue(Node n) {
String ret = "";
if(n!=null) {
NodeList children = n.getChildNodes();
for(int i=0;i<children.getLength();i++) {
if(children.item(i).getNodeType()==Node.TEXT_NODE) {
ret += children.item(i).getNodeValue().trim();
}
}
}
return ret;
}
private void fileCopy(String src, String dest) throws Exception {
File fSrc = new File(src);
File fDest = new File(dest);
System.out.println(src+" => "+dest);
new File(dest.substring(0,dest.lastIndexOf("\\"))).mkdirs();
FileChannel in = null, out = null;
in = new FileInputStream(fSrc).getChannel();
out = new FileOutputStream(fDest).getChannel();
long size = in.size();
MappedByteBuffer buf = in.map(FileChannel.MapMode.READ_ONLY, 0, size);
out.write(buf);
in.close();
out.close();
}
private String fileSafe(String name) {
return name.replace("?","")
.replace("*","-")
.replace("(","")
.replace(")","")
.replace("'","")
.replace(",","")
.replace("&","-");
}
}